
做智能体久了你会遇到一个特别尴尬的时刻模型明明不知道答案却还是能给你编出一个逻辑通顺的“标准答案”。RAG检索增强生成就是为这个场景而生的方案它把外部知识库的检索结果作为上下文喂给模型让智能体基于事实说话。这个系列走到第5篇我打算把知识库与 RAG 的接入这件事彻底聊透从知识库范式选型、文档清洗与切分、嵌入索引到 Dify、Coze 这类平台的流水线配置再到效果评估和常见排查全部按我实际踩过的坑来写。这篇内容适合正在做智能体开发、想给自己的 Agent 接上私有知识库的同学无论你是用现成平台还是自己用 Python 搭都能直接参考。1. RAG 到底解决了智能体的什么问题1.1 纯模型对话的三个短板很多人一开始觉得智能体嘛模型够聪明就行接个 API 就能用。但真正放到业务里跑一圈你会发现纯模型对话有三个绕不开的短板。第一是知识时效性。模型的训练数据有截止时间你问它今年最新的产品政策它只能按旧版本答甚至干脆答错。第二是私有数据缺失。企业内部 SOP、客服话术、农业种植手册、销售报价单这些数据根本不在公开语料里模型自然一无所知。第三是没有依据。模型天生是预测下一个词的机器它不知道“不知道”遇到没学过的内容就会一本正经地编。RAG 的核心思路很简单既然模型记不住那就别让它记改成在回答前先查资料。把用户问题先转换成查询语句去知识库里检索最相关的文档片段再把片段拼进 Prompt让模型基于这些材料作答。这样一来模型的角色就从“百科全书记忆体”变成了“读材料写报告的实习生”准确率会提升一个量级。1.2 知识库的三种范式关于知识库网上的讨论经常把概念混在一起尤其是“RAG 知识库”“KG 知识库”“结构化知识库”这三者的区分。据我接触过的项目可以把知识库按存储和检索方式分为三类知识库类型数据组织方式检索方式适合场景向量知识库文本切块后转为向量语义相似度召回非结构化文档、FAQ、长文本问答图知识库KG实体、关系、属性组成图图查询与路径推理关系密集型场景、多跳问题结构化知识库表结构、JSON、API接口SQL、字段精确匹配订单、库存、价格等精确查询狭义上的“RAG 知识库”多数指向量知识库因为它的门槛最低扔进去一堆 PDF切块、向量化、存起来就能用了。但严格来说图知识库和结构化数据也可以接进 RAG 流水线只是检索逻辑不同。选型时我会先问一个问题用户问的问题答案更依赖“相似段落”还是“确定关系”比如产品手册问答用户问“这个设备怎么保养”答案是手册里的某段说明用向量库就行。但用户问“哪些供应商供过某个零件且近一年有交货延迟记录”这就是典型的多跳关系查询用图或表格查询更合适。现在还有人提 ontology RAG本质是在图知识库之上加一层本体层把“实体有哪些类型、实体之间有哪些关系”先定义清楚再去做约束性检索。适合数据治理成熟、对答案一致性要求很高的团队。普通项目没必要一上来就上本体先把向量库跑通再说。1.3 RAG 的瓶颈在哪里很多人把 RAG 想得太简单以为“嵌入 召回了就万事大吉”但真正落地后你会发现瓶颈还挺明显。首先是检索不准。向量检索对相似度敏感换一个说法就可能召回一堆无关结果。比如农业知识库里有“浇水”相关的几十条记录它们分属于不同作物的不同生长阶段如果嵌入模型没理解语境检索结果排序就会一团糟。其次是噪声淹没上下文窗口里塞了太多低质量片段模型反而找不到关键信息答出来的内容会被“带偏”。第三是知识更新延迟知识库里的内容不会自动变你不去做增量更新它就会由“最新”变成“过时”。第四是效果难以度量很多人上线后连基本指标都没有只能靠肉眼判断好坏。想克服这些瓶颈不能只靠调 embedding需要把整条流水线拆开每一环都做出判断这也是后面几节内容的由来。2. 从文档到向量的流水线2.1 先把文档弄干净知识库的第一道工序不是向量化而是文档清洗。你手里的 PDF 可能是扫描件Word 里可能带一堆样式注释网页导出的 Markdown 可能夹杂广告。这些脏数据直接进知识库检索结果全是噪声。我的习惯是先统一转成结构化文本再入库顺序是扫描件先 OCRPDF/Word 用文档解析器抽文本网页用 Readability 类工具提取正文。这样至少能去掉大部分页眉、页脚、广告和水印。特别提醒表格类的 PDF 不能按普通文本处理行列关系一旦丢失检索出来的片段根本没有可读性推荐转成 Markdown 表格或结构化记录后再入库。这里回应一个高频问题RAG 知识库能不能存图片答案是能但要区分做法。如果你的向量模型是多模态的图片可以直接嵌入并召回原图如果用的是纯文本嵌入模型最好把图片转成文字摘要或 OCR 文本再入库否则图片的内容根本参与不了语义检索。对大多数中文业务场景我建议图片一律 OCR 字幕/摘要先用文本管住比硬接多模态省事得多。还有一个很实际的来源问题怎么把微信公众号文章保存到知识库。公众号网页结构特殊直接复制往往会带大量干扰信息。我常用的办法是在本地用剪藏工具保存成 HTML再用脚本抽取正文转 Markdown或者借助 Obsidian 这类支持剪藏的笔记工具先沉淀之后统一进知识库流水线。总之别嫌麻烦源头上干净后面检索会轻松很多。2.2 文本切分怎么定chunk_size 和 overlap 的经验值文档洗干净以后下一个关键动作是切分。切分的核心矛盾在于块太大语义模糊且超过模型可利用范围块太小上下文不完整信息被撕碎。我通常用基于 token 的切分而不是按字符数。中文场景下字符和 token 的换算大约 1 个汉字等于 1 到 1.5 个 token所以单纯按字符数切出来的块在不同文档里长度飘忽不定。推荐参数一般是 chunk_size 在 300 到 500 tokenoverlap 在 50 到 100 token。这样每块能容纳一个相对完整的段落重叠部分又可以让跨块的关键句子不至于被切断。切分策略必须跟着文档结构走。比如农业知识库里如果按“作物品种—生长阶段—病虫害防治”组织就应该优先按标题层级切保证同一块内都是同一主题而产品手册则适合按功能模块切而不是硬按长度切。结构化程度越高的文档越应该手动定义切分规则而不是依赖默认的通用切分器。如果你用的是 Dify 这类平台它会提供自动分段与自定义分段两种模式。我的经验是正式项目里花点时间写自定义分段脚本比平台自动分段更可靠。原因很简单平台不知道你的章节结构只能按空行和标点猜遇到无规律排版很容易切乱。2.3 嵌入模型怎么选嵌入模型决定了两段文本在向量空间里是否“语义相近”。选错了模型后面所有调参都白费。我的选择思路是这样开源模型优先考虑 BGE 系列和 BGE-M3它们在中文语义匹配上的表现在同尺寸模型里属于第一梯队而且支持本地部署不依赖外部 API适合私有化项目。闭源模型方面OpenAI 的 text-embedding-3-small 和 text-embedding-3-large 在英文和部分多语言场景更强但中文场景下性价比不一定比开源模型好。要注意两个细节。第一是维度嵌入维度不是越高越好高维度只是表达能力上限高真正的效果取决于训练数据分布。第二是长度限制嵌入模型通常对输入长度有上限比如 8192 token超长文本需要先切分再分别嵌入。同一套知识库里不要混用多套嵌入模型否则向量空间不对齐检索结果会很奇怪。我曾经为了省成本在知识库里先用了 A 模型后来又换了 B 模型结果旧数据没重建索引查出来的结果乱七八糟最后全部重新跑了一遍。多模态大模型这两年确实进展很快但落地到知识库场景我仍然建议文本嵌入为主、图片转文字为辅。当前多模态嵌入在文档级任务上效果不错但在细粒度的段落级检索上性价比不如成熟的文本模型。2.4 召回不只是向量检索很多人以为检索就是“query 转向量然后算余弦相似度”其实真实项目里我几乎都会做混合检索BM25 关键词检索 向量语义检索再用 Rerank 模型对两路结果统一排序。为什么要加 BM25因为语义检索对专有名词不敏感。有些专业缩写、型号编号、人名地名在向量空间里根本不是“语义相似”的关系但关键词能精确命中。比如用户问“ZL-1200 型温控器”语义检索可能因为训练语料缺乏这个词而召回失败BM25 却能直接按词命中。召回之后必须接 Rerank。向量排序只看 query 和 chunk 的语义距离Rerank 是把查询和候选片段拼在一起过一遍深度模型做精细相关性打分。两者的差距就像粗筛和精排。我实测过一个客服项目top5 命中率从 58% 提到 84%只靠加了一个 Rerank 模型效果非常明显。召回参数也要注意top_k 不是越大越好。上下文窗口有限塞进去的片段越多噪声越多回答越可能偏离。一般先把 top_k 设在 3 到 5再根据问答效果调整同时设置相似度阈值低于阈值的片段宁可不要也不要硬塞给模型。3. 接入智能体的落地流水线3.1 Dify 知识库流水线从导入到上线的几个关键配置如果你不想从零写代码Dify 是目前搭建知识库流水线最顺手的平台之一。我实际走完一整个项目的流程是这样的。第一步创建知识库应用上传清洗好的文档。Dify 支持 PDF、Word、Markdown、Excel 等格式但我还是会先把文档在外面清洗一遍再传因为平台内置的解析器对复杂格式的处理能力有限很考验运气。第二步配置分段和索引方式。分段策略一般选“自动分段 自定义分隔符”同时把 chunk_size 和 overlap 按前面说的经验值调好。索引方式建议选“高质量”即走 Embedding 向量检索但如果文档量极大、预算紧可以选“经济”模式只做关键词索引。代价是语义检索能力基本没了这种模式只适合关键词明确的场景。第三步接入智能体应用。在 Dify 里创建一个 Agent 应用把知识库作为工具或数据集绑定进去编排里加一个“知识库检索”节点再把检索结果传进 LLM 节点。这里有个容易被忽略的设置检索结果要控制数量默认可能返回 5 到 10 条但对多数问答场景来说3 到 5 条高质量的已经够了。关于网上常说的“Dify 知识库排队中”我遇到过几次。原因通常是在大量文档同时灌入时每个分段都要调用嵌入接口并发一高队列就卡住了。解决办法是把文档分批上传避开高峰期或者本地部署嵌入模型把外部 API 依赖去掉。少批次、多批次的节奏比一次性全量灌入要稳得多。3.2 Coze 智能体接客服场景的流程Coze 这类平台更适合快速搭建面向 C 端的智能体比如客服应答、销售助理。它和 Dify 的差别主要在于Coze 的插件生态和渠道分发更丰富可以直接对接钉钉、飞书、公众号也能对接千牛这类电商客服工具。在千牛客户端里接客服智能体大方向分三步先在 Coze 里创建智能体配置人设和开场白然后添加知识库节点导入产品手册和 FAQ 文档之后通过千牛的开放能力或机器人通道把用户消息转发到 Coze 智能体的对话接口再拿返回结果回传。中间的渠道对接需要申请权限各家平台的接入文档各不相同但智能体这边的逻辑是一样的用户消息进来检索知识库组装答案再由渠道 SDK 发出去。销售智能体的场景也类似。可以把报价单、折扣规则、客户常见问题整理成知识库让智能体在用户咨询时先检索产品信息再应答。区别是销售场景对精确价格和库存要求高价格类数据建议用结构化工具比如查数据库或调价格接口而不是放在向量知识库里。向量库能告诉你“这款产品有哪些卖点”但“当前价格是多少”这种事实还是交给数据库查稳妥得多。3.3 在 Mac 上自建一套知识库如果不想依赖云平台想在 Mac 上本地跑一套 RAGOllama Chroma LlamaIndex 的组合很顺。这套方案的成本基本为零适合个人学习、小团队内部验证。先装 Ollama本地拉一个文本嵌入模型再配合 LlamaIndex 做索引和查询。核心思路是这样的# 安装 Ollama 并拉取 BGE 中文嵌入模型 ollama pull bge-m3from llama_index.core import VectorStoreIndex, SimpleDirectoryReader from llama_index.embeddings.ollama import OllamaEmbedding from llama_index.vector_stores.chroma import ChromaVectorStore import chromadb # 初始化向量存储 chroma_client chromadb.PersistentClient(path./rag_db) chroma_collection chroma_client.get_or_create_collection(knowledge) vector_store ChromaVectorStore(chroma_collectionchroma_collection) # 读取本地文档目录生成索引 documents SimpleDirectoryReader(./docs).load_data() embed_model OllamaEmbedding(modelbge-m3, base_urlhttp://localhost:11434) index VectorStoreIndex.from_documents( documents, embed_modelembed_model, vector_storevector_store, show_progressTrue ) # 查询 query_engine index.as_query_engine(similarity_top_k3) resp query_engine.query(设备的日常保养步骤是什么) print(resp)这套流程跑通后再往里面加 Rerank、混合检索或者自定义切分就比较灵活了。Mac 上跑 bge-m3 这种量级的模型内存充足的话速度完全够用。其实本质上和平台型方案没有区别只是每一步都由你自己控制。3.4 多智能体场景下知识库怎么共享项目一复杂往往会拆出多个智能体比如客服智能体、销售智能体、运营分析智能体。如果每个智能体都自己建一套知识库索引重复、更新不一致会非常浪费。我的做法是把知识库抽成独立服务所有智能体共用同一套数据源按接口调用。向量库只存一份检索逻辑统一封装各 Agent 传入自己的业务标识检索时通过元数据过滤避免跨业务域串数据。如果你用的是平台型智能体比如 Coze/Dify 或者 hermes 这类开源智能体框架也是同样的思路知识库要么放在平台上共享要么走外部 API 查询。平台型方案胜在搭建方便适合快速验证代码型方案胜在可控性强可以精细控制 Prompt、检索和重排的每一个环节。两者的根本区别不在技术而在你愿意投入多少工程成本去换可控性。多智能体的测试也比单智能体复杂。如果你关注 Agent 的行为是否符合预期可以用 AgentDojo 这类测试环境预先定义一组任务和工具调用约束把智能体放进去跑一遍观察它有没有按知识库内容回答、有没有越权调用工具、有没有在多轮对话中说错。这比靠人工聊天试几轮要系统得多。4. 效果评估与常见问题排查4.1 怎么知道 RAG 效果好不好RAG 效果不能光靠感觉我一般会做两个层面的评估。第一个层面是检索质量常用两个指标命中率和平均倒数排名。命中率统计 top_k 里是否包含正确答案MRR 度量正确答案出现位置的倒数平均值位置越靠前越接近 1。实操中我会准备一批“问题 正确文档片段”的评测集批量跑检索看命中率低于 80% 时优先调切分和重排。第二个层面是生成质量重点看回答有没有忠实于检索到的上下文。可以在评测集里标注“知识库中有答案”“知识库中无答案”两类问题分别观察答案是否覆盖关键信息。对于检索充足但回答错误的情况要重点检查 Prompt 上下文顺序以及是不是把无关片段在摘要中排太靠前了。一个项目上线前至少要准备三五十条评测问题覆盖不同业务场景和提问方式。没有评测集就谈不上优化这已经是做 RAG 的基本功了。4.2 一张速查表解决八成知识库接入问题把项目里出现过的典型问题整理成速查表方便后面对照排查现象可能原因处理办法检索出来一堆不相干内容嵌入模型与文档语言/领域不匹配换用中文领域适配的嵌入模型调低 top_k 并加 Rerank答案在库里却查不到切分粒度太大或关键词没有被语义表达调小 chunk_size增加 overlap接入 BM25 混合检索查到了片段但回答跑偏上下文里噪声过多模型被弱相关片段干扰减少召回数量提高相似度阈值调整片段顺序知识库里的图片内容回答不了纯文本嵌入模型不处理图片信息图片先 OCR / 转文本摘要再入库Dify 上传后一直排队大量文档同时向量化导致并发阻塞分批上传或本地化嵌入模型公众号文章入库后效果差提取时带入了大量页脚、广告等噪声先剪藏清洗转 Markdown再入库数据更新后回答仍是旧内容旧索引未被替换增量更新索引确认查询打到新集合这张表格只列了高频问题真正排查时更重要的思路是“分段定位”。用户反馈答得不对先看知识库里到底有没有这个内容如果有再看检索有没有把它找出来如果找出来了再看模型有没有正确使用它。这三步定位法能解决大部分 RAG 的疑难杂症。4.3 三条经验元数据过滤、摘要索引、定期更新最后分享三个在项目里验证过很有用的经验。第一在知识块上挂元数据。每个块除了向量内容至少带上来源、更新时间、业务线、作者等字段。查询时按这些字段做前置过滤。举个例子同一个知识库里既有产品手册也有售后政策用户问“保修多久”如果不过滤业务线检索结果里可能混入产品描述片段回答质量瞬间下滑。加上过滤后命中率会有肉眼可见的提升。第二超长文档先建摘要索引再二次切片。整篇长文档直接切分会破坏文档层级比如一份 80 页的项目报告切成 200 个块检索时很难定位到具体章节。我的做法是先用 LLM 给每个章节生成摘要把摘要建成索引检索先命中摘要再根据摘要命中对应章节的完整内容这样既保证召回精度又保留上下文。第三知识库需要定期体检。我会每周看一次未命中问题列表把用户常问但知识库里没有的内容及时补充同时清理过期信息保证知识库里的内容不是“存了就完事”。很多 RAG 项目上线时效果不错跑了两三个月越来越差基本都是因为没有做增量更新和过期清理。平台型智能体与 Python 自建智能体的差异也跟这些经验有关。平台把流水线封装好了但想加元数据过滤、定期体检就只能依赖平台开放的功能Python 自建则可以随心所欲。两种方案没有绝对优劣取决于团队人员和维护预算。最后说一个我自己的感受。这套知识库与 RAG 的接入做下来最能拉开项目差距的反而不是模型或者平台而是数据工程。文档清洗、切分规则、元数据设计、评测集维护这些工作枯燥、繁琐但每一样都在实打实地提升最终效果。网上那些号称“换个模型效果翻倍”的帖子大多是没做过真实项目的营销话术真正靠谱的项目靠的都是一步步打磨细节。如果你正在做自己的知识库接入建议先把评测集搭起来哪怕只有几十条问题也能帮你少走很多弯路。