SETA 论文笔记:把终端环境当作需要验证的奖励程序

一个训练环境不仅提供题目,也决定什么行为会得到奖励。对环境合成工作而言,最值得追问的因此是:参考解通过测试,是否足以证明这个奖励值得学习? 本文围绕 SETA 的方法与实验展开讨论,再用一个原创 SQLite 案例推演环境生成、难度调整和验证器审计,并讨论没有训练 GPU 时可以独立完成的研究。

1. 先抓住论文的方法骨架

SETA-Synth 将真实问题转为规格,再生成环境、参考解和测试;先做空操作与参考解检查,再审查全失败轨迹。SETA-Evol 根据模型表现选择增难、降难或换场景。附录 A.3 的反例是:测试要求指令未声明的 JSON 字段,参考解却共享了这一隐含约定。§3.1–3.2、附录 A.3

我的理解是,这里最有启发性的贡献,是把环境有效性与相对模型的难度放进同一个迭代过程。环境生成者需要对两件不同的事负责:任务是否定义清楚,以及当前模型是否有机会从中学到东西。

把“再生成一道题”换成“再生成一个可执行世界”之后,错误空间会明显扩大。题意正确,但初始数据不满足约束;参考解正确,但依赖无法安装;测试能运行,却把一种合法实现判错——这些情况都可能表现为 agent 得分很低。

因此,失败轨迹不只是模型能力的观测,也可以是环境质量的证据。困难在于,二者不能直接画等号:模型失败可能是能力不足,也可能是任务、测试或运行条件有问题。

2. 用一个原创任务理解环境合成

以下案例、数据、测试和流程均为教学用设计,不是论文数据或 SETA 的完整实现。 选择 SQLite,是为了让问题可以在普通 CPU 上执行,并让正确性容易手算。

2.1 从一句需求补成完整契约

原始需求是:“按用户统计订单净消费额。”

如果直接把这句话交给 agent,至少有四个问题没有定义:金额用元还是分?退款是否可能分多次?没有退款的订单如何处理?结果应该写到哪里?

我们把任务约定为:

  1. 数据库包含 orders(order_id, user_id, amount_cents) 与 refunds(refund_id, order_id, amount_cents)。
  2. 金额使用非负整数分;每个订单的退款总额不超过订单金额。
  3. 每个有订单的用户都应出现在结果中,包括净消费为零的用户。
  4. 创建 user_net(user_id, net_cents),每个用户恰好一行。
  5. 不得修改输入表;重复运行应得到相同结果。

这一步的产物应是可检查的契约,而不只是更长的自然语言。新增一个约束,就需要确认初始数据能覆盖它,并为它设计独立的验收条件。

2.2 构造能暴露错误的数据

订单如下:

订单 用户 金额(分)
O1 U1 10000
O2 U1 5000
O3 U2 8000

退款如下:

退款 订单 金额(分)
R1 O1 2000
R2 O1 1000

正确结果可以直接计算:

\[ \operatorname{net}(U1)=10000+5000-2000-1000=12000, \]

\[ \operatorname{net}(U2)=8000. \]

为什么要给 O1 两条退款记录?因为这会暴露一个常见错误:先把订单与退款直接连接,再按用户汇总。

O1 在连接结果中出现两次,其订单金额也会被加两次。因此,这种错误实现会为 U1 算出:

\[ (10000-2000)+(10000-1000)+5000=22000. \]

这不是通过“多造一些随机行”自然保证的覆盖。需要先明确想区分什么能力,再构造可以区分正确解与错误解的实例。

一种正确实现是先按订单汇总退款,再与订单连接。验证器则可以用 Python 字典累计订单与退款,减少与 SQL 参考解共享同一种连接错误的机会。不同语言并不自动意味着独立,关键是实现路径是否真的不同。

2.3 两个执行检查分别能证明什么

初始环境中没有 user_net。让 agent 什么都不做,输出相关检查应失败;执行参考解后,检查应通过。

但这只能回答两件事:初始状态尚未完成任务,以及存在一个能被测试接受的实现。它没有穷尽合法实现,也没有证明错误实现一定会被拒绝。

假设测试要求结果表的物理行顺序恰好为 U1、U2,而任务没有要求排序。那么一个数值完全正确、行顺序不同的答案可能被误杀。修复办法不是把参考解输出拷贝进提示,而是检查业务契约是否真的需要顺序:需要就写清楚,不需要就按集合或显式排序后的结果比较。

2.4 验证器也要有正例和反例

为这个任务准备下列实现:

候选实现 契约上的判定 验证器应检查什么
先聚合退款,再连接订单 正确 接受
用 Python 累积后写回结果 正确 接受,不绑定 SQL 写法
忽略退款 错误 U1 应为 12000
直接连接后汇总 错误 拒绝重复计算金额
用内连接丢掉无退款订单 错误 检查用户覆盖与数值
第一次正确,第二次追加重复行 错误 检查重复运行
输出正确,但删除输入记录 错误 比较输入表前后内容

