RAG 不是银弹:哪些场景我宁可不用检索增强
补档说明:本文属于「AI 工程落地周记」系列,计划发布时间为 2025-01-16 14:30。当前先保留为草稿,后续补充真实案例、代码片段和复盘细节后再发布。
过去一年,RAG 几乎成了大模型落地的标准答案。只要有人问“模型回答不准怎么办”,大家第一反应往往就是“上 RAG”。这条路线当然没有错,很多知识型场景确实该这么做。但我越来越警惕另一种倾向:把 RAG 变成条件反射,仿佛只要做 AI 问答,前面就必须先接一个向量库。
现实没有这么简单。RAG 不是一个按钮,而是一整套系统:文档清洗、切分、索引、召回、重排、上下文拼装、引用展示、评估和回放。只要其中一个环节没做好,最后用户看到的就不是“更智能”,而是“更复杂且更不稳定”。
所以我现在会先问:这件事真的需要检索增强吗?如果不需要,硬上 RAG 不仅没有收益,反而会把系统搞重。
什么情况下我会优先考虑 RAG
先说结论,RAG 在下面这些场景里仍然非常有价值:
1. 知识是外部的,而且更新频繁
例如产品文档、内部制度、售后手册、运维 SOP、FAQ。这些内容不适合硬编码在 Prompt 里,也不应该指望模型参数天然记住最新版。
2. 用户需要“带依据”的回答
很多内部系统不是只要答案,还要知道答案来自哪篇文档、哪个章节、哪条规则。RAG 能把证据一起带出来,这一点非常关键。
3. 文档体量已经超出人工整理范围
如果文档多、主题散、更新频繁,靠人工维护提示词和模板很快就会失控。这时候检索层能明显降低维护成本。
4. 问题本身是“找知识”而不是“走流程”
比如:
- 某个报销规则怎么解释
- 某个接口参数在文档哪里
- 某个问题过去的处理手册是什么
这类问题适合“检索 + 生成”。
哪些场景我反而不想上 RAG
真正容易踩坑的,是下面这些场景。
1. 规则非常明确、结果必须唯一
例如:
- 优惠券是否可用
- 订单是否已付款
- 权限是否开通
- 审批是否满足条件
这些问题本质上是规则判断或数据库查询。你真正需要的是确定性系统,而不是从一堆文档片段里“检索后再总结”。
对这类场景,我更愿意直接做:
- SQL 查询
- 规则引擎
- 配置表
- 明确的业务接口
而不是绕一圈做“向量召回 + 语言总结”。
2. 知识规模很小,而且边界稳定
如果一个功能只依赖十几条规则、几份固定说明、几个常见问答,那我通常会优先考虑:
- 手写结构化知识
- 规则模板
- 小型 FAQ 映射
- Prompt 中直接嵌入关键信息
因为这类场景引入 RAG,带来的复杂度往往大于收益。你要维护 embedding、索引和召回质量,但知识本身并不复杂。
3. 数据源很脏,文档质量远远不够
这是我最不愿意上 RAG 的情况。很多团队的问题不是“没有检索层”,而是:
- 文档互相矛盾
- 文件版本混乱
- 标题和正文缺少结构
- 过期内容没人清理
- 关键规则只存在聊天记录里
这种情况下做 RAG,很容易把脏知识大规模送进模型。最后表面上是“模型幻觉”,实际上是检索给了它错误上下文。
如果数据还没整理好,我宁可先做内容治理,也不急着上 RAG。
4. 业务对延迟特别敏感
RAG 不只是多一次查询。完整链路通常包含:
- 文本切分与向量化
- 向量检索
- 可能的重排
- 上下文拼接
- 模型生成
只要流量一上来,延迟和成本都会被放大。如果一个业务必须非常快,例如实时交互、高频调用、低延迟推荐,那么我会先问自己:
- 这件事能不能直接查库?
- 能不能预计算?
- 能不能缓存?
- 能不能先命中规则,再把少数复杂请求交给模型?
低延迟场景很多时候不是不能上 AI,而是不适合默认用 RAG。
5. 用户真正需要的是“执行”,不是“解释”
很多产品把“我要完成一件事”误做成“我要问一段话”。例如:
- 帮我查出本周未付款订单
- 帮我创建一张退款工单
- 帮我把这个客户分到华东销售组
这类任务的核心不是知识问答,而是工具调用和流程执行。它更适合:
- 模型做参数抽取
- 后端接口做实际执行
- 规则系统做权限校验
这种情况下,如果还坚持上 RAG,往往只是多了一层不必要的复杂度。
一个我更常用的判断方法
我现在会先用一句话分类需求:
- 如果用户是在“找知识”,优先考虑 RAG。
- 如果用户是在“做动作”,优先考虑工具和流程。
- 如果用户是在“要结果”,优先考虑规则和结构化数据。
这句话虽然简单,但能帮我挡掉很多不必要的 RAG 项目。
RAG 最容易被低估的隐藏成本
很多人以为上 RAG 只是加一个向量库,其实真正花时间的是后面的治理工作。
1. 切分策略
切太短,语义不完整;切太长,召回噪音大。不同文档类型还得用不同切法。
2. 元数据治理
如果没有部门、版本、时间、产品线等元数据,检索结果会非常混乱。
3. 召回评估
你得知道:
- 该召回的有没有召回
- 不该召回的有没有混进来
- 哪些关键词会误导召回
4. 重排和上下文拼装
很多回答不准,不是模型不行,而是上下文里混进了三段正确内容和两段错误内容。
5. 文档生命周期
老文档是否过期、重复文档如何去重、错误文档如何下线,这些都不是调用一次 embedding 就能解决的。
所以我会把 RAG 当成一个“知识系统项目”,而不只是一个模型接入动作。
我更愿意用的几个替代方案
在不适合 RAG 的场景里,我更愿意优先考虑下面这些方案。
1. 规则 + 模型抽取
模型只负责把自然语言转成结构化参数,真正判断由规则系统完成。
const parsed = await extractIntent(userInput)
return checkCouponRule({
userLevel: parsed.userLevel,
orderAmount: parsed.orderAmount,
channel: parsed.channel,
})
2. 数据库/搜索引擎直查
如果答案本来就在表里,就别让模型重新“理解一遍”。
3. 小型静态知识注入
知识规模小的时候,直接把规则片段整理成稳定模板,常常更省事。
4. 多层路由
先走规则、查库、缓存;只有规则处理不了的尾部问题再交给模型。这通常比“所有请求都走 RAG”更稳。
那到底什么时候该上 RAG
如果一个需求同时满足这几个条件,我会比较积极:
- 知识量不小,而且持续变化
- 用户问题是自然语言形式
- 回答需要结合证据
- 允许一定延迟
- 团队愿意投入文档治理和评估体系
只满足其中一两个条件,我都会更谨慎。
总结
RAG 解决的是“模型缺少外部知识且需要带着证据回答”的问题,而不是所有 AI 项目的通用底座。
对知识型问答,它很有价值;但对规则判断、流程执行、低延迟查询和脏数据场景,它很可能只是增加复杂度。比起问“能不能上 RAG”,我现在更愿意先问:“这个问题到底是不是知识检索问题?”
先把这个问题答对,后面的架构通常会清晰很多。
