☰
AI Agent核心:RAG知识管道从架构到实践详解
2026/11/4 10:04:02 网站建设 项目流程

1. 先从 Agent 架构里把"知识管道"单独拎出来看

写 AI Agent 系列写到第四篇,前面几篇分别聊了 Agent 的基础认知、规划能力和工具调用,这一篇切入的角度非常关键——知识获取管道。简单说,就是 Agent 到底从哪里拿到它回答问题、做决策所需要的"事实"。

先给一个整体框架,免得大家陷入细节出不来。一个完整 AI Agent 的架构通常包含几个核心模块:

  • 感知模块:接收多模态输入,理解用户意图
  • 记忆模块:短期上下文 + 长期知识存储
  • 规划模块:任务拆解、步骤编排、路径选择
  • 行动模块:调用工具、执行动作、获取外部反馈

本篇聚焦的是记忆模块里的知识获取管道,也就是 RAG(Retrieval-Augmented Generation,检索增强生成)。你完全可以把它理解为 Agent 的"长期记忆外挂"——模型本身的参数知识是它的"先天记忆",RAG 解决的是"后天补充资料并随时查阅"的问题。

我见过很多初学者一上来就堆 LangChain 代码,把数据灌进向量库,然后调一个检索链条就跑,完全没想过为什么要这样设计。结果一问"知识更新了怎么办""检索不准怎么办""多轮对话里怎么用历史信息",全懵。这篇不从代码教起,而是从"为什么要这么设计""管道里每一环在解决什么问题"讲起,最后才落到实操参数和避坑经验上。

一句话概括:RAG 不是向量数据库 + Prompt 拼接的玩具,它是 Agent 知识的质量控制和分发中枢。

2. 为什么一篇讲 Agent 的文章要花大篇幅先讲 RAG

很多人会有个疑问:我已经有 LLM 了,模型本身知道那么多知识,为什么还要搞一套 RAG?这个问题我每次分享都要解释一遍,因为答案直接决定了整套系统的架构取舍。

2.1 模型参数知识的天花板

LLM 的知识存储在参数里,本质上是海量语料的压缩统计结果。它有三个绕不开的问题:

  • 知识新鲜度差:训练数据截止日期就是它的知识保质期。问它最近发布的产品信息、最新的行业政策、刚出来的论文结论,几乎必然出错或开始"编"。
  • 私有知识完全缺失:企业内部文档、个人笔记、特定项目的技术方案、某个系统的接口文档,这些东西根本不在公开语料里,模型自然无从知晓。
  • 知识粒度不可控:即便模型"知道"某个领域,它的回答粒度是全局统计的。你问一个具体到某个版本、某个参数、某个团队内部的约定事项,它只能给你一个相似但错误的内容。

这不是模型的问题,这是所有统计模型的边界。而 Agent 要落地到真实业务里,恰恰天天要面对这三类"模型不知道但系统必须知道"的知识。

2.2 Agent 场景里的 RAG 不是"可选优化",是"地基"

我做过一个企业内部文档问答 Agent,最开始没有接 RAG,纯靠给模型写一大堆 system prompt 去约束它。结果很惨:让它引用公司报销制度的具体条款,它给你编了个像模像样但根本不存在的"第 4.3 条";让它根据项目周报汇总进度,它把两个不同项目的相似描述合并到了一起。这就是典型的"参数知识污染"——模型分不清哪些是它见过的网上知识,哪些是它此刻应该依赖的企业知识。

加入 RAG 之后,逻辑变成了这样:

  1. 用户提问
  2. Agent 先从企业知识库检索出最相关的 3~5 段资料
  3. 把资料作为上下文注入 Prompt
  4. 模型基于"资料 + 问题"生成答案
  5. 答案末尾附上资料来源引用

本质上模型从"我凭记忆回答"变成了"我查阅资料后回答"。后者的可靠性、可追溯性、可更新性完全不在一个数量级。

2.3 RAG 给了 Agent "可验证的底气"

这是很多技术文章不点破的一点。Agent 一旦要自主行动、自主决策,它就必然会遇到"拿不准"的情况。这时候如果靠模型记忆硬猜,错误会被放大;如果有一条管道可以去查资料、去对比、去引用,Agent 的行为就变得可以被审计、被解释、被修正。说白了,RAG 让 Agent 的"不知道"和"瞎说"有了区分度。这个区分度,恰恰是 Agent 产品能否在企业里落地的最低门槛。

3. 让整套 RAG 管道真正跑起来:拆分、向量化、检索、生成

理论铺垫完,进入实操。我按一条最小可用管道的顺序拆解,每步都会讲清"为什么这么做"和"参数怎么定"。

