LangChain4j-RAG高级-检索增强器

news2024/11/18 11:27:21

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路由到何处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1955601.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql-覆盖索引和前缀索引

一.SQL提示 SQL提示,是优化数据库的一个重要手段,简单来说&#xff0c;就是在SQL语句加入一些人为的提示来达到 二.覆盖索引 尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到),减少select* 知识小贴士: using index condition :查找…

chk是什么文件格式 chk文件怎么恢复正常 chkdsk文件损坏怎么修复

在使用电脑和移动存储设备时&#xff0c;有时我们会发现磁盘中出现了大量的chk文件。这些chk文件无法打开&#xff0c;也无法得知其原本内容。那么&#xff0c;这些chk文件是什么呢&#xff1f;又该如何将chk文件恢复正常呢&#xff1f; chk文件是什么&#xff1f; 在我们查看…

环境搭建-Docker搭建ClickHouse

Docker搭建ClickHouse 一、前言二、ClickHouse安装2.1 拉取镜像运行ClickHouse服务 三、测试安装3.1 进入clickhouse容器3.2 命令补充说明 四、测试连接五、设置CK的用户名密码 一、前言 本文使用的Docker使用Windows搭建&#xff0c;Linux版本的搭建方式一样。 Windows系统搭…

【HarmonyOS】HarmonyOS NEXT学习日记:七、页面与组件的生命周期

【HarmonyOS】HarmonyOS NEXT学习日记&#xff1a;七、页面与组件的生命周期 页面和组件 组件&#xff1a;用Component装饰的代码称为自定义组件页面&#xff1a;Entry装饰的组件即页面的根节点 组件生命周期 aboutToAppear&#xff1a;在创建自定义组件的新实例后&#xf…

GPS定位系统(VUE框架)

源码下载&#xff1a;小宅博客网 博主之前写的《GPS定位系统&#xff08;MVC框架&#xff09;》版本&#xff0c;并没有做到前后端分离&#xff0c;不太适合多人协作开发&#xff0c;这边博主分享一个基于asp.net web api vue3的GPS定位系统框架&#xff0c;本框架继承了MVC框…

【Hot100】LeetCode—416. 分割等和子集

目录 题目1- 思路2- 实现⭐152. 乘积最大子数组——题解思路 3- ACM 实现 题目 原题连接&#xff1a;416. 分割等和子集 1- 思路 理解为背包问题 思路&#xff1a; 能否将均分的子集理解为一个背包&#xff0c;比如对于 [1,5,11,5]&#xff0c;判断能否凑齐背包为 11 的容量…

【shell】shell循环的几种方式

Shell循环的方式 for循环 for 变量名 in 值列表 do命令1命令2... done值列表情形&#xff1a; 值铺开变量数组 值铺开 变量 数组 while循环 while 条件判断 do命令1命令2... done条件判断情形 计算比较读取文本 计算比较 读取文本 until循环 until 条件 do命令1命令2... …

Imagination 面向大学推出 RISC-V 课程

Imagination Technologies发布了针对本科教学的 RISC-V 计算机架构完整课程&#xff0c;帮助学生了解处理器架构的关键元素&#xff0c;包括知识产权 (IP) 内核、修改 RISC-V 内核及其微架构。 该课程名为“RVfpga&#xff1a;理解计算机架构”&#xff0c;包含教学材料和实践…

【C++指南】类和对象(下)

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法》 期待您的关注

论文阅读_字节的语音生成模型_Seed-TTS

英文名称: Seed-TTS: A Family of High-Quality Versatile Speech Generation Models 中文名称: Seed-TTS&#xff1a;高质量多功能语音生成模型系列 链接: http://arxiv.org/abs/2406.02430v1 代码: https://github.com/BytedanceSpeech/seed-tts-eval (评测工具) 演示网站&am…

shell-awk命令详解

目录 一.概述 二.工作原理 三.工作流程 1.运行模式 2.运行流程 四.基本语法 1.命令格式 2.常用变量  五.变量类型 1.内建变量 2.内置变量 3.BEGIN END运算  4.awk高级用法 5.awk if语句 6.BEGIN END循环 一.概述 AWK是一种处理文本文件的语言&#xff0c;是一…

深入分析 Android ContentProvider (六)

文章目录 深入分析 Android ContentProvider (六)ContentProvider 的性能优化和实践案例&#xff08;续&#xff09;1. 性能优化技巧&#xff08;续&#xff09;1.6. 使用批量插入优化性能示例&#xff1a;批量插入实现 1.7. 使用 Projections 优化查询示例&#xff1a;使用 Pr…

Webpack 从入门到精通

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 一、Webpack 简介 二、Webpack 的核心概念 三、Webpack 的安装与配置 安装 Node.js 安装 Webpack 初始…

【Linux C | 网络编程】进程池退出的实现详解(五)

上一篇中讲解了在进程池文件传输的过程如何实现零拷贝&#xff0c;具体的方法包括使用mmap&#xff0c;sendfile&#xff0c;splice等等。 【Linux C | 网络编程】进程池零拷贝传输的实现详解&#xff08;四&#xff09; 这篇内容主要讲解进程池如何退出。 1.进程池的简单退…

超越基础功能:项目进度管理工具深度评测

国内外主流的10款项目进度管理网站对比&#xff1a;PingCode、Worktile、滴答清单&#xff08;TickTick&#xff09;、Todoist、NarTick、Teambition、Monday.com、Asana、ClickUp、Trello。 在选择合适的项目进度管理工具时&#xff0c;许多项目经理面临着如何找到既能满足团队…

二十二、作业

目录 1.求代码结果 2.求代码结果 3.使用指针打印数组内容 4.字符串逆序 5.计算求和 6.打印水仙花数 7.打印菱形 8.喝汽水问题 1.求代码结果 输出为00345 2.求代码结果 任何一个变量/表达式&#xff0c;都有2个属性&#xff0c;值属性和类型属性 int a 3&#xff1b;…

Python及Jupyter-Notebook安装

来源&#xff1a; “码农不会写诗”公众号 链接&#xff1a;Python及Jupyter-Notebook安装 文章目录 01 Python安装1.1 下载安装包1.2 双击安装包&#xff0c;开始安装1.3 选择安装配置1.4 选择需要安装的Optional Feature&#xff0c;点击Next1.5 选择需要安装的Advanced Feat…

matplotlib的科研绘图辅助

matplotlib的科研绘图辅助 趁着暑假&#xff0c;与和鲸科技合作了一个python绘图的教程&#xff0c;作为暑期夏令营的一小部分&#xff0c;主要内容是介绍如何使用matplotlib、pandas、seaborn和plotnine进行医学科研绘图&#xff0c;感兴趣的可以通过如下地址进行访问&#x…

Unity XR Interaction Toolkit设置或监听手柄按键事件(三)

提示&#xff1a;文章有错误的地方&#xff0c;还望诸位大神不吝指教&#xff01; 文章目录 前言一、XRI Default Input Actions1.导入官方案例2.设置控制器绑定&#xff0c;如手柄、主/辅助按钮、操纵杆等1.要设置控制器绑定&#xff0c;如左右手 手柄、主/辅助按钮、操纵杆等…

添加sidecar容器并输出日志

添加一个sidecar容器(使用busybox 镜像)到已有的pod 11-factor-app中,确保sidecar容器能够输出/var/log/11-factor-app.log的信息,使用volume挂载/var/log目录,确保sidecar能访问11-factor-app.log 文件 # 准备工作 创建一个 pod 11-factor-appapiVersion: v1 kind: Pod metada…