RAG 返回 0 个检索结果,应该怎么排查?
RAG 系统返回 0 个检索结果,不一定意味着“知识库里没有答案”。
它可能是数据没有入库、向量库连不上、权限过滤过严,也可能只是用户提问方式与文档表达差异太大。排查时最重要的原则是:
先判断这是“普遍故障”还是“个别问题”,再沿着 RAG 链路逐层定位。
一、第一步:先判断普遍还是特殊
先不要急着调模型或改提示词。应先选几个不同类型的问题测试:
- 常见 FAQ 是否也返回 0;
- 最近上传的文档是否能检索到;
- 不同用户、不同角色是否都返回 0;
- 只在某个知识库、某个部门或某类文档中发生;
- 关键词搜索能否找到,但向量检索找不到。
可以据此快速分类:
| 现象 | 初步判断 |
|---|---|
| 所有问题、所有用户都返回 0 | 系统级问题 |
| 只有某个知识库返回 0 | 数据源、索引或命名空间问题 |
| 只有某个角色返回 0 | 权限过滤问题 |
| 只有某类问题返回 0 | 查询理解、检索策略或数据覆盖问题 |
| 关键词能搜到,向量检索搜不到 | Embedding、向量索引或相似度阈值问题 |
这一步能避免一上来就在错误方向上耗时间。
二、如果是普遍问题,先排查系统链路
普遍返回 0 时,优先检查基础服务是否正常:
用户问题
→ 查询服务
→ Embedding 服务
→ 向量数据库
→ 权限过滤
→ 重排/阈值过滤
→ 返回结果
1. 向量数据库是否正常连接?
检查:
- 向量库连接是否成功;
- 当前索引、Collection 或 Namespace 是否存在;
- 索引中的向量数量是否为 0;
- 查询是否误连到测试环境、空索引或错误租户;
- API Key、数据库账号和网络连接是否过期。
最简单的验证方式是:直接用一条已知文档中的关键词或原句去检索。如果仍然返回 0,通常不是用户提问的问题。
2. 文档是否真的完成入库?
“文件上传成功”不等于“文件可以检索”。
应检查入库任务是否完整经过:
上传成功
→ 文本解析成功
→ 文本切分成功
→ Embedding 生成成功
→ 向量写入成功
→ 索引可查询
常见问题包括:
- PDF 是扫描件,实际没有可解析文本;
- 文档解析失败,但任务状态没有明显报错;
- 切片数为 0;
- Embedding API 调用失败;
- 向量写入了另一个索引;
- 文档刚上传,索引尚未完成。
建议每份文档都记录:原文档数、解析字数、切片数、向量数和入库状态。只要其中某一步为 0,就能快速定位问题。
3. Embedding 模型是否前后不一致?
文档入库和用户提问必须使用兼容的 Embedding 模型。
如果文档用模型 A 生成向量,查询却换成模型 B,向量空间不一致,检索效果会严重变差,甚至接近 0。
需要核对:
- 文档向量的模型版本;
- 查询向量的模型版本;
- 向量维度是否一致;
- 索引是否在更换模型后重新构建。
三、如果是特殊问题,重点看数据、查询和权限
1. 先确认知识库里是否真的有相关内容
不要只凭感觉判断“文档里肯定有”。
可以直接在原始文档中搜索关键词,确认:
- 是否确实存在该主题;
- 内容是否被 OCR、解析或切片遗漏;
- 文档是否已经入库;
- 文档版本是否最新;
- 内容是否被标为无效、过期或禁止检索。
有时用户问的是“为什么预算超支”,文档却只写“材料成本上升”“供应商延期”。传统检索未必能自动理解这种表达差异。
2. 检查查询改写和检索策略
用户问题不一定适合直接检索。
例如:
原问题:为什么项目超支?
改写查询:项目预算增加、成本上升、采购价格上涨、项目延期
当原始问题过于口语化、过短、包含错别字或指代不明时,可以尝试:
- 查询改写;
- 多路查询扩展;
- 关键词检索与向量检索混合;
- 将长问题拆成多个子问题;
- 增加检索 Top-K;
- 使用重排模型优化结果排序。
但要注意:如果系统已经返回 0,不应马上盲目增加 Top-K。要先确认是“没有召回”还是“召回后被过滤掉”。
3. 检查相似度阈值是否过高
很多系统会设定最低相似度阈值,例如:
相似度低于 0.75 的结果全部丢弃
阈值太高时,系统可能实际找到了相关文档,却在最后一步全部过滤掉。
排查方法是记录每次检索的:
- Top-K 原始结果;
- 相似度分数;
- 阈值过滤后的结果数;
- 重排前后结果数。
如果原始 Top-10 有内容、过滤后变成 0,问题大概率在阈值策略,而不在知识库。
四、权限过滤是企业 RAG 的高频原因
在有 RBAC、标签权限和部门隔离的系统里,0 个结果经常是“安全策略正常工作”的结果。
排查时需要区分:
没有检索到任何相似内容
和:
检索到候选内容,但用户无权访问,过滤后为 0
应检查:
- 用户的角色和部门标签是否正确;
- 文档、切片和向量是否带有权限标签;
- 文档标签与用户标签是否匹配;
- 权限规则是否过于严格;
- 是否把“无标签文档”默认拒绝;
- 多租户、项目 ID、Namespace 是否一致。
这类场景中,不能为了“让用户搜到结果”而绕过权限。正确做法是给出明确但不泄密的提示:
未找到您当前权限范围内可用的相关资料。您可以更换关键词,或联系资料负责人申请访问权限。
五、推荐建立一张排查记录表
每次 0 结果,都建议记录如下信息:
| 字段 | 用途 |
|---|---|
| request_id | 关联整条请求链路 |
| 用户与角色 | 判断是否为权限问题 |
| 原始问题与改写问题 | 判断查询理解是否异常 |
| 知识库/索引名称 | 排查是否连错库 |
| 文档数、切片数、向量数 | 判断入库是否成功 |
| 原始 Top-K 结果 | 判断是否真正召回 |
| 相似度分数 | 判断阈值是否过高 |
| 过滤后结果数 | 判断权限或规则是否拦截 |
| 最终返回原因 | 形成可追溯结论 |
六、一个实用的排查顺序
1. 判断普遍还是特殊
2. 检查索引、向量库和服务健康状态
3. 确认文档是否解析、切分、向量化并成功入库
4. 核对 Embedding 模型与向量维度
5. 查看原始 Top-K 结果和相似度分数
6. 检查相似度阈值、重排和过滤规则
7. 检查 RBAC、标签、租户和权限范围
8. 优化查询改写、混合检索和数据覆盖
结语
RAG 返回 0 个结果,本质上不是一个单点错误,而是一次“检索链路诊断”。
最关键的是先判断:系统根本没有找到资料,还是找到了资料但被阈值或权限过滤掉。
只有先分清这两件事,后续的优化才不会变成盲目调参。