RAG 系统优化方法论(二):局部提升为什么传导不到最终答案
副标题:每层的 proxy 指标与单调性验证
作者:James Xie
这是《RAG 系统优化方法论》系列的第二篇。第一篇讲了怎么找到进攻方向:X/Y 对照集、归因分堆、从竞品答案反推分层金标准。
这一篇讲一个每个优化过 RAG 链路的人都撞过的墙:某一层明明改好了,最终答案却毫无变化,甚至更差。
问题拆解组的优化项目,结项汇报时的数据很漂亮。
背景是第一篇的瓶颈分布表:X 对照集里有 15 条死在拆解层——用户问”公司单方调岗我不去算旷工吗”,系统只拆出”调岗是否合法”,漏了”不去是否构成旷工”和”员工如何救济”。团队花了三周,改了拆解 prompt,加了覆盖检查器,子问题召回率从五成提到了八成五。对着金标准逐条验,条条命中。PPT 上的曲线昂首向上。
然后跑端到端评测。总分变化:几乎没有。有两条甚至变差了。
会议室里的气氛很微妙。三周的工作,局部指标涨了 35 个点,端到端一动不动。有人开始怀疑评测集有问题,有人开始怀疑拆解优化本身,有人提议”要不再跑一遍,可能是随机波动”。老板的问题是那个终极问题:“所以这三周到底有没有用?”
有用,也没用上。这个项目的复盘后来成了我们内部优化方法论的奠基文档——它把”局部提升传导不出去”这个玄学问题,拆成了三个具体的、可检查的工程断点。局部提升和端到端提升之间不是一根管道,是三道闸门。任何一道关着,提升就传导不过去。
一、断点一:端到端分数取决于瓶颈层,不取决于你优化的层
先讲最反直觉、也最常见的一个。
链路的端到端质量服从木桶原理的加强版:不只取决于最短的那块板,而且只有最短的那块板变长,水位才会涨。把第二短的板加长一倍,水位一毫米都不动。你优化的层如果不是这批样本的瓶颈层,局部指标涨上天,端到端也不会动。
回到拆解组的案例。事后把那 15 条样本逐条复查,发现一个尴尬的事实:

