Agent知识获取管道:RAG检索增强生成实战解析

发布时间:2026/11/4 14:04:39
Agent知识获取管道:RAG检索增强生成实战解析 你在本地跑过 Agent 之后大概率会撞上同一堵墙模型什么都知道一点但一问到你们团队的内部文档、你个人的笔记、最新的业务数据它就哑火了。这不是参数不够而是它的知识边界在训练那天就焊死了。所以这个系列走到第四篇我们把注意力从Agent 怎么思考挪到Agent 怎么拿知识——也就是 RAGRetrieval-Augmented Generation这条知识获取管道。RAG 不是新概念但它在一线 Agent 项目里被反复提起不是因为它能当搜索引擎而是因为它能让模型在回答问题之前先从一个可控的管道里取到证据。这篇我按自己的落地经验拆一下 RAG 的基础它解决什么问题、一条最小管道怎么搭、Agent 和 RAG 怎么真正耦合以及跑通之后那些文档里不会写的坑。1. Agent 为什么需要一条知识获取管道先看上下文窗口的物理限制很多朋友第一次做 AI Agent第一反应是把知识全塞进 system prompt 不就行了。我刚开始也这么干过把一个几十页的产品手册写成摘要丢进去结果模型一回答问题就开始胡编。问题不在模型态度而在知识取用的方式。1.1 大模型的知识天生有保鲜期模型参数的训练是有截止时间的你用它做知识问答时它只能回忆训练语料里见过的东西。业务的内部规范、你昨天刚写的技术方案、某产品的实时价格这些根本不在它的记忆范围里。你问我为什么要专门给 Agent 修一条知识管道就是因为模型自己没法感知时间、没法主动查询它只有一条路——看你给它的输入里有没有。有人想用微调来解决这是另一个方向但微调解决的是模型的行为习惯和回答风格不是高频更新的业务知识。你没必要为了让模型知道某个新接口的文档去重新训练一次模型。知识获取管道的第一条原则就是让知识以运行时输入的方式进入模型而不是以训练时记忆的方式存在参数里。1.2 上下文窗口不是无限书柜就算你把所有资料都拼进 prompt上下文窗口也扛不住。你可以算一笔账一份 5000 字的文档大概 7000 个 token一个 128K 窗口的模型塞 10 份就吃掉一大半。而真实业务场景里的文档池往往是几十万甚至上百万字的规模不可能整包塞进去。更麻烦的是注意力稀释。我做过对比实验把相关段落杂在一堆无关背景里模型回答准确率会明显下降。你以为它看得见,但它在长上下文里定位关键信息的能力没有想象中那么强。所以 Agent 需要的不是更大的书柜而是一个先找书、再翻开确定页给你看的过程。这就是 RAG 管道存在的意义。1.3 RAG 解决的不是知识不够而是信息取用RAG 的全称是 Retrieval-Augmented Generation检索增强生成。它的核心思路拆成三句话就是先把文档切成小块并向量化存入检索库用户提问时先从库里检索相关片段把检到的片段塞进 prompt让模型基于这些材料回答。这套逻辑跟人查资料很像模型就像那个坐在书桌前回答你的人RAG 就是一个在你提问后主动帮你翻书、把相关段落摊开放在桌上的助手。它不改变模型本身只改变模型看到了什么。这决定了 RAG 的上限如果检索环节找错了材料后续生成环节再强也救不回来。所以后面我讲实操时会反复强调一个判断——你的瓶颈在召回不在生成。2. RAG 三段式的工程本质切分、检索、拼接RAG 看起来只是查一下再回答落到工程上其实是三个独立环节的拼接。很多人一上来就全链路调优效果差的时候根本不知道是哪一段出了问题。我的建议是先把三段拆开各自搞清楚评价指标。2.1 索引侧切分策略与向量化建索引的第一步是切分splitting。你要把一个长文档切成小段每一段是一个待检索单元。切分粒度直接决定召回质量。我用过一个粗暴的经验值普通技术文档按 300 到 500 个 token 切一段重叠区设 50 到 80 个 token这个量级在多数场景下表现稳定。但这不是死的代码文件按函数切、合同按条款切、对话记录按轮次切都比固定长度切更贴合语义边界。切分之后是向量化embedding。这一步通过 embedding 模型把文本转成高维向量让语义相近的文本在向量空间里距离更近。选 embedding 模型时我比较看重两点一是中文效果二是向量维度。常见的开源中文 embedding 模型在 768 到 1024 维之间维度太高会占内存太低又可能损失语义区分度。这个环节有个常见误解——不是模型越贵越好而是嵌入模型要跟你的文档领域匹配。医疗、法律、代码、客服语料的最佳选择都不一样。2.2 检索侧向量召回与混合检索检索的核心动作是拿 user query 的向量去库里做相似度搜索常用的算法有余弦相似度、点积、欧氏距离。向量检索的优势是能处理同义改写这类语义匹配问题比如用户问怎么退款文档里写的是退费流程字面不同但语义接近向量检索能把它们对上。但纯粹靠向量检索有一个盲区——精确词匹配。合同编号、订单号、专业术语、版本号这类字符串向量相似度反而容易模糊处理。所以完整一点的检索器通常做混合检索一半向量召回一半关键词召回比如 BM25然后再用重排序模型reranker把两部分结果合并排序。你可以把混合检索理解成用语义理解大方向用关键词抓精确锚点两者互补。我在一个产品检索项目里做过对比纯向量召回 hit rate 大约 72%加上 BM25 和 reranker 之后能提到 88% 左右。2.3 生成侧拼接模板与引用溯源检索完成之后系统会把命中的片段按顺序拼进 prompt再让模型生成最终回答。这里最容易翻车的是语境完整性如果你只截取命中的那一小段模型可能看不懂上下文所以我通常会把命中片段前后各扩展一段原文再一起拼进去。拼接模板同样有讲究。我的写法是明确告诉模型以下是从知识库检索到的参考片段请基于这些内容回答如果不足以回答问题请直接说明不知道不要编造。这句话看着简单但能明显减少幻觉。另一个重要设计是引用溯源每段检索片段保留文档 ID 和页码信息让模型在回答里标注来源。这一条既能方便用户核查又能倒逼工程侧去检查这个回答到底有没有参考依据。3. 从 0 到 1 搭一条最小 RAG 管道写代码级别的实操说再多原理不如跑通一遍。我理解的基础标准是能用本地文档建库、能检索、能基于检索结果回答。这一步走通了后面加 Agent 工具、加记忆、加重排都是在同一套骨架上面加东西。下面这条管道是通用的最小实现我用伪代码来写重点不在某个库的具体 API而在链路本身。3.1 环境与模型选型二选一的常见方案是 LangChain 和 LlamaIndex两者都能把加载、切分、向量化、检索串起来。我的建议很简单如果你后面主要做 Agent选 LangChain因为它的工具调用生态更完整如果你只是想把一堆文档变成问答服务选 LlamaIndex 会更顺手。也可以用更轻的方式直接调 embedding API 和向量数据库核心流程完全一样。三个组件必须提前备好一个 embedding 模型、一个向量数据库、一个生成模型。我测试时常用的组合是开源的 embedding 模型 Chroma本地轻量向量库 兼容 OpenAI 接口的 LLM。Chroma 适合个人项目和原型验证它足够简单而且能本地跑不需要额外的服务端。如果要上生产我后面会换用更重的向量库但测试阶段的逻辑是完全一样的。3.2 文档切分与入库先把文档读进来切成小块再批量向量化入库。核心代码逻辑如下# 伪代码最小 RAG 管道 - 建索引部分 from document_loader import load_pdf, load_markdown, load_txt from text_splitter import RecursiveTextSplitter from embedding_model import get_embedding_function from vector_store import VectorStore # 1. 加载文档 docs [] for path in [manual.md, faq.pdf, api_notes.txt]: docs.extend(load_pdf(path) if path.endswith(.pdf) else load_markdown(path) if path.endswith(.md) else load_txt(path)) # 2. 切分每块 400 token重叠 50 token splitter RecursiveTextSplitter(chunk_size400, chunk_overlap50) chunks splitter.split_documents(docs) print(f文档切分成 {len(chunks)} 个片段) # 3. 向量化并写入向量库 embeddings get_embedding_function() vector_store VectorStore(collection_nameknowledge_base) ids [fchunk-{i} for i in range(len(chunks))] vector_store.add_documents(idsids, documentschunks, embeddingsembeddings)这里我想特别说两个容易忽视的地方。第一切分器要按文档类型选RecursiveTextSplitter 是通用兜底但对 Markdown 文档最好保留标题层级对代码文件则要按函数切否则语义会被拦腰切断。第二入库时一定要保存元数据至少包括来源文件、页码、标题路径。后面做引用溯源和过滤检索都要靠这些字段等出了问题再回去补元数据会非常痛苦。3.3 检索测试与链路联调库建好之后先不要急着接 LLM单独测检索这一步。原因是如果检索结果本身就不相关你接下来怎么调 prompt 都没用。我会写一段独立的检索测试脚本输入几个真实用户问题打印出命中的片段和相似度分数。你一眼就能看出来命中的内容是不是对的。# 伪代码单独测试检索环节 query 客户在哪里可以修改订阅计划 hits vector_store.similarity_search(query, k5) for i, hit in enumerate(hits): print(f[Top {i1}] score{hit.score:.4f}) print(hit.text[:120]) print(---)检索没问题之后再把生成环节接上把命中的片段拼进 prompt 调 LLM。我第一次搭的时候检索结果明明是对的模型回答还是偏了——后来发现是 prompt 里没有明确只依据参考内容回答,模型把常识和检索内容混在一起了。把指令改成仅根据参考片段回答片段之外的不要推测之后输出质量立刻提升。到这里一条最小管道就通了。整个过程快的话半小时能跑通。接下来真正花时间的不是管道本身而是对切分粒度、embedding 选择、检索召回的反复调优。4. Agent 与 RAG 的三种耦合方式从工具调用到Agentic RAG管道通了它只是一个被动的工具用户提问它检索它回答。但放在 AI Agent 体系里RAG 不能只是孤零零的问答接口。Agent 有自己的任务目标有规划有多步操作RAG 要嵌进这个过程才算完整。4.1 方式一把 RAG 封装成 Agent 的一个检索工具最简单、也是最常见的做法是把 RAG 检索器封装成一个函数或者说工具注册进 Agent 的工具列表里。Agent 在思考过程中判断这个问题需要查知识库就调用这个工具把检索结果拿回来作为下一步决策的上下文。这一层的好处是解耦。你的 Agent 可以做别的任务需要知识时随时调一下知识库。我在做客服 Agent 时就是这么接的主 Agent 负责判断意图如果想了解产品规则就调 RAG 工具拿到片段后再组织回答。这种方式很稳妥适合大多数业务场景。工具的描述信息很重要比如在公司产品知识库中检索售后政策相关内容输入为问题原文这能帮助 Agent 决定什么时候该用、什么时候不该用。4.2 方式二让 Agent 自己决定检索策略Agentic RAG耦合再深一层是让 Agent 不只会查一次还会自己决定怎么查。比如它先检索到一个大概念发现信息不够再决定拆成多个子问题继续检索再比如它发现检索结果太旧就换关键词重新查。这被称为 Agentic RAG——检索的步骤、次数、重查策略都由 Agent 动态规划而不是一次性固定检索。我做过一个对比测试同样的知识库普通 RAG 在一道多条件组合问题上答得比较差因为单个 query 很难覆盖全部条件。Agentic RAG 会把问题拆成价格区间适用平台限制条件三个子查询分别检索再汇总准确率高很多。代价是调用次数增加延迟和成本同步上升。所以我现在的实践是简单问题走普通 RAG复杂问题才放 Agent 自主规划检索。判断标准可以是一个简单的意图分类器也可以让 Agent 自己判断。4.3 方式三知识管道与规划、执行的协同如果你的 Agent 已经具备规划—执行—观察的循环能力RAG 就可以更进一步变成整个循环里的知识底座。Agent 规划出的每一步都可以引用知识库里的信息来校验执行完一个操作后也可以把观察结果和新知识写回知识库形成闭环。这种方式最适合知识密集型的运维或分析场景。比如排查一个问题时Agent 先从知识库里找到相关的排障手册执行检查命令把输出结果和手册对照判断下一步动作。RAG 在这里不再是回答用户问题的附件而是 Agent 做决策的证据源。代价是链路复杂度上来很多你得处理知识写入、版本覆盖、上下文累积等一连串问题。我的建议是前两种方式先跑稳再考虑第三种。5. 跑通之后必须面对的五个实际问题最小管道跑通只是起点。问题会在你真正用起来之后浮出来而且每一个都跟效果不好直接挂钩。下面五个问题我基本都在项目里踩过有些是调参能解决的有些必须改设计。5.1 召回质量怎么评估命中率之外还有重排很多团队只看最终回答好不好,但 RAG 管道的上游是检索必须单独评估。基础指标是命中率hit rate对测试集里的每个问题检查 top-k 结果里是否包含人工标注的正确片段。更深一点要评估平均倒数排名MRR看正确答案排在第几位。如果你发现命中率不达标先别急着换 embedding 模型大概率是切分粒度问题。切块太大语义混杂检索模糊切块太小上下文不足模型看不懂。我调过一次文档切分粒度从 512 降到 256命中率反而涨了 6 个百分点。另外在检索环节之后加一个重排器是性价比很高的做法top-20 的粗召回结果经 reranker 精排后取 top-5 送给 LLM能显著减少前几个结果看着相关但其实不是最优的问题。5.2 切分粒度不是越小越好新手最容易走极端切得碎以为这样检索精确。结果片段太短语义不完整模型拿到手根本不知道在讲什么。我的经验是切分粒度要配合下游指令一起看。如果你的 prompt 里明确告诉模型参考每一段时注意它所属的章节标题那么切分时保留标题元数据会比单纯缩小 chunk 更有效。另一个细节是重叠区。切分时让相邻片段保留一小段重叠文本可以避免一个完整句子或关键术语在切缝处被截断。重叠不是越大越好我控制在 10% 到 20% 之间。重叠太大会引入大量重复片段导致检索结果里前后两条几乎一样的内容白白浪费上下文窗口。5.3 多轮对话中的上下文污染Agent 几乎都是多轮对话场景。你第一轮问了这个功能怎么配置第二轮追问那权限呢此时如果直接把上一轮检索结果继续拼进这一轮的 prompt会产生严重的上下文污染。我踩过最明显的坑是第二轮模型把上一轮的配置步骤带进了权限问题的回答里。解决思路是每一轮的检索上下文只与当轮 query 相关历史对话只保留用户意图摘要不要保留历史检索片段。更精细的做法是让 Agent 先判断这个问题是不是对上一轮的延续如果是就把上一轮关键结论压缩成状态摘要再和新的检索结果一起输入。这一条对体验影响非常大。5.4 更新与删除知识库的版本管理RAG 最难维护的部分之一不是建库而是文档更新。今天改了产品手册如果只把新文档重新入库而没有删除旧的碎片检索结果里会出现新旧版本打架的情况。尤其是技术方案类的文档版本冲突会让回答自相矛盾。我在项目里的做法是把整套知识库按数据源版本管理。每次同步时先删掉这个数据源对应的所有旧 chunk再写入新文档的 chunk。同时给每个 chunk 记录更新时间检索拼接时可以做一层过滤比如优先取最近 3 个月的数据。如果你用的是支持按元数据过滤的向量数据库这类版本控制实现起来不复杂关键是别省掉这一步。5.5 成本与延迟每一步检索都要算账RAG 管道的额外成本来自三块embedding 调用、向量库存储、重排序。其中重排序的延迟最容易被低估一次 rerank 可能增加 200 到 500 毫秒对实时问答场景是不可接受的开销。我的实践是简单问题跳过 reranker只做向量召回快复杂问题才启用完整链路准。成本上我还有一个不算技巧的技巧把 embedding 结果做本地缓存。同一个 query 在一段时间内重复出现的情况非常多缓存命中能直接省掉 embedding 调用。另外向量库的存储量要有意识控制按当前业务真正需要被检索的内容来建库而不是把所有历史文件一股脑全塞进去。知识管道不是仓库它是取用频率高的资料抽屉。我在实际项目里最深的体会是RAG 的参数和策略没有一个通用最优解它高度依赖你的文档形态、用户提问方式和延迟要求。所以如果你做完一遍之后发现效果不够好不要沮丧这很正常。比较好的处理方式是把你自己的测试集固定下来每次改动只动一个变量慢慢逼近适合你场景的配置。知识获取管道本身不是一个做完就结束的功能它是一个需要持续维护的工程环节。希望这篇能帮你把 RAG 的基础链路跑通也让你在看到 Agentic RAG 这类进阶方案时心里知道那些能力是在什么地基上长出来的。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询