对正例集合计算误拒绝率,对反例集合计算误接受率,可以帮助发现测试缺口。结果只对所选样例成立,不能被表述为对所有可能程序的正确性证明。

3. 难度演化应该改变什么

在这个教学案例中,可以把演化拆成几种有明确含义的修改:

演化方向 具体修改 需要重新验证的部分
增加组合能力 加入多次退款与重复运行要求 聚合逻辑、幂等性、说明充分性
减少能力要求 暂时取消重复运行要求 指令、测试和评价目标同步变更
更换工具语境 将输入改为 CSV,保持业务规则 文件解析与结果格式;重新测难度

删掉一个测试并不等于合理降难。 如果题目仍要求重复运行正确,测试却不再检查,那只是奖励变得不完整。真正降难应当改变任务契约,并保留剩余要求的完整验证。

同样,把 SQLite 改成 CSV 只说明工具语境变化,不能保证难度相同。模型可能熟悉 Python 文件处理,却不熟悉 SQL;所谓“同等难度”,需要在固定 agent 和预算下测量。

3.1 为什么中间难度可能更有用

考虑最简化的二元结果:一次轨迹成功的概率为 \(p\),奖励 \(R\) 取 0 或 1。在独立同分布的教学假设下:

\[ \operatorname{Var}(R)=p(1-p). \]

当 \(p=0.5\) 时方差为 0.25;当 \(p=0.95\) 时为 0.0475;当 \(p=0\) 时为 0。

再考虑每个任务采样 4 条轨迹。组内至少有一条成功、也至少有一条失败的概率为:

\[ P(\text{mixed})=1-p^4-(1-p)^4. \]

代入 \(p=0.5\),得到 \(0.875\);代入 \(p=0.95\),约为 \(0.1855\)。这是一个解释相对奖励信号的简化推导,不是论文给出的数据选择定理,也不能证明成功率 50% 总是最优。

训练价值还取决于技能覆盖、奖励可信度、轨迹成本和可迁移性。一个测试有漏洞的任务也可能产生很高的奖励方差,但那不意味着它值得训练。

3.2 部分得分增加信号,也引入新的设计问题

论文 §3.4 用测试通过比例加全通过奖励;正文写额外 0.2,附录 Table 8 写 0.5,两处不一致,复现时应核对运行配置。§3.4 与附录 A.8

下面只为讲解取 \(b=0.2\),定义:

\[ R(k,m)=\frac{k}{m}+b\,\mathbf 1[k=m], \]

其中 \(m=4\) 是这个教学环境的测试数,\(k\) 是通过数。四条假想轨迹分别通过 0、1、3、4 个测试,则:

\[ R=[0,0.25,0.75,1.2],\qquad \bar R=0.55. \]

只减去组均值,得到相对分数:

\[ R-\bar R=[-0.55,-0.30,0.20,0.65]. \]

因此,完成较多子目标的轨迹即使没有全通过,也可能获得高于组均值的分数。这里省略了标准差归一化、重要性比率、clipping、token 聚合和 KL,这些数值不应被当成 SETA 训练代码中的实际 advantage。

这种奖励还有一个容易被忽略的问题:测试粒度会改变权重。假如“金额正确”只有一个测试,“文件存在”却拆成三个近乎重复的测试,那么按测试数平均,实际上会给文件检查更多权重。改进可以是先按业务要求分组,再设置组间权重;代价是新增人工设计与校准工作,需要检验是否真的降低了奖励与真实完成度的偏差。

4. 实验结果的读取边界

Table 3 中 Qwen3-8B 在 Terminal-Bench 2.0 的 pass@1 为:

模型 平均值 ± 标准差
基座 3.1% ± 0.6%
SETA RL 10.7% ± 1.3%

绝对提升为 7.6 个百分点;12% 是最佳结果。标准差来自 8 次评测的采样波动,不是 8 个独立训练种子。训练硬件分别为 Qwen3-8B 的 8 张 H200、DeepSeek-V4-Flash 的 64 张 H200。§4.1–4.2、Table 3

我的分析是,这些结果支持“完整训练方案带来收益”,但不能单靠前后模型比较,把收益分别归因给任务来源、演化策略、验证或奖励设计。要回答某个模块值不值得投入,最好固定训练预算、基础任务池和 agent 配置,逐项替换模块。

也要区分三个层次的证据:

结论 至少需要的证据
环境构建更稳定 干净环境下的重复构建与执行
验证器更可靠 独立标注的正确解、错误解与失败案例
模型训练更有效 匹配预算的训练对照和外部能力评测

前两项改善有明确工程价值,但不能自动推出第三项。可靠却过于简单的环境,未必给当前模型增加能力。

5. 局限与可以继续研究的问题

作者在 §5 承认验证的模型范围和训练预算仍有限,交互也局限于终端。论文讨论 以下是我的进一步分析与待验证建议。

5.1 少量试跑容易误判难度

假设真实成功概率为 0.2,独立试跑 5 次全部失败的概率仍然是:

