news 2026/9/30 0:28:36

AI Agent知识获取管道:RAG检索增强生成实战与稠密嵌入调优

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI Agent知识获取管道:RAG检索增强生成实战与稠密嵌入调优

1. 为什么知识获取管道是 AI Agent 落地的第一道坎

做 AI Agent 的人迟早会撞上一堵墙:模型本身很聪明,但你问它公司内部的报销标准、上周刚更新的产品参数、某个客户的特殊约定,它要么一本正经地胡说,要么干脆告诉你"我没有这方面的信息"。这不是模型不行,而是它的知识边界被训练数据锁死了。知识获取管道要解决的,就是把这个边界打开,让 Agent 在回答问题之前,先去外部知识源里把相关材料捞出来,再基于材料组织答案。这套机制的核心实现方式,就是RAG(检索增强生成)。

我在过去一年里帮几个团队搭过 Agent 的知识层,从最初用现成框架跑通 Demo,到后来自己拆开每一层做调优,踩过的坑比想象中多。很多人以为 RAG 就是"把文档切一切、塞进向量库、检索出来拼进 Prompt",真上手才发现:切分策略不对,检索出来的全是半截话;嵌入模型选错,语义相近的问题匹配不到;召回率看着挺高,但真正有用的片段排在第十几位,模型根本用不上。这些问题不会在 Demo 阶段暴露,一旦上真实数据就集中爆发。

这篇内容适合三类人:正在从零搭建 AI Agent、需要给它接上私有知识库的开发者;已经跑通了 RAG 流程、但效果不稳定的工程师;以及想搞清楚 RAG 到底怎么回事、不想被各种框架名词绕晕的技术负责人。我会从知识获取管道的整体结构讲起,把稠密嵌入、向量检索、上下文组装这几个关键环节拆开,配上我实际调参的经验和踩坑记录。读完你应该能自己判断:我的场景该用多大的切分粒度、嵌入模型怎么选、检索结果怎么过滤才不浪费上下文窗口。

先说一个反直觉的结论:RAG 的效果瓶颈,八成不在生成模型,而在检索质量。你换一个更强的 LLM,回答可能更流畅,但如果检索回来的材料本身就是错的、残缺的、不相关的,再强的模型也只能基于垃圾输出垃圾。所以这篇的重点会放在管道的前半段——知识怎么进来、怎么存、怎么被准确捞出来。

2. 知识获取管道的完整链路拆解

2.1 从原始文档到可检索片段的四个阶段

一条完整的知识获取管道,我习惯把它拆成四个阶段:摄取、切分、嵌入、索引。这四个阶段环环相扣,任何一个环节偷懒,后面都要加倍还回来。

摄取阶段负责把各种格式的原始资料读进来。PDF、Word、Markdown、网页、数据库导出、甚至聊天记录,格式五花八门。这一步最容易被低估,很多人直接拿个库把 PDF 转成纯文本就完事,结果表格结构全丢了、页眉页脚混进正文、多栏排版读成了乱序。我的做法是:对结构化程度高的文档(比如产品手册、API 文档),优先保留其原有的层级结构,用 Markdown 作为中间格式;对扫描件或排版复杂的 PDF,宁可多花点时间做版面分析,也不要图省事直接抽文本。

切分阶段是把长文档拆成适合检索和嵌入的小块。这里有个核心矛盾:块太小,语义不完整,检索出来是断章取义;块太大,噪声多,嵌入向量被稀释,匹配精度下降。业界常见的做法是 256 到 512 个 token 一块,配合一定的重叠(overlap)。但我不建议你直接抄这个数字,后面会专门讲怎么根据自己的数据定切分粒度。

嵌入阶段是把每个文本块转成一个高维向量,也就是稠密嵌入。这个向量捕捉的是文本的语义,语义相近的文本,向量在空间里的距离就近。嵌入模型的选择直接决定了检索的天花板,选错了后面怎么调都费劲。

索引阶段是把这些向量存进向量数据库,建立高效的相似度检索结构。常见的有 HNSW、IVF 这类近似最近邻算法,目的是在百万级甚至亿级向量里快速找到最相近的若干个。

2.2 检索与生成之间那道容易被忽略的缝

很多人把管道理解到"检索出 Top-K 个片段"就结束了,其实检索和生成之间还有一道关键的缝:上下文组装。检索回来的片段不能原封不动全塞进 Prompt,你得考虑几件事。

