ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Agent知识库实战:RAG、KG与结构化选型及切片检索优化

Agent知识库实战:RAG、KG与结构化选型及切片检索优化 1. 为什么你的 Agent 总是“一问三不知”很多人搭智能体的路径都差不多先选个框架把大模型接上写个提示词跑起来发现对话挺流畅于是兴冲冲地丢给它一堆业务问题——结果要么答得驴唇不对马嘴要么干脆编一段听起来很像那么回事的假话。这时候大部分人的第一反应是“模型不行换个更强的”但换完之后发现问题依旧。真正的原因往往不在模型而在你根本没给它可查的东西。大模型本身是一个被冻结在训练时间点上的参数集合它脑子里装的是公开语料的统计规律不是你公司的产品手册、不是你的项目文档、也不是你上周刚整理的那份会议纪要。你问它这些它只能靠“猜”猜得越像真的越危险。知识库要解决的就是这件事把散落在文件夹、聊天记录、网页收藏、PDF 里的资料整理成模型在推理时能真正检索到、并且能引用来源的外部记忆。这一篇是 Agent 系列的第三篇前两篇聊了智能体的基本循环和工具调用这一篇专门啃知识库这块硬骨头。我会把“资料怎么进来、怎么切、怎么存、怎么被查出来、查出来之后怎么塞进上下文”这条链路完整走一遍中间穿插我自己踩过的坑。适合已经能跑通一个基础 Agent、但被“答不准”折磨过的开发者也适合刚接触 RAG 想搞清楚它到底怎么回事的新手。读完你至少能判断你的场景到底该不该上知识库该上哪一种以及为什么你现在的方案效果差。先给一个反直觉的结论知识库效果差八成不是检索算法的问题而是资料在进入知识库之前就没被处理好。后面我会用大量篇幅讲这个“前置处理”因为它才是决定成败的地方。2. 先分清三种知识库RAG、KG、结构化别一上来就选错热词里有个很典型的问题“kg知识库、rag知识库和结构知识库区分以及应用场景”。这个问题问得特别好因为很多人把“知识库”当成一个东西实际上它至少是三种完全不同的形态选错了后面全是白费功夫。2.1 RAG 知识库把文本切片后做向量检索RAGRetrieval-Augmented Generation检索增强生成是当前最主流、上手最快的方案。它的核心思路是把文档切成一段段文本块chunk用嵌入模型把每块转成一个向量存进向量数据库用户提问时把问题也转成向量在库里找最相似的若干块拼进提示词让模型基于这些块回答。它擅长的是非结构化文本产品说明、FAQ、技术文档、政策条款、聊天记录。你问“退货流程是什么”它能从一堆文档里捞出相关段落。它的短板也很明显对“精确匹配”和“多跳推理”比较弱。比如你问“A 产品的负责人是谁”而答案需要先查到 A 属于哪个部门、再查部门负责人这种链式关系 RAG 一次检索往往搞不定。2.2 KG 知识库用实体和关系表达事实KGKnowledge Graph知识图谱知识库把信息表达成“实体—关系—实体”的三元组比如“张三—负责—A产品”“A产品—属于—X部门”。它擅长关系查询和多跳推理问“谁负责 A 产品所在部门”可以顺着图走两步就出来。缺点是构建成本高需要定义本体schema、做实体抽取和关系抽取维护起来也比 RAG 重得多。2.3 结构化知识库表格和数据库结构化知识库就是老老实实的表格、SQL 数据库、Excel。它擅长精确的数值查询和聚合比如“上个月销售额是多少”“库存低于 10 的有哪些”。让模型直接读表格容易出错正确做法是让 Agent 生成 SQL 去查把结果拿回来再组织语言。类型数据形态擅长不擅长构建成本RAG非结构化文本语义检索、问答多跳推理、精确聚合低KG实体关系三元组关系查询、多跳模糊语义、冷启动高结构化表格/数据库精确数值、聚合语义理解、开放问答中实际项目里最常见的是混合方案结构化数据走 SQL文档走 RAG关键实体关系再补一张轻量图谱。但对绝大多数人来说先把 RAG 做扎实比急着上图谱划算得多。我见过太多团队一上来就要搞知识图谱结果连文档切片都没切明白最后项目烂尾。提示判断标准很简单——如果你的问题大多是“某段话说了什么”选 RAG如果是“A 和 B 是什么关系、经过几层能连上”才考虑 KG如果是“算个数、排个序”直接上结构化查询。3. 资料入库前的清洗决定成败的隐形战场这一节是全文最想让你重视的部分。很多人搭 RAG 的流程是把 PDF 往解析器里一丢切完直接入库然后抱怨效果差。问题就出在这个“丢”字上。3.1 原始资料的三种典型脏数据第一种是格式噪声。PDF 解析出来经常带着页眉页脚、页码、水印文字甚至表格被拆成乱七八糟的字符流。我处理过一份产品手册解析后每页顶部都混进“内部资料 请勿外传”八个字结果用户问任何问题检索出来的块里都带着这句话模型被干扰得很厉害。第二种是结构丢失。一份 Markdown 或 Word 文档本来有清晰的标题层级解析成纯文本后层级全没了一段话脱离了它所属的章节语义就变了。比如“该参数默认关闭”这句话放在“安全设置”章节和放在“性能优化”章节含义完全不同。第三种是重复与冲突。同一个问题在旧版文档和新版文档里答案不一样两份都进了库检索时随机命中一份模型给出的答案就时对时错。这种问题最隐蔽因为单看每次回答都“有据可依”。3.2 清洗的具体动作我的做法是分三步走。第一步保留结构信息。解析时尽量保留标题层级把每个 chunk 的“所属章节路径”作为元数据存下来比如产品手册 第三章 配置 3.2 安全设置。检索时这个路径能帮模型判断上下文。第二步去噪。用规则把页眉页脚、页码、重复出现的免责声明过滤掉。这一步不用太智能正则表达式往往就够了。关键是你要先抽样看几十个解析结果亲眼看看脏数据长什么样而不是盲目相信解析器。第三步去重与版本管理。给每份文档打上版本号和生效时间检索时优先返回最新版本。如果新旧答案冲突且都需保留就在元数据里标注清楚让模型知道“这是旧版仅供参考”。# 一个简单的去噪示例过滤页眉页脚和页码 import re def clean_text(raw: str) - str: # 去掉纯数字页码行 raw re.sub(r^\s*\d\s*$, , raw, flagsre.MULTILINE) # 去掉固定页眉 raw raw.replace(内部资料 请勿外传, ) # 合并多余空行 raw re.sub(r\n{3,}, \n\n, raw) return raw.strip()注意清洗规则一定要基于你真实的数据来写不要抄网上的通用模板。不同来源的文档脏法完全不一样抄来的规则大概率不匹配。3.3 一个容易被忽略的点给资料打“可回答范围”标签有些资料是给内部人看的包含大量缩写和黑话有些是对外的措辞规范。如果混在一起用户问一个口语化的问题可能检索到内部黑话文档模型解释起来就很别扭。我的做法是给每份文档打一个audience标签internal / external检索时根据提问场景过滤。这个动作很小但能明显减少“答非所问”。4. 切片策略切得好检索就成功了一半切片chunking是 RAG 里被讨论最多、也最容易被做砸的环节。切太大一个块里混了好几个主题检索出来噪声多切太小一句话被拦腰截断语义不完整。这里没有万能参数只有针对你数据的合理策略。4.1 三种主流切法及适用场景固定长度切分按字符数或 token 数硬切比如每 500 字一块块间重叠 50 字。优点是简单、快适合格式规整、主题均匀的文本。缺点是经常在句子中间切断遇到列表、表格更是灾难。按结构切分顺着文档的标题、段落、列表项来切。Markdown 按##、###切代码按函数切合同按条款切。这是效果最好的方式前提是你的解析阶段保留了结构。我现在的默认策略就是结构优先结构切出来的块如果太大再在块内做二次切分。语义切分用嵌入模型判断相邻句子的语义相似度在语义“断层”处切开。效果不错但计算成本高一般用于对质量要求极高的场景。4.2 重叠overlap到底要不要设要设但别设太大。重叠的目的是防止关键信息正好落在切割边界上被切断。比如一句话前半段在块 A、后半段在块 B如果没重叠检索到 A 也拿不到完整信息。一般重叠 10%–20% 就够了设成 50% 会导致大量冗余检索时同一内容反复出现浪费上下文窗口。4.3 给每个块补“上下文头”这是我强烈推荐的一个技巧在每个 chunk 前面拼一句它所属的上下文。比如一个块本身是“默认值为 30 秒”单独看完全不知道在说什么但如果拼上“本文档介绍 API 超时配置以下为超时时间参数说明默认值为 30 秒”检索和生成的质量都会明显提升。def build_chunk_with_context(chunk_text, section_path, doc_title): header f文档{doc_title}章节{section_path}\n return header chunk_text这个 header 会一起被嵌入所以检索时它也在参与匹配相当于给每个块加了一个“身份说明”。成本几乎为零收益却很实在。4.4 表格和图片怎么处理热词里有人问“rag知识库能存储图片嘛”。答案是向量库存的是图片的向量表示或图片的文字描述不是图片本身。常见做法有两种一是用多模态模型给图片生成一段文字描述把描述入库二是用图文嵌入模型直接把图片转向量。前者实现简单、可解释性强后者效果更好但依赖特定模型。表格则建议转成 Markdown 或自然语言描述再入库直接塞原始表格字符流模型很难理解。5. 检索环节为什么你搜出来的东西总是不对资料洗干净了、切好了、入库了接下来就是检索。这一步的坑同样不少。5.1 纯向量检索的天然缺陷向量检索擅长语义相似但对精确关键词不敏感。用户问“错误码 E1024 怎么解决”向量检索可能返回一堆讲“错误处理”的通用文档却漏掉那条专门讲 E1024 的记录因为“E1024”这个 token 在嵌入时被稀释了。解决办法是混合检索向量检索 关键词检索BM25 之类两路结果融合排序。这是目前工业界比较稳的做法。5.2 重排序Rerank值不值得上值得。向量检索是“粗筛”召回一批候选重排序模型是“精排”用更强的模型对候选逐一打分把最相关的排到前面。加了重排序之后通常能把最相关的结果从第 5、6 位提到第 1 位对最终答案质量影响很大。代价是多一次模型调用延迟增加几百毫秒。我的建议是只要对准确率有要求就上重排序。5.3 检索数量top-k怎么定top-k 太小可能漏掉关键信息太大噪声多、上下文被塞满。经验值是先召回 20–50 条候选重排序后取前 3–5 条塞进提示词。具体数字要看你块的大小块小就多取几条块大就少取几条。别拍脑袋定拿一批真实问题测一下看 top-k 取多少时答案最准。5.4 查询改写让用户的问题更好搜用户提问往往很口语、很模糊直接拿去检索效果差。可以在检索前让模型把问题改写成几个更规范的查询分别检索再合并。比如用户问“那个登录老是失败咋整”改写成“登录失败 原因”“登录失败 解决方法”“认证错误 排查”召回率会明显提升。REWRITE_PROMPT 把用户问题改写成3个适合检索的查询每行一个不要编号 用户问题{question} 提示查询改写会增加一次模型调用如果对延迟敏感可以只在检索结果置信度低时才触发。6. 把检索结果喂给模型上下文组装的讲究检索出一堆块之后怎么塞进提示词也是有讲究的。6.1 顺序很重要模型对上下文里开头和结尾的内容更敏感所谓“中间遗忘”现象。所以最相关的块应该放在开头或结尾不要埋在中间。我一般按相关性排序后把最强的放最前次强的放最后。6.2 明确标注来源和边界每个块前面标清楚来源块之间用分隔符隔开让模型知道“这是资料 A 的内容那是资料 B 的内容”。这样模型在回答时能引用来源也减少了把不同文档内容混为一谈的概率。【资料1来源产品手册 3.2】 超时时间默认 30 秒…… 【资料2来源FAQ 第 12 条】 如果超时频繁发生建议……6.3 明确告诉模型“查不到就说查不到”这是减少幻觉的关键。提示词里必须写清楚如果提供的资料里没有答案就直说没有不要自己编。我见过太多项目因为少了这句话模型在检索为空时依然一本正经地胡说。6.4 上下文窗口不是越大越好有人觉得反正现在模型上下文窗口大把检索到的几十个块全塞进去。结果模型被大量无关信息干扰反而答不准还费 token。精准的 3 个块胜过杂乱的 30 个块这是我在多个项目里反复验证的结论。7. 实测中的几个典型故障与排查思路理论讲完了说几个我实际遇到过的故障以及怎么定位的。7.1 故障一答案总是差一点点现象是模型答得“沾边但不准”。排查下来发现是切片把关键定义切断了定义的前半句在上一块、后半句在下一块检索只命中一块。解决办法是加大重叠或者改用按结构切分。这个故障很典型先怀疑切片再怀疑检索。7.2 故障二同一个问题两次回答不一样这种“不稳定”通常来自重复或冲突的资料。排查方法是把检索到的块打印出来看往往能发现新旧两份文档都被召回了。解决办法是加版本过滤或者入库前就去重。7.3 故障三专有名词检索不到公司内部的产品代号、项目简称向量检索经常抓不住。解决办法是在清洗阶段给这些专有名词建立同义词表检索时做查询扩展或者干脆上混合检索让关键词那一路兜底。7.4 故障四检索明明对了模型还是答错这时候问题在生成环节。检查提示词里资料和问题的位置关系、有没有明确要求“基于资料回答”。有时候把资料放在问题前面、并加一句“请仅根据以上资料回答”效果就完全不一样。故障现象最可能的原因优先排查方向答得沾边不准切片切断语义切片策略、重叠回答不稳定资料重复冲突去重、版本管理专名搜不到向量对关键词不敏感混合检索、同义词检索对但答错提示词组装问题上下文顺序、约束语8. 关于 MCP 和知识库工具链的一点实践体会热词里 MCP 出现频率很高这里简单说下它和知识库的关系。MCPModel Context Protocol本质上是一套让模型和外部工具、数据源对接的协议。对知识库来说它的价值在于把“检索”这件事标准化成一个工具Agent 需要查资料时通过 MCP 调用知识库服务拿到结果再继续推理。这样知识库就不再是硬编码在提示词里的死数据而是 Agent 可以按需调用的能力。我自己的做法是把知识库封装成一个检索服务通过 MCP 暴露出去Agent 在需要时主动调用。好处是解耦——知识库更新不用动 Agent 代码Agent 换框架也不用重做知识库。至于具体用哪个框架、哪个向量库我的建议是别在选型上纠结太久先用最简单的方案把链路跑通效果不行再换。我见过太多人花两周对比向量数据库结果连数据都没清洗干净。提示知识库的迭代是个长期活。上线只是开始之后要持续收集“答错的问题”反推是资料缺失、切片问题还是检索问题然后针对性优化。没有一劳永逸的知识库。最后分享一个我自己的习惯每次调整切片或检索参数后我都会固定用同一批 20–30 个真实问题跑一遍记录准确率变化。没有这个基准测试集你根本不知道改动是变好还是变坏全靠感觉调参最后一定是一团乱麻。这个测试集不用多复杂把用户真实问过的问题攒起来就行它是你优化知识库时最值钱的东西。
返回列表