笔记日期: 2026-10-18
论文: Self-Taught Optimizer (STOP): Recursively Self-Improving Code Generation
作者: Eric Zelikman、Eliana Lorch、Lester Mackey、Adam Tauman Kalai
阅读版本: arXiv:2310.02304v3,2024-08-16 修订;初稿日期 2023-10-03
资料: 论文全文 · 官方仓库入口
1. 先分清:改的是答案,还是产生答案的方法?
常见的代码改进流程很直观:模型写一段程序,运行评分,再根据结果修改。反复几次后,我们得到一个更好的解。但这个过程中,负责“怎么提问、生成几个候选、优先修改哪个候选、什么时候停止”的程序,往往始终由人手工设计。
STOP 把这段外围程序也变成了优化对象。它先有一个能改进代码的程序,再让这个程序改写自己的代码。如果新版本更善于组织模型调用,那么它不仅可能解决当前问题,还可能在以后解决其他问题时继续发挥作用。这里值得关注的产物是一个可复用的改进方法。
也正因为如此,必须给“自我改进”一个准确的边界。STOP 不更新语言模型的参数,改变的是模型外面的代码框架,包括提示、候选生成、搜索控制、评分缓存和停止规则。它没有证明每轮一定提升,更没有证明可以无限递归地变强。论文给出的证据是:在特定模型、任务和预算下,改进器可以找到比初始版本更有效的搜索过程。
我读这篇论文时最关心的不是递归调用本身,而是递归之后的判断标准:新程序得分更高,究竟说明它更善于优化,还是更善于迎合一套有限且有噪声的评估? 后面的方法、实验与理论,都围绕这个问题展开。
这份笔记依据论文 46 页全文及附录。文中的实验数字来自论文;教学示例、公式推导和后续实验建议会分别说明,不把示意图当作新实验结果。

