深入学LangChain 官方文档(十一)Retrieval 检索入口首 深入学 LangChain 官方文档十一Retrieval 检索入口首讲本篇对应的官方文档Retrieval检索解决的问题、知识库构建组件以及 2-Step、Agentic、Hybrid RAG 的架构差异。Build a semantic search engine with LangChainDocument、切分、embedding、vector store 与语义查询的最小实现链路。本篇讲解范围本篇主要从“客服怎样依据最新退款政策回答”出发建立索引与查询双阶段、Retrieval 与 RAG 的关系、三类 RAG 架构及最小代码闭环。生产向量数据库选型、复杂 rerank、多模态检索、Graph RAG 和完整评测平台留给后续专题。上一章把执行政策放到了明确的调用边界新的问题马上跟了上来模型需要回答的内容未必已经在当前上下文里。用户问客服 Agent“耳机已经拆封还能七天无理由退货吗”模型当然能直接给出一句话但这句话很难让人放心。退款政策会更新不同商品可能有例外企业内部规则也不在模型训练数据里。即使碰巧答对系统仍然解释不了它依据的是哪个版本、哪一条规定。Retrieval检索改变的是回答前的信息路径不需要修改模型参数。问题到来后系统先从外部知识源取回相关证据再把数量有限、来源可追踪的内容交给模型。检索和生成接在一起才是通常所说的 Retrieval-Augmented Generation也就是 RAG检索增强生成。这里有两个词要抓住。“运行时”意味着知识不必在训练阶段进入模型“相关”意味着系统只取当前问题需要的片段不会把整本政策手册塞进上下文。接下来沿着取证链往下拆先划清 Retrieval、Memory 与业务数据库的责任再把原始政策处理成带来源的Document和 chunk。随后看 embedding、vector store 与 retriever 怎样返回候选证据最后比较三类 RAG 架构并把空结果、噪声、过期和越权放进工程验收。闭卷回答依赖模型已有参数无法跟随企业政策更新运行时取证会在问题到来后查询当前知识源把相关片段连同来源一起交给模型。RAG 的增量不是笼统地“知道更多”而是让本次回答建立在可更新、可追踪的外部证据上。沿着取证路径继续走第一步是把“找证据”和“写答案”分开。一、Retrieval 负责取证RAG 负责基于证据生成官方文档先点出模型的两项限制上下文窗口装不下整个语料库训练得到的知识也不会自动跟随企业政策更新。Retrieval 接收查询从外部系统取回相关信息正面处理这两个限制。但检索结果还不是面向用户的回答。它通常是一组Document每个对象包含page_content和可选metadata。应用还要决定片段怎样整理、放进哪一段 model context以及证据不够时怎样要求模型停止猜测。把检索、注入和生成连起来才构成 RAG。三者的输出边界很清楚Retrieval 的输出是候选证据Generation 的输出是面向用户的回答RAG 的质量取决于证据能否被正确取回也取决于模型是否只在证据边界内作答。如果检索漏掉“拆封耳机不适用”的例外条款模型写得再流畅也补不回来。反过来正确条款已经取回prompt 却允许模型随意混入常识答案还是会跑出证据范围。所以 RAG 不是接上向量库就结束而是一条要逐段验收的证据供应链。二、Retrieval、Memory 与业务数据库各自回答不同问题第 09 篇讲过 Memory 以后很容易把所有“将来还要读取的信息”放进同一个概念。退款政策、用户偏好和订单状态确实都会再次出现责任却完全不同。Retrieval 回答“当前问题需要哪些外部知识证据”适合政策、手册、FAQ、技术文档和历史报告。Memory 保存的是用户或线程已经发生的内容以及可以复用的偏好例如用户希望中文简洁回答。业务数据库维护当前权威事实例如订单是否发货、退款是否到账。一次客服回答可能同时用到三类信息。此时要看的是每条路径最终对哪类事实负责而不是底层用了什么存储产品。政策条款从知识库检索表达偏好从 Memory 读取订单状态回交易系统查询三条路径分别承担知识证据、交互连续性和业务真相。把业务事实向量化后当作唯一答案或把政策正文塞进用户记忆都会让更新与权威边界失控。有些企业已经建好了 SQL、CRM、文档搜索或内部知识 API。使用 LangChain 并不要求把这些系统全部搬进新的向量库。现有系统可以直接作为 Agentic RAG 的工具也可以由确定性步骤先查再把结果注入 2-Step RAG。LangChain 提供的是组合接口不是强制迁移方案。三、检索系统分成索引阶段和查询阶段最小语义检索系统包含两条发生时间不同的链路。索引阶段读取原始资料把文件、网页或数据库记录转成标准Document。长文档经过 text splitter 切成更小的 chunkembedding model 再把文本映射为向量vector store 同时保存向量、原文与 metadata。这条链路随政策发布或更新运行不会在每次用户提问时重做整本手册。查询阶段才发生在用户提问时。问题被映射到同一向量空间系统执行相似度搜索或 retriever 查询取回少量候选Document再交给后面的 RAG 链路。两阶段共用 embedding 语义和 metadata 规则负载、延迟与失败方式却不相同。索引链把来源文档处理成可搜索的向量和元数据查询链只处理当前 query 并返回 top-kDocument。索引失败会造成知识缺失或过期查询失败则表现为空结果、低相关结果或延迟两条链必须分开监控。这个区分会直接影响更新策略。退款政策第 3.2 条修改后应该只重建受影响的文档或 chunk并更新版本字段。没有稳定文档 ID 却反复全量追加很容易留下新旧重复。查询端面对的是另一组约束租户、语言、商品分类和生效日期都可能进入过滤条件不能只凭语义相似度取前几名。四、Document、chunk 与 metadata 共同定义证据单元LangChain 用Document统一表达检索内容。page_content保存参与搜索和生成的正文。metadata则保存回溯和过滤需要的信息例如source、section、version、effective_date、tenant_id与权限标签。原始政策通常太长需要先切分。chunk 过大一个向量会混入多个主题查询“耳机拆封”可能拉回整章售后制度chunk 过小主规则与例外条件又会被拆开模型只看见“支持七天退货”漏掉下一句“不适用于拆封音像和特定卫生商品”。政策被切成可以独立召回的 chunk每个 chunk 同时保留正文与来源、章节、版本、生效日期等 metadata。切分边界决定语义是否完整metadata 决定结果能否过滤、引用、更新和删除两者共同构成证据单元。切分不只是字符计数。标题层级、段落、表格行、代码块和条款编号都可能是语义边界。初期可以用通用 splitter 建立基线再拿真实问题观察命中片段能否独立表达判断前后文是否必须一起返回重复 chunk 是否挤占 top-k。metadata 也不能只留文件名。客服答案要引用“2026-07 版售后政策 3.2 条”这些字段就必须在索引阶段保存。华东租户只能读取自己的内部政策时tenant_id过滤要在检索前生效不能等内容取回后再让模型忽略。文档生命周期还需要稳定标识。可以给原始文档保存document_id切分结果保存可重复计算的chunk_id再记录内容哈希。政策只改一节时索引任务就能删掉旧 chunk、写入新 chunk而不是把整份文件又追加一遍。缺少稳定 ID 的知识库看似结果丰富实际可能是同一条款的三个历史版本一起占满 top-k。删除也属于索引合同。员工手册撤回、租户解除授权或用户要求删除资料后原文件、向量、缓存与派生摘要都要同步处理。只在 metadata 标记“已删除”旧向量却仍能进入候选集等于把合规问题推给生成阶段。可靠知识库必须回答得出一条证据从哪里来现在是否有效还有哪些派生数据需要一起失效。五、embedding 搜索的是语义邻近不是事实正确embedding model 把文本转成数值向量。语义相近的文本通常会落在更近的位置所以用户问“拆开包装还能退吗”也可能命中“商品启封后不适用无理由退货”两边不需要使用完全相同的关键词。query 与文档 chunk 经同一 embedding model 进入向量空间“拆开包装”和“商品启封”因为语义接近而距离更近。这个距离只表示相关性不能证明条款有效、来源可信或答案正确版本与权限仍由 metadata 和业务规则约束。相似度不是事实置信度。旧条款可能与问题高度相似却早已失效营销文章可能更贴近用户措辞却不具备政策权威性互相冲突的文档也可能一起进入前几名。VectorStore 通常支持字符串或向量查询、同步或异步调用、是否返回分数以及 similarity 或 maximum marginal relevance 等策略。similarity_search(query, k4)只是起点生产系统还要叠加 metadata filter、最小相关阈值、去重与多源排序。Retriever 把“给定非结构化 query返回一组Document”抽象成统一接口。内部可以使用向量搜索、关键词检索、数据库查询、外部搜索服务甚至组合多个 retriever。上层 RAG 只依赖返回的Document底层策略就可以替换。这层抽象也方便测试。开发阶段可以用内存向量库验证消息与生成链路生产时再换成企业搜索 API只要Document与 metadata 合同不变上层无需重写。反过来工具只返回一段没有来源边界的长字符串后续的过滤、引用、去重和评测就都失去了对象。候选形成可以拆成四步先应用租户与权限过滤再计算语义相关性随后选择 top-k 或兼顾多样性的结果最后检查分数、来源和重复度判断证据是否足够进入生成。检索不是从全库直接抓几个最近向量。租户、权限、版本和生效日期先缩小合法候选集相似度与多样性策略再形成 top-k。过滤过晚会产生越权k 过小容易漏掉例外k 过大则会把噪声带进上下文。候选证据下一步怎样进入模型取决于检索固定发生在生成之前还是由 Agent 或校验循环决定检索时机。六、三类 RAG 架构的差别在“谁决定何时检索”官方总览把常见 RAG 分成 2-Step、Agentic 和 Hybrid。三者可以共用同一个知识库区别落在检索时机、控制权和验证步骤。2-Step RAG每次回答前固定检索。用户问题先进入 retriever证据和问题再一起交给模型。调用次数有上限延迟比较可预测适合 FAQ、文档问答和“没有证据就不应回答”的场景。代价是用户只说“谢谢”时也可能触发无用检索复杂问题通常也只有一次查询机会。2-Step 的固定路径是 query → retrieve → context → model → answer。检索一定发生控制强、调用数可预测答案质量也直接受单次 query、top-k 和上下文拼装影响。Agentic RAG把检索暴露为工具。Agent 先判断当前问题是否需要外部知识第一次结果不足时还可以改写 query 再查。研究助手、多知识源或需要在检索与其他工具间交替的任务更适合这种方式。代价是延迟和调用次数不稳定还要防止 Agent 跳过检索、反复检索或选错知识源。Agent loop 把 retriever 当作工具模型根据当前 messages 决定是否查询以及查询什么Document再以ToolMessage回到下一轮推理。检索时机更灵活也因此需要调用限制、准确的工具描述和无证据拒答规则。Hybrid RAG在固定链和 Agent 之间加入校验。常见流程先改写含糊问题检索后判断相关性不足时重新检索生成后再检查答案是否得到证据支持。它适合质量要求高的行业问答但每个判断节点都会增加成本循环也必须有明确上限。Hybrid 在检索前后加入 query 改写、相关性判断和答案校验证据不足就回到检索不让模型直接补全。循环换来更强控制也必须设置终止条件并记录每次改写避免质量检查演变成无限调用。选择架构时不用按“高级程度”排序。退款政策每次都必须引用文档2-Step 往往简单可靠需要跨多个来源调查原因时Agentic 更灵活监管场景要求证据校验和稳定拒答再考虑加入 Hybrid 节点。七、把检索结果注入上下文时要保留来源边界拿到Document以后常见做法是把若干page_content拼成 context再连同用户问题交给模型。片段不是越多越好至少要保留明确的分隔、来源标识和指令边界。可以为每个片段编号并附上 source、section、version。system prompt 要求模型只根据这些片段回答证据不够时说明缺少依据关键结论引用对应编号。这样做不能从数学上消灭幻觉却让追踪和评测有了具体对象。多个片段共同构成一个判断时还要处理它们之间的关系。主规则和例外条款分别命中不能简单按分数排序后截断。可以恢复同一章节的邻近片段或用 metadata 把条件和结论放回一起。不同版本彼此冲突时也应由应用先判断有效版本而不是交给模型碰运气。Token 预算要在拼装前确定。系统指令、用户问题、检索证据和回答分别预留空间再在证据预算内按相关性、权威性与多样性挑选片段。把 k 从 4 直接提到 20 往往只会增加延迟和噪声每个进入 model context 的 chunk 都应该补充一条必要证据。答案引用最好绑定内部文档 ID不要只让模型手写“来源售后政策”。生成后应用根据引用 ID 渲染标题和链接并核对该 ID 确实属于本轮候选集。文档以后移动或改名追踪关系仍然存在模型也更难凭空编造来源。知识片段中即使出现“忽略之前规则”它仍然是待引用的数据不会因此升级为系统指令。消息层级和分隔格式要足够清楚敏感工具权限也不能交给检索文本决定。Retrieval 负责提供知识没有权限改写 Agent 的控制政策。八、四类失败需要回到不同环节修复RAG 回答错误时先改 prompt 往往治标不治本。把失败归类以后才能找到真正需要修复的位置。空结果用户措辞与文档差异太大、过滤过严、索引漏文档或阈值过高。应该检查索引覆盖、query 改写和 filter不能让模型在空 context 里猜。噪声结果chunk 过大、k 过高、重复文档太多或来源混杂。修复点在切分、去重、rerank 和来源权重。过期冲突新旧政策并存或两个权威来源结论不同。需要用版本、生效日期和权威等级过滤无法自动裁决的冲突要交给用户或人工流程。越权结果权限过滤发生在向量搜索之后或缓存键没有包含租户和角色。模型的一句“不要泄露”挡不住这种错误非法文档必须在检索层就被排除。空结果回查索引覆盖和 query噪声回查切分与排序过期冲突回查版本治理越权回查过滤与缓存隔离。它们都会表现成“模型答错”真正的修复位置却分布在四条不同路径上。失败责任清楚以后最小代码只需要保留建库、查询、返回证据和生成回答四个动作。九、最小代码闭环先建证据库再让 Agent 按需检索示例用三条简化政策构建内存向量库。Document.metadata保存条款和版本search_refund_policy把检索封装成工具Agent 收到问题以后自行决定是否调用再根据工具结果回答。fromlangchain.agentsimportcreate_agentfromlangchain.toolsimporttoolfromlangchain_core.documentsimportDocumentfromlangchain_core.vectorstoresimportInMemoryVectorStorefromlangchain_openaiimportChatOpenAI,OpenAIEmbeddings documents[Document(page_content未拆封商品自签收次日起七日内可申请无理由退货。,metadata{section:3.1,version:2026-07,source:售后政策},),Document(page_content耳机等直接接触皮肤的商品包装启封后不适用无理由退货。,metadata{section:3.2,version:2026-07,source:售后政策},),Document(page_content商品存在质量问题时可提交检测结果进入质量退货流程。,metadata{section:4.1,version:2026-07,source:售后政策},),]vector_storeInMemoryVectorStore(embeddingOpenAIEmbeddings(modeltext-embedding-3-small))vector_store.add_documents(documents)tooldefsearch_refund_policy(query:str)-str:检索当前退款政策并返回带条款和版本的候选证据。resultsvector_store.similarity_search(query,k2)ifnotresults:return未检索到可用政策不要根据常识回答。return\n\n.join(f[{doc.metadata[source]}{doc.metadata[version]}f第{doc.metadata[section]}条]\n{doc.page_content}fordocinresults)modelChatOpenAI(modelqwen3.7-plus,api_keyYOUR_API_KEY,base_urlYOUR_OPENAI_COMPATIBLE_ENDPOINT,)agentcreate_agent(modelmodel,tools[search_refund_policy],system_prompt(回答退款问题前先检索政策。只依据工具返回的条款作答证据不足时明确说明并在结论后标注条款与版本。),)resultagent.invoke({messages:[{role:user,content:耳机拆封后还能无理由退货吗}]})print(result[messages][-1].content)输入先进入 Agent loop。模型根据工具描述生成search_refund_policy调用工具用 query 做相似度搜索返回两个带 metadata 的证据片段。工具结果进入下一轮模型调用最终答案从result[messages][-1]取得。没有结果时工具明确返回“不要根据常识回答”让空证据成为一条可见状态。这段代码只实现最小机制。生产系统还要在搜索前加入租户、权限、版本和生效日期过滤embedding 与 vector store 需要持久化结果要记录文档 ID方便答案追踪。外部接口失败也要与“确实没有匹配文档”区分。InMemoryVectorStore适合演示不能替代生产知识库。闭环从来源摄取和版本化索引开始经过权限过滤、语义检索、上下文注入与引用式回答再把真实问题、命中文档和答案结果交给评测。链路对象都可追踪以后团队才能判断错误来自知识、检索还是生成。对象能够逐层追踪评测也就不能再停留在笼统的答案印象上。十、评测对象不是“回答好不好”这一项RAG 至少要分三层评测。检索层检查目标证据是否进入 top-k、无关片段比例、权限和版本过滤生成层检查答案是否得到证据支持、关键条件有没有遗漏、引用能否对应真实片段系统层再观察延迟、成本、空结果率与更新时效。评测集应该来自真实问题不能只让开发者照着文档标题编写。用户会使用简称、错别字、上下文指代和模糊说法“拆了还能退吗”比“耳机包装启封后是否适用无理由退货”更接近生产流量。每个问题最好标记期望证据 ID而不只是保存一个标准答案这样检索错误与生成错误才能分开。上线后还要记录 query、filter、命中文档 ID、分数、版本、最终引用和用户反馈同时对敏感字段脱敏。文档更新时重跑受影响问题可以提前发现新版本破坏旧正确答案的回归。还要单独准备一组系统本来就不该回答的问题知识库没有覆盖的商品、权限之外的内部政策、无法自动裁决的冲突条款。合格结果是稳定进入拒答、澄清或人工升级不是勉强给出一句听起来合理的话。把“不知道”纳入评测RAG 才能堵住召回率之外的猜测缺口。成本也要按阶段拆开。索引成本随文档更新发生在线成本来自 query embedding、检索、可能的 rerank 和模型调用。高峰期延迟上升时只有分别记录各阶段耗时才能判断向量库变慢、过滤失效还是 Agent 发起了额外检索。十一、回到主线可靠回答始于可靠证据Retrieval 的机制并不神秘模型不知道或当前窗口装不下的知识在问题到来时从外部系统取回。真正困难的是把它变成可靠供应链——来源要权威chunk 要语义完整metadata 要支持版本与权限查询要召回相关证据生成要守住证据边界失败还要能够定位。实践顺序可以收成一条线先划清知识、记忆与业务事实的责任再分开索引和查询用Document metadata建立可回溯证据根据控制需求选择 2-Step、Agentic 或 Hybrid RAG最后从检索、生成和系统三个层次验收。到这里单个 Agent 已经拥有模型、工具、状态、记忆、Middleware 和 Retrieval。但能力继续增加新的压力也会出现一个上下文窗口要同时装下多少领域知识一组工具还能不能由同一个角色准确选择不同团队维护的专业能力又由谁协调下一篇我们将进入 Multi-agent 与 Frontend的学习。它不会推倒这些零件而是继续回答两件事当单 Agent 的上下文和工具开始过载时控制权怎样拆分后端执行状态又怎样变成用户能看懂、能操作的界面状态。