§1.1.4

什么场景不适合 RAG(纯推理、创意生成、风格迁移)?

核心概念

检索增强生成(Retrieval-Augmented Generation, RAG)是一种将大型语言模型(LLM)与外部知识库相结合的架构。其核心思想是,在生成回答之前,首先从一个庞大的文档集合(如维基百科、公司内网、数据库)中检索出与用户问题相关的“上下文”或“证据”,然后将这些检索到的信息连同原始问题一起提供给 LLM,引导其生成更准确、更具事实性的回答。RAG 的本质是为 LLM 提供一个“开卷考试”的环境,而非依赖其自身参数中存储的(可能过时或不准确的)“闭卷”知识。

原理与推导

从概率建模的角度看,标准的大型语言模型(LLM)试图直接对给定输入 xx(问题)生成输出 yy(答案)的概率 P(yx)P(y|x) 进行建模。其生成过程可以看作是自回归地预测下一个词元(token):

P(yx)=i=1NP(yiy<i,x)P(y|x) = \prod_{i=1}^{N} P(y_i | y_{<i}, x)

其中 yiy_i 是输出序列的第 ii 个词元。这个模型的知识完全存储在模型的参数 θ\theta 中,是“参数化知识”。

RAG 引入了一个外部知识库 D\mathcal{D} 和一个中间步骤:检索。它将生成过程分解为两部分:

  1. 检索(Retriever):给定问题 xx,从知识库 D\mathcal{D} 中检索出一个或多个相关文档 zz。这一步建模为 P(zx)P(z|x)
  2. 生成(Generator):基于问题 xx 和检索到的文档 zz,生成最终答案 yy。这一步建模为 P(yx,z)P(y|x, z)

整个 RAG 模型的概率公式是通过对潜在文档 zz 进行边缘化得到的:

PRAG(yx)=zDP(yx,z)P(zx)P_{RAG}(y|x) = \sum_{z \in \mathcal{D}} P(y|x, z) P(z|x)

推导与动机:

  • 动机: 直接计算上式是不可行的,因为知识库 D\mathcal{D} 可能非常巨大。
  • 近似: 在实践中,我们使用一个近似方法。检索器 pη(zx)p_\eta(z|x)(例如,一个稠密向量检索模型,如 DPR)被训练来为给定问题 xx 返回一个最相关的文档子集。我们通常只考虑 top-k 个最相关的文档。
  • 实用公式: RAG 的实际生成过程可以简化为:首先,用检索器找到 top-k 个文档 {z1,z2,...,zk}\{z_1, z_2, ..., z_k\};然后,将这些文档与原始问题拼接起来,形成一个新的 prompt,输入给生成器。
PromptRAG="Context: "z1,z2,...,zk Question: "x Answer: "\text{Prompt}_{\text{RAG}} = \text{"Context: "} z_1, z_2, ..., z_k \text{ Question: "} x \text{ Answer: "}

生成器在此基础上计算 P(yPromptRAG)P(y | \text{Prompt}_{\text{RAG}})

为什么 RAG 不适合某些场景? 从公式 PRAG(yx)P(yx,ztop-k)P_{RAG}(y|x) \approx P(y|x, z_{\text{top-k}}) 可以看出,RAG 的输出 yy强行与检索到的外部文档 zz 绑定。

  • 当任务成功与否不依赖于、甚至排斥外部特定事实 zz 时,RAG 就会失效或产生负面效果。
  • 纯推理: 逻辑推理(如 "如果 A>B 且 B>C,那么 A 和 C 的关系是?")依赖于通用的逻辑规则,而非特定的外部文档。检索一篇关于 "A" 或 "B" 的文章是毫无意义的,甚至会因为引入无关信息而干扰模型的逻辑链。
  • 创意生成: 创作一首诗或一个故事,其价值在于新颖性、想象力和情感表达。RAG 会从知识库中检索现有文本,这会极大地限制模型的想象空间,使其生成的内容更像对现有材料的“缝合”或“改写”,而非真正的创作。
  • 风格迁移: 这类任务的核心是保持内容(Content)不变,转换风格(Style)。RAG 的检索器是基于内容的相似性来查找文档的,它无法理解“风格”这个抽象概念。检索到的文档很可能在内容上相关,但在风格上与目标风格南辕北辙,从而污染生成过程。

代码实现

下面的代码将通过一个“写诗”的例子,直观地展示 RAG 如何限制创意生成。我们将对比一个“无 RAG”的纯 LLM 生成和“有 RAG”的生成。