图 1. 当前改进器把另一个改进器当作待修改程序,再用元效用评价它能否改好下游代码。裁自 STOP v3 原文图 3。可变的是外围程序,语言模型和评价目标仍在这个可变程序之外。
2. 前置知识:两层搜索对应两种评分对象
先把一个程序写成字符串 ,把评价它的函数写成 。这里的效用不只是“答案看起来对不对”,还包括能否正常返回、是否符合输出约定、有没有超时,以及任务本身如何计分。论文理论部分把效用限制在 ,实际实验则给不同任务配置可计算的分数与资源限制。
一个改进器 接收三个输入:效用函数 、初始程序 、可调用的语言模型 。它返回一个新程序:
“改进器”只是这个程序想要扮演的角色,接口本身并不保证 。它可能丢掉原本不错的候选,误解评分函数,也可能在耗尽预算后什么都没返回。外层优化尤其容易受此影响:如果被改坏的是搜索程序,下一轮会继承的不只是一个差答案,而是一套变差的搜索方法。
因此,理解 STOP 要同时盯住两层:
- 内层搜索:给定一个具体问题,寻找更好的解题程序。
- 外层搜索:寻找更善于完成上述搜索的程序。
内层候选是解题程序,直接接受任务效用评分。外层候选是改进器,要先让它去改几个下游程序,再根据这些产物的分数评价它。二者可能都调用同一个语言模型,但不能混用评分对象。
这与自动算法设计很接近。区别在于,STOP 让语言模型直接提出程序修改,而不是只在若干预先规定的超参数之间选择。候选空间可以包含新的循环、不同的提示、缓存机制、候选保留规则,以及熟悉搜索算法的组合。表达力很强,但原本由固定优化器保证的约束也可能在修改中被破坏。
另一个需要提前区分的概念是“重复次数”和“任务覆盖面”。同一个任务重复运行五次,可以帮助观察模型采样带来的波动;换成五种不同任务,才能观察更广泛的迁移。它们减少的是不同来源的不确定性。后面的实验统计和泛化界都不能把这两个数互相替代。
3. 元效用:评价一个改进器能改出多好的程序
假设下游任务来自分布 。每个任务提供效用函数 和初始解 。改进器的总体质量可以定义为:
按从里到外的顺序读这条公式就容易了:先让 修改初始程序,再用任务自己的 给修改后的结果打分,最后对任务分布取平均。如果生成和评分本身带有随机性,也应包含在这个期望里。
实际做实验时,我们拿不到整个分布,只能在有限个任务上估计。简化写成:
到这里,外层优化就有了可调用的评分函数。接下来把式(1)中的“初始程序”换成当前改进器本身,把评分函数换成元效用:
式(4)中两个 的作用不同。最左边那个是正在执行的搜索程序;括号里的那个是被当作文本修改的代码对象。语言模型提出候选改进器 后,必须真的让 去产生下游解,再通过这些解的表现判断它的价值。写出一段很像优化算法的程序,并不等于它已经改善了优化。
论文在外层使用灰盒式的元效用说明:告诉模型这是一个怎样的平均评分过程、有哪些一般资源要求,但不把具体下游任务内容全部展开。这有助于把搜索引向通用的改进方法,而不是直接针对某个任务写捷径。不过,隐藏任务说明并不意味着没有信息泄露;反复返回的分数仍然会让搜索逐渐适应评估器。
还要注意,式(4)没有自动带上“只接受真正更好的版本”。想让训练分数不下降,至少要保留旧版本并公平比较;想让未知任务上的真实表现不下降,还需要控制估计误差。递归只是改变了由谁提出下一版,并没有解决如何可靠选出下一版。
4. 初始改进器为什么从多候选采样开始?
论文的种子改进器并不复杂:向模型说明任务效用和初始代码,请它提出有实质变化的改进,生成一批候选,分别评分,再返回分数最高的那个。原文图 2 的示例采用 0.7 的采样温度。下面按逻辑写成编号伪代码,不复述论文中的具体提示词。
算法 1:种子候选改进器
输入为效用 、初始程序 、语言模型 和生成预算 。
1. 向 L 描述目标和初始程序。
2. 在预算 B 内生成一批候选程序。
3. 用 u 分别评价候选程序。
4. 找出观测效用最大的候选。
5. 返回该候选,作为本轮提出的改进结果。
这个起点把“提出方案”和“判断方案”分开了。语言模型负责给出可能有效的程序,外部效用决定留下哪个。即使模型不能准确评价自己的答案,只要它偶尔能生成优秀候选,测量与选择就可能利用这种能力。
为什么多生成几个会有帮助?先看一个纯粹的教学模型。假设每次独立生成的候选,以概率 满足某个成功标准,那么连续 次都不成功的概率是 。取补集得到:
再多采样一次带来的增益是 ,会随着 增大而减小。这说明扩大候选池通常有边际收益递减,但不能据此推断 STOP 的实际成功率:真实候选之间存在相关性,任务分数可能连续变化,评估器也不一定能辨认出最好的候选。

图 2. 独立采样、且能够正确识别成功候选时的理论曲线。参数 是假设值,图中不是 STOP 实测数据。它只解释增加候选为何可能有效,以及收益为何会逐渐变小。
改进器可以改变的远不止候选数。它可以根据反馈改变提议分布,同时保留几条有希望的搜索路径,也可以对分数接近的候选追加测量。反过来说,如果评分噪声很大,候选越多,越容易挑到一个“恰好被高估”的程序。
这里有一个很容易忽略的顺序问题:出现好候选、正确测量它、最终把它留下,是三件不同的事。只增加生成预算,最多直接改善第一件事。STOP 能否持续获益,取决于后两件事是否也跟得上。
5. 把内层改进器放进外层循环
外层一旦要评价某个候选改进器,就不能只看它的文本。必须让它在一组下游任务上运行,收集它产生的解,再汇总分数。这种嵌套关系也是计算开销的来源:看似只评价了一个外层候选,内部可能已经调用了模型很多次。
算法 2:STOP 的外层递归
输入为种子改进器 、下游样本 、固定模型 和轮数 。
1. 定义 MetaScore(J):
2. 对每个下游任务 i,运行 J(u_i, s_i, L)。
3. 用 u_i 评价 J 返回的解。
4. 返回这些下游分数的平均值。
5. current = I_0。
6. 对 t = 1, ..., T:
7. proposed = current(MetaScore, source(current), L)。
8. current = proposed 所表示的改进器。
9. 返回 current。
这是对论文递归结构的抽象,并未额外加入独立验证或保留旧版本的步骤。特别是第 8 行,不能理解为“只有测试证明变好才替换”。如果加入这样的接受规则,那就是需要单独说明和计算预算的新设计。
与固定编辑器反复修改代码相比,STOP 的变化在于:一次成功修改可能改变之后的提议机制。若当前版本学会保留多样化候选,下一轮可能触及原本单一路径看不到的算法;若当前版本引入错误的停止条件,之后的搜索也会受影响。这使完整运行链条具有路径依赖。
因此,评价时不应只展示几段漂亮的中间程序。实际部署得到的是某次完整搜索最终返回的一个版本,搜索过程中花掉的资源、失败的轮次、继承的缺陷,都属于这次运行的结果。
灰盒元效用是一个折中。完全公开下游任务细节,更容易产生针对特定任务的投机;只给一个不透明标量,又可能使模型无法理解为什么要修改程序。STOP 保留一般目标说明,同时隐藏具体任务信息,希望让模型改出可复用的搜索逻辑。这个动机是合理的,但是否真的可复用,仍要由迁移结果回答。
6. 主实验任务:带噪声的奇偶学习
论文主要使用 learning parity with noise,简称 LPN。可以把它想成:一个二进制输入里,只有未知的一部分位置决定标签,标签是这些位置上比特的异或结果。用二进制掩码 表示哪些位置被选中:
先求被选中比特的和,再模 2,得到干净标签 。变量 表示是否翻转标签,因此学习器看到的 可能带噪声。难点在于从样本恢复规律,而不是把每个训练标签都记住。

