第二章:RAG、微调与长上下文的三方取舍¶
2.1 不要把它当成单选题¶
讨论 RAG 和微调时,最常见的误区是二选一思维:把它们当成互斥选项,说完其中一个的优点就结束了。
支持长上下文的模型让选型多了一个维度:「既然材料装得下,为什么还要检索?」窗口长度只是条件之一,不能代替质量与成本验证。
更合适的比较方式,是把微调、长上下文和 RAG 放在一起看,再决定是否组合使用。
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 22, "padding": 8, "wrappingWidth": 160}}}%%
flowchart TB
NEED[需求] --> Q1[区分行为与知识]
Q1 --> CHOICE[选择或组合方案]
要改变行为、风格或格式,可以考虑微调。对知识需求,小且稳定的材料可以直接放入长上下文;语料规模大、频繁变化或需要权限过滤时,更倾向于 RAG。实践中经常组合使用这些方法。
2.2 三种方案的区别¶
可以先这样区分:
| 方案 | 知识存在哪 | 什么时候确定 | 改一条知识的代价 |
|---|---|---|---|
| 微调 | 模型参数里 | 训练时 | 再训练或模型编辑后验证、发布 |
| 长上下文 | Prompt 里 | 每次调用时 | 改输入即可 |
| RAG | 外部知识库 | 每次调用时动态检索 | 更新数据、索引与相关缓存 |
微调改的是模型本身,另外两个都是在推理时提供材料,区别只在于材料是「全塞」还是「先检索再塞」。
这个区分决定了后面的判断方式:长上下文和 RAG 都是在推理时提供材料,区别在于 RAG 多了一步「筛选」。因此真正要判断的不是「要不要 RAG」,而是「需不需要在把材料给模型之前先筛一遍」。
2.3 微调:把能力烧进参数¶
2.3.1 微调更适合什么¶
微调擅长的是改变模型的行为方式,而不是灌输事实:
- 提高固定格式、特定报告结构的遵循率;严格 JSON/schema 约束还需结构化输出或程序校验,不能靠微调保证;
- 特定的语气与风格(客服话术、法律文书口吻);
- 领域术语与表达习惯(医疗、金融的专业措辞);
- 特定任务的能力提升(分类、抽取这类结构化任务);
- 让小模型在窄任务上逼近大模型,从而降低推理成本。
最后一条在长期运行的窄任务里尤其重要:微调一个小模型专做某个任务,长期推理成本可能远低于持续调用大模型。
2.3.2 微调不擅长的¶
- 注入大量事实知识。这需要足够多的样本反复强化,成本高且效果不稳定;
- 频繁更新的知识。需要再训练或模型编辑并回归,难以像数据库一样可靠地逐条更新、撤销;
- 溯源。参数本身不提供可靠的逐条事实来源;模型生成一个书名或链接,不等于证明该事实来自那里;
- 权限隔离。共享参数不提供可靠的文档级 ACL,不能保证敏感知识不会被无权限用户诱出;外部授权仍然必要。
「不可溯源」和「无法做权限隔离」这两条,往往是企业选择 RAG 的关键原因之一,而不只是效果好坏的问题。
2.3.3 微调可以学知识,但不适合当知识库¶
微调和继续预训练可以学习事实,但是否划算取决于任务、更新频率和监督数据。更准确的说法是:
参数学习可以补充领域知识,但不等价于一个可逐条更新、撤销和审计的知识库。
2.4 长上下文:直接把材料全塞进去¶
模型窗口变大后,一个很自然的想法是:把所有资料一次性放进 Prompt,让模型自己找。
这个做法值得作为基线:当前用户有权访问的材料装得下,且读取成本可接受。它省掉检索链路,不会在检索阶段漏掉证据,但模型仍可能在长输入中漏读。长上下文同样可以先执行权限过滤,并逐条标注引用。
配合 Prompt Caching,重复使用同一批材料的成本还能进一步降低。
如果知识库只有几十篇稳定文档,直接全塞往往比搭一套 RAG 更快,工程复杂度也更低。
2.4.1 但它有四个硬约束¶
%%{init: {"flowchart": {"nodeSpacing": 12, "rankSpacing": 16, "padding": 8, "wrappingWidth": 110}}}%%
flowchart TB
LC[全文放入上下文] --> C[检查四项约束]
C --> D[测量有效利用率]
四项约束分别是:规模(语料超过窗口就装不下)、时效(频繁更新使缓存失效)、权限(输入前执行 ACL,不同权限降低缓存复用)和质量(位置与干扰内容可能降低有效利用率)。
前三条是常见工程约束,第四条直接影响最终效果。
2.4.2 窗口容量不等于有效利用能力¶
这不是猜测,而是有系统性实验证据的。
早期的 Lost in the Middle 研究发现:模型对上下文开头和结尾的信息利用得更好,放在中间的关键信息容易被忽略。
后续更严格的实验进一步表明:
- 在所测模型和任务上,输入变长可能导致性能下降,且可早于窗口上限;下降不是对所有模型都单调成立的定律;
- 当问题和答案之间是语义关联而非字面匹配时,下降更明显;
- 语义相近但错误的干扰内容,比完全无关的内容伤害更大;
- 经典的「大海捞针」测试拿满分,不代表模型在真实长上下文任务中可靠——因为它只考察字面匹配。
这个现象通常被称为 Context Rot(上下文腐化)。
这些结果支持的工程判断是:单纯塞更多材料不一定提升效果,应区分必要证据与干扰。RAG 的最终上下文选择也面临相同问题——见 2.6 节。
2.4.3 长上下文能取代 RAG 吗¶
已有研究测试了若干模型与任务,显示长上下文不能无条件替代检索、SQL 等组件;这不排除它在某个小语料任务上比 RAG 更合适。需要检查:
- 语料规模超出窗口——这是硬性的;
- 语料频繁更新——变化位置可能影响前缀缓存复用,需测实际预填充成本;
- 需要精确检索的结构化查询;
- 相关信息稀疏地分布在大量文档中时的多文档融合。
工程上可以把两者组合,但不应把某年的“共识”当作选型证据。
RAG 负责「从海量语料中筛出候选」,长上下文负责「把候选读得更充分」。
一个正在增多的做法是把两者结合:检索阶段不再返回几百 Token 的小片段,而是返回整篇文档或大段落,交给长上下文模型阅读。这样既避免了小片段丢失语境的问题,又避免了全量塞入的规模问题。
2.5 三方对比表¶
| 方案 | 主要预算与失败模式 |
|---|---|
| 微调 | 容量、训练数据与发布流程限制知识更新;可能过拟合或遗忘。推理成本和首 Token 延迟由实际模型、输入和服务负载决定 |
| 长上下文 | 受窗口及有效利用能力限制;预填充、缓存命中和更新位置影响成本与延迟,材料装得下也可能漏读 |
| RAG | 受存储、摄取、检索和治理预算限制;查询多了召回、重排等工作,也可能因缩短输入减少预填充;主要风险是漏检、错检和生成误读 |
溯源和权限应单独比较:长上下文与 RAG 都能携带引用,也都需要在输入前外部授权并校验引用;共享模型参数本身不提供文档级 ACL 或可靠事实来源。前期投入和首 Token 延迟不能简单排成“高、中、低”,小模型微调、长前缀缓存和复杂检索链路可能改变次序。
比较总成本时,把数据与训练、索引构建与更新、每次查询、缓存写入/命中和运维分别计费。只有微调后能换用较小模型或明显减少输入时,才可能摊薄训练成本;高命中率长上下文缓存也可能比复杂检索链路便宜。
2.6 Top-K 不是越大越好¶
「多召回一些 chunk 总没坏处」并不成立。
很多人默认 Top-K 越大越好,反正模型自己会挑。但 2.4.2 节的证据表明,无关或语义相近但错误的内容会主动损害答案质量,模型并不会干净地忽略它们。
正确的做法是:
- 把 Top-K 当作需要实测调优的超参数,而不是设个大数了事;
- 用 Rerank 把候选压缩到少而准,而不是把粗排结果直接全给模型;
- 注意最优 K 值依赖于具体模型和任务,换模型后需要重新测。
Anthropic 的 Contextual Retrieval 博客在所测设置中比较了 5、10、20 个片段,并报告 20 更好;长上下文研究则显示干扰内容可能损害质量。这不矛盾:片段数量、长度、相关性和模型共同决定结果,不存在通用的最优 K。
2.7 怎么选:一套可执行的判断顺序¶
%%{init: {"flowchart": {"nodeSpacing": 16, "rankSpacing": 22, "padding": 8, "wrappingWidth": 160}}}%%
flowchart TB
B{语料能装入窗口?} -->|否| RAG[RAG]
B -->|是| C[检查工作负载条件]
C --> D[比较总成本]
这一步针对知识需求;行为、格式或风格变化仍然对应微调。语料能装入窗口时,依次检查更新是否频繁、是否按用户过滤、调用量是否很大。任何一项为“是”,都应比较更新、授权过滤、缓存与检索的总成本。只有三项都为“否”时,直接将全部材料放入长上下文才是简单的起点。
可以按四个问题依次判断:装不装得下 → 更不更新 → 要不要过滤 → 调用量大不大。超出窗口时必须筛选、分组或分轮处理;频繁更新和权限差异则要求比较方案,不自动排除长上下文。即使选择全量输入,也要在固定任务集上检验漏读和干扰。
2.8 组合使用才是常态¶
这三者不是互斥的,生产系统中经常同时存在:
| 组合 | 分工 |
|---|---|
| 微调 + RAG | 微调解决「怎么说」(格式、语气、领域表达),RAG 解决「说什么」(事实依据) |
| RAG + 长上下文 | RAG 粗筛出相关文档,长上下文模型完整阅读,而不是只读碎片 |
| 三者齐用 | 微调一个小模型做领域任务,RAG 提供实时知识,长上下文承载检索出的完整文档 |
「微调解决怎么说,RAG 解决说什么」说明了两者的分工:它们处理的不是同一个问题,因此通常不是互斥关系。
还有一种把两者结合的思路:针对 RAG 场景微调模型,设计抗干扰样本,训练它区分给定材料中的有用信息与干扰信息。若任务要求答案必须有材料依据,还应单独设计并评估证据不足时的拒答训练。两者不能混为一种已被证明的能力:所引 RAFT 的训练包含移除正确文档但仍保留目标答案的样本,鼓励模型利用参数知识回答,不能据此认定它已学会在缺少证据时拒答。
2.9 常见错误¶
2.9.1 把问题答成单选题¶
如果完全不考虑组合使用,往往会遗漏实际系统里的常见做法。
2.9.2 说「微调学不到知识」¶
不准确。可以学习事实,但共享参数不适合承担频繁的逐条更新、撤销与来源审计。
2.9.3 认为长上下文已经淘汰了 RAG¶
有明确的实验证据反驳,且忽略了规模、时效、权限、成本四个约束。
2.9.4 认为窗口够大就可以随便塞¶
长输入中的位置效应和干扰风险有实验证据,但不是“每加一个 Token 必然变差”;需在当前模型和任务上复测。
2.9.5 只比效果不比成本结构¶
不计调用量、模型大小、缓存命中和更新频率,就无法比较训练、检索与长上下文的总成本。
2.9.6 忽略权限与溯源¶
在企业场景里,这两条经常直接决定方案选型,且不可通过「效果更好」来弥补。
2.10 本章总结¶
- 微调改的是模型行为;长上下文和 RAG 都是在推理时提供材料,区别在于 RAG 先做筛选;
- 微调更适合格式、风格、领域表达和小模型降本,不适合承载大量事实知识、频繁更新、溯源和权限隔离;
- 长上下文在语料小且稳定时很有效,但仍受规模、时效、权限和质量四个约束;
- 长输入可能出现非均匀退化,「大海捞针」满分不代表真实任务可靠;
- 长上下文可在特定小语料任务中替代检索,也可与 RAG 组合;不能无条件推广到海量语料;
- Top-K 需要按模型和任务实测调优,不存在一组固定答案;
- 实际判断通常按四个问题展开:装不装得下、是否频繁更新、是否需要过滤、调用量是否足够大;
- 三种方案可以组合,但是否增加一个组件,应由它解决的失败问题和新增成本决定。
参考资料¶
本章的参考资料、阅读建议与来源说明见集中参考资料章节。