python
1import torch
2from transformers import AutoModelForCausalLM, AutoTokenizer
3
4# 为了方便演示,我们使用一个较小的、公开可用的中文模型
5# 在实际环境中,您需要替换为您自己选择的模型,例如 ChatGLM, Qwen 等
6# 这里使用 'uer/gpt2-chinese-cluecorpedia' 作为示例
7model_name = "uer/gpt2-chinese-cluecorpedia"
8tokenizer = AutoTokenizer.from_pretrained(model_name)
9model = AutoModelForCausalLM.from_pretrained(model_name)
10
11# 确保模型和分词器已加载
12if tokenizer.pad_token is None:
13 tokenizer.pad_token = tokenizer.eos_token
14
15def generate_text(prompt, max_length=100):
16 """一个简单的文本生成函数"""
17 inputs = tokenizer(prompt, return_tensors="pt", padding=True)
18 # 使用 .generate 方法进行自回归生成
19 outputs = model.generate(
20 inputs.input_ids,
21 max_length=max_length,
22 num_return_sequences=1,
23 pad_token_id=tokenizer.pad_token_id,
24 attention_mask=inputs.attention_mask,
25 do_sample=True, # 开启采样以增加创造性
26 top_k=50,
27 top_p=0.95,
28 temperature=0.9, # 较高的温度可以增加生成文本的多样性
29 )
30 return tokenizer.decode(outputs[0], skip_special_tokens=True)
31
32# --- 场景1:纯粹的创意生成 (不使用 RAG) ---
33print("--- 场景1:纯粹的创意生成 (不使用 RAG) ---")
34creative_prompt = "请写一首关于星空的短诗。"
35# 为什么这样做:直接向模型提出创意请求,让其自由发挥其在训练数据中学到的语言模式和创造力。
36creative_output = generate_text(creative_prompt)
37print(f"输入提示: {creative_prompt}")
38print(f"生成结果:\n{creative_output}\n")
39
40
41# --- 场景2:被 RAG 限制的创意生成 ---
42print("--- 场景2:被 RAG 限制的创意生成 ---")
43# 模拟 RAG 的检索结果:一段关于星空的、非常科学和事实性的描述
44retrieved_knowledge = "星空是由地球上观察到的宇宙天体(如恒星、行星、星系)在夜间的景象。恒星是巨大的、发光的等离子体球,由引力束缚在一起。例如,太阳是距离地球最近的恒星。"
45
46# 为什么这样做:这是 RAG 的核心操作。将检索到的知识(retrieved_knowledge)作为上下文,
47# 强制模型在生成时必须参考这些信息。这模拟了 RAG 将外部事实注入提示的过程。
48rag_prompt = f"""
49根据以下信息,写一首关于星空的短诗:
50
51信息:{retrieved_knowledge}
52
53短诗:
54"""
55rag_output = generate_text(rag_prompt, max_length=150)
56print(f"输入提示: {rag_prompt.strip()}")
57print(f"生成结果:\n{rag_output}\n")
58
59# --- 结论观察 ---
60# 预计结果:
61# 场景1的输出会更具诗意、想象力和发散性。
62# 场景2的输出会更像对“信息”部分的复述或总结,可能会提到“等离子体球”、“引力”等词,
63# 从而失去了诗歌的美感和创造性,证明了 RAG 在此场景下的局限性。

工程实践

在实际项目中,判断是否使用 RAG 的核心标准是:任务的成功是否依赖于模型外部的、可检索的、事实性知识。