3.1 文档加载与清洗:脏数据进,脏答案出

管道的第一环是文档接入。这里的核心原则是:你对文档做的预处理质量,决定了整个 RAG 检索质量的上限。

我常用的做法:

  • 格式归一化:PDF、Word、Markdown、HTML、TXT 全部转成纯文本或 Markdown。PDF 用 PyMuPDF 提取,遇到扫描件还要先走 OCR,这时候选 Tesseract 还是 PaddleOCR 取决于语言和清晰度,中文文档我推荐 PaddleOCR,准确率明显高一截。
  • 结构信息保留:直接用 pdfplumber 之类按页提取会丢失标题层级、表格结构、代码块的上下文关系。更好的办法是转成 Markdown,保留#标题层级,后面切块和检索都能利用这些结构信号。
  • 噪声过滤:页眉页脚、导航栏文案、重复的版权声明、乱码残留,这些都要在清洗阶段干掉。否则入向量库以后,检索到的片段里有一半是无关噪声,再好的模型也回答不出准确的答案。

注意:清洗阶段最容易被忽视的是表格数据。表格一旦被摊平成纯文本,表格的语义关系就丢了。后续检索如果依赖表格做题,效果会很差。建议至少把标准表格按"表头 : 单元格"的键值对形式转换,或者干脆用多模态模型直接从图片表格里抽取结构化数据再入文本。

3.2 分块策略:切多少、怎么切、要不要重叠

文档进入管道后,要切成固定大小的文本块。这里没有一个万能参数,但有几个经验和试错方向。

块大小的选择逻辑

模型推理的上下文窗口有限,检索回来的每段文本都会占用 Prompt 空间。块太小,语义不完整,检索到局部却看不懂全局;块太大,三个块就把上下文塞满了,答案生成的自由度变小,检索的精确命中率反而下降。

我自己的经验值:

文档类型初始块大小重叠长度理由
技术文档/操作手册512 token50~100步骤性内容较多,512 足以容纳完整操作步骤
长论文/研究报告768~1024 token128段落逻辑较强,拆太小会破坏论证结构
代码文件按函数/类切块0代码语义边界清晰,按函数切最合理
对话记录/问答对256~384 token32问答内容短促,块太大检索命中率低

切块方式

字符数切块、token 数切块、语义边界切块三者的区别我实际感受是很大的。字符切简单粗暴,中文环境下 500 字和 512 token 差距不大,但英文文档 token 切更合理;语义边界切(按段落、按 Markdown 标题分节、按代码函数分块)是最好的,因为每一块都是一个相对完整的"话",检索到它之后模型能看懂全局。

重叠窗口的必要性

重叠是为了防"一句话被拦腰切断"的情况。比如一段文字在第 499 个 token 处讲到关键结论,上一块只包含它的前半句,下一块只包含后半句。不重叠的情况下,检索结果就是两段残缺的话,模型要费力拼接。重叠 50~100 token,代价是向量库体积增加 10%~20%,但检索准确率提升明显,我在大多数项目里都保留重叠。

3.3 向量化:Embedding 模型的选择与比较

切好块之后,要把每块文本转成向量。Embedding 模型的选择直接决定"语义相似"的判断标准,这个环节不夸张地说,比后面的检索代码重要得多。

怎么选一个够用的 Embedding 模型

  • 中文场景:我现在的主力是BAAI/bge-m3,它在中文语义匹配、检索任务上非常稳定,支持 8192 的输入长度,还能做多语言混合。早期项目用过shibing624/text2vec-base-chinese,也能跑,但长文本和多语言混合场景明显弱一截。
  • 英文场景:OpenAI text-embedding-3-large或BAAI/bge-large-en-v1.5都可以,BGE 系列的开源优势在于数据完全可控,不用把企业内部文档发给外部接口。
  • 行业特殊术语多(医疗、法律、金融):通用 Embedding 经常对专业术语理解不到位,这时候优先考虑领域微调,或者改用专门的领域模型。

实际对比的方法

别听人推荐就拍板。拿你自己领域里的 50~100 个真实问答对,分别用候选模型做检索,看 top5 命中率,这个指标叫 hit rate。我自己选型时给三个模型各跑了 200 条 query,误差低于 3% 才会定下来,不然宁可用稍慢但更准的模型。

提示:本地部署还是 API 调用,这个决策不只看单次成本。RAG 检索通常是高频操作,每个用户问题都要检索多次,如果走 API,成本会线性涨。企业场景、文档量大、调用频繁的,建议本地部署一个 7B 级别的 Embedding 模型,一张消费级显卡甚至纯 CPU 都能带动。