拆解确实漏了子问题,但其中有 9 条,就算拆解对了也没用——漏掉的那个子问题对应的材料,检索层根本回不来。拆解从 1/3 修到 3/3,检索还是只供得起 1/3 的材料,答案原地踏步。对这 9 条样本来说,瓶颈从来不在拆解,在检索。拆解指标涨了,是因为金标准只考核拆解这一层自己的输出,不考核”拆解对了有没有用”。
这就是”局部提升传导不出去”的第一个断点:提升打在了非瓶颈层上,被瓶颈层原样拦住。 它也再次证明了第一篇那条纪律的价值:先归因分堆再动手。瓶颈分布表的作用不是仪式感,是防止你把资源投进一个不是瓶颈的层。拆解组的正确姿势不是把 15 条全领走,而是领走分堆后真正瓶颈在拆解的那 6 条——剩下 9 条的归属是检索组,拆解优化得再好也替他们解决不了。
这里还有一个组织层面的教训。拆解组为什么把 15 条全领了?因为”拆解层的 bad case”是按表面症状归口的——答案缺了一块,看起来像拆解漏了。按症状归口,就像按疼痛部位分科室:腰疼可能是腰椎的事,也可能是肾的事,还有可能是睡姿的事。 最早异常边界存在的意义,就是把”看起来是哪层的问题”翻译成”实际上从哪层开始坏”。
优化之前先问自己:这个层,是这批样本的最早异常边界吗?不是的话,你优化的是自己的指标,不是用户的问题。
二、断点二:下游是在旧分布上调出来的
第二个断点更隐蔽。假设你优化的确实是瓶颈层,拆解真的修好了,子问题从 1 个变成 3 个——端到端还是没涨,甚至跌了。
原因是下游失配。
链路里每一层都是在上一层的旧输出分布上调出来的。检索的 top-k,是当年按”每条 query 平均 1.3 个子查询”定的;结果精简的 token 预算,是按旧拆解的输出长度定的;生成 prompt 的上下文排版模板,是按旧的子问题格式排的。这些参数没有写在任何”拆解模块”的文档里,它们散落在下游各层的配置里,沉默地假设着上游的样子。
拆解层升级了,输出分布变了——子查询数量翻倍、表述方式变了、粒度变细了——下游每一层看到的都是一个没见过的世界。就像一条装配线上,上游工序突然把零件的规格升级了,下游所有工位的模具还是按旧规格开的。零件本身更好了,装配质量反而下降。
拆解组那两条”变差”的样本就是这么来的:拆解输出了完整的三个子问题,结果精简环节的预算没变,第三个子问题的材料被挤掉了——修好的部分被下游的固化配置吃掉了。从监控上看,每个环节都”正常工作”,只有端到端分数知道发生了什么。
这是局部提升传导不出去在技术上的主因:你改的是一层的输出分布,而下游所有层都是旧分布的人质。 神经网络里冻结后面层、只训第一层之所以可行,是因为梯度会穿透冻结层完成适配——后层虽然是冻的,但它们和新的前层输出在同一个训练动力学里。RAG 链路里没有梯度,下游不会自己适应,它只会沉默地失配。
解法不是不动,是动完之后加一个步骤:再校准(recalibration)。A 层优化完成后,对下游做一轮轻量适配——不动下游的结构,只调浅参数:检索的 top-k、精简的预算、prompt 里的排版说明、各路的融合权重。这些参数重新对着新的输入分布标定一遍,传导链就重新接上了。
再校准的精神是”接口跟着上游走”:上游的语义升级了,接口参数必须重新对齐,否则升级在接口处被磨平。这个步骤的具体操作形态——怎么只动接口、不动结构——是第三篇的主题。这里先记住结论:改一层,至少要顺手标定下游的接口参数,否则提升会被接口吃掉。
三、断点三:proxy 指标和端到端目标根本不单调
第三个断点出在指标本身。
局部优化需要局部指标——行话叫 proxy(代理指标):真正想优化的目标没法直接、便宜地度量时,找一个可度量、且与目标同方向变化的指标来顶替它。就像血压是心血管健康的 proxy:它不是健康本身,但它可测、且和健康同向。第一篇给每层建的金标准,落到度量上就是各层的 proxy:拆解看子问题召回率,检索看应召回文档命中率,rerank 看 NDCG。但这里有个必须验证、而大多数团队从不验证的假设:这个局部指标的提升,和端到端质量是同方向的吗?
不一定。举两个真实的反例。
拆解层的子问题召回率:为了提高召回,团队的自然倾向是”多拆”——把一个问题的子问题越拆越多。召回率确实涨了,但子问题太多,检索预算被摊薄,每个子问题分到的材料变少;生成环节面对十七八个子问题,只能每个提一句,答案变成了什么都沾、什么都不透的流水账。召回率和端到端质量的关系不是单调递增,是一条倒 U 曲线:

漏拆有害,过度拆同样有害,最优点在中间——而且最优点的位置随类目变化:事实型问题拆一两个就够,争议型问题需要五六个维度。一个不分场景、只管”召回率越高越好”的指标,会推着团队一路冲进倒 U 的右半段还自以为在进步。
检索层的命中率同理:为了提高应召回文档的命中,最省事的办法是把 top-k 拉大,召回五十篇,金标准当然全在里面。命中率满分,但噪声文档也跟着进来了,rerank 的负担加重,生成的上下文被无关材料稀释。命中率涨了,端到端跌了。
这就是 Goodhart 定律的链路版:一个指标被当成目标的那一刻,它就开始失真。 proxy 指标是手段,不是目的——它的全部合法性来自它和端到端质量的相关性。这个相关性不验证,优化就是在对着一个可能指错方向的仪表猛踩油门。
四、给每层建 proxy,并且验证它的单调性
那 proxy 到底怎么建、怎么验?我们的做法分两步。
第一步:建 proxy。 原则是用第一篇的分层金标准,指标本身要机械可算,不依赖主观判断:

- 拆解层:子问题召回率(对金标准子问题清单的覆盖),外加子问题数量的护栏——防过度拆解
- 检索层:应召回命中率、recall@k,外加噪声比护栏(召回集合里不在金标准里的文档占比)
- rerank 层:金标准文档的 NDCG,外加头部噪声率护栏
- 上下文层:关键材料存活率——金标准文档有多少活着进入了模型输入
- 生成层:引用支撑率、材料利用率(进入 context 的金标准材料有多少真的被答案用上),外加答案长度与自信度漂移护栏
注意每个主指标旁边都配了护栏指标。这是被 Goodhart 教育出来的设计:单指标必然被榨取——召回率会被”多拆”榨取,命中率会被”拉大 top-k”榨取,材料利用率会被”无脑堆砌引用”榨取。主指标回答”好不好”,护栏回答”是不是作弊式的好”。 主指标涨、护栏也涨,优化立刻叫停,回去想别的路径。
第二步:验证单调性。 proxy 建好不能直接上岗,要先证明它配。两个方法。
一是历史数据相关性分析。把过去几个月的生产请求捞出来,同时算每层的 proxy 和最终的用户反馈(点赞点踩、是否追问、是否转人工)。proxy 和用户满意度显著相关的,留下;不相关的,换掉。