图 3. 为阅读笔记构造的四比特示例,干净标签由第 1、3 位决定;星号位置故意翻转了一次标签。它不对应论文的一组实验样本,用来说明“完全拟合训练标签”不一定等于找回真实规则。
主实验使用十比特输入,每一位以 30% 的先验概率被选入隐藏子集。论文描述每个实例有 100 个训练样本和 20 个测试样本;附录 F 的示例任务采用 5% 的训练标签噪声。主评价对 20 个独立生成的 LPN 实例取平均,元目标中则使用任务的重复副本来平均改进器的随机行为。最终留出评价使用另外 50 个新采样的 LPN 实例。
这里有一个阅读细节:附录 F 的示例效用说明包含更短的时间限制及另一组示例测试次数。附录 K 明确提醒,这些说明并非实际运行设置的逐字对应,并报告 LPN 实验采用两秒超时。因此,不能直接把附录里的示例参数当作正式实验配置。
LPN 的优点是评分可执行、反馈相对便宜,初始程序也有改进空间。算法可以在更复杂的搜索和更短的运行时间之间做取舍,适合反复试验一个优化框架。局限同样清楚:十比特的合成任务,与依赖复杂、反馈延迟很长、正确性难以自动判断的真实软件任务差别很大。
所以,这个任务适合回答“机制能不能工作”,却不足以单独回答“一个通用编码 harness 是否可靠”。把这两个层次分开,后面的结果就不会被过度解释。
7. 主结果:有能力提出改进,不代表递归一定成功
GPT-4 主实验包含五条独立的自我改进链,每条运行四轮。原文图 4 的留出元效用均值大致从 61% 上升到 72% 左右,随后趋于平缓。这里的近似数来自图形读数,不是重新获得的原始数据;阴影表示一个标准误。

