ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

LLM评判器:为自我改进编程智能体评估降本增效

LLM评判器:为自我改进编程智能体评估降本增效

最近在折腾自我改进编程智能体的时候,我发现一个特别尴尬的事实:真正吃预算的根本不是模型推理,而是评测。跑一轮实验下来,生成代码可能只花了几百美元的API费,但等你去起环境、装依赖、跑测试套件、判读输出,时间和钱一下子就翻了好几倍。MIT和Sakana AI放出的这个新框架,核心就是冲着这个痛点去的——用LLM评判器来给自我改进编程智能体做低成本评估。这篇文章我想从“为什么评估成本会爆炸”讲起,再把框架的设计逻辑拆开,最后给一份能直接落地的复现思路和避坑经验,适合正在做智能体开发、跑迭代实验、或者被CI评测账单吓到的同学参考。

1. 先算一笔账:自我改进编程智能体的钱都花在哪了

1.1 自我改进循环里“测试”才是隐藏的大头

一个典型的自我改进编程智能体,跑一圈的逻辑是这样的:模型先根据任务描述生成初始代码,然后测试环境给它一个反馈,再根据失败信息修改代码,如此循环往复,直到通过所有测试或者到达轮次上限。

很多人直觉上觉得贵的是模型调用,毕竟一次生成要消耗大量token。但真把实验跑起来,你会立刻发现瓶颈在“评价”这一步。每生成一个候选解,你都要做这些事:开一个干净的容器、装依赖、编译、跑测试套件、解析输出、判断是超时还是崩溃还是输出格式不对。这一套流程快的十几秒,慢的几分钟,而一个正常的自我改进实验一轮就要生成几十上百个候选解,后续还要迭代多轮。我自己的实测里,评估环节占据的总时长经常超过70%,费用占比更高,因为环境构建和并行计算资源是最烧钱的。

如果是SWE-bench这类真实仓库级别基准,那就更夸张了。你得在真实项目环境里构造出代码变更、运行预置的隐藏测试、比对执行结果,单次评测的复杂度比“跑一道算法题”高一个数量级。整个流程走完,你根本分不清是在跑模型实验还是在维护一套测试基础设施。

1.2 评估成本是指数级膨胀的,不是线性增长

把开销模型拆开看,大概是这样:

  • 总开销 = 候选样本数量 × 迭代轮数 × 单次评估成本 + 模型生成成本
  • 更现实一点,还要加上失败重试:某个候选解编译不过、某个测试环境炸了,都需要额外重跑

问题在于这三项不是独立变量。候选数量越多,越有可能通过“广撒网”找到更好的代码;迭代轮数越多,每一步的改善空间越有可能被挖掘出来。于是人们倾向于加大这两个量,但它们和单次评估成本是乘法关系。方向一多,总开销就呈指数级往上蹿。

那砍掉一些评测不行吗?不行。编程任务最麻烦的地方在于“看起来能跑”和“真正正确”差距非常大。一个代码可能语法正确、模块能加载、示例测试也能过,但换到隐藏测试就彻底崩了。如果你为了省成本减少评测,坏样本就会顺着筛选漏洞混进来,自我改进循环会被错误信号带着跑偏,最后模型能力没提升,反而学会了“制造假阳性”。

2. MIT和Sakana AI这个框架,核心是给评估加了一道“预筛”

2.1 一句话概括:把评测拆成快的和慢的两档

我之前看到很多团队想省评估成本,思路都是“减少样本、减少轮次”,也就是从量上做减法。这套新框架的思路不一样,它动的是评估结构本身。

它的做法可以概括成:先把每个候选解交给一个LLM评判器打分,选出分数最靠前的一小撮,再送去做完整的外部验证。完整验证的结果最后会回流到评判器那里做校准。

用大白话说,以前的模式是“每个候选都要过一遍正规考试”,现在的模式是“先用AI阅卷老师快速筛一遍,只有预选通过的少数人才进考场”。快的一档负责高频、低成本的粗筛,慢的一档负责低频、高成本的终审。整个循环里,贵的外部验证从“每轮多次”变成“每轮少数几次”,预算自然就降下来了。

