Skip to main content
基于 LLM 的最强大的应用之一是复杂的问答(Q&A)聊天机器人,它通过向 LLM 提供推理时访问数据集的方式增强 LLM。 这可能涉及私有数据、最新数据,或不是 LLM 训练数据集一部分的数据。 这些应用使用一种称为检索增强生成(Retrieval Augmented Generation,简称 RAG 的技术。 :::python Deep Agents 为 RAG 提供了基础组件:自定义检索工具、文件系统后端、子智能体、技能 和 评分标准。你可以根据语料库大小、延迟需求和答案必须严格基于源数据的程度,以不同的方式组合它们。 ::: :::js Deep Agents 为 RAG 提供了基础组件:自定义检索工具、文件系统后端、子智能体 和 技能。你可以根据语料库大小、延迟需求和答案必须严格基于源数据的程度,以不同的方式组合它们。 ::: 本指南介绍了多种 RAG 模式,并通过一个端到端示例进行说明:一个文档问答智能体,它索引 docs.langchain.com 的一个子集,在查询时检索相关片段,将它们卸载到文件系统,并将分析委托给子智能体,以便协调器上下文保持清晰。

RAG 模式

Deep Agents 允许你以多种方式编排检索、分析和综合:
  • 技能引导检索:用户提出问题。智能体加载一个描述如何搜索你语料库的相关技能(使用哪个索引、查询格式化、引用格式)。智能体按照该指导调用你的检索工具,然后综合答案。
  • 评分标准检查的依据:用户提出问题。智能体检索证据并起草答案。一个配置了 RubricMiddleware 的评分标准子智能体评估响应是否基于检索的源材料。智能体会修改,直到评分标准通过或达到迭代上限。
  • 任务驱动调查:用户提出问题。如果你 选择参与任务规划,智能体将使用规划工具创建一个待办事项列表,包括要调查的文档页面或搜索查询。它检索每个项目的结果,然后从收集的证据中综合答案。
  • 检索、卸载和委托:用户提出问题。智能体检索匹配的片段并将它们写入文件系统后端,而不是在协调器上下文中保留完整文本。子智能体并行读取、搜索和总结单个文件。对于大文档,智能体可以使用内置搜索工具翻页浏览文件,或运行 代码解释器 从源数据生成表格、时间线或可视化内容。
:::python
评分标准需要 deepagents>=0.6.5,目前处于 测试阶段。
::: 本教程实现了 检索、卸载和委托 模式。其他模式中也出现了相同的原语:技能通常包装检索工作流,评分标准可以对这些流程进行评分,而选择性的待办事项规划有助于将复杂问题分解为专注的搜索。

检索的重要性

语言模型本身无法访问您的文档。如果您向它询问最近更改的特定 API,它将根据训练数据回答:通常合理,有时错误,并且从未基于您的真实来源。 即使文档可用,您通常也无法将所有内容都放入上下文窗口中。因此,您必须仅选择与给定问题相关的段落,而本身就是一个非平凡的任务。 本教程始终使用一个问题:
如何从子智能体流式传输中间工具结果?
将此问题传递给一个没有自定义工具且无法访问文档语料库的 Deep Agent,看看模型会提出什么: :::python

View example trace

为此示例打开一个公开的 LangSmith 运行。
::: :::js

View example trace

为此示例打开一个公开的 LangSmith 运行。
::: 没有检索,智能体无法查找当前的 LangChain 文档。响应往往比较通用,可能遗漏诸如 subagent streaming 等指导,或包含过时的信息。 本教程中的示例索引了 LangChain 文档,使用向量搜索工具检索证据,并行分析每个片段,并使用文档中的引用来回答问题。

您将构建的内容

  1. 索引:将 LangChain 文档加载到向量存储中。
  2. 搜索:构建一个自定义工具,运行向量相似度搜索并将每个检索到的片段写入智能体文件系统。
  3. 分析:将文件分析委托给一个子智能体,该智能体读取文件并返回专注的摘要。
  4. 合成:使用主智能体从子智能体报告中获取最终答案。

前提条件

API 密钥:

设置

:::python
1

Create project directory

2

Install dependencies

3

Set API keys

对于任何其他提供者,请参阅相应的 对话模型 文档。
4

Set up LangSmith

RAG 应用程序按顺序运行检索和生成。当您运行本教程中的示例时,LangSmith 为每个查询记录跟踪,以便您可以检查检索、工具调用和模型响应。 在您 注册 LangSmith 后,设置环境变量以开始记录跟踪:
或者,在 Python 中设置它们:
如果您正在构建生产智能体,我们还建议您设置 LangSmith Engine,该引擎监控您的跟踪、检测问题并提出修复建议。
::: :::js
1

Create project directory

2

Initialize the project

npm
3

Install dependencies

npm
安装代码示例中选择的模型的匹配 @langchain/<provider> 包(Google、OpenAI 和 Anthropic 已在上文中包含)。
4

Set API keys

在您的 shell 中导出密钥,或在项目目录中创建一个 .env 文件。代码使用 import "dotenv/config" 自动加载 .env(在索引步骤中添加)。
或者,在 .env 中:
在您的代码中使用与模型提供者匹配的环境变量(ANTHROPIC_API_KEY 用于 Claude,GOOGLE_API_KEY 用于 Gemini,OPENAI_API_KEY 用于 OpenAI)。
5

Set up LangSmith

RAG 应用程序按顺序运行检索和生成。当您运行本教程中的示例时,LangSmith 为每个查询记录跟踪,以便您可以检查检索、工具调用和模型响应。 在您 注册 LangSmith 后,设置环境变量以开始记录跟踪:
如果您正在构建生产智能体,我们还建议您设置 LangSmith Engine,该引擎监控您的跟踪、检测问题并提出修复建议。
:::

LangChain 文档索引指南

在索引步骤中,您将把源内容转换为 片段 的数值表示。这种数值表示捕捉了片段的语义意义。将这些数值表示及其对应的文档片段存储在一个 VectorStore 中,可以在用户基于其自身的数值表示发送查询时,帮助您高效地检索相关内容。 索引通常包含四个步骤:
  1. 加载: 将您的数据源加载到 @[Document] 对象中。
  2. 分割: 使用 文本分割器 将大型 Document 分割成更小的片段。这对于索引数据和将其传递给模型都很有用,因为大型片段更难进行搜索,要么无法适应模型有限的上下文窗口,要么会使用不必要的 Token。
  3. 嵌入: 嵌入 模型将每个片段转换为一个数值向量,该向量捕捉其含义,从而能够在您的内容中进行相似性搜索。
  4. 存储: 使用一个 向量存储 来索引片段及其嵌入,以便进行检索。
index_diagram 在索引步骤中,获取文档页面,将它们分割成片段,嵌入这些片段,并将它们存储在一个 VectorStore 中。智能体在运行时搜索此索引;它不会在每次提问时重新获取整个网站。 LangChain 在 https://docs.langchain.com/{path}.md 发布 Markdown 文档。本教程索引了一个精选的开源文档路径列表。您可以扩展 DOC_PATHS 或从 llms.txt 解析 URL 来覆盖更多页面。 :::python 创建 agent.py:
::: :::js 创建 agent.ts:
:::
有关索引、向量存储和检索的更详细教程,请参阅 语义搜索。

加载文档

首先将 LangChain 文档页面加载到一个 @[Document] 对象列表中。 :::python 使用 requests 从 https://docs.langchain.com/{path}.md 获取每个页面作为 Markdown。精选的 DOC_PATHS 列表选择要索引的页面。
如果您运行此代码,它将打印:
您还可以查看页面内容本身:
::: :::js 使用 fetch 从 https://docs.langchain.com/{path}.md 获取 DOC_PATHS 中每个路径的 Markdown。
如果您运行此代码,它将打印:
您还可以查看页面内容本身:
:::

分割文档

加载的文档很长,总共有超过 100k 个 Token,这使得它太大而无法适应许多模型的上下文窗口。 对于那些能够将完整语料库放入其上下文窗口的模型,模型也可能难以在非常长的输入中找到信息。使用上下文窗口处理大量内容也不是 Token 高效的。 为了方便使用,将 @[Document] 对象分割成片段。这些片段将用于后续步骤中的嵌入和向量存储。 使用 RecursiveCharacterTextSplitter 递归地分割文档,使用常见的分隔符(如换行符),直到每个片段达到适当的大小。 RecursiveCharacterTextSplitter 是推荐的 TextSplitter,适用于通用文本用例。 :::python
如果您想了解更多关于文本分割器的信息,请查看 TextSplitter 接口 和 文本分割器集成。 ::: :::js
:::

选择嵌入模型

嵌入是一个数值向量,用于捕获每个文档块的含义。@[Embeddings]模型将这些块转换为向量,使得含义相似的块在向量空间中彼此靠近,从而在用户提问时能够检索到相关的部分。 您可以从许多不同的嵌入集成中选择,它们都使用相同的 @[Interface][Embeddings]: :::python
::: :::js
:::

将块和嵌入存储在向量存储中

向量存储VectorStore持久化存储文档块及其嵌入,使得在用户提问时能够通过相似性搜索检索到相关的部分。 您可以从许多不同的向量存储集成中选择,它们都使用相同的 @[Interface][VectorStore]。 使用在上一步骤中选择的嵌入模型来配置您的 VectorStore: :::python
::: :::js
::: 然后,使用上面初始化的 vector_store来嵌入和存储所有文档分割: :::python
运行时,这将输出:
::: :::js
运行索引代码时,您会看到类似以下的输出:
:::
在本教程中,索引在启动时运行一次。在生产环境中,将向量存储持久化到磁盘或托管向量数据库,并在文档发生变化时按计划刷新。
本教程的索引部分到此完成。现在您已经拥有一个包含分块LangChain文档的可查询向量存储。 下一步是构建一个深度智能体,该智能体在运行时搜索此索引,将检索到的块卸载到文件系统,并将分析委托给子智能体。参见构建智能体。用RAG术语来说:
  1. 检索:给定用户输入,使用Retriever从存储中检索相关的分割。
  2. 生成:使用包含问题和检索数据的提示词,model生成答案。
retrieval_diagram

构建智能体

:::python 将此代码添加到 agent.py: ::: :::js 将此代码添加到 agent.ts: :::
1

Add the search tool

search_documentation工具对索引语料库运行相似性搜索,然后将每个检索到的块写入智能体文件系统下的 /retrieved/{batch_id}/。它返回文件路径,以便协调器可以在不将完整块文本加载到其上下文的情况下委托分析。:::python 该工具使用 backend.upload_files()将检索到的块写入智能体后端。将相同的后端实例传递给 create_deep_agent,以便内置文件系统工具(如 read_file 和 grep)可以读取保存的路径。 ::::::js 该工具使用 backend.uploadFiles()将检索到的块写入智能体后端。将相同的后端实例传递给 createDeepAgent,以便内置文件系统工具(如 read_file 和 grep)可以读取保存的路径。 ::::::python
::::::js
:::
2

Add prompts

:::python 将协调器工作流和子智能体提示词模板添加到 agent.py: ::::::js 将协调器工作流和子智能体提示词模板添加到 agent.ts: ::::::python
::::::js
:::
3

Create the agent

:::python 为 agent.py 添加模型初始化和智能体创建:
::::::js 为 agent.ts 添加模型初始化和智能体创建:
:::主要智能体保留 search_documentation 工具。chunk-analyst 子智能体使用内置文件系统工具读取块文件,但不会直接搜索向量存储。

运行智能体

使用示例查询运行 RAG 智能体: :::python
::: :::js
::: 当智能体运行时,它会:
  1. 使用关于子智能体流式输出的查询调用 search_documentation。
  2. 接收文件路径,例如 /retrieved/a1b2c3d4/chunk_1.md。
  3. 启动一个或多个针对 chunk-analyst 的 task() 调用,每个调用都针对单个块文件进行作用域限定。
  4. 使用链接到相关文档页面的最终答案进行综合。
如果你在 设置 中启用了 LangSmith,请打开 LangSmith 并检查跟踪信息,以查看搜索调用、文件系统写入、子智能体委托和最终响应。

安全注意事项

RAG 应用程序容易受到 间接提示词注入 的影响。检索到的文档可能包含类似于指令的文本。由于检索到的块与您的系统提示词共享上下文窗口,模型可能会遵循文档中嵌入的指令,而不是您的预期提示词。
没有提示词或分隔符策略可以完全防止间接提示词注入。本教程中的协调器和子智能体提示词要求模型将检索到的内容视为数据,并且搜索工具在块前添加一个 # Source: 标头,以便分析师可以将元数据与正文内容区分开来。这些模式在某些情况下可能有所帮助,但它们不能提供可靠的防护。 在将智能体输出呈现给用户之前进行验证。检查答案是否引用了预期的文档路径,并且断言是否与检索到的源材料一致。 有关更多内容,请参阅关于 提示词注入 的研究。

完整代码

以下是使用一组示例模型智能体的完整脚本。对于其他模型,请参阅分步方法以了解具体变化: :::python 保存为 agent.py 并使用 python agent.py 运行:

View example trace

为此示例打开一个公开的 LangSmith 运行。
::: :::js 保存为 agent.ts 并使用 npx tsx agent.ts 运行:
:::

下一步

:::python 您使用 @[create_deep_agent 实现了一种 RAG 模式。结合其他 Deep Agents 功能或尝试 RAG 模式 中的不同模式: ::: :::js 您使用 @[createDeepAgent 实现了一种 RAG 模式。结合其他 Deep Agents 功能或尝试 RAG 模式 中的不同模式: :::
  • 将 技能 添加到包检索工作流和特定领域搜索指南中
  • 使用 LangSmith 数据集和评估器 评估 RAG 应用
  • 阅读 上下文工程 以实现卸载和子智能体隔离策略
  • 使用 托管深度智能体 部署,以便在生产环境中运行智能体而无需管理基础设施。或者,为了在使用相同的深度智能体框架时获得最大灵活性,可以自行托管智能体或使用自定义的 LangSmith 部署 :::python
  • 使用 评分标准 来验证答案是否基于检索到的源材料 :::

官方原文:src/oss/deepagents/rag.mdx · 非官方翻译,译文由 AI 生成,以英文原文为准。
Last modified on November 3, 2026