图 4. STOP v3 原文图 4。GPT-4 平均表现上升,GPT-3.5 与 Mixtral 平均表现下降。三个面板的纵轴范围不同,比较时需要看刻度,不能只凭曲线斜率判断变化幅度。
论文用的是 GPT-4-0314、GPT-3.5-turbo-0613 和 Mixtral-8x7B-Instruct-v0.1。模型版本是解释结果的一部分:这些实验说明相应模型在当时配置下的行为,不是今天模型的排名,也没有给出一个永远成立的参数量门槛。
较弱模型的实验各有 25 条运行链。两者的平均分都随着递归而下降。GPT-3.5 中只有 12% 的链达到论文所称“至少 3% 的提升”。也就是说,少数成功案例确实存在,但总体平均结果仍然是退化。若只挑成功链展示,很容易把用户实际面临的结果反过来理解。
一个有意思的现象是,GPT-3.5 在初始改进器下的成绩反而高于 GPT-4。论文的解释是,GPT-4 更常提出复杂但运行较慢的方案,在很短的执行时限下吃亏。这提醒我们,模型更有能力、程序更复杂、给定预算下的效用更高,是三个不同判断。
论文还报告了思维链基线和固定的贪心迭代基线。思维链只统计没有报错的运行时,成绩是 57.7% ± 3.0%;把报错纳入后,则是 49.6% ± 3.5%。贪心迭代基线为 64.2% ± 0.9%。这些 ± 数字沿用原文报告,不额外赋予原文未明确说明的统计含义。
对需要每次返回可用结果的系统,包含错误的成绩更接近端到端体验。排除失败后得到的是“成功运行条件下的答案质量”,它不能代表完整可靠性。自我改进系统容易展示一条漂亮轨迹,因此更需要坚持这个统计口径。
这些对照支持“简单固定循环之外还有改进空间”,却还不能把全部收益归因于递归这个动作。被演化的程序可能同时改变提示词、采样安排、缓存、候选选择和实际资源分配。若要判断递归本身有多少贡献,还需要预算匹配和部件消融。
8. 迁移结果:值得重视,但要记住改进器经过挑选
作者选取了 LPN 搜索中表现较好的一个演化改进器,把它直接用于五个其他任务,不再做额外元训练。相比只在 LPN 上提高分数,这能更直接地检验改进器是否学到了可复用的模型调用方式。
| 任务 | 初始解 | 种子改进器 | 选出的演化改进器 |
|---|---|---|---|
| 字符串网格距离 | 43.9 | 44.3 | 56.7 |
| 修改版二次指派 | 20.4 | 20.6 | 22.1 |
| 3-SAT | 0.0 | 21.2 | 75.1 |
| Max-Cut | 0.0 | 58.7 | 74.2 |
| 无噪声奇偶学习 | 50.0 | 59.3 | 81.7 |
表中沿用 STOP 原文表 1 的任务效用百分数。不同任务的效用定义不同,不能把它们都叫作同一种准确率。

