编码 Agent 失败之后:该反思、重做,还是直接上大模型?CodeRescue 的三动作路由方案
编码 Agent 失败之后:到底是该反思、重试,还是直接上大模型?
> 论文:CodeRescue: Budget-Calibrated Recovery Routing for Coding Agents > 作者:Qijia He, Jiayi Cheng, Chenqian Le 等(华盛顿大学 / 纽约大学 / 字节跳动) > arXiv: 2607.19338 > 代码:https://github.com/Qijia-He/agent-budget-control
---
一个再熟悉不过的场景
凌晨两点,你让一个编码 Agent 去实现一个解析器。便宜模型(比如 GPT-5.4-nano)跑完第一版,测试挂了——边界用例没处理。
这时候 Agent 面前摆着三条路:
1. 反思(reflect):把错误日志喂回去,让便宜模型自己修。最便宜,但可能修不好。 2. 重做(replan):让便宜模型丢掉旧方案,从新计划开始写。稍贵,但换个思路可能就过了。 3. 升级(escalate):直接把问题丢给 GPT-5.4 这种大模型。最贵,但能力最强。
你会怎么选?
如果你的第一反应是"那肯定直接上大模型啊,一步到位"——恭喜,你和大多数现有的 cost-aware 路由系统想法一样。但这也正是这篇论文要挑战的直觉。
旧范式的问题:把失败当成"该换大模型了"的信号
过去几年,cost-aware LLM 推理的主流范式是级联(cascade):先用便宜模型试一把,不行就升级到强模型。FrugalGPT、RouteLLM、HybridLLM、C3PO 都是这条路线的变体。
这个范式有一个隐含假设:便宜模型失败了,说明它的能力不够,需要更强的模型参数。
但编码 Agent 有一个特殊性,论文点破了这一点:失败本身就是信息。编译器报错、测试失败、超时——这些执行反馈把一个"欠定的问题"变成了一个"已诊断的修复问题"。这时候,再给便宜模型一次机会,带上反馈,它可能就修好了。直接升级到大模型,等于浪费了便宜模型已经积累的上下文理解。
用论文的话说:
> Spending another cheap call with the right feedback may exploit the small model more effectively than immediately escalating.
这不是"哪个模型更强"的问题,而是"哪种恢复动作更划算"的问题。
三个动作,不是一个阶梯
论文的核心创新是把失败后的决策从"要不要升级"的二元选择,扩展为三个异构动作的路由问题:
| 动作 | 模型 | 行为 | 相对成本 |
|---|---|---|---|
| reflect | 便宜模型 | 用错误反馈做局部修复 | 最低 |
| replan | 便宜模型 | 丢弃旧方案,重新规划 | 中低 |
| escalate | 强模型 | 强模型从头解决 | 最高 |
- 28% 的失败只能靠便宜动作(reflect/replan)解决
- 45% 的失败只能靠 escalate 解决
- 27% 的失败便宜动作和 escalate 都能解决
训练一个路由器:学会"看人下菜"
有了三个动作,下一个问题是:怎么决定用哪个?
论文没有用规则,而是训练了一个监督式恢复路由器。具体做法:
1. 收集 rollout 数据:在 5 个编码基准(APPS、TACO、BigCodeBench、LiveCodeBench、CodeContests)上,约 27,300 道题,用 GPT-5.4-nano 先做,失败后分别跑三个恢复动作,记录哪些动作能解。 2. 标注:对每道失败题,标注"最便宜的成功动作"(cheapest successful action)。如果三个动作都解不了,就排除出训练集。 3. 训练:用 Qwen3.5-4B 做全参数微调,输入是(题目 + 执行判决 + stderr),输出是三个动作的概率。
这里有一个细节值得注意:评估用 solve rate 而不是分类准确率。因为同一道题可能多个动作都能解,预测了一个和标注不同但也能解的动作不算错。这个设计避免了"非此即彼"的标签噪声。
还有一个关键发现:元数据前缀很重要。只给模型(题目 + 错误信息)不够,加上来源、难度、算法标签等元数据后,solve rate 从 0.656 提升到 0.697。这说明执行反馈本身不足以判断该用哪个动作,还需要问题的分布信息。
Conformal Risk Control:一个旋钮控制预算
到这里为止,路由器还只是一个普通的分类器。论文真正的亮点在于下一步:如何让同一个路由器适应不同的预算。
传统做法是把预算写进训练目标里(比如 RACER),换个预算就得重新训练。论文用了一个更优雅的方案——Conformal Risk Control(CRC)。
核心想法极其简洁。路由器对每个动作给出一个分数 $s(a|x)$,我们不再单纯取 argmax,而是引入一个成本惩罚项 $\lambda$:
$$\pi_\lambda(x) = \arg\max_a \{ s(a|x) - \lambda \cdot c(a,x) \}$$
- $\lambda = 0$:完全不考虑成本,只看成功率(最激进)
- $\lambda$ 越大:越偏向便宜动作(保守)
但 $\lambda$ 不是随便选的。CRC 提供了一个有限样本保证:在可交换的校准集上,选择最小的 $\lambda$ 使得
$$\frac{n \cdot \hat{C}_n(\lambda) + c_{\max}}{n+1} \leq B$$
这里 $B$ 是用户指定的预算,$c_{\max}$ 是最坏情况成本,$n$ 是校准集大小。这个公式看起来简单,但它保证了一个数学性质:在可交换性假设下,未来样本的期望成本不超过 $B$。
用大白话说:你告诉系统"每次恢复平均花不超过 2.56 毫美元",CRC 就帮你找到一个 $\lambda$,数学上保证长期平均成本确实不超过这个数。
这里有一个精妙的工程哲学:CRC 控制的是成本,不是 solve rate。solve rate 是路由器学到的经验性质,CRC 不保证它。这很诚实——你无法用统计学保证"解对率",但你可以保证"花费上限"。
数据说话:35% 的成本,超过 always-escalate 的 solve rate
来看主结果(GPT-5.4-nano / GPT-5.4 配对,360 道留出测试题):
| 策略 | Solve Rate | 平均成本 (m$) |
|---|---|---|
| Always-reflect | 0.275 | 1.24 |
| Always-replan | 0.453 | 1.59 |
| Always-escalate | 0.686 | 7.22 |
| Binary cascade | 0.636 | 2.56 |
| CRC (B=2.56 m$) | 0.717 | 2.56 |
| CRC argmax (λ=0) | 0.817 | 5.51 |
1. Always-escalate 花了 7.22 m$,solve rate 只有 0.686。大模型不是万能的,有 31.4% 的失败它也解不了。 2. CRC 在 2.56 m$ 预算下达到 0.717,比 always-escalate 的 solve rate 还高,但只花了 35% 的成本。这是论文标题性的结论。 3. 无约束路由器(λ=0)达到 0.817,比 always-escalate 高 13 个百分点,成本还低 24%。
还有一个对照实验很有意思:prompt-only 路由器不行。直接让 Claude Sonnet 4.6、Gemini 3.1 Pro、GPT-5.4 这些大模型 zero-shot 做路由,solve rate 最高只有 0.453(Claude),远不如微调过的 Qwen3.5-4B(0.817)。这说明路由信号不是写在动作描述里的,必须从 rollout 数据中学习。
跨模型验证:不是 GPT 专属
为了证明方法不是 GPT 模型对的过拟合,作者还用 Gemini-2.5-Flash / Gemini-2.5-Pro 重做了整个流水线(附录 C)。结论一致:三个动作互补,CRC 校准有效。这个跨模型验证很重要——如果只在 GPT 上有效,方法的价值就打了折扣。
工程洞察:这个方法能落地吗?
从工程角度看,CodeRescue 有几个让人喜欢的特性:
1. 一次训练,多次部署。 路由器只训练一次,CRC 校准表预计算一次。换预算只是查表选 $\lambda$,O(K) 时间(K 是断点数,通常几十个)。这在生产环境中极其友好——不同客户、不同时段、不同 SLA 都可以用同一个模型。
2. 路由器很小。 Qwen3.5-4B 全参数微调,4B 参数的模型做路由,推理成本可以忽略不计。和一次 escalate 动辄几毫美元相比,路由器本身的开销几乎免费。
3. 动作集可扩展。 论文选了 reflect/replan/escalate 三个动作作为"最小一阶恢复集",但框架本身不限制动作数量。你可以加"搜索文档"、"问人类"、"跑静态分析"等动作,只要能定义成本和收集 rollout 数据。
4. 诚实的局限性。 论文明确说:只建模单步恢复(实际 Agent 可能多轮恢复);cheapest-successful 标签是代理而非校准的概率;CRC 控制成本不控制 solve rate。这种诚实让结论更可信。
我的思考:从"哪个模型"到"哪种动作"
这篇论文让我想到一个更广的趋势:LLM 推理的决策粒度正在从"选模型"细化到"选动作"。
早期的 cost-aware 系统问的是:"这道题该用小模型还是大模型?" CodeRescue 问的是:"这次失败后,该反思、重做、还是升级?"
这个转变背后是一个认知:在 Agent 时代,推理不是一次调用,而是一条轨迹。轨迹上的每一个决策点都有多种动作可选,而动作之间的成本-质量关系不是线性的、不是单调的、也不是先验可知的。你需要从数据中学习这个关系。
更深一层:失败是信息,不是终点。在传统级联里,失败只触发一个动作(升级)。在 CodeRescue 里,失败触发一个路由决策,而路由器从失败的特征中学到了哪种恢复最划算。这和人类工程师的直觉一致——老手不是失败就找大佬,而是根据报错类型决定是自己 debug、重写、还是求助。
CRC 层的加入则提供了另一个工程启示:当你无法保证质量时,至少保证成本。在 LLM 部署中,solve rate 受太多因素影响(模型版本、prompt、数据分布),很难给出统计保证。但成本是确定的、可测的、可控制的。CRC 聪明地把保证放在了成本侧,把质量留给经验数据去说话。这种"保证能保证的,承认不能保证的"态度,比那些声称"最优质量"的系统要可信得多。
开源代码
论文代码已开源:https://github.com/Qijia-He/agent-budget-control
仓库结构清晰,包含:
data_generation/:rollout 收集流水线(含 reflect/replan/escalate 的 Agent 实现)sft_runs/:路由器训练配置(LLaMA-Factory 格式)conformal/:CRC 校准和评估脚本
data_generation/agents/ 里的三个恢复动作实现,可以直接作为编码 Agent 的参考设计。---
论文链接:https://arxiv.org/abs/2607.19338 代码链接:https://github.com/Qijia-He/agent-budget-control
---
*当你的编码 Agent 下次失败时,别急着升级。先想想:这次失败,到底在告诉你什么?*
🌟 智谱 GLM-5 已上线
我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。
🎁 领取 2000万 Tokens