平台研究

知识库里明明写了,AI 为什么答不上来:一次检索复现定方向

八成以上「知识库没生效」的排查结果,其实是内容没被检索到,而不是内容缺失。本文拆解混合召回的五环链路(范围、召回、扩展、重排、拼装),给出内容问题与排名问题的判定表,以及在动手补内容之前该做的免费复现。

一个高频困惑:「知识库里明明写了,AI 就是答不上来」

这是接入知识库之后第一个月最容易遇到的问题。团队把产品手册、FAQ、案例、资质证书全部导进去,问一句「你们支持哪些部署方式」,AI 答得含含糊糊,或者干脆说“资料中没有相关信息”。

多数人的第一反应是「知识库没生效」或「模型太笨」。但实际排查下来,八成以上的情况不是内容缺失,而是内容没被检索到。

这两件事的处置完全不同:

  • 内容缺失 → 去补内容;
  • 检索没召回 → 内容写着也没用,改的是检索条件或内容组织方式。

如果用错方向,就会陷入「按 AI 提示的缺口反复补文章,补了还是答不上来」的死循环。这篇文章就是讲怎么在动手补内容之前,先用一次检索复现把方向定准。

一、先理解检索是怎么走的

我们的知识库检索不是单纯的向量相似度。完整链路大致是这样:

① 范围确定。 先确定这次检索在哪些知识库里找。这一步会按当前租户、项目、可见性做筛选——如果某些知识库被排除在范围外,再怎么调召回也找不到它。

② 混合召回。 三条通道并行:

通道 权重 说明
向量召回 0.7 语义相似,能匹配“意思相近但用词不同”的问法
关键词召回 0.3 字面命中,对产品型号、专有名词、编号类查询很重要
标题/章节召回 0.15 命中标题或章节名,对结构化资料的定位很有效

三条通道的结果用 RRF(Reciprocal Rank Fusion,k=60) 融合。RRF 的意义在于:它不看原始分数的绝对值,只看排名——这样不同通道的分数尺度不一致也不会互相干扰。

另外有一个元数据加成(0.08),按知识库身份给一个静态质量分。它不参与 RRF,因为它对同一个库的每个切片都相同,排序它等于按库名排序,没有信息量。

③ 查询扩展(按需触发)。 如果基础召回的数量低于门槛(默认是候选限额的 50%),系统会自动生成查询变体再捞一轮,去重后合并。这是“召回不足时的补救”,不是每轮都跑。

④ 重排。 召回结果会经过重排(rerank)再取前若干条拼成证据上下文。

⑤ 拼装上下文。 最终返回的是证据条目(默认取前 5 条,上下文长度上限 3200 字符),连同来源信息一起交给生成模型。

看明白这条链路,排查就有顺序了:范围 → 召回 → 扩展 → 重排 → 拼装,每一环都可能把内容滤掉。

二、诊断对象:为什么“没检索到”是可观测的

平台为每次检索记录了一份诊断信息,字段刻意保持少量但语义明确:

  • 范围规模:请求了几个库、实际参与检索几个、有没有被安全阀截断;
  • 候选规模:向量通道和关键词通道各召回了多少切片;
  • 各阶段滤除计数:被时效性排除多少、被范围筛选排除多少;
  • 查询扩展:是否触发、触发门槛是多少、用了哪些变体、额外捞到多少;
  • 最终返回:几条、耗时多少、有没有告警。

这份诊断的价值在于:它能回答「到底哪一步把内容滤掉了」。

举一个实际会遇到的形态:诊断显示向量候选 40 条、关键词候选 12 条,最终返回 5 条,但答案里没有你需要的那条。这说明召回没问题,问题在排名——你的目标切片进了候选池,只是没排进前 5。这种情况下补内容没用,要改的是这条内容的表述方式或检索参数。

反过来,如果诊断显示范围里只剩 1 个库、向量候选只有 3 条,那问题在范围或召回——要么库被过滤了,要么切片太少。

三、两类失败:内容问题与排名问题

这是本文最重要的一张对照表:

现象 判据 正解
内容确实没有 检索复现时完全没进候选,且按关键词搜库内也搜不到 补内容
内容有但排不进前 K 进了候选池,但最终取证时被挤掉 改表述/补专题篇章,不是补一行
内容有但召回不到 按字面关键词能在库里搜到,语义检索却召不回 内容与问法词汇差异过大,补同义表述
召回正常但答不好 证据进了上下文,模型仍答错 检索/生成口径问题,不是知识库问题

特别提醒第三行和第四行:按“缺口”补一行表项,往往召回还是打不过——因为一行表项的语义信号太弱。要补就补专题篇章:标题和段落里覆盖用户真实会用的问法词,这样语义召回的信号才够强。

四、一次免费的最小复现

排查不该拿付费对话来试。检索复现本身只花 embedding 的钱,成本极低。

具体做法:

  1. 把用户那个问句原样(不要改写)拿去跑一次 retrieveEvidence —— 取前 8 条证据;
  2. 逐条看你期望的那段内容在不在里面;
  3. 按上面表格定位是哪一类失败;
  4. 再决定是补内容、改表述、还是调参数。

关键纪律:用用户的原话,不要用你整理过的规范问法。用规范问法测出来能召回到,不代表用户那样问也能召回到——而线上是用户在问。

五、几个容易被忽略的坑

「改了默认值」不等于「生效了」。 检索和生成的相关配置有优先级:数据库里保存的值优先于代码里的默认值。只改代码默认值,线上跑的还是 DB 里那份旧配置。这类“看起来改了但没变”的问题,靠界面是看不出来的,必须核对实际生效值。

分块没同步完,检索结果就是 0。 内容入库是异步链:准备 → 向量化 → 完成。这期间状态是 pending 或 processing,切片数是 0。这时候去检索当然什么都没有——看起来完全像“入库失败”,实际是在正常处理中。判据是看切片同步状态是否 ready,不是看入库脚本有没有返回成功。

时效性会静默排除内容。 过了时效的资料会被排除在检索范围外。如果某个库里的内容都属于“会过期的事实”,而你没维护复审时间,它可能整体失效而不报错。

“检索到”和“答对了”是两件事。 证据进了上下文,模型仍可能组织错。这时候要看生成侧的提示词与上下文拼装,不要在知识库上继续加内容。

六、这套做法的适用边界

需要说清楚的几点:

  • 检索诊断是排查工具,不是评分。它不给你“知识库质量 78 分”这种数字,因为质量问题不是单一维度能概括的。
  • 混合召回的权重与 RRF 参数是默认值,可调。不同知识库类型(结构化手册 vs 叙事型案例)最优参数不一样,调参前先做上面那套复现,否则是盲调。
  • 补内容永远是最后一招。先确认前面五环都没问题,再动内容——否则你会补一堆用不上的东西,还破坏了原本的组织结构。

相关阅读