第一是去重和排序。同一个知识点可能在多个片段里重复出现,全塞进去既浪费上下文窗口,又可能让模型过度关注某个重复信息。我一般会做一次相似度去重,把高度重叠的片段合并或丢弃。

第二是相关性阈值过滤。不是所有检索结果都值得用。如果某个片段的相似度分数明显低于其他片段,它大概率是噪声,硬塞进去反而干扰模型判断。设一个动态阈值,比固定取 Top-5 要靠谱得多。

第三是上下文预算分配。模型的上下文窗口是有限的,检索片段、系统提示、对话历史、用户问题都要占地方。你得算清楚留给检索材料多少 token,超了就按相关性从低到高砍。我见过有人检索回来二十个片段全塞进去,结果把对话历史挤没了,多轮对话直接失忆。

提示:上下文组装这一步没有标准答案,但有一个原则——宁可少而精,不要多而杂。三个高度相关的片段,效果通常好过十个良莠不齐的片段。

2.3 一个最小可用的管道长什么样

如果你现在就想动手,我给你一个最小可用的管道结构,不依赖任何重型框架也能跑起来:

  1. 用文档解析库把原始资料转成带结构的文本(Markdown 优先)
  2. 按语义边界切分成块,块之间保留 10% 到 20% 的重叠
  3. 用嵌入模型把每个块转成向量,连同原文和元数据一起存进向量库
  4. 用户提问时,把问题也转成向量,在向量库里做相似度检索
  5. 对检索结果做去重、阈值过滤、重排序
  6. 把筛选后的片段拼进 Prompt,交给 LLM 生成答案

这个结构看起来简单,但每一步都有讲究。接下来我逐个拆开讲,重点讲那些"看起来能跑、实际会出问题"的地方。

3. 稠密嵌入:检索质量的天花板由它决定

3.1 嵌入模型到底在做什么

稠密嵌入这个词听起来唬人,本质其实很朴素:把一段文本映射成一个固定长度的数字数组,比如 768 维或 1024 维。这个数组就是这段文本在语义空间里的坐标。语义相近的文本,坐标就靠近;语义无关的,坐标就离得远。检索的时候,把用户问题也映射成同样的坐标,然后找离它最近的那些文本块。

关键在于"语义相近"这四个字。传统的关键词检索只能匹配字面相同的词,你搜"如何退款",它匹配不到写着"申请退货流程"的文档。而稠密嵌入能捕捉到这两者在语义上的关联,因为它们表达的是同一件事。这就是为什么 RAG 比传统搜索更适合处理自然语言提问。

但嵌入模型不是万能的。它对训练数据覆盖的领域表现好,对完全陌生的领域会退化。比如一个主要用通用语料训练的嵌入模型,拿去处理法律条文或医疗术语,效果可能还不如关键词检索。所以选嵌入模型时,领域匹配度比模型大小更重要。

3.2 选嵌入模型时我实际看的几个指标

市面上的嵌入模型很多,从开源的到商业 API 都有。我选型时主要看这几个维度:

维度说明我的取舍
向量维度维度越高表达能力越强,但存储和计算成本也越高768 到 1024 维是甜点区,超过 1536 收益递减明显
最大输入长度单次能嵌入多长的文本至少要覆盖你的切分块大小,否则会被截断
领域适配是否在你的领域语料上训练或微调过通用模型够用就用通用,专业领域优先找适配版
多语言能力是否支持中英文混合中文场景必须实测中文语义匹配效果
推理成本本地部署还是 API 调用,延迟和费用如何数据量大且敏感就本地部署,追求快速上线用 API

我踩过的一个坑是:早期图省事用了一个英文为主的嵌入模型处理中文文档,结果中文语义匹配一塌糊涂,两个意思完全不同的中文句子,向量相似度却很高。后来换成中文优化过的模型,检索准确率立刻上了一个台阶。中文场景一定要用中文语料训练或优化过的嵌入模型,这一点没有捷径。

3.3 嵌入不是一劳永逸,数据变了要重建

有个容易被忽略的问题:嵌入是静态的。你把文档嵌入成向量存进库里的那一刻,这个向量就固定了。如果嵌入模型升级了,或者你的文档内容更新了,旧向量和新向量就不在同一个语义空间里,混在一起检索会出问题。

我的做法是给向量库里的每条记录都带上嵌入模型版本和文档版本的元数据。模型升级或文档大改时,触发一次全量重建。增量更新也要小心:新文档用新模型嵌入,旧文档还是旧模型,两者相似度计算就不可比了。所以要么全量重建,要么保证新旧文档用同一个模型版本。