2.2 为什么评判器选的是LLM,而不是规则或静态检查

有同学可能会问,做一个基于规则的预筛不行吗?比如检查代码是否有main函数、是否调用了指定库、是否有明显异常。这些能覆盖一部分问题,但编程智能体评估的核心困难是语义正确性,规则完全抓不住。静态检查工具也一样,能查风格、能查未使用的变量,但查不出“算法的思路是不是对题”。

这也是为什么标题里强调的是LLM评判器。一个语言模型可以同时看任务描述、候选代码、测试运行输出,综合考虑代码能不能满足约束、逻辑是否自洽。它不需要真正跑完所有测试,却能给出一个和真实质量大体相关的排序信号。从成本维度看,LLM做一次判定通常只要几秒钟、几分钱,比起一个完整测试环境跑的几分钟、几块钱,确实便宜太多了。

这个框架由MIT和Sakana AI两家一起做,我觉得也挺合理。Sakana AI本身就在演化算法和低成本AI训练上做了很多探索,他们很习惯“资源受限”的场景;MIT这边更关注推理智能体如何从反馈中学习,两边一碰撞,自然就会想到“评估别用蛮力,用更聪明的方式”。

3. 评判器给出的不是“真理”,而是“带噪声的排序信号”

3.1 别让评判器做最终裁决,只让它做候选筛选

我第一次看到这种方案时,最担心的一个问题就是:LLM评判器靠谱吗?它能替代真实测试吗?

这个框架的聪明之处就在于此——它压根就没打算让评判器替代真实测试。评判器的输出是一个“带噪声的排序信号”,它只在大量候选里筛出相对更好的那一小批。至于最终答案对不对,还是要交给外部验证来做最终裁决。

这个设计特别重要。大家可以做一个简单实验:拿一个开源小模型去给一堆代码候选打分,你会发现它的绝对分数经常不可信,同一个候选换个提示词表述,分数都可能波动。但如果你让它对几十个候选排序,靠前的那几个平均质量大概率比靠后的好。也就是说,你可以不信任它的绝对值,但可以信任它的相对比较能力。

筛选场景利用的恰恰是这种相对比较能力:我不需要你知道“这个代码值多少分”,只需要你能告诉我“这批候选里哪些值得送进去跑真实测试”。

3.2 评判器的分数不可信时,用不确定性信号来兜底

一个负责任的评判器,在拿不准的时候应该“表示不确定”,而不是硬给一个平庸的分数。这里最常见的实现方式就是重复采样。同一个候选交给评判器打三次分,如果三次结果差异特别大,说明评判器自己都没把握,这时候强行按照平均值排序就很危险。更稳妥的做法是把这类高方差样本直接标记为“不确定”,然后跳过预筛,直接送进外部验证。

这个思路有点像我们平时做自动化测试的pytest-flaky处理:一个测试用例不是每次都能稳定通过时,你不会直接断言它是好消息或坏消息,而是先重跑几遍,再决定要不要上报失败。评判器的不确定性信号就是编程智能体评估里的“flaky检测”。

3.3 一旦外部验证结果回流,评判器就需要持续校准

框架里还有一环容易被忽略:外部验证的结果必须回灌给评判器,去做校准。为什么?因为评判器的排序能力不是恒定的。

假设某个版本的候选代码特别爱写大量注释和防御性检查,评判器可能觉得这代码很细致、很全面,于是给了高分。但外部验证会发现,这代码的实际运行效率一塌糊涂。如果外部验证结果不回流,评判器就会一直保持这个坏习惯,越筛越偏。

校准的做法在工程上也很直接:定期把外部验证的真实结果和评判器分数放到一起算相关性,比如斯皮尔曼排序相关系数。数值一旦掉下去,就说明评判器开始被某些表面特征欺骗了,要么调整打分维度,要么换一个更强的评判模型,要么临时提高外部验证的比例。