\[ (1-0.2)^5=0.32768. \]

所以“五次全失败”既不是任务无解证明,也不能稳健地确定它超出模型能力。可以优先追加评测那些难度判断最不确定的环境;代价是调度更复杂,评测预算需要在覆盖面与置信度之间分配。

检验这种方法,应比较固定 rollout 预算下的难度误分类率,以及最终保留任务的质量,而不只看生成数量。

5.2 审查触发条件可能漏掉部分缺陷

如果只有全失败的任务进入深入审查,那么“少数样例恰好通过,但大多数合法实现被误杀”的环境可能漏检。可以增加两种抽样:随机质量审查,以及不同求解器分歧较大的任务审查。

多求解器一致也不能证明正确;它们可能共享习惯和盲点。因此,还应保留人工核验的子集,并报告审查成本与漏检率。

5.3 演化后的低成功率可能来自运行成本

假设父任务处理 100 行数据,子任务改成 100 万行,而时间预算保持不变。成功率下降可能主要反映执行时间增加,而不是规划能力要求提升。

可以同时报告成功率、工具执行时间、模型调用次数和终止原因,并在更宽松的运行预算下复测。若放宽运行时间就恢复成功,更准确的结论是资源要求提高了,而不是笼统地说推理更难。

5.4 参考解与测试的独立性需要具体设计

让两个模型分别写参考解和测试,可能降低共同错误,但不保证消除它们。更可执行的办法是给每条验收规则记录来源,并增加三类证据:已知正确的替代实现、已知错误的变体、随机输入上的一致性检查。

这也会引入成本,而且“已知错误”本身需要验证。一个变体可能在某些输入上仍然合法,所以不能只因为代码经过修改,就把它当作负例。

6. 没有训练 GPU,可以完成哪种工作

可以把研究对象暂时限定为环境生成与验收过程,并公开承诺较窄的结论。一个适合开源的项目问题是:

在相同生成与审查预算下,能否通过独立参考计算和错误解测试,提高有效环境的产出率?

6.1 一个最小实验设计

选 10 个 SQLite 任务家族,每个家族生成若干输入实例。比较三条流程:

  1. 直接生成任务、参考解和测试。
  2. 在第一条流程上增加执行检查与独立审查。
  3. 在第二条流程上增加契约覆盖、替代合法解和错误解测试。

这是建议的实验设计,不是对 SETA 的完整复现。划分开发集与测试集时,应按任务家族拆分:同一父任务的轻微变体不宜同时出现在调参集和测试集。

至少保留以下指标:

指标 作用
可重复构建率 区分运行基础问题与语义问题
合法解误拒绝率 检查验证器是否过严或绑定写法
错误解误接受率 检查奖励漏洞
每个有效环境的成本 防止靠无限修复次数获得表面质量
留出任务家族表现 检查方法能否推广到未调参的任务

“有效环境”应根据预先确定的验收协议标注,不能直接定义为“通过自己的新检查”。否则,新增检查必然显得有效,实验会陷入循环论证。

6.2 开源仓库的交付重点

仓库可以包含任务契约、可重置环境、独立参考实现、验证器、候选正确解与错误解、评测脚本,以及环境演化记录。最有说服力的 demo 是一个完整失败案例:旧流程为什么接受了坏环境,新检查发现了什么,修复后哪些证据发生变化。

官方代码提供本地 Docker、远程 Docker 和 CPU 环境服务等运行方式,并分开组织环境执行与模型训练;可把它作为接口和工程组织的参考,而不必自行重写分布式训练系统。SETA 仓库

没有 GPU 不代表没有成本。人工参考解、CPU 测试可以先做;自动生成、模型试跑与多轮审查通常还需要推理服务。第一轮应先记录 5 个种子的真实 token、重试和运行成本,再决定规模。

最后的研究边界应明确:这个阶段可以证明环境更稳定、验证更可靠或成本更低;训练收益需要之后补充匹配预算的 RL 实验。 把这一边界写清楚,会让开源成果更可信,也更容易让后续合作者知道还需要补什么。

7. 读完后值得保留的判断

环境合成值得投入的部分,是把“这个任务应该能做”转化成可执行、可审计的证据。一个通过参考解检查的环境,仍可能漏掉错误解或误杀合法解;一个更难的环境,也不一定提供更好的训练信号。

对资源有限的研究者,先验证奖励程序,再研究任务分布,是一条可以独立推进的路线。相邻问题还包括如何离线建立环境演化谱系,以及如何在训练过程中安排课程,可继续阅读本站的 Environment Evolution 论文笔记。


SETA 论文笔记:把终端环境当作需要验证的奖励程序
https://kissshhot.github.io/2026/09/18/seta-scaling-environments-terminal-agents/
作者
丁一帆
发布于
2026年9月18日
许可协议

点赞与评论

喜欢这篇文章?点个赞,或留下你的想法。登录 GitHub 后即可参与。

如果评论无法加载,请检查网络连接后刷新页面。