3.4 索引与存储:向量库 + 元数据过滤

向量数据存储层,市面上的方案不少:FAISS、Milvus、Weaviate、Qdrant、Chroma。我现在的选型标准很简单:

  • 练手和原型:FAISS 就够了,轻量、无需额外服务,跑在内存里。
  • 小团队生产环境:用 Qdrant 或 Milvus,支持过滤、副本、持久化、多租户隔离。
  • 需要和生态整合:PostgreSQL + pgvector 也很好,一个库把业务数据和向量都管了,运维省心。

元数据过滤是我强烈建议一开始就设计的。比如企业内部知识库,文档可能按部门、文档类型、时间、权限级别打标签。检索时如果有元数据过滤条件,就能先圈定范围再算相似度,精度和性能都大幅提升。没有元数据过滤,你检索全公司的文档,某个团队的内部方案经常淹没在不相关的资料里。

3.5 检索与重排序:别只信 Top-K 相似度

第一步检索通常用余弦相似度或内积取 Top-K(K 我默认 20~50)。但原始向量召回只是"粗排",必须接一个**重排序(Re-rank)**环节。

为什么?向量检索擅长找"语义相关",但不擅长判断"精确匹配"。比如你问"报销标准是多少",向量召回可能给你一堆"报销流程""报销类型"的文章,真正的数字标准却排到了十几名开外。粗排取太多噪声、取太少漏答案,最稳妥的做法是:

  1. 向量检索先召回 Top50
  2. 用一个交叉编码器(Cross Encoder)模型对(query, 文档块)逐对打分
  3. 按精排分数取 Top3~5 进入 Prompt

重排序模型我常用BAAI/bge-reranker-v2-m3,它对中英文混合和长文档都支持得不错。加了 rerank 之后,我几个项目的答案准确率从 60%~70% 提升到了 85% 以上,这个环节投入产出比极高。

3.6 生成:把检索结果组织成模型可用的上下文

最后一步,把重排序后的文本块拼进 Prompt,让生成模型回答。这个过程有三个经验:

  • 引用标注:每个检索块前面加编号,生成时要求模型在答案中标注来源编号,比如"根据 [1][2] 所述……"。这样答案可以追踪,出错时能定位是知识库哪个文档造成的。
  • 限制生成边界:Prompt 里要清晰说明,如果检索资料不足以回答问题,明确回答"知识库中没有找到相关内容",而不是强行编造。这能显著降低幻觉率。
  • 保留原始问题上下文:多轮对话里,别只把当前问题丢给检索管道,要把整个会话的压缩摘要作为检索输入的一部分。不然"它呢?效果怎么样?"这种代词引用式问题会完全检索不到正确资料。

4. 我在配置 RAG 时反复调整的几个工程细节

讲完主流程,这节把我的踩坑总结集中写一下。这些细节正常情况下文档里不会写,但对生产环境的影响非常大。

4.1 块大小和真实查询粒度的匹配

一个很隐蔽的问题:你切块的大小,要和用户真实问题的"粒度"匹配。如果用户问的是"Python 里怎样做字符串格式化",而你文档切的是 1024 token 的大段落,那么每一块里既有字符串格式化又有文件读写又有异常处理,检索回来的"相关"其实是一坨大杂烩。相反,如果文档是操作手册,用户问"部署步骤是什么",你切 256 token 就会把完整流程切开,检索回来只有第一步和第五步,模型根本拼不出全流程。

我的做法是:先做一轮用户真实问题聚类,分析高频问题涉及的文档片段大概多长,再反过来定 chunk 大小。这不是一次定死的,上线之后还要定期根据 bad case 分析反推调整。

4.2 元数据过滤比想象的更有价值

这个在 3.4 提过,但我要再强调一遍。RAG 检索不准的最大来源之一,就是"知识库里东西太多,什么都像相关"。加一层时间过滤,能让"最近三个月的数据"优先返回;加一层部门过滤,能让 A 组的方案不会干扰 B 组的检索。尤其常见的是产品说明书类知识库,新旧版本混在一起,不加版本过滤,检索结果经常新旧参半,答案自相矛盾。

4.3 混合检索:一定要打开的关键字能力

纯向量检索有一个盲区:专有名词、缩写、型号、人名、编号。这些东西的字面信息比语义信息更关键。比如技术文档里频繁出现的 "LSTM-3000" 这种型号名,向量化之后语义相近的 "3000L" 设备文档也可能被召回,但你真正想找的是完全匹配的型号。

