首页 > 其他分享 >LangChain4j-RAG高级-检索增强器

LangChain4j-RAG高级-检索增强器

时间:2024-07-28 23:26:53浏览次数:11  
标签:检索 RAG LangChain4j builder 增强器 Content dataSource Query build

Retrieval Augmentor 检索增强器

RetrievalAugmentor 是 RAG 管道的入口点。它负责使用从各种来源检索的相关 Content 来扩充 ChatMessage

可以在创建 AiService 期间指定 RetrievalAugmentor 的实例:

Assistant assistant = AiServices.builder(Assistant.class)
    ...
    .retrievalAugmentor(retrievalAugmentor)
    .build();

每次调用 AiService 时,都会调用指定的 RetrievalAugmentor 来扩充当前的 UserMessage

可以使用LangChain4j中提供的 RetrievalAugmentor 的默认实现(DefaultRetrievalAugmentor) 或 实现自定义实现。

Default Retrieval Augmentor 默认检索增强器

LangChain4j 提供了RetrievalAugmentor接口的现成实现: DefaultRetrievalAugmentor ,它应该适合大多数 RAG 用例。

官方使用示例:

public class _04_Advanced_RAG_with_Metadata_Example {

    /**
     * Please refer to {@link Naive_RAG_Example} for a basic context.
     * <p>
     * Advanced RAG in LangChain4j is described here: https://github.com/langchain4j/langchain4j/pull/538
     * <p>
     * This example illustrates how to include document source and other metadata into the LLM prompt.
     */

    public static void main(String[] args) {

        Assistant assistant = createAssistant("documents/miles-of-smiles-terms-of-use.txt");

        // Ask "What is the name of the file where cancellation policy is defined?".
        // Observe how "file_name" metadata entry was injected into the prompt.
        startConversationWith(assistant);
    }

    private static Assistant createAssistant(String documentPath) {

        Document document = loadDocument(toPath(documentPath), new TextDocumentParser());

        EmbeddingModel embeddingModel = new BgeSmallEnV15QuantizedEmbeddingModel();

        EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();

        EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
                .documentSplitter(DocumentSplitters.recursive(300, 0))
                .embeddingModel(embeddingModel)
                .embeddingStore(embeddingStore)
                .build();

        ingestor.ingest(document);

        ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
                .embeddingStore(embeddingStore)
                .embeddingModel(embeddingModel)
                .build();

        // Each retrieved segment should include "file_name" and "index" metadata values in the prompt
        ContentInjector contentInjector = DefaultContentInjector.builder()
                // .promptTemplate(...) // Formatting can also be changed
                .metadataKeysToInclude(asList("file_name", "index"))
                .build();

        RetrievalAugmentor retrievalAugmentor = DefaultRetrievalAugmentor.builder()
                .contentRetriever(contentRetriever)
                .contentInjector(contentInjector)
                .build();

        ChatLanguageModel chatLanguageModel = OpenAiChatModel.builder()
                .apiKey(OPENAI_API_KEY)
                .baseUrl(OPENAI_API_URL)
                .logRequests(true)
                .build();

        return AiServices.builder(Assistant.class)
                .chatLanguageModel(chatLanguageModel)
                .retrievalAugmentor(retrievalAugmentor)
                .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
                .build();
    }
}

源码逻辑梳理:

  • 用户在定义AiService的时候需要设置是否需要检索增强器
  • 在触发AiService的调用的时候会在invoke()函数中检查是否有添加RetrievalAugmentor增强器
  • 如果有则会调用context.retrievalAugmentor.augment(augmentationRequest)Query进行处理:

  • augment()方法中使用的QueryTransformer有三种实现类:
    • DefaultQueryTransformer: 默认的转换器,不会对Query做任何处理,而是封装成集合后返回。
    • ExpandingQueryTransformer: 扩展转换器,对Query进行措辞的修改和拆分为多个(默认3个)具体的Query,达到增强效果。
    • CompressingQueryTransformer压缩转换器,根据提供的历史聊天和当前提问内容,LLM理解后会给出更精确的提问。

Query

Query表示 RAG 管道中的用户查询。它包含查询文本和查询元数据。

Query Metadata 查询元数据

Query中的Metadata包含可能对 RAG 管道的各个组件有用的信息,例如:

  • Metadata.userMessage() - 应该增强的原始UserMessage
  • Metadata.chatMemoryId() - @MemoryId注释的方法参数的值。这可用于识别用户并在检索期间应用访问限制或过滤器。
  • Metadata.chatMemory() - 所有历史的ChatMessages 。这可以帮助理解提出Query的上下文。

Query Transformer 查询转换

QueryTransformer将给定的Query转换为一个或多个Query 。目标是通过修改扩展原始Query来提高检索质量。

一些已知的改进检索的方法包括:

  • Query compression 查询压缩
  • Query expansion 查询扩展
  • Query re-writing 查询重写
  • Step-back prompting 后退提示
  • Hypothetical document embeddings (HyDE) 假设文档嵌入

Content

Content表示与用户Query相关的内容。目前,它仅限于文本内容(即TextSegment ),但将来它可能支持其他模式(例如,图像、音频、视频等)。