注意:向量库不是数据库,它不擅长频繁的增删改。如果你的知识更新很频繁,建议设计成"批量重建 + 版本切换"的模式,而不是实时逐条更新。

4. 切分策略:决定检索精度的隐形手

4.1 固定长度切分为什么经常翻车

最简单的切分方式是按固定字符数或 token 数切,比如每 500 个字符一块。这种方式实现简单,但问题很明显:它会在句子中间、段落中间甚至词语中间切断,导致每个块的首尾都是残缺的语义。

我做过一个对比实验:同一批产品文档,一组按固定 500 字符切,一组按段落和标题层级切。检索同一个问题时,固定切分的组经常召回一些"上半句在讲 A、下半句在讲 B"的块,模型拿到这种材料,回答要么含糊要么跑偏。而按语义边界切的组,召回的块基本都是完整表达一个意思的,回答质量明显更稳。

所以我的原则是:优先按文档的自然结构切,结构不明确时再退回到固定长度加重叠。Markdown 的标题、段落、列表项,HTML 的标签层级,代码的函数边界,这些都是天然的切分点。

4.2 重叠窗口设多少才合适

块之间保留重叠,是为了防止一个完整的语义被切分点劈成两半,导致两边都检索不到。比如一句话跨越了两个块,如果没有重叠,这句话在两个块里都是残缺的,检索时可能都匹配不上。

重叠比例我一般设在10% 到 20%。太小起不到保护作用,太大则会造成大量重复内容,浪费存储和检索开销。具体怎么定,可以这样想:如果你的块是 500 token,重叠 50 到 100 token 基本够用。如果文档里长句、跨段逻辑特别多,可以适当加大到 25%。

但重叠不是越多越好。我见过有人设 50% 重叠,结果检索出来的 Top-5 里有三个块内容高度重复,等于白白浪费了上下文窗口。重叠是为了兜底,不是为了堆量。

4.3 按标题层级切分的实操细节

对于结构清晰的文档,我最推荐按标题层级切分。具体做法是:把文档解析成树状结构,每个叶子节点(最细一级的标题下的内容)作为一个基础块。如果某个叶子节点内容太长,再在内部按段落二次切分;如果太短,就和相邻的兄弟节点合并。

这样做的好处是每个块都自带上下文路径。比如一个块来自"产品手册 > 第三章 计费规则 > 3.2 退款政策",检索出来的时候,你可以把这个路径作为元数据一起带上,模型看到路径就知道这段内容属于哪个部分,理解起来更准确。

我在实际项目里会给每个块存这些元数据:来源文档、标题路径、块在文档中的位置、创建时间、文档版本。这些信息在检索后过滤和结果展示时非常有用。比如用户问的是最新政策,你就可以按创建时间过滤掉旧版本的内容。

4.4 特殊内容的切分要单独处理

表格、代码、公式这几类内容,用通用的文本切分方式处理会出大问题。

表格如果被按行切开,表头和数据行分离,检索出来就是一堆没有意义的数字。我的做法是把表格整体作为一个块,或者转成"字段名: 值"的键值对形式再嵌入。如果表格特别大,就按行分组,但每组都要重复带上表头。

代码要按函数或类切分,保持语法完整。把函数从中间切断,嵌入出来的向量语义是混乱的。同时代码块最好带上它所在的文件路径和函数签名作为元数据。

公式建议转成 LaTeX 或自然语言描述再嵌入,直接嵌入公式符号,嵌入模型基本理解不了。

5. 向量检索与重排序的配合打法

5.1 相似度计算方式的选择

向量检索的核心是计算两个向量的相似度。常见的有余弦相似度、点积、欧氏距离。余弦相似度只看方向不看长度,对文本嵌入最常用;点积受向量长度影响,如果嵌入模型输出的是归一化向量,点积和余弦等价;欧氏距离衡量的是空间直线距离,对绝对位置敏感。

大多数嵌入模型配套的检索库会默认用余弦相似度,你直接用就行。但要注意一点:不同嵌入模型的相似度分数不可比。A 模型算出来 0.85 算高度相关,B 模型算出来 0.85 可能只是中等相关。所以阈值过滤的数值必须针对你实际用的模型来标定,不能照搬别人的经验值。

5.2 为什么需要重排序这一步