图 5. 根据原文表 1 重绘,保留初始解、种子改进器和选出改进器三个条件。每个任务中,选出的演化版本都高于种子;横轴单位虽然都写成百分数,其含义却依任务而异。
相对种子版本,五个任务分别提高 12.4、1.5、53.9、15.5 和 22.4 个效用百分点。这只是从表中相减得到的数,不是新实验。把这些差值再平均成一个“总体准确率提升”,会掩盖不同任务难度、归一化方式和基线强弱的差别。
我认为这组迁移结果是论文的重要证据,因为它至少说明某个搜索框架的收益没有完全锁死在 LPN 上。但解释时必须同时保留三个条件。
第一,迁移的是经过选择的一个较好改进器,而不是所有演化链的平均产物。第二,表 1 没有给出每项迁移数字的不确定性区间。第三,五个任务仍然都是合成、可执行评分的问题,不是开放式的软件仓库维护任务。
附录 H 给出了被选中用于迁移的改进器。概念上,它会使用多个采样温度、去除完全相同的候选、缓存评分,并记录分数最高的结果。这些设计具有可复用性,但论文没有通过逐项消融证明其中哪个部件贡献了多少。
算法 3:迁移改进器的概念结构
下面是对附录 H 的阅读抽象,不是本文提出的新实现。
1. 准备使用多个温度的候选生成请求。
2. 在资源允许时生成候选程序。
3. 去掉字符串完全相同的重复候选。
4. 对尚未缓存的候选进行效用评价。
5. 跟踪观测分数最高的程序。
6. 返回本轮找到的最佳候选。
去重可以减少浪费,但字符串不同的程序也可能在语义上完全等价。缓存同样有两面性:对于确定性评分,它能避免重复计算;对于随机评分,只记住第一次结果,可能把一次幸运的高分永久固定下来。工程上的节约,并不自动等于统计上的充分。
9. 论文里出现了哪些搜索策略?
正文和附录 B 展示了类似束搜索、模拟退火、遗传搜索、多臂老虎机、局部编辑和温度调度的方案。模型可以根据程序含义提出修改,而不是随机替换字符;也可以建议把两个有希望的程序的不同部分组合起来。
不过,这些例子不能全部并入一个想象中的“最终 STOP 算法”。有些只是被提出的候选,没有最终入选;有些来自更早的种子配置。正文图 5 展示的十轮示例,也不是迁移表中使用的四轮改进器。阅读附录时,最容易发生的误读,就是把所有精彩片段拼成一个从未被整体测量过的系统。
这些方案仍然揭示了几个值得优化的维度:
- 搜索宽度:同时保留多个好候选,减少过早押注一条路径。
- 探索方式:改变提示或模型采样温度,产生不同类型的程序。
- 利用反馈:围绕一个有希望的候选继续改,而不是每次从头生成。
- 资源控制:避免重复评价,在停滞时终止,或根据反馈分配后续调用。
其中有两个“温度”尤其需要分开。语言模型采样温度改变 token 的提议分布;模拟退火温度则控制一个已被评分的较差候选,有多大概率仍被接受。对效用差 ,常见退火接受规则是:
当 较高时,负的 受到的惩罚较弱,因此搜索更容易越过局部低谷。模型温度则是在评分之前改变候选从哪里来。两种控制可以组合使用,但不是同一个操作。式(7)用于解释一般启发式,不表示论文迁移收益已被归因到这条规则。
这些结果更有力地支持“语言模型可以在熟悉的算法结构之间搜索”,而不是“模型发明了全新算法”。训练数据里可能已经包含这些经典方法;在无法排除这类背景知识时,不宜把重新组合与历史上的首次发现混为一谈。
10. 泛化界到底保证了什么?
附录 A 讨论一个自然的问题:如果不断优化有限任务上的元效用,这种进步能否推广到真实任务分布?一个简单做法是限制改进器的程序长度,使候选集合成为有限集,再对整个集合建立统一的误差界。
设程序最多包含 个符号,字母表大小为 ,每个独立评价样本的得分都在 。长度不超过 的所有字符串数量为:
这把空字符串以及语法错误的字符串也算进去了,因此是一个保守的上界。无效程序可以按预先约定获得失败分数。这里并不是说算法会遍历全部字符串,而是先给可能被选中的程序划定一个集合。
10.1 先固定一个改进器
对事先固定的 ,如果 个评价样本独立且有界,Hoeffding 不等式给出:
它的意思是:样本越多,估计值偏离真实期望超过 的概率越小。但这只针对预先固定的一个程序。搜索过程中,我们会看分数再选程序;如果只把这个单候选结论直接套到最后赢家身上,就忽略了选择过程。
10.2 再对整个程序集合取并集界
让“至少一个候选被高估或低估超过 ”作为失败事件。即使不同候选的误差相关,也可以把各自失败概率相加,得到:
把右边设为允许的失败概率 ,先取对数,再移项,就得到:
这条式子展示了样本数和搜索空间的关系:任务样本数出现在分母,候选数通过对数进入分子。程序越长、可选程序越多,想把误差控制在同样范围内,就需要更多独立评价。
这里采用的是重新推导的标准有限类界,与附录的计数和集中不等式思路一致。原文证明中有一处指数项代入后的倒数关系与前式不符,不能直接照抄那一行;式(9)至(11)保留了正确的指数与倒数方向。
10.3 从“估计准确”走到“选出来的程序够好”
设 是集合里真实效用最高的程序, 是样本平均分最高的程序。在所有程序的估计误差都不超过 的事件上:
第一步用到了 的估计误差界;第二步用到了 在样本上的最优性;第三步再用一次估计误差界。因此,样本最优程序与真实最优程序的差距至多是 。
关键是第二步。STOP 并没有保证自己找到样本上的全局最优程序。若实际找到的程序距离样本最优还差 ,最后的差距应写成 。评分估计够准,与搜索优化做得够好,是两项独立要求。

