做了几年 AI 落地项目之后,我发现自己最愿意反复翻看的,不是那些跑通 demo 的漂亮案例,反而是生产环境里摔过跟头的失败复盘。最近把手上几个项目重新过了一遍,越想越觉得有一个结论值得写出来:大多数项目的坑,其实不在模型,而在知识库。所谓“模型不行”“幻觉严重”“答非所问”,细追下去,十有八九是知识库没有做到位——数据脏、分块乱、检索不到、上下文拼错、版本冲突。这篇文章从我自己的视角,把失败的真实过程、排查思路和能直接照抄的改进方法摊开讲,适合正在搭 RAG、做知识库问答、想用 AI Agent 提效的朋友。无论你是技术负责人,还是刚接触 AI 应用的爱好者,顺着这些踩坑记录走一遍,至少能少绕几趟远路。
1. 复盘三个真实项目,问题全出在“知识”这一环
把失败项目复盘成文档的时候,我习惯先还原现场,而不是急着下结论。这里挑三个印象最深的案例,它们的共性是:模型都是当时能拿到的最强版本,但最后都没上线,或者上线后被用户喷到下线。
1.1 电商客服助手:文档很全,回答却很“飘”
第一个项目是给一家电商卖家做的客服机器人。需求很明确:把售后规则、物流说明、产品 FAQ 放进去,让买家随时问,减少人工客服压力。当时我们花了两周收集资料,把客服聊天记录、平台规则、商品详情页全部导出来,丢进向量库,再接入当时效果不错的模型,demo 跑得很顺。
结果一上真实流量就露馅了。用户问“七天无理由退货要满足什么条件”,机器人给出了三种互相矛盾的答案。原因后来一查才发现:退货政策有三个版本,旧版写“需原包装”,新版写“不影响二次销售即可”,还有一条活动页规则写“特价商品不支持退”。模型不知道哪个才是当前有效口径,只能随机抽一条来回答,或者自己拼接出一条“看起来合理”的规则。
这个项目让我第一次意识到,知识库不是全文堆料场。它必须是一套口径统一、权责清晰、时效明确的事实源。官网页面上的一句话、历史聊天记录里的一句客诉,背后的业务含义完全不同,不能一视同仁灌进去。
1.2 企业内部问答:PDF 带表格,一问就“失忆”
第二个项目是给一家制造企业做内部文档问答。资料大部分是 PDF:报价单、审批表、设备手册、合同扫描件。老板的要求很简单:“以后这些文件直接问 AI 就行。”
实际做起来才发现,真正的瓶颈根本不在模型,而在 PDF 解析。那些报价单里大量的合并单元格、跨页表格、带缩进的条款,解析出来的结果经常是结构错乱:表格的列头丢了、一行数据被拆成两段、扫描件里的手写数字识别成乱码。模型拿到的所谓“知识”本身就是残缺的,回答自然七零八落。
我印象最深的一次,用户问“某型号设备第三季度的维保费用是多少”,模型答出一串数字,引用来源也标注了,但对照原 PDF 一看,那是第二季度的数据。因为表格解析时把“季度”那一列当成了无关文字清掉。信息进了知识库不等于能被模型理解,从非结构化文档到结构化知识,中间这段路没修好,后面全是白费。
1.3 Agent 工具调用:知识库检索到了,却被“截胡”
第三个项目是带有工具调用能力的 Agent,可以查天气、查库存、查工单系统,也可以检索知识库。当时我犯了一个隐蔽的错误:编排上让 Agent “优先看工具结果,再决定是否查知识库”。
听起来没毛病,但实际执行中,Agent 在大部分场景下根本不会去查知识库。为什么?因为模型发现工具返回了一个库存数字,就觉得已经回答了用户问题,而不再去检索知识库中的退换货政策。更隐蔽的是,有些时候 Agent 确实检索了知识库,但在拼接上下文时把正确的片段排在了后面,Top-K 截断之后直接被丢掉。
这个案例让我明白:知识库质量高还不够,还要让它在决策流里有足够的“话语权”。一个不检索知识库的 Agent,本质上就是个失去了记忆的模型,你再怎么优化模型参数都等于零。
2. 为什么“模型不行”常常是障眼法:知识库决定上限
复盘完这几个案例,我再跟人讨论失败原因时,就会特别警惕“模型幻觉”“模型能力不够”这类说法。它们往往是障眼法。真正的问题通常藏在知识库里,而且藏得很深。
2.1 幻觉和“信息缺失”是两码事
很多人一看到 AI 回答得不对,就归因为“模型幻觉”。但在我实际排查里,有很大一部分不是模型在“幻觉”,而是模型压根没拿到该有的信息。
打个比方:一个再聪明的人,如果失忆了,你问他昨天吃什么,他只能靠猜。模型在这个位置也一样——知识库没给到资料,它能做的只有基于自身训练数据“编一个像样的答案”。这和它能不能推理是两件事。只有当知识库里明明有正确资料、模型却无视它去瞎编时,才算真正意义上的“生成层”问题。
所以排查问题的第一句话,应该是先问“知识库到底有没有把这个信息交到模型手上”,而不是急着换模型。
2.2 RAG 管线里的每一步,都可能毁掉最终结果
知识库问答现在主流做法是 RAG(检索增强生成),它的链路比很多人想象的要长:文档解析、清洗、切分、向量化、索引、检索、重排序、拼接上下文、最终生成。九个环节,任何一个出问题,最后的回答都会歪。
我的经验里,最常翻车的四个点是:
- 解析失败:PDF、图片、复杂表格没有正确转成文本和结构,知识在源头就丢了。
- 切分错误:按固定字数硬切,把一段完整的逻辑链拦腰截断,检索时找到的是“半句话”。
- 向量化不匹配:Embedding 模型和语料语言、领域不匹配,语义相似的句子向量距离却不近。
- 检索覆盖不足:只取 Top-K 个片段,正确答案排在第 K+1,直接被截掉。
这几个点里,前两个属于“知识入库”问题,后两个属于“知识出库”问题。它们合起来,占了失败原因的绝大多数。
2.3 用评估指标拆穿“模型不行”的谎言
我们后来建立了一套很朴素的评估方式:把业务里常见的问题攒成黄金测试集,每条问题标注参考答案和来源片段。每次改造完,用三个指标看结果。
- 命中率:检索出来的片段里有没有包含正确答案所在的片段。命中率低,说明问题在检索环节。
- 忠实度:最终生成的回答是否严格基于检索到的片段,有没有自己加戏。忠实度低,才需要考虑约束生成或换模型。
- 完整性:回答是否覆盖了问题的所有得分点。完整性低,通常是片段数量不够或切分太碎。
这套指标最大的作用,是帮我把“模型不行”这个大帽子拆成可以定位的具体环节。大多数时候,测下来发现是命中率只有 40%,模型本身没问题——是知识库没把料送上来。
2.4 一个很直接的比喻:模型决定下限,知识库决定上限
我经常跟团队讲一句话:模型决定了回答的“下限”,知识库决定了回答的“上限”。模型再强,没有知识库支撑,回答也就是泛泛而谈,正确率、时效性、业务深度都上不去。反过来,知识库做得扎实,即便用一个中等规模的模型,也能在垂直场景下给出令人满意的回答。
这不是说模型不重要,而是说多数项目的瓶颈根本没那么靠后。把昂贵的模型换来换去,不如先低下头看看自己的知识库是不是已经烂到没法用了。
3. 把知识库当产品来做:从“存文档”升级到“知识服务”
很多人对知识库的理解就是“开个数据库,把文档传进去”。但做成过几个项目之后,我越来越倾向于把它当成一个独立产品来设计。它要有边界、有结构、有生命周期,还要有质量门禁。
3.1 先定义使用场景,再谈知识库设计
知识库设计的第一件事不是选工具,而是回答三个问题:谁来用?问什么?答案用来干什么?
我给客服做知识库,要的是“口径一致”;给研发做知识库,要的是“代码、接口、架构文档准确且版本对应”;给个人做知识库,比如用 Obsidian 管理笔记,要的是“卡片之间能自动关联、快速定位”。同样是知识库,这三个场景的数据结构、更新频率、检索方式完全不同。
我见过最典型的失败做法是:不管业务场景,先“把资料都传进去”,然后等用户来问。这种没有边界的知识库,最后一定是什么都搜不到,或者搜到一堆过时信息。
3.2 文档解析是第一公里,也是最容易翻车的地方
如果你接触过真实企业文档,就知道里面远比 demo 里的 Markdown 复杂得多。扫描件要 OCR、要纠正识别错误;复杂表格要还原行列结构;跨页的段落要拼接;页眉页脚要去除;代码要保留缩进。这一整套做下来,本身就是一个小项目。
我的建议是:优先把源文件转成结构化程度更高的中间格式,比如带标题层级和表格结构的 Markdown,再进入切分环节。如果用的是 Dify 这类平台,尽量选用“自动分段和清洗”能力,它会帮你做一部分智能清洗,但关键表格最好人工抽检几份,别全交给默认规则。
3.3 切分策略要按语义来,别按字数硬切
向量检索的基本单位是“块”(chunk)。块怎么切,直接决定检索能不能命中。固定长度切分最简单,比如 512 个 token、重叠 128 个 token,但它有个致命问题:会把列表切断、把代码块劈开、把一条完整逻辑拆成两段。检索时找到的半截内容,模型读起来莫名其妙。
更合理的做法是按语义边界切分。Markdown 里的标题、段落、列表、代码块,都是天然的边界。Obsidian 之类的笔记工具之所以适合做知识库,就是因为它天然保留了这些结构。另一层技巧是“滑动窗口”:检索时用较小的块提高命中粒度,喂给模型时再扩展到它所在的整节内容,保证上下文完整。这样既保精度,又保语义。
3.4 知识维护不是一次性的,它是持续运营
知识库最大的隐形杀手,不是构建时的粗心,而是上线后的腐烂。业务规则变了,文档版本更新了,但知识库里旧版本还在,且没有标注生效时间;员工离职,原本该归档的知识散落在聊天记录里没人整理;权限调整了,某些内容不该被检索到,依然留在索引里。
这套“知识生命周期管理”看似和 AI 无关,却直接决定了 AI 回答的正确性。我们后来在每个知识条目上都加了三个字段:负责人、更新时间、生效状态。回答时优先采用“生效中”的版本,并让模型自己判断时效性,旧数据不再有资格进入上下文。
4. 可直接参考的落地实操:模型选型到知识库流水线搭建
复盘归复盘,最后还是要落到能复制的方法上。这里讲一套我最近用着比较顺的组合,覆盖从模型选型到知识库流水线的完整路径,有本地部署的,也有用现成平台快速搭建的。
4.1 先选 RAG 的“配方”,再动工
不是所有场景都需要一套完整的 RAG + Agent。我一般按复杂度把配方分成四档:
- 简单 FAQ:关键词检索 BM25 + 向量检索混合,Top-K 取 5,不需要 Agent。适合客服问答、产品手册。
- 企业内部问答:文档解析 + 语义切分 + 重排序,结果必须带引用来源。适合制度查询、项目资料。
- 工具型 Agent:知识库 + 外部工具调用 + 意图路由。适合需要查库存、查工单、查排期再回答的场景。
- 高可靠场景:在上一档基础上加入人工审核出口,或者对低置信度结果强制“拒答”,比如医疗、金融对公业务。
配方选错了,后面做越多越难受。
4.2 Embedding 模型怎么选,真别只看排行榜
最近总有人问我 Embedding 模型排行榜上谁第一。我的回答是:排行榜可以参考,但它不能替代你自己业务语料上的测试。不同模型在中文、英文、代码、专业术语、口语化表达上的表现差异很大,光看综合分没有意义。
我自己的选型逻辑是三个步骤:
- 从业务里挑 50 到 100 个典型问题,手工标出正确答案所在的原文段落。
- 用候选 Embedding 模型把它们向量化,测检索命中率。
- 比较命中率和显存占用,再定用哪个。
最常用来做基准的开源模型有 bge-m3、bge-large-zh、m3e、multilingual-e5 这些。它们在中文上的综合表现已经很能打,而且大部分都有量化版本,低显存环境下也能跑。如果不想自己部署,商业 API 的 Embedding 服务也可以,但要留意限流和单次文本长度上限。
我踩过一个典型的坑:一开始用了英文为主的 Embedding 模型,中文文档检索出来全是对不上语义的碎片。换成多语言模型之后,同样一套知识库,命中率直接翻倍。
4.3 混合检索 + 重排序,把正确答案挤进 Top-K
单纯用向量检索,有个绕不开的毛病:它擅长语义相似,但不擅长精确匹配。型号“ABC-100”、工单号“WO-20240312”、人名“张三”,这些词在向量空间里反而容易飘。所以我的标准配置是混合检索:BM25 关键词检索和向量检索并行,再用重排序模型把两路结果合并打分。
重排序(Rerank)比普通 Embedding 更准,因为它会用交叉编码器把“问题”和“候选片段”一起过一遍模型,直接算相关性。本地可以部署 bge-reranker 这类模型,显存占用不算大,但在精度上提升非常明显。经过重排序之后,Top-K 可以缩到 3 到 5 个片段,上下文干净了,模型生成质量也会高很多。
另外,一定要给相似度分数设一个阈值。比如低于 0.6 的片段,宁可不给模型,让它直接说“这个信息我暂时没找到”,也别逼它瞎编。这是成本最低的防幻觉手段。
4.4 用 Dify + Obsidian 快速搭一套个人知识库流水线
很多人想问“从哪里开始”,我建议拿个人知识库练手。我自己现在的工作流是 Obsidian + Dify,成本低,见效快,还能反向验证前面说的所有知识点。
具体操作可以这样走:
- 在 Obsidian 里老老实实写 Markdown 笔记,每一篇都用标题分节、用列表和表格组织内容,保持结构清晰。
- 在 Dify 中创建一个知识库,上传这些 Markdown 文件。
- 分段模式选“自定义分段”,用 Markdown 标题作为分段边界,而不是固定 token 数。这样每个片段基本都是完整的小节。
- Embedding 模型我可以选本地部署的开源多语言模型,也可以选 API 方式接入。
- 创建一个“聊天助手”应用,关联这个知识库,打开引用来源开关。
- 拿自己最常问的 20 个问题去测,看检索出的片段对不对,再调 Top-K 和相似度阈值。
这套流程跑顺之后,你会很直观地感受到:同样一个模型,在不同切片策略、不同检索配置下,回答质量的差距有多大。这是理解“知识库决定上限”最好的入门实验。Dify 这类平台把所有环节可视化之后,你也能清楚地看到一条问题从输入到输出的完整流转轨迹。
4.5 低显存环境下的离线部署经验
不是所有人都有 A100 显卡。我自己很多实验是在一张 8G 显存的卡上跑的,完全够用于知识库问答。关键是选对量化和模型规模。
Embedding 模型选小体量的多语言版本,比如 bge-small 或 m3e-small,量化之后只占几百 MB。生成模型走 GGUF 格式,用 ollama 加载 Q4_K_M 量化,比如 7B 到 14B 量级的模型,8G 显存下能跑得很稳。重排序模型也可以用量化版本,不需要单独占太多显存。
配置的时候给自己留一点余量,别满载跑,否则并发一上来,显存爆了,整个服务直接挂掉。我通常会控制在显存占用 70% 以内,剩余留给推理时的临时缓存。
5. 常见问题与排查笔记:一张能直接拿去对表的速查表
复盘的尾声,我想把那些最常踩的坑整理成速查表。以后项目出问题,先对着这张表定位,大概率比盲目调模型有效得多。
5.1 问题速查表
| 症状 | 可能原因 | 排查动作 |
|---|---|---|
| 回答看着合理,但知识库里根本没有对应内容 | 相似度阈值过低,模型被无关片段带偏 | 打开引用来源,降低 Top-K,提高阈值,强制低置信度拒答 |
| 回答用的是旧版规则 | 索引里存在多个版本且未标记生效状态 | 检查知识库版本字段,只向模型提供“生效中”内容 |
| 中英文混合检索效果差 | Embedding 模型语言覆盖不足 | 换多语言模型,或叠加 BM25 关键词检索 |
| 表格类问题答不上来 | PDF 表格解析后结构丢失 | 使用表格解析工具把表格转成 Markdown,抽检关键文件 |
| 答案信息量少,总感觉差一截 | 切分太碎,片段里只有半句话 | 改用语义切分,开启滑动窗口,或换父子分段结构 |
| 检索出来的片段相关性很高,但生成时被忽略 | 上下文太长或系统提示词权重不够 | 精简无关片段,改写系统提示词,明确要求“优先使用知识库内容” |
| Agent 始终不调用知识库 | 工具描述不清晰,模型无法判断何时使用 | 改写工具描述,加入“当用户问到 XX 时,必须调用知识库”等明确条件 |
这张表是我做项目时贴在工位上的,每次排查都从它开始。
5.2 我实际踩过的一个低级错误:Embedding 模型升级后忘重建索引
有一次我为了提升检索效果,把线上知识库的 Embedding 模型从旧版换成了新版。维度没变,语义空间却变了。测试时单条文本的相似度还挺合理,但整库跑起来,旧向量和新向量之间的相对距离变得很混乱。结果线上问答突然开始答非所问,排查了半天才发现是索引没重建。
这个教训是:任何涉及 Embedding 模型的升级,都必须做“全量索引重建”,否则新旧向量混在一起,检索质量大打折扣。这个操作在 Dify 里就是“清空分段并重新召回”,但要记得先备份原文件,别把源文档搞丢了。
5.3 三步定位法:别再让所有问题都叫“幻觉”
最后分享一个我常用的定位流程,总共三步。
第一步,准备 30 到 50 条带标准答案的测试题,先关闭知识库,只看模型裸答的表现。第二步,开启知识库,观察命中率和生成质量有没有提升。第三步,把答错的题目聚类,看它们的问题出在“检索不到”“检索到但被忽略”“检索到但拼接错误”“模型擅自发挥”这四类里的哪一类。
这套方法跑完,很多“模型幻觉”的结论都会改成“知识库召回不足”“切分不完整”“阈值不对”。说起来只是换了个归类,但下一步的动作方向完全不一样了。
6. 最后说点个人体会
我在项目里最常见的开局,就是同事拍着桌子说“这模型太弱了,换一个更强的”。每次我都劝先等等,先拿 20 条问题跑一遍知识库单测,看看命中的片段到底对了几条。现实中,我真没见过几次是模型能力不够导致的失败,大多数时候是知识库没把该说的话送到模型嘴边。
所以我把“复盘几个失败的 AI 项目”这个主题写出来,最想表达的是:做 AI 应用,真正拉开差距的地方是数据组织能力。模型是基建,知识库是装修;基建可以租、可以换,装修必须你自己一砖一瓦地打磨。下次项目黄了,别急着甩锅给模型。把知识库端出来,测一测、查一查、清洗一通,很可能问题当场就水落石出。