RAG 上线后效果不好,多半不是模型的问题
RAG 的 demo 和线上是两回事。多数团队遇到的"模型答错了",查下去其实是"模型根本没看到正确的文档"。这篇把生产环境里真正会出问题的几个环节拆开,给出对应的评估方法。
验证截至 2026-10-21。内容依据多家公开工程实践文章与向量数据库选型资料综合整理,文中标注了哪些结论属于团队个案报告、哪些属于通用实践。
环境与版本
- 适用对象:已经跑通原型、准备上生产或上线后效果不达标的检索增强问答系统
- 不涉及具体框架选型(LangChain / LlamaIndex / Haystack / 自研均可),讨论的是与框架无关的环节
- 需要的前置条件:一批真实的查询样本,以及"哪些文档应该被检索到"的人工标注
第一条:检索和生成必须分开测
这是整个 RAG 工程里最该先立起来的规矩。在评判答案质量之前,先评判有没有把正确的上下文找出来。
理由很实际:如果检索这一步就没召回正确文档,那么后面换什么模型、怎么改 prompt 都没用——模型没看见,就答不对。把两层混在一起评估,你得到的信号是噪声。
检索侧该看的指标:
| 指标 | 含义 | 用途 |
|---|---|---|
| Recall@k | 前 k 条结果里包含了多少相关文档 | 判断召回是否够 |
| Precision@k | 前 k 条里有多少是相关的 | 判断噪声是否多 |
| MRR | 第一条相关结果排在第几位 | 判断排序质量 |
| nDCG | 对排序位置加权的综合分 | 整体对比用 |
生成侧该看的指标: faithfulness(每个论断是否被检索到的上下文支撑)、answer relevance(是否回答了用户的问题)、context precision/recall(送进上下文的片段是不是既相关又必要)、citation accuracy(引用是否指向正确的来源和片段)。
生成侧用 LLM-as-judge 可以加快迭代,但必须拿人工标注校准过——评审模型天然偏向长答案和自己风格的答案,这个偏差不校准就会把优化方向带偏。
第二条:golden dataset 是唯一的验收依据
公开实践里反复出现的一个数字区间是:起步 100 条真实查询,成熟期扩到 300–500 条,每条配专家确认过的参考答案;另一些团队的起点是 50–100 条。
关键不在数量在多样性:要覆盖长尾、歧义、多跳、以及"文档里根本没有答案、应该拒答"的那一类。漏掉拒答类,你的系统会学会胡编。
配套的纪律是:prompt、分块策略、检索配置全部进版本管理,每次改动跑一遍评测集。 模型升级也要重跑——回归是常态,不是意外。
第三条:失败模式对照表
下面这些是生产环境里反复出现的形态,以及对应的处理方向。
| 现象 | 根因 | 处理方向 |
|---|---|---|
| 有上下文仍然胡编 | 模型忽略证据或混入了参数知识 | 收紧 prompt 约束、明确拒答、校验引用 |
| 证据埋在长上下文中间被忽略 | lost-in-the-middle | 重排、上下文压缩、把高相关片段放到两端 |
| 答案正好跨两个块,两边都没被完整召回 | 分块边界 | 加 overlap、父子块检索、句子窗口检索 |
| 文档更新了但答案还是旧的 | 索引陈旧 | 增量入库、索引版本化、新鲜度过滤 |
| 换了 embedding 模型后效果整体下滑 | 向量空间漂移 | 索引版本化,先在影子管线重嵌再切 |
| 用户用词和文档用词对不上 | 查询失配 | 查询扩展、混合检索、领域同义词表 |
| 用户看到了他没权限看的文档 | 权限泄漏 | 在检索时做 ACL 过滤,不是检索完再过滤 |
| 索引里混进了恶意或错误内容 | 上下文投毒 | 来源白名单、入库清洗、溯源记录 |
权限那条值得单独强调:事后过滤看似简单,但它在分页、重排、top-k 截断之后才生效,既可能漏,也可能让本该返回的 k 条变得不足 k 条。过滤必须发生在检索阶段。
第四条:检索出来的内容是不可信输入
这一点在接了 Agent 之后尤其致命。检索到的文本里可能藏着指令,试图覆盖系统提示词或让模型去调用工具。
处理原则是:检索内容一律当作不可信输入——用分隔符隔离、建立指令层级、对输出做校验;并且不要让检索到的文本直接决定工具调用或权限判断。入库前做敏感信息脱敏,传输和存储加密,同时保留"哪次回答引用了哪些文档"的审计线索。
第五条:延迟是几段加出来的,从最划算的那段优化
一次问答的耗时 = 查询改写 + embedding + 向量检索 + 重排 + 生成。常见的优化顺序:
- 缓存高频查询与其 embedding(相同问题反复付费是最常见的浪费)
- 生成用流式,让用户早点看到字
- 检索与重排能并行就并行
重排这一步要算账:top_k 较小时重排带来的延迟可能超过它的精度收益,有团队的做法是只在 top_k 较大时才启用重排。这笔账要按你自己的 k 值和重排模型的延迟来算,不能照抄。
公开资料里给出的经验阈值(属于参考值不是标准):向量检索延迟控制在 100ms 内、端到端 3 秒内。是否适用取决于你的场景,别直接拿去当 SLO。
边界与坑
- 混合检索 + 重排的效果提升幅度是团队个案报告,不同语料差异很大。有团队报告幻觉减少一半,这个数字不能外推,要在自己的评测集上重新量
- 中文场景要用中文语料微调过的 embedding 模型,通用多语模型在垂直领域的表现常常明显低于预期
- 向量库选型跟着数据量走:百万条以内 pgvector 或 Chroma 起步;百万到千万级考虑引入混合检索与重排;千万级以上再评估分布式方案。每次迁移前用真实数据和真实查询做基准,别只看文档参数
- 成本侧可做的:向量量化(float32 → int8 / binary)、用带稀疏输出的 embedding 模型替代独立维护的 BM25、冷热数据分级存储
- "更多上下文"不等于更好:塞进无关文本既增加成本也干扰模型
常见问题
Q:效果不好是不是该换更大的模型?
先跑一遍检索侧指标。如果 Recall@k 上不去,换模型是浪费钱——多数"模型不行"其实是"检索没找到"。
Q:评测集要多大才够?
100 条能起步,300–500 条是成熟期。多样性比数量重要,务必包含应该拒答的样本。
Q:什么时候该考虑微调而不是 RAG?
RAG 解决事实性、时效性、需要溯源的知识;微调解决风格、格式、以及难以用 prompt 表达的行为模式。需要动态更新和可审计的知识,先用 RAG。
Q:多轮对话怎么处理?
先把历史对话压缩成独立的查询再送检索;已经引用过的历史片段不要重复注入,否则既浪费 token 又干扰上下文。压缩失败时加 few-shot 示例引导。
参考与延伸
- Habsi Tech《RAG in Production: Architecture, Evaluation, and Failure Modes》与《A Practical Architecture for RAG》——失败模式与评估指标的主要来源
- FreshCodes《RAG in Production: 7 Lessons》——golden dataset 规模与分层评估口径(其中"幻觉减半"为该团队个案报告)
- 向量数据库选型与分阶段迁移路径:国内技术团队公开实践整理
- 中文 RAG 实战资料:查询压缩、重排与 top_k 取舍的工程经验