Content Retriever 内容检索

ContentRetriever使用给定的Query从底层数据源检索Content 。底层数据源几乎可以是任何东西:

  • Embedding store 陷入存储
  • Full-text search engine 全文搜索引擎
  • Hybrid of vector and full-text search 矢量和全文搜索的混合
  • Web Search Engine 网络搜索引擎
  • Knowledge graph 知识图谱
  • SQL database SQL数据库

Embedding Store Content Retriever 嵌入存入内容检索

EmbeddingStoreContentRetriever使用EmbeddingModel来嵌入QueryEmbeddingStore检索相关Content

使用示例:

EmbeddingStore embeddingStore = ...
EmbeddingModel embeddingModel = ...

ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
    .embeddingStore(embeddingStore)
    .embeddingModel(embeddingModel)
    .maxResults(3)
     // maxResults can also be specified dynamically depending on the query
    .dynamicMaxResults(query -> 3)
    .minScore(0.75)
     // minScore can also be specified dynamically depending on the query
    .dynamicMinScore(query -> 0.75)
    .filter(metadataKey("userId").isEqualTo("12345"))
    // filter can also be specified dynamically depending on the query
    .dynamicFilter(query -> {
        String userId = getUserId(query.metadata().chatMemoryId());
        return metadataKey("userId").isEqualTo(userId);
    })
    .build();

Web Search Content Retriever 网络搜索内容

WebSearchContentRetriever使用WebSearchEngine从网络检索相关Content

目前WebSearchEngine接口有 2 个实现:

  • langchain4j-web-search-engine-google-custom模块中的GoogleCustomWebSearchEngine
  • langchain4j-web-search-engine-tavily模块中的TavilyWebSearchEngine

使用示例:

WebSearchEngine googleSearchEngine = GoogleCustomWebSearchEngine.builder()
        .apiKey(System.getenv("GOOGLE_API_KEY"))
        .csi(System.getenv("GOOGLE_SEARCH_ENGINE_ID"))
        .build();

ContentRetriever contentRetriever = WebSearchContentRetriever.builder()
        .webSearchEngine(googleSearchEngine)
        .maxResults(3)
        .build();

SQL Database Content Retriever SQL数据库内容检索

SqlDatabaseContentRetrieverContentRetriever实验性实现,可以在langchain4j-experimental-sql模块中找到。后续可能会删除或改动较大,所以并不推荐直接使用到生产。

它使用DataSourceLLM为给定的自然语言Query生成并执行 SQL 查询。

使用示例:

public class _10_Advanced_RAG_SQL_Database_Retreiver_Example {


    /**
     * Please refer to {@link Naive_RAG_Example} for a basic context.
     * <p>
     * Advanced RAG in LangChain4j is described here: https://github.com/langchain4j/langchain4j/pull/538
     * <p>
     * This example demonstrates how to use SQL database content retriever.
     * <p>
     * WARNING! Although fun and exciting, {@link SqlDatabaseContentRetriever} is dangerous to use!
     * Do not ever use it in production! The database user must have very limited READ-ONLY permissions!
     * Although the generated SQL is somewhat validated (to ensure that the SQL is a SELECT statement),
     * there is no guarantee that it is harmless. Use it at your own risk!
     * <p>
     * In this example we will use an in-memory H2 database with 3 tables: customers, products and orders.
     * See "resources/sql" directory for more details.
     * <p>
     * This example requires "langchain4j-experimental-sql" dependency.
     */

    public static void main(String[] args) {

        Assistant assistant = createAssistant();

        // You can ask questions such as "How many customers do we have?" and "What is our top seller?".
        startConversationWith(assistant);
    }

    private static Assistant createAssistant() {

        DataSource dataSource = createDataSource();

        ChatLanguageModel chatLanguageModel = OpenAiChatModel.withApiKey(OPENAI_API_KEY);

        ContentRetriever contentRetriever = SqlDatabaseContentRetriever.builder()
                .dataSource(dataSource)
                .chatLanguageModel(chatLanguageModel)
                .build();

        return AiServices.builder(Assistant.class)
                .chatLanguageModel(chatLanguageModel)
                .contentRetriever(contentRetriever)
                .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
                .build();
    }