向量检索是粗筛,它快,但不够准。它把语义相近的候选捞出来,但排序未必符合真正的相关性。这时候就需要重排序(Rerank):用一个更精细但更慢的模型,对粗筛出来的候选重新打分排序。

重排序模型通常是交叉编码器(Cross-Encoder),它把问题和候选片段拼在一起输入模型,直接输出相关性分数。这种方式比向量点积精确得多,因为它能捕捉问题和片段之间的细粒度交互。代价是慢,所以只用在粗筛后的少量候选上。

我的标准流程是:向量检索召回 Top-20 到 Top-50,重排序后取 Top-3 到 Top-5 送给 LLM。实测下来,加了重排序之后,真正有用的片段排进前三的概率大幅提升,模型回答的准确率也跟着涨。这一步的投入产出比非常高,强烈建议加上。

5.3 混合检索:稠密加稀疏的组合拳

纯稠密嵌入有个短板:对专有名词、产品型号、错误码这类精确匹配需求,它不如关键词检索。比如用户搜"错误码 E5021",稠密嵌入可能把它和"错误码 E5022"匹配得很近,因为语义上都是"错误码"相关,但用户要的是精确的那一个。

解决办法是混合检索:一路用稠密嵌入做语义召回,一路用稀疏检索(比如 BM25)做关键词召回,然后把两路结果融合。融合方式有加权求和、倒数排名融合(RRF)等。我一般用 RRF,因为它不需要调权重,对两路结果的分数尺度不敏感,比较省心。

混合检索在真实业务里几乎是标配。纯语义检索在 Demo 上看着很美,一上真实数据,遇到型号、编号、专有名词就露馅。

5.4 检索结果去重与多样性控制

检索回来的片段经常有大量重复。同一个知识点在文档里出现多次,或者切分时的重叠导致相邻块内容高度相似,都会让 Top-K 里塞满重复信息。

我的去重做法是:对候选片段两两计算相似度,超过阈值的只保留分数最高的那个。另外还可以做多样性控制,比如用 MMR(最大边际相关性)算法,在保证相关性的同时,让选出的片段之间尽量不重复,覆盖不同的信息点。

这个在处理"总结类"问题时特别有用。用户问"这个产品的核心功能有哪些",如果检索回来的五个片段都在讲同一个功能,模型总结出来就只有一个功能。多样性控制能保证检索结果覆盖到不同方面。

6. 把管道跑起来之后才会遇到的真实问题

6.1 召回率看着高,回答却不对

这是最典型的"数据好看、效果拉胯"场景。你测召回率,Top-10 里确实有相关片段,召回率 90% 以上,但用户就是觉得回答不对。问题往往出在排序上:相关片段排在第七第八位,而模型只用了前三个,自然答不好。

解决办法就是前面说的重排序,把真正相关的顶上来。另一个原因是片段本身质量差,虽然相关,但内容残缺或表述混乱,模型基于它生成也会跑偏。这时候要回头检查切分策略。

6.2 多轮对话里检索结果打架

单轮问答时检索很准,一到多轮对话就乱套。原因是多轮对话里,用户的问题经常是省略的、指代的。比如第一轮问"退款政策是什么",第二轮问"那超过七天呢",这个"那"指代的是退款政策,但检索时如果只拿"那超过七天呢"去搜,根本搜不到相关内容。

我的处理方式是查询改写:在检索之前,先用 LLM 结合对话历史,把当前问题改写成独立完整的查询。上面那个例子会被改写成"退款政策中超过七天的规定是什么",再去检索就准了。这一步会增加一次 LLM 调用,但对多轮场景几乎是必需的。

6.3 知识库更新后的检索漂移

知识库更新后,新文档嵌入了,旧文档还在,如果两者内容有冲突,检索时可能同时召回新旧两个版本,模型不知道该信哪个。更隐蔽的问题是,新文档的嵌入分布和旧文档不一致,导致检索结果整体偏向某一批。

我的做法是给文档打上生效时间和版本号,检索后按时间过滤,只保留当前有效的版本。如果新旧版本需要共存(比如查历史政策),就在元数据里区分,让用户或系统明确指定查哪个版本。

6.4 上下文窗口被检索材料挤爆

检索回来一堆片段,加上系统提示和对话历史,直接超出模型上下文窗口。这时候要么报错,要么模型自动截断,把最重要的信息截掉了。

我的做法是预算管理:先算好系统提示和对话历史占多少 token,剩下的留给检索材料。检索材料按相关性排序,从高到低往里塞,塞满为止。同时给每个片段设一个最大长度,超长的片段先做摘要或截断。这样能保证最重要的信息一定进得去。