所以我默认管道里同时保留关键词检索(BM25)和向量检索,再用 RRF(Reciprocal Rank Fusion)把两路结果融合。实践下来,带型号、工单号、订单号这类查询,混合检索的准确率比纯向量检索高出 20% 以上。

4.4 重排序该在什么时候接入

不是所有场景都需要重排序。如果知识库只有几百个文档块,向量搜索 Top5 直接进 Prompt 就够了,再加一个 rerank 模型纯属增加复杂度和延迟。但一旦文档块数量超过几万,或者检索结果相关性经常不稳定,重排序就必须上。

延迟预算也要考虑:重排序模型需要把 query 和每个候选块配对做前向计算,50 个候选大约增加 100~300ms,对于实时对话场景是个可感知的成本。批量离线分析场景则无所谓,直接用最强模型。

4.5 检索结果的自查机制

一个容易忽略的问题:你怎么知道检索结果"够好"?我现在的做法是给管道加一层"自查逻辑"——重排序后拿到 Top3 分数,如果最高分低于某个阈值,说明知识库里大概率没有相关内容。这时候 Agent 不该硬答,而应该明确告诉用户"知识库中未找到足够相关信息,建议补充资料或换种问法",或者启动备用管道(Web 检索)。

这个阈值必须用离线评估集去标定,取"开"和"关"之间分界最清晰的点。别拍脑袋定,否则你会发现很多问题被静默吞掉了。

5. 知识新鲜度、多轮记忆和检索智能化的三层演进

基础 RAG 跑通之后,进入 Agent 场景里你会碰到三个进阶问题:知识更新、多轮对话、检索策略本身要不要动态化。一个个说。

5.1 知识更新:增量索引而不是全量重建

知识库不可能静止。企业内部文档每周都在产生新的,产品手册每发一个版本就要替换旧的。最笨的方法是隔段时间全量重建向量库,简单但慢,文档多的时候一次费几小时,而且期间检索质量不可控。

增量更新的做法是:每个文档块记录来源文件的版本号和变更时间,每次上传新文档,解析后只对新块做向量化,同时把旧版本的块标记为无效(软删除)。检索时通过元数据过滤排除已失效版本。这套方案配合一个简单的版本管理表,完全不需要引入复杂的向量库运维组件。

5.2 多轮检索记忆:Agent 不能每次都"失忆"

单轮 RAG 好做,多轮对话才是 Agent 的主战场。用户第一轮问"公司的差旅标准",第二轮问"那住宿标准呢",Agent 要能带着第一轮的话题去检索。最简单的做法是把最近几轮对话压缩成一个"当前话题摘要",喂给检索管道。更进一步的做法是引入记忆分层:短期记忆(最近几轮对话原文)、长期记忆(用户偏好、历史关键决策),让检索管道能同时参考这两层信息。

我踩过的坑是,把完整对话历史全文都喂给检索管道,结果历史里的噪声文本污染了检索查询,相关性反而下降。压缩摘要的效果远好于原文拼接。

5.3 Agentic RAG:从一次检索到按需检索

最后聊一下 agentic rag。传统 RAG 是一问一检——用户提问,系统检索,模型回答。但复杂问题往往需要多步检索:先检索目录了解知识库有哪些内容,再逐步深入子话题;或者先检索到一个初步结论,再针对结论中的未知点发起第二轮检索。这种"检索 - 判断 - 再检索"的循环,本质上就是 RAG 管道被 Agent 的规划能力驱动。

我的经验是,不要把 agentic rag 当作炫技。它适合知识库维度多、问题复杂度高的场景,比如政策咨询、技术合规审查。简单的 FAQ 检索用固定管道就足够了,引入 agentic rag 反而增加了延迟和 token 消耗。

5.4 RAG 之外的知识获取方式

RAG 是知识获取管道的核心,但不是全部。系统提示词(system prompt 里写死的团队规范)、函数工具调用(查数据库、查 API)、代码解释器(执行 Python 做计算)都是 Agent 获取知识的途径。我在设计 Agent 时通常按三层组合:先查结构化 API,再检索非结构化文档,最后才依赖模型参数记忆。顺序很重要,结构化数据的准确性最高,非结构化文档次之,参数记忆最不可控,尽量只用它做语言组织而不是提供事实。

Agent 的知识获取管道建设,本质上是解决"模型不知道但任务需要知道"的问题。把 RAG 的每一环——清洗、分块、向量化、检索、重排序、生成——都理解成一种对知识的"精炼"工序,整个系统的设计思路就会清晰得多。下一篇可以接着聊 Agent 的记忆管理机制,RAG 作为记忆模块的一部分,如何和短期上下文、长期偏好记忆协同工作。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询