AI编程智能体犯错谁来管:Salesforce提出Opera审稿框架
你有没有遇到过这种情况:让一个新来的程序员帮你改代码,他兴冲冲地改完了,告诉你"搞定了",结果你一测试,发现他压根改错了地方。更麻烦的是,等你发现这个问题的时候,他已经在这个错误的基础上又往前走了十步,返工成本直接翻倍。这正是现在的AI编程智能体正在经历的事。这些智能体可以自己浏览代码仓库、编辑文件、运...
让一个新来的程序员帮忙改代码,他兴致勃勃地改完,丢下一句“搞定了”,结果一测发现改错了地方。更麻烦的是,你发现问题的时候,他已经顺着这个错误又往前走了十步,返工成本直接翻倍。这种场景,做开发的人恐怕都不陌生。
现在的AI编程智能体,正在经历同样的事。
它们能自行浏览代码仓库、编辑文件、运行测试,整个流程不需要人插手。听起来很美,可实际跑起来,这些智能体常常在长时间作业中反复执行同样的无用操作,或者沿着一个错误方向越走越远。有时候任务根本没做完,它也会很有自信地宣布“任务完成”。
Salesforce AI Research的一篇论文就在琢磨这件事:怎么给AI程序员配一个靠谱的“审稿人”,关键时刻能拦一下,又不至于瞎指挥。
批评一个还没写完的程序,难在哪
设想你是一名编辑,要给一本写到一半的小说提修改意见。
书已完稿,你可以通读全文,判断逻辑自不自洽、结局合不合理。可作者只写了三分之一呢?某个情节走向到底是“犯了错误”,还是“正常的中间过程”,你很难分辨。也许作者正在为后面的反转埋线,你一句“这里写得不对”,反而打断了他原本正确的构思。
AI编程智能体面对的审查困境正是如此。
任务还在执行,证据不完整,当前这一步是合理的中间步骤,还是已经南辕北辙,很难分清。论文作者把这个问题拆成了三个具体难题。
第一个是时机问题:审查该在什么时候介入?固定隔几步看一次,可能眼看着智能体把同一条错误命令重复执行好几遍才轮到下一次检查,反应太慢;一有动静就插手,又会打断那些本来能自己走通的正常流程。
第二个是反馈的可靠性问题:批评者给出的意见本身靠谱吗?
论文里提到一个关键发现,叫做RuVerBench。
RuVerBench:一项研究,发现用大语言模型来验证评分标准时,存在相当多的噪音,也就是说AI评委自己也经常判断失误。
评判标准即使定得再细,交给AI照章打分,错误照样躲不掉。一份听上去头头是道的诊断,背后也许只是把局部证据读岔了,最终反倒让原本做得成的事走了弯路。
第三个是执行跟踪问题:批评意见发出去之后,到底有没有被真正解决?智能体可能表面上听话照做,但问题的根源还在那里,没真正修复。这就好比你让学生改作文里的病句,他确实在那句话上动了手,改出来的新句子依然不通顺,只是换了一种错法。
三个问题叠在一起,才是这篇论文真正要解决的核心矛盾。
Opera:把每一次批评变成一张持续追踪的便利贴
论文给出的方案叫Opera,核心思路可以用一个很朴素的比喻来理解。
想象你带一个实习生做项目,你不会把每个问题都写成一次性的训话,说完就忘。你更可能在便利贴上写“这里的参数传错了,改成XX,改完之后看看单元测试是否通过”,把这张便利贴贴在实习生桌上,直到确认问题真的解决了才撕掉。
如果没有这张便利贴会怎样?
你很可能提完意见就不管了,下次检查时完全不记得之前说过什么,实习生也可能已经把你的话忘了,或者敷衍地改个表面东西就当交差。没有持续追踪,批评就变成了一次性的噗嗤一声,响完就没了。
Opera的设计正是围绕这张“便利贴”展开的,论文里管它叫做note。
note:这是一条持久保存的笔记,里面写清一个被诊断出的问题、眼下给出的建议,以及一条始终不变的解决标准;在问题得到确认已解决或被归档之前,这条笔记一直算数。
这个框架围绕三个核心机制展开,分别对应前面提到的三个难题。
该在什么时候出手?靠的是双轨触发机制
Opera并没有隔几步瞄一眼,也不是稍有风吹草动就急着插手,它把两类触发方式搭在一起用。
一类是固定周期检查,每过若干轮就整体看一次进展;另一类是事件触发检查,只要智能体冒出五种可疑举动中的任意一种,就马上介入核查。这五种举动是:原地打转、没有实质推进;反复做同样的操作;动作或工具调用失败;宣称任务已经完成;提交最终的修改。
哪个信号先冒出来,就先触发一次检查;而且事件触发之后,固定周期的计时器会重新开始计数,免得两次检查撞在一起白费功夫。
有件事得说清楚:检查本身并不等于一定要插手。
批评者看完一轮,完全可能给出“方向没问题,接着走”的判断,然后一言不发。这其实是在学一个成熟审稿人该有的分寸——不是逮着机会就刷存在感,只在真需要的时候才开口。
打个比方,老师批作业,不会看到学生写字就去点评字迹,只在学生真把题解错了才圈出来。要是每个字都要评一句,学生反倒被无关紧要的噪音淹没,抓不住真正的重点。论文的实验也印证了这一点:把这种“按需静默”的机制拿掉,效果明显往下掉。
诊断得精确:九种类型化操作符
只知道“什么时候该说话”还不够,说什么同样关键。
论文里有个很实在的观察:泛泛而谈的批评,像“考虑一下边界情况”这类,对智能体来说基本等于没说。它得知道具体哪儿出了问题、该怎么改、改完又怎么验证改对了。
所以Opera要求每一次诊断都必须用一个
operator,也就是类型化的操作符,把诊断出的问题绑定到具体证据、修正方向和一个可验证的解决标准上。论文里设计了九种,分别覆盖搜索、查看、编辑、测试、提交五个阶段。
举例来说,“repo_localization_search”用来指出目标代码还没找到;“implementation_target_shift”用来指出改错了文件;“requirement_contract_review”用来指出改动违反了任务要求本身;“state_transition_review”用来指出执行逻辑本身有问题,比如先用了数据再做空值检查,顺序反了。每种操作符都遵循一种叫
契约式设计(Design by Contract)是软件工程里的一种方法:它要明确一个组件在什么条件下能用、需要哪些证据、能给出哪些修正、什么算问题已解决,以及它和哪些问题彼此排斥
的规范方式。这样每条笔记的边界都很清楚,不会跟别的问题搅在一起说不明白。
这个设计化解的根本矛盾在哪?批评意见里要是混了好几个问题,智能体很难判断先改哪个,改完一个之后另一个问题的责任算谁的也说不清。限定每次只提一个问题,用一个明确的操作符加一个固定的验收标准,等于把一次模糊的训话变成了一份可执行的任务清单,“后续追踪”这才变得可能。
效果如何?论文做了消融实验:只保留编辑类操作符的版本,和只保留非编辑类操作符的版本,各自都能保住大部分提升效果,但两者的提升并非简单相加。这说明批评者经常能用不同的操作符指向同一个底层问题,具备一定的互相补偿能力。
说出去的话得先过一道关:双重审计机制
这里要面对第二个难题——批评本身的可靠性。批评者也是一个大语言模型,它自己也可能出错,给出一个听着很有道理、实际上却是误读的诊断。
Opera设了两道审计关卡,一道管开笔记和改笔记,另一道管关笔记。这两道关卡不会去改写批评者提的建议,只做一件事:接受或者拒绝。
这就像公司财务审批里专设的审核岗,审核员不会替申请人重写报销单,只在金额不对、票据不全或者重复报销的时候打回去。少了这道关卡,任何一笔申请不管合不合理都直接放行,财务系统很快就乱成一团。
开笔记的审计会核查:这个诊断有没有证据支撑、提出的修正是不是真有必要、给出的验证方式能不能真正证明问题已经解决。论文举了具体的反例,像那种跟任务本身无关的“顺手优化一下代码风格”的建议,或者没有新证据支撑、只是重复之前说过的话的提醒,都会被拒掉,这条笔记保持原样不变。
关笔记的审计更严,必须有实际证据支撑,比如执行结果或者可见的代码改动,才能宣布这个问题真的解决了,随后笔记会被归档,并从智能体的上下文里移除。
这里有个很细致的设计:笔记的解决标准在开笔记的时候就定死了,后面即便批评者在跟进过程中调整了具体建议的措辞,这个最终的验收标准也不会变。
这样的设计用意何在?设想一下,若每次更新笔记都把验收标准一并改动,批评者就可能暗中降低门槛,让问题看起来已经解决,跟踪问责也就失去了意义。只有把最初的目标钉死,才能判断问题是真的被处理掉,还是被绕了过去。
论文专门做了消融实验,检验这道审计关卡的实际作用,结论很直接。
| 实验设置 | Terminal-Bench 2.1 | SWE-Bench Pro | DeepSWE ||---|---|---|---|| 无批评者 | 65.9 | 75.3 | 32.4 || **Opera(带审计)** | **73.8** | **79.3** | **41.3** || Opera(去掉审计) | 68.5 | 78.3 | 36.9 |
以Terminal-Bench 2.1为例,拿掉审计后,原本7.9个百分点的增益缩到2.6个百分点,少了将近三分之二;DeepSWE上同样从8.9个百分点降到4.5个百分点,折半。可见在中间证据容易被误读、乱提建议代价又高的场景里,这道关卡确实起了过滤作用。
三个基准上的成绩单
论文在三个测试环境中验证Opera:Terminal-Bench 2.1、SWE-Bench Pro的100任务子集,以及DeepSWE v1.1。每个环境搭配了不同的智能体执行框架,并各自使用四个能力水平不同的基础模型。
与四个有竞争力的对比方法相比,Opera在三个基准上的平均解决率都是最高的。
| 方法 | Terminal-Bench 2.1 | SWE-Bench Pro | DeepSWE ||---|---|---|---|| 无批评者 | 65.9 | 75.3 | 32.4 || SWE-PRM | 68.9 | 77.7 | 36.6 || SWE-Search | 70.0 | 77.3 | 38.6 || LLM-as-verifier | 71.2 | 78.7 | 38.9 || Agentic Rubrics | 71.9 | 78.3 | 39.5 || **Opera** | **73.8** | **79.3** | **41.3** |
再把不同基础模型的表现拆开看,能发现一条规律。
能力偏弱的模型,从批评者那里拿到的好处更多。
举个例子,Qwen3.5-9B这个相对小的模型,在Terminal-Bench 2.1上涨了12.4个百分点,在SWE-Bench Pro上涨了15.0个百分点,是四个模型里涨幅最大的。本身已经较强的DeepSeek-V4-Flash,在它原本就做得不错的基准上提升有限,可换到更难的DeepSWE,涨幅又明显变大。
道理其实很朴素:批评者能发挥多大作用,取决于智能体自己留下多少“犯错空间”。
不过批评者并非万能。论文里有个很诚实的发现:Qwen3.5-9B在DeepSWE上,有没有批评者帮忙,一个任务都没解决。提醒再多,也补不上智能体自身缺失的能力。它更像一个称职的教练,能纠正动作、提升发挥,却没法让还没学会跑步的人直接去跑马拉松。
有意思的是,模型能力不同,被批评者挑出的毛病也不一样。实验统计了四种模型收到的笔记类型分布:相对较弱的Qwen3.5-9B最常被提醒“需求理解错误”,任务到底要什么,它常常没弄明白;更强的Qwen3.8-27B和DeepSeek-V4-Flash则更多收到“执行逻辑错误”,目标它们理解得没问题,问题出在具体执行时逻辑出了岔子。好比考试,有的学生审题就错了,有的学生审题没错但算错了,错误类型完全不同,批评者得能分辨这个差异。
批评者会不会好心办坏事:拯救与误伤的权衡
有个很诚实的发现:批评者对强模型和弱模型的影响并不对称。
在收到提醒的任务里,强模型从批评者那里获得的“拯救”更多——本来做不出来的任务,提醒之后做出来了。但强模型也承受了更多“误伤”——本来能自己做对的任务,因为被插了一句不必要的提醒反而做错了。弱模型正好反过来,很少被误伤,被拯救的次数也少。
论文的解释是,强模型更愿意立刻按反馈行动,这种行动力是把双刃剑:对的提醒能迅速纠偏,错的提醒也会迅速把原本正确的路线带偏。就像一个经验丰富的老司机,一听到副驾说“前面好像要转弯”就立刻打方向,技术好能快速纠正,可万一副驾说错了,老司机也会立刻跟着错下去;新手司机可能半信半疑磨蹭半天才动作,反倒躲过了一些错误提醒的坑。
训练配方:用批评者生成的数据训练一个更小的模型
Opera的用途不只限于推理阶段的临场纠偏,它产生的交互轨迹本身就是宝贵的训练数据。
研究团队设置了一组对照:学生模型选Qwen3.5-9B,批评者用Qwen3.8-27B,先让前者在后者指导下跑完一批任务,再把这些轨迹拿去微调。另一组则让Qwen3.8-27B单独完成同样的任务,用这位“老师”留下的轨迹做微调。结果两批数据训出的模型,在训练时没碰过的SWE-Bench Pro仓库上成绩相差无几,涨幅都在10个百分点左右。
差别出现在换一个完全不同的测试环境时。
| 训练数据 | SWE-Bench Pro(held-out) | Terminal-Bench 2.1 |
|---|---|---|
| 不训练(基线) | 28.7 | 23.6 |
| 用老师模型的轨迹训练 | **39.5** | 7.9 |
| 用Opera指导下学生自己的轨迹训练 | 38.9 | **25.8** |
用老师的轨迹训练出来的模型,在Terminal-Bench 2.1上成绩从23.6%直接掉到了7.9%,这是一种叫做
遗忘:模型在学习新任务时,丧失了原本已经具备的其他能力。
的现象。而用Opera指导的学生自己轨迹训练出来的模型,在目标任务上提升幅度相当,还几乎完整地保留了原来在Terminal-Bench 2.1上的表现。
为什么会有这个差异?论文的解释和一个叫做
on-policy:训练数据中的所有动作都来自被训练的模型自身,而不是来自另一个模型的示范。
的概念有关。老师模型的轨迹对学生来说是完全陌生的行为方式,强行学这种陌生方式,就像让一个习惯左手写字的人去模仿右手写字的笔迹,模仿久了反而会打乱他原本熟练的左手书写能力。Opera指导下的学生轨迹不一样,每一个具体动作都是学生自己做出来的,批评者的影响只通过笔记这种外部提示体现,学生学的是“收到这种提示时该怎么调整”,而不是“该模仿另一个人怎么做事”,这更接近强化学习里让模型从自己的尝试中学习的方式,天然更不容易破坏原有能力。
这个发现呼应了机器学习里一个经典的思路,叫做
DAgger属于模仿学习算法,思路是让学习者在自身真正会碰到的状态里接受专家纠正,而非一味照搬专家从头做到尾的完整示范。
这也说明了“批评者指导下的自我纠错轨迹”为何比“单纯模仿更强模型”更管用:学生掌握的是在自身真正出错的那个节点上如何改回来,而这类节点老师多半碰不到——老师根本不会犯学生那种错。
批评者本身该选谁:自我批评还是请外援
论文还专门对比了一种更贴近实际的用法:让模型自己给自己的产出挑毛病,跟另请一个更强的外部模型当批评者,效果到底差多少。结论是,只要策略模型本身底子够好,自我批评同样能拿到可观的涨幅——在DeepSWE上,Qwen3.8-27B和DeepSeek-V4-Flash靠自我批评各自提升了6.2个百分点,跟拿Claude当批评者差不多。可见不少时候模型并非“不懂”怎样做才对,而是在执行途中没机会停下来琢磨一下;批评者框架给的正是这个停一停、想一想的契机,哪怕提醒它的就是它自己。
可要是策略模型本身能力有限,自我批评就不太灵了:批评者和被批评者共用同一片盲区,自己看不出的毛病自然也指不出来。这种时候换一个更强的外部模型来挑错,涨幅会明显大得多。例如请GPT当批评者,Qwen3.5-9B至少提升12.4个百分点,而自我批评最多只提升2.7个百分点。
写在后面
通读这篇论文,有个点让我反复琢磨:人们习惯把AI智能体的长进理解成模型本身越来越聪明,而这篇论文给出的视角不太一样——有时不必换一颗更强的大脑,只要给现有的大脑配一套合理的流程,在恰当的时机被提醒、被追问,表现就能明显往上走。这跟人类团队管理里的某些朴素道理挺像:很多时候不是人不行,是流程没给他留出纠错的窗口。
另一个值得单独拎出来说的是拯救与误伤之间的权衡。论文很诚实地写明,批评者并非纯赚不赔:强模型拿到更多拯救的同时,也挨了更多误伤。这是实打实的代价,不是被藏起来的瑕疵。不少论文只爱展示好看的一面,这篇把权衡摊开来讨论,反倒让整套方法显得更可信。
还有一个问题论文没展开,留了白:若把这套“持久笔记”机制用在批评者与执行者属于完全不同种类智能体的场景里,会是什么样?比如批评者看的是代码,执行者操作的却是机械臂或其他物理系统,这种跨模态的持续追踪还能不能成立。目前没有答案,但想想挺有意思。
Q&A
Q1:Opera是什么?A:它是
Salesforce AI Research提出的一个批评者框架,面向长时任务的编程智能体。每次纠错都被当成一张持续追踪的笔记,直到诊断出的问题真正解决才关闭,而不是提完意见就撒手不管。
Q2:Opera和其他批评者方法相比效果怎么样?A:在不加批评者的智能体面前,Opera于Terminal-Bench 2.1、SWE-Bench Pro和DeepSWE三个测试基准上分别最多提升12.4、15.0和8.9个百分点;与SWE-PRM、Agentic Rubrics等竞品对比时,它也拿到了最高的平均解决率。
Q3:Opera生成的数据能不能用来训练模型?A:可以。拿Opera指导下学生模型自己产生的轨迹去微调更小的模型Qwen3.5-9B,效果能匹配直接模仿更强模型轨迹的训练方式,同时还能避免模型换到新测试环境时出现明显的能力下降。