4. 落地复现笔记:把框架思路转成工程的五个步骤

4.1 第一步先搞清楚你的评估到底贵在哪

别急着上评判器。我之前见过一个团队,花了很大力气集成LLM评判器,最后发现他们的任务本身跑一次测试只要几十毫秒,瓶颈完全不在评估,而在生成模型太慢。方向直接做反了。

做之前先抽几轮全量评测,算三组数字:

  • 单样本外部验证的平均耗时和平均费用
  • 单轮实验平均生成的候选数量
  • 整个自我改进循环的预期迭代轮数

把这三项乘起来,你就知道评估的总预算量级。只有当“外部验证的单价 × 候选数量”高到明显影响实验迭代速度时,引入评判器才划算。

4.2 第二步选定评判器和打分维度

评判器模型的选择有自己的门道。最佳实践是选一个比主模型便宜数倍的开源模型,而不是用和主模型同一级别的大家伙。既然评判器只是做相对排序,一个中等规模模型往往就够用了,关键是它的打分要稳定。

打分维度这个事,我建议初始不要贪多。我自己的经验是:先只评两个维度,第一是“根据任务描述和已有输出,这个代码在多大程度上能实现目标功能”,第二是“代码的可维护性和对约束的遵守程度”。两个维度各打一个分,再按固定权重合成排序分。等跑稳了再加第三个维度,比如“异常处理是否合理”。维度越多,评判器的注意力越分散,排序稳定性反而下降。

另外一个特别容易踩的坑是:不要把参考实现或最终答案发给评判器。一旦评判器见过参考实现,它就不是在判断候选质量,而是在做模式匹配。这和小学生对着答案批卷子一样,分数必然失真。

4.3 第三步搭双通道管线并接入外部验证

候选生成之后做两件事:

  • 先走评判器快速打分,按排序取Top-k进入外部验证
  • 外部验证结果写回校准队列,用于后续评判器调优

这里的k怎么定?我的建议是不要拍脑袋设一个固定值,而是先拿历史上50个候选同时跑人工评测和评判器打分,观察“Top-5”,也就是评判器打出来的前五名里真正通过外部验证的比例有多高。如果很高,说明评判器比较可靠,可以适当把k调小;如果偏低,就得把k调大,甚至回到全量评测。这个比例就是你的“预筛命中率”,它应该成为管线日常监控的核心指标。

下面是思路级别的伪代码,真实项目里建议把各个阶段拆成异步任务来跑,方便定位问题:

for task, reference in task_queue: candidates = agent.generate(task, N) # 生成N个候选解 scores = judge.score(candidates, times=3) # 评判器重复打分 uncertain = flag_uncertain(scores, threshold) # 高方差样本标记 selected = select_top_k(scores, k) + uncertain # 高分样本+不确定样本 for cand in selected: real_result = full_validate(cand) # 外部真实验证 log_pair(scores[cand], real_result) # 记录分数-结果对

4.4 第四步调校准频率,别等到崩了再补救

校准不是一次性工作,而应该是循环里持续跑的“后台任务”。每跑一批实验,就拿上一批sample的“评判器分数-真实结果对”更新一次相关性统计。我习惯用滑动窗口,只统计最近200个验证样本,这样既不会太敏感,也不会让历史脏数据长期拖着评判器不放。

如果发现相关性持续下降,先别急着重训评判器。最容易先中招的问题不是模型变笨,而是候选分布漂移了。比如生成模型换了参数,代码风格大变,评判器没见过这种风格,打分自然失真。这时候最快的方法是微调评判器的打分提示词,把新风格里的特征词写清楚;再不行就切一个更强的开源评判模型。

4.5 第五步设安全阀,保留随时退回全量评测的能力

框架省预算的前提是评判器还靠谱。一旦你发现预筛命中率突然崩了,比如最近Top-k里真实通过率只剩原来的一半,这时候整个循环继续跑只会越来越歪。所以管线里必须有一个熔断机制:命中率跌破阈值时,自动把后续所有候选都送去外部验证,同时暂停评判器筛选,等待人工介入调整。

