14.02-RAG适用场景
要点
- 上一篇讲了 RAG 的基本概念,这一篇回答一个前置问题:什么时候该用 RAG
- RAG 不是万能的——它解决的是「基于外部知识回答问题」,其他问题有更好的方案
- 决策树:知识是否会变?是否需要溯源?知识量有多大?
- RAG 擅长的场景:私有知识库、实时信息、大规模文档、多租户
- RAG 不适合的场景:风格学习、简单任务、知识已经在模型训练数据里
- 有时候,长上下文 + 好 Prompt 就够了,不需要上 RAG
1. 先问自己三个问题
决定要不要上 RAG 之前,先问三个问题:
问题一:需要的知识在哪里?
- 在模型训练数据里 → 不需要 RAG,模型本身就知道
- 在你的私有数据里 → 需要 RAG(或微调)
- 在实时数据里 → 需要 RAG(训练数据有截止日期)
模型训练数据包含的是公开、通用、截至训练时间的知识。它知道 Python 是什么、HTTP 状态码的含义,但不知道你公司的报销流程、今天的新闻、某个用户的订单状态。
问题二:知识会更新吗?
- 几乎不变 → 微调可能更合适
- 会频繁更新 → RAG 更合适(更新知识库即可,不需要重新训练)
- 实时更新 → RAG 是唯一选择
微调的成本主要在训练阶段。如果知识经常变,每次变化都要重新训练,成本不可接受。RAG 更新知识库是实时的。
问题三:需要溯源吗?
- 需要告诉用户「这个答案来自哪个文档」 → RAG
- 只要答案对,来源不重要 → 微调或长上下文都行
RAG 天然支持溯源——每个回答都可以追溯到具体文档片段。微调的知识融入了模型权重,无法溯源。
三个问题的答案组合起来,基本可以判断是否该用 RAG:
| 知识位置 | 更新频率 | 需要溯源 | 推荐方案 |
|---|---|---|---|
| 模型已知 | 不变 | 不需要 | 直接用模型,不需要额外方案 |
| 私有数据 | 不变 | 不需要 | 微调 |
| 私有数据 | 不变 | 需要 | RAG 或微调都可以 |
| 私有数据 | 频繁更新 | 需要 | RAG |
| 实时数据 | 实时 | 需要 | RAG |
| 实时数据 | 实时 | 不需要 | RAG 或 Function Calling |
2. RAG 擅长的场景
场景一:企业内部知识库问答
最典型的 RAG 场景。公司有几万份文档(产品手册、技术规范、会议纪要),员工用自然语言提问,AI 基于文档回答。
为什么 RAG 适合:
- 文档量大,上下文窗口装不下
- 文档会持续更新(新版本发布、政策变化)
- 员工需要知道答案来自哪个文档(验证、追溯)
- 不同部门看到不同知识库(权限隔离)
// 企业内部 RAG 的典型架构
const ragSystem = {
knowledgeBases: [
{ id: 'kb-product', name: '产品文档', accessibleBy: ['all'] },
{ id: 'kb-hr', name: '人事政策', accessibleBy: ['hr', 'managers'] },
{ id: 'kb-finance', name: '财务规范', accessibleBy: ['finance', 'managers'] },
{ id: 'kb-eng', name: '技术规范', accessibleBy: ['engineering'] },
],
// 查询时根据用户权限过滤
async query(question: string, userId: string) {
const user = await getUser(userId)
const accessibleKBs = this.knowledgeBases.filter(
(kb) => kb.accessibleBy.some((role) => user.roles.includes(role))
)
return vectorDB.query(queryVector, {
filter: { kbId: { $in: accessibleKBs.map((kb) => kb.id) } },
})
},
}场景二:客服机器人
基于产品文档和 FAQ 回答客户问题。
为什么 RAG 适合:
- 产品信息会更新(新功能、价格变化)
- 回答必须准确——不能编造不存在的功能
- 需要溯源——客户问「你说的保修期是多久」时,要能找到原始文档
- 不同产品线用不同的知识库
// 客服 RAG 的 Prompt 设计
const CUSTOMER_SERVICE_RAG_PROMPT = `你是{product_name}的客服助手。
## 规则
1. 只基于以下知识库内容回答
2. 如果知识库里没有答案,回答「我需要查询后回复您」
3. 不要编造产品功能或政策
4. 回答时引用来源编号
## 知识库
{retrieved_docs}
`场景三:法律 / 医疗 / 金融领域的专业问答
这些领域对准确性要求极高,模型不能「凭记忆」回答。
为什么 RAG 适合:
- 法规 / 指南会更新(新版本发布、监管变化)
- 回答必须有依据——能追溯到具体条款
- 不同客户适用不同的法规版本
- 幻觉的后果很严重(法律建议错误、医疗建议错误)
// 法律 RAG 的溯源要求
const legalRAGResponse = {
answer: '根据《劳动合同法》第四十七条,经济补偿按劳动者在本单位工作的年限...',
citations: [
{
source: '《劳动合同法》',
article: '第四十七条',
text: '经济补偿按劳动者在本单位工作的年限,每满一年支付一个月工资的标准向劳动者支付...',
effectiveDate: '2008-01-01',
},
],
}场景四:实时信息问答
新闻、股票、天气、体育赛事——这些信息变化太快,训练数据追不上。
为什么 RAG 适合:
- 信息实时变化——每次查询都要获取最新数据
- 知识库可以是实时的数据流(新闻 API、股票 API)
- 不需要重新训练模型
注意:这个场景也可以用 Function Calling(让模型调用外部 API 获取数据)。RAG 和 Function Calling 的区别在于:RAG 适合「从大量数据中检索」,Function Calling 适合「调用特定 API 获取特定数据」。
场景五:多租户 SaaS
不同客户有不同的知识库,需要数据隔离。
为什么 RAG 适合:
- 每个客户独立的知识库
- 数据必须隔离——A 客户不能看到 B 客户的数据
- 知识库可以独立更新
- 可以用向量数据库的 namespace 做物理隔离
3. RAG 不适合的场景
场景一:学习特定风格或语气
如果目标是让模型学会特定的写作风格(比如公司品牌语气、特定作者的文风),RAG 帮助不大。
原因:RAG 检索的是「事实」,不是「风格」。你可以用 RAG 检索到「这个产品有什么功能」,但很难用 RAG 教会模型「用什么样的语气描述这些功能」。
更合适的方案:微调。让模型从大量风格一致的文本中学习。
场景二:知识已经在模型训练数据里
如果问的是「Python 怎么安装」「HTTP 状态码 404 是什么意思」,模型本身就知道答案,不需要 RAG。
加 RAG 反而可能:
- 增加延迟(多了一次检索)
- 增加成本(多了一次 embedding 调用)
- 引入噪声(检索到的文档可能不准确)
判断标准:如果通用模型(如 GPT-4o)已经能准确回答,就不需要 RAG。
场景三:简单的格式转换
如果任务是「把 JSON 转成 XML」「把 Markdown 转成 HTML」,这是确定性的转换,不需要知识,也不需要 RAG。
直接写代码做转换,比用 LLM 更可靠、更便宜。
场景四:知识库太小
如果你的「知识库」只有 10 页内容,直接塞进 Prompt 就够了,不需要 RAG。
// 知识库 < 5000 字时,直接塞进 Prompt 可能更简单
const smallKB = await loadSmallKnowledgeBase() // 几页内容
const prompt = `
根据以下信息回答:
${smallKB}
问题:${userQuestion}
`RAG 的价值在知识库大到装不进上下文窗口时才体现出来。
场景五:需要深度推理而非事实检索
如果问题是「根据 A 公司的财务数据和行业趋势,分析它明年的增长潜力」,这需要深度推理,不是事实检索。
RAG 能提供相关数据,但深度推理需要模型自己思考。这种情况可能需要 RAG + CoT(Chain of Thought)结合,或者直接用更强的推理模型。
4. 决策树
把上面的判断整理成决策树:
需要基于外部知识回答问题?
│
├── 否 → 不需要 RAG
│
└── 是 → 知识在哪里?
│
├── 模型训练数据里 → 不需要 RAG
│
└── 私有数据 / 实时数据 → 知识会更新吗?
│
├── 几乎不变 → 需要溯源吗?
│ │
│ ├── 不需要 → 考虑微调
│ │
│ └── 需要 → RAG 或微调
│
└── 会频繁更新 → RAG
简化版:
- 模型本身就知道 → 不需要 RAG
- 知识在私有数据里 + 会更新 → RAG
- 知识在私有数据里 + 不变 + 需要溯源 → RAG
- 知识在私有数据里 + 不变 + 不需要溯源 → 微调
- 实时数据 → RAG 或 Function Calling
5. 一个容易误判的场景:长上下文 vs RAG
现在的模型上下文窗口越来越大(GPT-4o 128K、Claude 200K),有人会觉得:直接把所有文档塞进上下文就行了,不需要 RAG。
这个判断在某些情况下是对的。如果知识库只有几千字,直接塞进上下文确实更简单。
但长上下文有几个问题:
- 注意力稀释——上下文越长,模型对中间部分的注意力越差(「Lost in the Middle」现象)
- 成本——上下文越长,Token 消耗越大,成本越高
- 延迟——上下文越长,模型处理越慢
- 上限——即使 200K 上下文,也装不下几十万字的文档
RAG 的优势在于每次只给模型看最相关的几段,上下文短、成本低、延迟小、注意力集中。
经验法则:
- 知识库 < 5000 字 → 直接塞进上下文
- 知识库 5000-50000 字 → 长上下文或 RAG 都可以,看成本预算
- 知识库 > 50000 字 → RAG
6. RAG 的成本估算
决定是否上 RAG 之前,先估算一下成本。
索引阶段成本
- Embedding 调用:按 Token 计费
- 向量数据库存储:按向量数量计费
// 索引成本估算
const totalDocs = 10000 // 1 万份文档
const avgDocLength = 2000 // 平均每份 2000 字
const totalTokens = totalDocs * avgDocLength / 2 // 约 1000 万 token(中文 2 字约 1 token)
// OpenAI text-embedding-3-small: $0.02 / 1M token
const embeddingCost = (totalTokens / 1_000_000) * 0.02 // ≈ $0.2
// 向量数据库:10 万条向量(1 万文档 × 10 chunk/文档)
// Pinecone 免费层:100K 向量
// Qdrant Cloud:按集群计费一次性索引成本很低(几毛钱)。
查询阶段成本
每次查询:
- 1 次 Embedding 调用(问题向量化)
- 1 次向量检索
- 1 次 LLM 调用
// 单次查询成本估算
const queryTokens = 50 // 问题约 50 token
const contextTokens = 2000 // 检索到的上下文约 2000 token
const outputTokens = 500 // 模型输出约 500 token
// Embedding: $0.02 / 1M token × 50 / 1M = $0.000001
// LLM (GPT-4o): 输入 $2.5/1M × 2050/1M + 输出 $10/1M × 500/1M
// = $0.005125 + $0.005 = $0.01
// 向量检索:通常包含在数据库费用中
// 单次查询总成本 ≈ $0.01(1 美分)每天 1000 次查询 ≈ $10/天 ≈ $300/月。
这个成本对大多数企业来说可以接受。但如果查询量更大,需要考虑优化(缓存、用小模型做初筛等)。
7. 常见误区
误区一:所有 AI 功能都要上 RAG
不是所有功能都需要 RAG。如果一个功能用 Prompt + 模型本身的知识就能做好,不要为了用 RAG 而用 RAG。
误区二:RAG 能解决所有知识问题
RAG 解决的是「事实性知识检索」。如果问题是「这个产品应该怎么改进」,这需要推理和判断,RAG 能提供的帮助有限。
误区三:RAG 不需要评估
「检索 + 生成」听起来简单,但每个环节都可能出问题。没有评估就上线,等于盲飞。第 14.17 节会讲 RAG 评估。
误区四:向量数据库选好了就万事大吉
向量数据库只是 RAG 链路中的一环。切分策略、Embedding 模型、检索算法、Rerank、Prompt 设计——每个环节都影响最终效果。
总结
回顾这一节的要点:
- 三个前置问题:知识在哪里、会不会更新、是否需要溯源
- RAG 擅长的场景:私有知识库、客服、法律医疗金融、实时信息、多租户
- RAG 不适合的场景:风格学习、模型已知的知识、简单格式转换、小知识库、深度推理
- 长上下文 vs RAG:小知识库直接塞上下文,大知识库用 RAG
- 成本估算:索引成本低,查询成本约 1 美分/次
- 常见误区:不是所有功能都要 RAG,RAG 不能解决所有问题
下一篇讲文档上传流程——RAG 索引链路的第一步。