    private static DataSource createDataSource() {

        JdbcDataSource dataSource = new JdbcDataSource();
        dataSource.setURL("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
        dataSource.setUser("sa");
        dataSource.setPassword("sa");

        String createTablesScript = read("sql/create_tables.sql");
        execute(createTablesScript, dataSource);

        String prefillTablesScript = read("sql/prefill_tables.sql");
        execute(prefillTablesScript, dataSource);

        return dataSource;
    }

    private static String read(String path) {
        try {
            return new String(Files.readAllBytes(toPath(path)));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static void execute(String sql, DataSource dataSource) {
        try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement()) {
            for (String sqlStatement : sql.split(";")) {
                statement.execute(sqlStatement.trim());
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

Azure AI Search Content Retriever Azure AI 搜索内容检索

AzureAiSearchContentRetriever可以在langchain4j-azure-ai-search模块中找到。

Neo4j Content Retriever Neo4j 内容检索

Neo4jContentRetriever可以在langchain4j-neo4j模块中找到。

Query Router 查询路由

QueryRouter负责将Query路由到适当的ContentRetriever

Default Query Router 默认查询路由

DefaultQueryRouterDefaultRetrievalAugmentor中使用的默认实现。它将每个Query路由到所有配置的ContentRetriever

Language Model Query Router 大语言模型查询路由

LanguageModelQueryRouter使用LLM决定将给定的Query路由到何处。

标签:检索,RAG,LangChain4j,builder,增强器,Content,dataSource,Query,build
From: https://blog.csdn.net/Box_clf/article/details/140758017

相关文章

  • 手把手教你集成GraphRag.Net:打造智能图谱搜索系统
        在人工智能和大数据发展的背景下,我们常常需要在项目中实现知识图谱的应用,以便快速、准确地检索和使用信息。        今天,我将向大家详细介绍如何在一个新的.NET项目中集成GraphRag.Net,这是一个参考GraphRag实现的.NET版本,能够实现图谱数据的存储、检索、和问......
  • 稠密向量+稀疏向量+全文搜索+张量重排=最佳检索RAG?
    RAG中的混合检索如下图:为什么要混合搜索(multi-wayrecall)?越来越多的人认为,仅仅依靠向量搜索,通常是密集向量,可能并不总是产生令人满意的结果。当用户的特定查询关键字与存储的数据不精确匹配时,这种限制就会变得明显。这是因为向量本身不能表示精确的语义信息:向量可以表示一......
  • 【活动预告】Easysearch 结合大模型实现 RAG
    2024搜索客社区Meetup首期线上活动正式启动,本次活动由搜索客社区、极限科技(INFINILabs)联合举办,诚邀广大搜索技术开发者和爱好者参加交流学习。活动时间:2024年7月31日19:30-20:30(周三)活动形式:微信视频号(极限实验室)直播报名方式:关注或扫码海报中的二维码进行预约活......
  • RAG关键技术及未来趋势
    “在当今科技领域,RAG关键技术的重要性日益凸显,让我们一同探讨它的未来趋势。”1、如何进行检索增强?RAG系统中主要包含三个核心部分,分别是“检索”,“增强”和“生成”。正好也对应的RAG中的三个首字母。想要构建一个好的RAG系统,增强部分是核心,则需要考虑三个关键......
  • [二、状态管理]3管理应用拥有的状态(3)AppStorage:应用全局的UI状态存储
    AppStorage是应用全局的UI状态存储,是和应用的进程绑定的,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。和AppStorage不同的是,LocalStorage是页面级的,通常应用于页面内的数据共享。而AppStorage是应用级的全局状态共享,还相当于整个应用的“中枢”,持久化数据Pers......
  • [二、状态管理]3管理应用拥有的状态(2)LocalStorage:页面级UI状态存储
    LocalStorage是页面级的UI状态存储,通过@Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility实例内,在页面间共享状态。本文仅介绍LocalStorage使用场景和相关的装饰器:@LocalStorageProp和@LocalStorageLink。说明本模块从APIver......
  • 基于《红楼梦·元春省亲》 测试GraphRAG的问答效果
    一、GraphRAG基本介绍GraphRAG是一种基于图的检索增强方法,由微软开发并在2024年7月初开源,最为新鲜热乎的知识图谱与大模型融合的前沿开源技术。它通过结合LLM和图机器学习的技术,从非结构化的文本中提取结构化的数据,构建知识图谱,以支持问答、摘要等多种应用场景。GraphRAG的特色......
  • 使用RAG-GPT快速搭建LangChain官网智能客服
    引言随着GPT等大型语言模型(LLM)能力越来越强大,如何将这些模型精准地应用于特定垂直领域,让各行业开发者快速利用LLM赋能也成为热点和痛点。众所周知,LLM在处理超出其训练数据或涉及最新实事时,常会产生“幻觉”现象,简单理解就是会出现一本正经的胡说八道,回答不准确。针对此问题......
  • langchain4j:用LLM的强大功能为Java应用程序赋能
    吾名爱妃,性好静亦好动。好编程,常沉浸于代码之世界,思维纵横,力求逻辑之严密,算法之精妙。亦爱篮球,驰骋球场,尽享挥洒汗水之乐。且喜跑步,尤钟马拉松,长途奔袭,考验耐力与毅力,每有所进,心甚喜之。 吾以为,编程似布阵,算法如谋略,需精心筹谋,方可成就佳作。篮球乃团队之艺,协作共进,方显力......
  • 所见即所得,赋能RAG:PDF解析里的段落识别
    前几天,有一位用户使用OCR产品识别多栏论文后向我们询问:要怎么解决不合适的断句、分段以及错误阅读顺序的问题?我们用一个相似案例为大家直观展示这位用户遇到的情况。 如图中的多栏期刊,如果用OCR识别,或直接在一些办公软件对文字进行复制黏贴,我们就会得到右侧的效果——按PDF排......