让Agent自己迭代:闭环优化里的评分器怎么设计
原文:Anthropic Research - 《Designing more efficient quantum circuits with Claude》(https://www.anthropic.com/research/designing-efficient-quantum-circuits)
前言
大部分人写 Agent 还停在"问一次、答一次"的模式。想让它真正变强,靠的不是把 prompt 写得更长,而是把它放进一个能自己拿到分数、自己改下一版的闭环里。
Anthropic 10 月 16 日发的一篇研究给了个很干净的样本:让 Claude Mythos 5 在闭环里设计量子电路。模型提出电路实现,程序化评估器先检查正确性、再按"量子比特数乘以门数"打分,分数回传给模型,模型据此改下一版,轮与轮之间没有人插手。八个任务全部超过了此前公开发表的最好设计,部分提升达到一个数量级以上。
量子电路离日常开发很远,但这套闭环的骨架离我们很近:任何"能用程序判对错、能给一个数"的任务,都可以照这个套路搭。这篇把它拆成可复用的部分——什么样的任务适合闭环、评分函数怎么选、以及模型在这种循环里会犯什么毛病。
一、闭环成立的三个前提
研究里挑量子电路不是随便挑的,原文给了三条理由,恰好也是判断"我的任务能不能上闭环"的清单:
- 任务能用代码表达。量子电路本身就是用 Python 描述的程序,模型能写、能跑、能改。换成"写一份市场分析",模型改起来就没有抓手。
- 输入到输出是确定的,普通计算机能验。原文的说法是每个输入给出一个确定输出,普通计算机可以检查。有确定答案,评估器才敢判对错。
- 有单一、客观、可比较的分数。这篇文章用的是量子比特数乘以门数,作为电路运行时间的代理指标。
三条缺一条,闭环就会变形。缺第三条最要命——没有客观分数,模型只能给自己打分,那不叫优化,叫自我感觉良好。
二、一轮闭环长什么样
原文对循环的描述很直白:模型设计新的 Python 实现,送进程序化评估器;评估器先检查实现是否正确,再按所需量子比特数和门数打分;分数回到模型,模型据此改进下一版。整个过程中,轮次之间没有任何人工输入。
把它写成一个最小骨架,大概是这样:
# 闭环骨架(自拟示意,非 Anthropic 官方实现)defclosed_loop(propose,evaluate,rounds=30):feedback="先给出一版最简实现,说明你压的是哪一项资源"best=Noneforrinrange(rounds):cand=propose(feedback)# 模型产出:可执行代码 + 一句思路自述report=evaluate(cand)# 评估器:先判对错,再算分ifnotreport["correct"]:# 错解不参与比较,只把错误原因回传,避免模型在错方向上继续优化feedback=f"第{r}轮验证失败:{report['error']}"continueifbestisNoneorreport["score"]<best["score"]:best={"score":report["score"],"code":cand}# 回传三件事:本轮分数、历史最好分数、还能压哪一项feedback=(f"本轮{report['score']},历史最好{best['score']}。"f"资源明细:{report['breakdown']}")returnbest参数和调用链值得说清楚:
propose接收一段文本反馈,返回一段可执行代码。它的输入是自然语言,输出是代码,所以模型必须是能写代码的那个;evaluate是纯程序,先做正确性验证,再算分,返回correct/score/breakdown/error四个字段;- 主循环只做两件事:把错解挡在比较之外,把分数和明细回传给下一轮。
有个细节容易被忽略:分数越小越好这件事,必须在给模型的说明里写死。原文给模型的简报里就明确写了评估器会怎样检查、按什么打分,模型才知道往哪个方向走。
三、评分函数比模型更关键
这篇研究里最值得抄的不是 prompt,是评分函数的设计。
它选的是"量子比特数 × 门数",理由是这两个量相乘可以当作电路运行时间的代理。这个指标便宜、确定、模型改不动,是评估器该有的样子。
但单一标量会抹掉权衡。原文提到其中一个设计族的电路:比此前最小的设计多用 12% 的量子比特,但门数少了 17 倍。如果只看一个乘积分数,这种"用比特换门"的结构性取舍就被压扁成一个数字,你根本看不出模型在往哪个方向探索。所以文章用帕累托前沿来展示这一族设计,而不是只报一个最优值。
落到工程上,比较稳妥的做法是:报一个主分数用来排序,同时把两三个分项原样回传。模型看到分项,才知道该动哪一边;人看分项,才知道这个"更优"是不是自己想要的更优。
四、让模型自己测量,替掉最坏情况预留
第二个任务是个很好的例子:优化某个量子纠错码的解码器。
按最坏情况预留资源,要假设异常值在 35 个不同轮次里都出现,那需要 665 个量子比特。这个数字大到不划算。Claude 的做法是写一个高速模拟器,跑了 4.03 亿次采样解码,统计异常到底多常发生——结论是几乎每次运行最多只需要保存一个值。
于是电路只留一个值的空间,19 个量子比特。代价是大约万分之一概率会不够用而失败,这个概率落在任务允许的错误率之内。整个解码器的门数相比 Google 此前的构造少了 12 倍。作为对照,朴素的每轮存 12 个量子比特的做法,累计要 840 个。
这段的可迁移点很强:当"最坏情况"贵得离谱时,别直接按最坏情况做设计,让 Agent 去测真实分布,用统计结论换资源。前提有两个——失败是允许的,并且你有明确的错误率预算。
五、模型在闭环里的通病:过度保守
原文没有只报好消息,专门写了一段局限:早期实验里 Claude 偏保守,会反复质疑看起来像改进的结果,有时对已经被充分支持的结论还要二次、三次复查。
这个毛病一半是好事。正是这种谨慎,让它主动去写 Lean 形式化证明来验证自己的设计。另一半是坏事——它倾向于偏好已有的、知名的方法,而不是真正新的方法。
研究里的两个干预手段很实用:
- 要求模型提出几条性质不同的路线,并并行推进,而不是只沿着一条路往下磨;
- 偶尔提示它"把搜索范围放宽一点",把它从局部最优里拽出来。
第一个任务给了它一段话的简报,它带着极少的人工输入工作了 53 小时,最后给出了一套全新的点加法实现思路。这说明长循环是能跑出东西的,但前提是你在结构上逼它发散,而不是等它自己发散。
六、搬到自己的项目上
如果你手上有个 Agent 想加闭环,先过一遍这几条:
- 评估器必须便宜、确定、且 Agent 改不到。评估器一旦能被优化对象改写,整个闭环立刻失效;
- 分数要能被人读懂。一个 0.8732 的分数没有意义,"门数 1.2 万、比特 19"才有;
- 保留失败样本。错解的错误信息是下一轮最有价值的输入,别只存最优解;
- 给分数设边界。允许"用一点资源换大量另一项资源"的探索,但要能看出越界;
- 每轮存 diff,不只存最终版。否则你无法判断它是在优化,还是在反复横跳。
小结
闭环优化里,模型只是那个不断提方案的执行者,真正决定它能走多远的是评估器:判得对不对、分给得准不准、能不能被钻空子。量子电路这个案例的特殊性在于答案可验证,而它的普适性也在于此——只要你能把任务写成"可执行 + 可判定 + 可打分",同一套循环就能搬到你自己的场景里。
文中的方法与数字均来自 Anthropic 该篇研究,具体实现细节以其官方发布为准;引用到的模型能力与接口如有更新,以官方文档为准。