不适合 RAG 的典型场景:

  1. 纯逻辑与数学推理

    • 场景: 解决数学题、逻辑谜题、代码算法问题。
    • 原因: 这些任务依赖于符号操作和推理规则,而非外部世界的具体事实。检索一篇关于“微积分”历史的文章对求解一个积分问题没有帮助。
    • 替代方案: 使用具备更强推理能力的模型(如通过思维链 CoT 微调)、集成符号计算引擎(如 WolframAlpha)。
  2. 高度主观或创意性任务

    • 场景: 写诗、写小说、生成营销文案、进行头脑风暴。
    • 原因: RAG 的事实性约束会扼杀创造力。目标是“无中生有”或情感表达,而非“有据可查”。
    • 替代方案: 使用高质量的基座模型,通过精巧的 Prompt Engineering(如角色扮演、风格引导)来激发其创造力。
  3. 风格转换与文本改写

    • 场景: 将一段正式文本改为口语化风格、将 Python 代码转换为 JavaScript 代码。
    • 原因: 任务的核心是“形式”而非“内容”。RAG 按内容检索,会引入无关信息。例如,改写一段关于“经济衰退”的文本,RAG 可能会检索到更多关于经济衰退的报告,而不是关于“口语化风格”的例子。
    • 替代方案: 使用经过指令微调(Instruction-tuning)的模型,直接下达转换指令。
  4. 通用对话与闲聊

    • 场景: 智能助手(如 Siri, Alexa)的日常聊天功能。
    • 原因: 对话是开放域的,不总是需要特定的事实。为每一句闲聊(如“今天天气不错”)都进行一次检索会带来不必要的延迟和成本,且检索结果很可能无用。
    • 替代方案: 使用强大的对话模型。只在对话中明确出现知识查询意图时(例如“帮我查一下明天天气怎么样?”),才触发 RAG 或其他工具调用(Tool Calling)。
  5. 上下文完全自足的任务

    • 场景: 对用户在当前会话中已提供的文档进行总结、翻译或问答。
    • 原因: 所有需要的信息已经存在于当前的上下文中,无需从外部知识库进行“检索”。此时再进行 RAG 是画蛇添足,增加了系统的复杂性和延迟。
    • 替代方案: 直接将用户提供的文档作为上下文输入给 LLM。注意处理长上下文(Long Context)的挑战。

权衡:

  • 延迟与成本: RAG 引入了至少一次网络往返(到向量数据库)和一次额外的模型调用(Retriever),显著增加了延迟和计算/API成本。如果任务收益不明显,就不应使用 RAG。
  • 维护: RAG 需要维护一个向量数据库和一套数据更新、清洗、分块(Chunking)的 ETL 流水线,这带来了额外的工程和维护成本。

常见误区与边界情况

  • 误区一:“RAG 就是为了解决幻觉,所以任何需要事实的场景都应该用 RAG。”

    • 辨析: RAG 是缓解幻觉的有效手段,但不是唯一手段,也非万能手段。如果所需事实是通用、稳定且不常更新的(如“法国的首都是巴黎”),一个经过良好训练的基座模型本身就可能知道。只有当知识是领域特定、动态更新、或过于长尾以至于模型无法在参数中有效记忆时,RAG 的优势才最明显。
    • 面试追问: “如果一个事实,基座模型好像知道,但有时会答错,我应该用 RAG 还是微调?”
    • 回答要点: 这取决于错误的模式。如果错误是零星的、随机的,用 RAG 快速提供正确信息是低成本的选择。如果模型对某一类概念(如公司内部产品术语)系统性地理解错误,那么进行微调(Fine-tuning)来修正模型的“世界观”可能更根本。最佳实践常常是 RAG + 微调的结合。
  • 误区二:“我的任务需要一点事实,也需要一点创意,所以 RAG 没用。”

    • 辨析: 很多任务是混合型的。例如“写一篇关于苹果公司发布第一代 iPhone 的历史故事”。这个任务既需要事实(日期、人物、事件),也需要创意(叙事手法、情感渲染)。
    • 边界情况处理: 这种情况下,可以策略性地使用 RAG
      1. 分步执行: 先用 RAG 检索出所有关键事实点(时间线、关键人物、技术规格等),形成一个“事实大纲”。
      2. 创意生成: 再让 LLM 基于这个“事实大纲”进行创意写作,并明确指示它可以进行艺术加工。Prompt 可以是:“请基于以下事实大纲,用引人入胜的笔法,讲述乔布斯发布 iPhone 的故事...”。
      3. 后置事实核查: 或者,先让模型自由创作,然后用 RAG 或其他工具对其生成内容中的事实性声明进行核查和修正。
  • 误区三:“只要把所有文档都扔进向量数据库,RAG 就会变好。”

    • 辨析: 检索的质量是 RAG 系统的上限。如果知识库中充满了大量低质量、过时或无关的文档,检索器很可能会取回“垃圾”,导致“垃圾进,垃圾出”(Garbage In, Garbage Out)。这在不适合 RAG 的场景中问题更严重,因为无关的“垃圾”会严重干扰模型的推理或创作过程。
    • 面试追问: “如何评估我的 RAG 系统中的检索器部分是否在拖后腿?”
    • 回答要点: 建立一个“Retriever-only”的评测集。该评测集包含(问题,期望检索到的文档ID)对。使用 Recall@KMRR (Mean Reciprocal Rank) 等指标来量化检索器的性能。如果检索器性能差,需要优化分块策略、Embedding 模型或使用更高级的检索技术(如混合检索、重排模型 Re-ranker)。
相关题目