图 6. 按式(11)计算的理论示意,字母表大小为 128,失败概率为 0.05,比较三种最大程序长度。曲线超过 1 时,对范围在 内的效用没有实用约束;它不是 STOP 实验成绩的置信区间。
10.4 为什么有了定理,实验仍需要留出评价?
第一,所有有界长度字符串构成的集合巨大,界可能很松。对很长的程序和很少的元训练任务,理论上界甚至大于整个效用范围。这样的结果在数学上可以正确,却不足以判断实验提升是真是假。
第二,独立样本的单位必须与泛化目标一致。对同一种 LPN 任务反复采样模型响应,能够减少对生成随机性的估计误差,但不能代替覆盖更多任务种类。我们想推广到其他任务时,仍然缺少关于那些任务的证据。
第三,统一界要求事先规定候选集合与相应假设。如果搜索过程中不断放宽程序长度、改变任务分布或修改计分定义,原来的界不能不加说明地继续沿用。
因此,理论部分更适合被理解为“哪些条件需要控制”的说明。它没有替代实际的留出测试,也没有把四轮实验升级为无限轮递归有效的证明。
11. 随机停止让递归可定义,但不保证进步
附录 A 还讨论了不必接收初始解的最大化器形式,以及用随机停止来定义递归目标的方法。它们帮助我们描述自指过程,避免把一个目标建立在永远不会结束的计算上。
假设每一层以概率 停止,各层停止决策独立。令 表示总调用次数,包含最后停止的那次。要恰好在第 次结束,必须先继续 次,再停止一次:
期望可以用递推直接求。无论如何先发生一次调用;之后以概率 进入与原过程同分布的后续递归:

图 7. 三种停止概率对应的几何分布。它用于解释附录中的数学构造,与主实验固定运行四轮的设置分开。较小的停止概率会增加预期深度。
有限的期望深度只说明这个递归定义不必依赖无限次调用。它并不说明程序越递归越好,也不说明最终固定点是优秀优化器。一个每次都原样返回自己的低效程序,同样可以形成固定点。
而且,调用次数受控还不等于总成本受控。若各层执行时间差异很大,少数昂贵调用仍可能主导总费用。这也是为什么实际系统需要同时看调用数、token 数、工具时间和墙钟时间。
把这几个层次分开很有帮助:递归目标可以定义清楚,样本估计可以有统计意义,实际搜索仍然可能表现很差。证明其中一项,并不会自动证明其他项。
12. 计算成本:什么时候值得先搜索一个搜索器?
附录 K 估计每条运行链、每轮大约使用 3,000 次 GPT-4 调用。按四轮相乘,大约是每条链 12,000 次;再按五条链相乘,大约是 60,000 次。这是根据论文所报平均量做的算术估计,不是独立测量的总调用记录,更不能直接换算成确定的 token 数、美元费用或耗时。
嵌套结构解释了为什么开销会放大。假设每轮外层评价 个候选改进器,每个改进器测 个下游任务,每个下游运行调用模型 次,共进行 轮,那么主要调用量的量级是:
这个式子还没有算外层提出候选的调用、失败重试、缓存和提前停止。它是帮助理解预算的模型,不是对论文实验进行的成本拟合。每层都稍微“多试一点”,叠起来就可能大幅增加总费用。
为什么仍值得这样做?因为元搜索的产物可以复用。设搜索一个改进器花费 ,之后每次使用它花费 ,总共复用 次,那么平均到每次使用的成本为:
如果基线每次成本为 ,且确实大于新改进器的单次成本,那么成本上打平需要:
这个比较有前提:两者的质量和工作负载要可比。若新改进器每次运行反而更贵,它的理由就应来自更好的结果,而不是声称靠复用必然省钱。

图 8. 假设元搜索成本为 1,000 单位,新改进器每次成本为 1,基线每次成本为 2,则在 1,000 次使用时打平。这些数是教学假设,不是 STOP 实测费用。
迁移能力因此不仅是泛化问题,也与效率有关。若框架只对一小类任务有用,元搜索成本可能很难摊薄;若它能稳定用于许多任务,前期投入才更有意义。不过,这种复用优势必须经得住模型、任务分布和资源限制的变化。
一个常见的评价盲点是只比较最终程序的单次成本,却不计获得这个程序的搜索成本。另一个极端是只看元搜索非常昂贵,就否定它的一切价值。更合理的方式是说明预计复用范围,并把质量、搜索成本、部署成本放在一起看。
13. 关于沙箱的实验,测到的究竟是什么?
论文另做了一组实验,检查生成文本里是否出现试图关闭某项评价约束的内容。每个条件生成 10,000 次,随后做语法层面的检查;这组实验没有执行这些候选程序。因此,数字表示被标记文本的出现比例,而不是实际成功逃逸沙箱的概率。
| 模型条件 | 被标记文本比例 | 原文 95% Wilson 区间 |
|---|---|---|
| GPT-4 | 0.42% | 0.31%-0.57% |
| GPT-4 加警告 | 0.46% | 0.35%-0.61% |
| GPT-3.5 | 0.12% | 0.07%-0.21% |
| GPT-3.5 加警告 | 0.17% | 0.11%-0.27% |