这个安全阀看着简单,但绝大多数人不会提前做。等发现问题的时候,一轮实验可能已经烧掉几千个错误评分样本,自我改进信号已经被污染了。

5. 实际操作中我踩过和见过别人踩的坑

5.1 评判器会无意识偏爱“好看的”代码

我第一次用评判器做预筛时,发现Top候选里大量出现那种注释特别详细、变量命名特别冗长、但算法效率并不高的代码。原因不难理解:语言模型的打分偏好里天然包含了“看起来完整、解释清楚”的权重,它很容易把详尽的注释和防御性编程误判为高质量。

从那以后,我的打分提示词里会特别注明:如果候选代码与任务描述不匹配,或者存在明显冗余逻辑,即便注释详尽,也不应加分。此外还会做“字段盲评”,把代码内部的注释先剥离掉一部分再让评判器打分,减少表面特征的干扰。效果立竿见影,Top-k的命中率明显回升。

5.2 只验证Top-k会让累积偏差快速变大

这个坑更隐蔽,也更致命。你每轮只挑打分最高的几个送外部验证,被淘汰的低分样本压根没有真实结果。一轮两轮还好,几十轮之后,候选池里那些“能骗过评判器但过不了真实验证”的样本会不断积累,而真正的优质样本反而因为数量少被稀释掉。

这本质上是用模型标注数据去训练模型的闭环退化问题。我后来的做法是每轮固定从排序靠后的候选里额外抽5%也送去外部验证,并把结果一并写入校准集。这样等于给系统引入了抽样真值,让评判器能及时发现自己的排序偏差,不让偏科长期存在。

5.3 这个框架解决的是评估成本,不是模型能力上限

最后说一个心态层面的坑。省下来的预算如果不投回“生成更多更好的候选”,模型是不会有真实能力提升的。评判器帮你降低了评估成本,但候选本身的质量上限还是由生成策略和搜索空间决定的。如果生成模型每次产出的都是同一水平的代码,省再多评估费,自我改进也到不了天花板。

我在跑这类实验时最后养成的习惯是:把省下来的预算全部投入去增加初始生成样本数量,以及多轮迭代的轮次上限。只有让生成侧充分探索,评估侧的降本才真正转化成能力提升。

6. 这套评估策略的延展空间

6.1 从编程智能体推广到别的智能体任务

只要满足“生成成本低、验证成本高”的场景,这个双层评估思路都值得一试。我后来在数据分析智能体任务里也套过类似的逻辑:让一个轻量模型先对候选分析报告的合理性和数据覆盖度打分,选Top几再去做真实的数据验证和指标计算。核心条件和编程场景一模一样——生成候选很快,但真正验证一份报告是否可靠,往往需要跑整个分析管线,贵得多。

判断能不能套用有一个很简单的试金石:记录一下单次真实验证的成本,再算一笔“如果验证次数下降到五分之一,实验迭代速度能提升多少”。只要收益大于引入评判器带来的噪声,这套思路就成立。

6.2 什么场景别硬套这把锤子

反过来,如果外部验证本身已经非常便宜,跑完一个测试用例只要零点几秒,就别硬塞一个评判器进来。那一层额外的模型打分不仅贵,还引入了新的噪声源。判别任务模糊的时候也一样,比如让模型判断“这段代码风格好不好”,本身就没有严格标准,评判器的分数就更加不可靠,直接用真实评分反而更稳。

6.3 和现有CI系统结合的前景

这套框架放在团队工程环境里,天然适合改造成CI的预筛策略。普通提交先走轻量级评判器,配合少量关键测试快速通不过就退回;合并前的高成本门禁再做完整回归。等于是在CI前面加了一道“智能体检”,让大部分不合格代码在最便宜的阶段就被拦下。这种落地方式不需要推翻现有测试体系,只是往外层铺一个快速筛选层,工程风险小得多,我认为这也是这个研究最值得借鉴的现实价值。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进