7. 我在实际项目里沉淀的几条经验

第一条,先把检索做扎实,再考虑花哨的生成。很多人一上来就研究怎么让 LLM 输出更漂亮,却忽略了检索回来的材料是不是对的。我建议把 70% 的精力放在管道前半段:文档解析、切分、嵌入、检索、重排序。这部分做好了,哪怕用普通的生成模型,效果也不会差。

第二条,建立一套自己的评估集。不要凭感觉判断 RAG 好不好,要有一批标注好的问题和标准答案,每次调整管道后跑一遍,看准确率、召回率、回答质量的变化。我一般会准备 50 到 100 个真实用户问题作为评估集,覆盖不同难度和类型。没有评估集,调优就是盲人摸象。

第三条,元数据是宝藏,别浪费。来源、时间、版本、标题路径、文档类型,这些元数据在检索过滤、结果展示、问题排查时都能派上大用场。我见过有人只存了向量和原文,后面想按时间过滤都做不到,只能重建整个库。

第四条,别迷信框架,理解原理更重要。各种 RAG 框架层出不穷,封装得越来越厚,但底层逻辑就是这篇讲的这些:切分、嵌入、检索、重排序、组装。理解了原理,你才知道框架里哪些参数该调、哪些默认值不适合你的场景。框架是工具,不是黑盒。

第五条,从小数据量开始验证。不要一上来就把整个知识库灌进去,先拿几十篇文档跑通全流程,把每个环节的问题暴露出来,再逐步扩大数据量。数据量一大,很多在小规模下不明显的问题(比如检索延迟、存储成本、更新策略)会集中爆发,提前验证能省很多返工。

最后分享一个我常用的排查思路:当 RAG 回答不对时,我会按顺序检查——检索回来的片段里有没有正确答案?如果有,是不是排序太靠后?如果排序没问题,是不是片段内容残缺?如果片段完整,是不是上下文组装时被截断了?如果都正常,那才轮到怀疑生成模型。这个顺序能帮你快速定位问题出在管道的哪一段,而不是盲目地换模型、调参数。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 0:28:28

深度拆解PCB焊盘重叠的隐形诱因与失效机理

在PCB研发量产流程中,多数工程师依赖EDA软件DRC规则检查排查设计问题,但时常出现软件检测合规、量产通电后突发短路、焊接不良等故障,核心诱因多为隐性焊盘重叠。不同于肉眼可见的明显焊盘叠加,隐性重叠具备极强迷惑性&#xff0c…

作者头像 李华
网站建设 2026/9/30 0:20:46

Codex 额度重置全解析:手动、自动与续费三种路径怎么选

1. Codex 额度机制到底怎么运转的先把一个容易混淆的概念掰开:Codex 的“额度”并不是一个单一数字,它至少由三层东西叠加而成——订阅套餐自带的基础配额、按时间窗口滚动的速率限制、以及平台侧根据负载动态调整的软性阈值。很多人只盯着第一层&#x…

作者头像 李华
网站建设 2026/9/30 0:13:45

AnythingLLM 实战:从 0 到 1 搭建 local-first AI Agent 工作区

1. 为什么"私有 ChatGPT"这个说法在 2026 年已经不够用了第一次接触 AnythingLLM 是在一个做工业设备运维的朋友那里。他当时的需求很朴素:公司有一堆设备手册、故障记录、维修工单,想让工程师用自然语言直接问,答案要能溯源到具体…

作者头像 李华
网站建设 2026/9/30 0:06:49

Spring AI 1.x核心:ChatModel与StreamingChatModel从阻塞到流式输出全解析

写这篇的时候,我其实是带着一点"终于写到这儿了"的心情。前面几篇把 Spring AI 1.x 的项目结构、自动配置、提示词模板都过了一遍,但真正让一个应用"活"起来、能和用户对话、能把结果一段一段吐给前端的,就是ChatModel和…

作者头像 李华
网站建设 2026/9/30 0:00:14

模型优化器实战:从FP32到INT8的推理加速与精度平衡

1. 模型优化器到底在解决什么问题第一次接触 Model-Optimizer 这个概念,是在一个推荐系统的排序模型上。当时线上推理延迟死活压不下去,单次请求要跑 180ms,业务方要求降到 50ms 以内。我试过换更小的模型、砍特征、加机器,效果都…

作者头像 李华