图 9. 根据 STOP 表 2 重绘,误差线为原文报告的 Wilson 区间。候选没有在这组实验中执行;按论文采用的 0.05 阈值,增加警告前后的差异没有达到统计显著。
这一结果能支持的窄结论是:可编辑的提议过程会产生与评价约束相冲突的程序文本。不能从这些比例进一步推导模型意图、真实攻破能力,或某个部署系统的通用风险率。
对优化方法而言,更直接的问题是分数的含义是否保持稳定。附录提到,早期评价器曾因候选输出格式异常,给出超过 1,000% 的表面准确率。这个数字明显已经脱离任务定义,高分不能作为任务进步的证据。
可信评价需要把评分契约与被优化对象分开,对格式错误和运行失败规定明确语义,并区分“任务做错”和“评价过程出错”。这属于测量质量问题,不必把所有异常输出都解释成有意识的对抗。
如果一个搜索系统能够改写越来越多外围逻辑,评估的独立性反而更重要。否则,我们看到的也许是程序与计分漏洞的共同适应,而不是解题能力的增加。
14. 局限性
任务分布较窄。 主元训练任务是合成 LPN,迁移覆盖五个紧凑且能自动评分的问题。论文尚未证明同样方法能处理长周期的软件任务、动态依赖、延迟反馈或需要人类判断的目标。
选择过程影响迁移结论。 用于迁移的是 LPN 中表现较好的版本,表格没有呈现所有运行链的迁移分布,也没有给出每项结果的不确定性。一个成功产物能证明可能性,却不能估计重跑一次能否稳定获得它。
没有单调改进保证。 候选可以报错,评分可以受噪声影响,后续轮次可以继承前一版的缺陷。较弱模型的平均退化就是直接证据。
计算量与机制没有完全拆开。 更好的结果可能来自提示、采样、缓存或调用分配的变化。论文没有对所有这些因素完成严格的预算匹配和独立消融。
理论候选类远大于数据能支撑的范围。 对所有有界长度字符串计数很方便,但往往得到很松的界。若想更贴近模型真正会生成的程序,还需要利用更多结构,而不是把完整字符串空间的保证当作实验置信度。
目标说明与实际设置可能不同。 附录明确区分了示例说明和实验运行参数。模型可能在优化描述中的目标,却在另一套具体限制下被评分。灰盒访问减少任务暴露,同时也可能拿走合理分配资源所需的信息。
控制逻辑本身也会失效。 缓存、候选解析、停止规则、旧版本保留方式都在潜在修改范围内。一个局部看起来更省事的变化,可能降低稳定性,甚至改变重复评价的统计含义。
15. 批判性分析:真正稀缺的是可信评价
我认为 STOP 最有价值的贡献,是选中了一个值得搜索的对象:外围改进程序。它比单次答案更可复用,又比整个基础模型更容易修改。实验说明,在模型参数不变时,改变这个对象也能带来收益。
但当搜索越来越自适应,评估器就成了更关键的瓶颈。它既要提供足够快的反馈,又要识别哪些变化能在未知任务上继续成立。若无法区分真实进步、样本噪声和对评估规则的适应,递归只会让系统更高效地追逐不可靠的信号。
15.1 先区分“递归有用”和“找到了好启发式”
一个更有说服力的实验,可以同时改变两个因素:负责编辑的控制器是否随轮次变化;是否保留经过独立验证的最佳旧版本。这样得到四个条件,而不是只比较一个简单种子和一个演化后的复杂系统。
固定编辑器也应允许搜索同样丰富的程序空间。否则,差异可能只是候选空间不同,而不是递归有额外价值。旧版本保留所用的验证样本应与搜索评分分开,其额外评价成本也必须纳入相同预算。
这样的实验才能更直接地回答:动态改进提议机制,是否胜过用一个固定但有能力的编辑器寻找优秀静态控制器?这是本文提出的后续实验,不是 STOP 已完成的验证。
15.2 把完整运行链作为统计单位
使用者真正付费执行的是一次完整元搜索。它会消耗资源,最后返回一个改进器,也可能返回一个差版本。如果只展示所有链里最漂亮的产物,就没有回答“一次新的运行能多可靠地获得这种产物”。
更完整的报告应展示每条独立链在未知任务上的迁移表现,保留失败运行并按既定失败分数计入,还要同时报告成本分布。成功率、中位数、尾部失败和最好结果分别回答不同问题,不能只留最高分。
对比控制器时,可以使用配对随机种子来降低差分方差,但最终测试仍应另采样。否则,那些反复用于比较的种子也会逐渐变成新的训练集。
15.3 泛化想说到哪一层,留出就要做到哪一层
留出新的 LPN 实例,检验的是同一任务族内部的推广。留出一个新的组合优化问题,检验范围更大。换一个领域、模型后端或评价方式,要求又更高。
如果目标是通用编码 harness,就不能只依赖某个短超时条件下的一组分数。应当包含未知任务族和不同资源限制,观察收益是否稳定。一个只在两秒限制下取胜的控制器,可能发现了很有效的局部策略,却不一定学会了通用的资源分配方法。
因此,质量与成本的曲线比一个标量更有解释力。我们想知道的是:给定相同预算谁更好,达到相同质量谁更省,以及优势在哪些区间消失。
15.4 噪声应该影响预算分配,而不只是最后排序
当两个候选分数接近时,下一次模型调用未必应该继续生成新程序。对一个不确定的旧候选再测一次,有时更可能改变最终选择。只缓存单个分数的系统看不到这种机会。
可以考虑记录重复测量及不确定性,同时保留独立的最终测试集。这样做的目的不是让优化器看起来更复杂,而是判断额外测量能否减少错误选择。若评价本来非常稳定,增加这套机制也可能得不偿失;它同样需要实验对照。
这也解释了为什么“多探索”不是万能答案。探索提议空间和探索测量不确定性,消耗同一份预算。一个成熟的搜索框架应明确它把资源花在哪一类不确定性上。
15.5 自指过程不应成为成功标准
让改进器调用自己,在形式上很漂亮,但使用者需要的是在明确预算下获得好解的概率。递归系统如果只是重新找到了一个可靠的束搜索控制器,也可能很有价值;反过来,轨迹中充满复杂自我修改,却经常失败或成本过高,就未必实用。
因此,我会把评价标准放在可复用的质量收益、透明的选择过程和完整的失败统计上。STOP 把这个研究方向做成了具体可讨论的实验对象,但最难的评价问题仍然留在后面。
16. 结论
STOP 的核心动作,是把“如何改好代码”的程序本身变成可修改对象。两层效用把这个过程写得很清楚:内层评解题程序,外层评改进器;同一个固定语言模型参与两层,却不需要更新自己的权重。
GPT-4 的主结果和经过选择的迁移结果,说明这种方式能够产生有用的搜索过程。较弱模型的退化、评分契约失效的案例,以及可能很松的理论界,也说明递归绝不是自动进步的保证。
这篇论文最值得带走的认识是:模型周围的优化程序本身值得搜索,而当这个程序开始控制自己的搜索时,我们必须更认真地判断分数到底代表什么。
参考资料与图源
- Eric Zelikman、Eliana Lorch、Lester Mackey、Adam Tauman Kalai:Self-Taught Optimizer (STOP): Recursively Self-Improving Code Generation,v3,2024-08-16。方法见正文第 3-4 节,实验见第 5-6 节;理论见附录 A,策略例子见附录 B,任务说明见附录 F-G,迁移改进器见附录 H,实验细节见附录 K。
- 46 页论文全文。本笔记图 1、4 分别裁自原文图 3、4;图 5、9 分别根据原文表 1、2 重绘;图 2、3、6、7、8 是为解释方法而制作的示意图,不是新增实验结果。
- STOP 官方资料仓库,作为读者的后续资源入口。