这一步经常有意外的发现。我们就发现过团队精心维护的”答案完整度评分”和用户满意度几乎零相关——完整度高的答案用户照样点踩,因为它完整得又臭又长;而”首句是否直接回答问题”这个看起来粗糙的指标,相关性高得多。用户要的不是百科全书,是先给结论。如果没有相关性分析,优化资源就会投给那个精致的、零相关的指标。
二是干预实验。对 proxy 做一次人为的小幅扰动——比如刻意把检索 top-k 从 10 调到 15——看端到端指标是否同方向跟随。proxy 动、端到端不动,说明这个 proxy 在当前取值区间里已经失真了:可能撞上了瓶颈转移(断点一,瓶颈早就不在这层),也可能进了倒 U 的右半段(断点三,已经在过度优化的区间)。干预实验回答的不是”这个指标理论上对不对”,而是”这个指标在当前系统的当前区间还灵不灵”——后者才是优化决策真正需要的。
验证通过的 proxy 才敢用来指导优化。验证本身也要定期重做:链路和用户都在变,去年单调的指标今年可能就不单调了。指标也有保质期。
五、让传导发生:三道闸门的检查清单
把三个断点合起来,局部优化上线前就有一张检查清单:

闸门一:瓶颈检查。 我优化的层是这批目标样本的最早异常边界吗?——归因分堆,第一篇的方法。
闸门二:单调性检查。 我的 proxy 指标和端到端质量在当前区间同向吗?——相关性分析加干预实验,本篇的方法。
闸门三:接口检查。 A 层的输出分布变了,下游的接口参数重新标定了吗?——再校准,第三篇展开。
三道闸门都过,局部提升才有资格变成端到端提升。拆解组那个项目后来复盘,三道闸门的情况分别是:没过(15 条里只有 6 条瓶颈在拆解)、没过(子问题召回率冲进了倒 U 右半段)、没做(下游 top-k 和精简预算没动)。三个断点全踩,三周工作只转化出了六条样本的端到端改善。
但这不是说那三周白干了。proxy 体系的建立、金标准的标注、覆盖检查器的开发,都是后续循环的基础设施。第一次循环的产出从来不只是指标变化,而是整套传动装置的安装。 第二次优化检索层的时候,从立项到出结果只用了一周——因为仪表都装好了,瓶颈是真的,单调性是验过的,接口是顺手标定的。同一个团队,同样的三周工作量,第二次的端到端转化率是第一次的四倍。差别不在能力,在顺序。
结语:指标是仪表,不是目的地
这篇的核心产物,四件东西:
- 瓶颈检查:优化前确认目标层是目标样本的最早异常边界
- Proxy 指标体系:每层一个主指标加护栏指标,对着金标准机械可算
- 单调性验证:相关性分析加干预实验,证明 proxy 配当 proxy
- 再校准:A 层优化后对下游接口参数的轻量标定
回头看,“局部提升传导不出去”从来不是玄学,它是三个具体的、可检查的工程问题:优化错了层、下游没适配、指标失了真。三件事都有确定性的检查方法,也都应该在动工之前查,而不是结项汇报时被老板问出来。
这套检查清单还有一个隐藏价值:它把”优化没效果”从一种情绪变成了一个可诊断的事件。以前项目没效果,复盘只能停留在”下次注意”;现在可以指着三道闸门说,是哪一道没查、为什么没查、谁负责查。方法论的终极产出不是提升,是让失败也变得有信息量。
局部指标是仪表,不是目的地。仪表的全部价值,在于它和目的地的方向一致。
下一篇讲完整的行动循环:选定了层、建好了 proxy、确认了单调性——具体怎么动手优化?冻结主干、挂补丁、对着金标准调参、配对评测验收、有效则 merge 回主干,一套从 QLoRA 借来的打法。
下一篇:《RAG 系统优化方法论(三):像打 LoRA 补丁一样优化链路——冻结主干,只训适配器》。
🖼️ [封面图]: 极简数据主义风格,一组精密的管道系统,左侧注入明亮的青色流体,管道中间有三道闸门,只有一道打开,流体在关闭的闸门处积聚成暗色漩涡,深邃黑背景,冷峻高智力感,8k 分辨率