← 返回文章选择

打砖块卡在 387 分以后,代码改了哪里

Learning Beyond Gradients 的 Breakout 记录:先打破循环,再让扰动及时收手。

作者记录的 387 分 Breakout 版本挺有意思:球接得住,游戏没结束,分数却不怎么动了。挡板把球送回一条重复路线,剩下的砖一直碰不到。接球已经做得不错,继续只调接球精度,看起来解决不了眼前的问题。

Jiayi Weng 在 Learning Beyond Gradients 里保留了这次迭代。他本来想给 EnvPool 找便宜、可复现的测试策略,让环境走到比随机动作更有信息的状态。编码 Agent 看运行记录、修改策略代码,作者把这个过程叫 Heuristic Learning。下文的实验和录像都来自原作者,我没有复现。

本文为后续修订稿,5 月 6 日仅保留作原归档日期;以下引用固定在英文稿 2026 年 5 月 11 日的提交。该英文文件首次入库为 5 月 8 日,晚于本文归档日期。

先让球换一条路线

原文处理停滞的办法很直接:连续很久没有奖励,就给预测落点加偏移,并让偏移换方向、换幅度,试着打破周期。

这里有快慢两层。接球程序每一步都在执行;修改这些规则的 Agent 在一轮运行之后才看反馈,两者速度和职责都不同。

加入这项处理后,记录里的分数从 387 到了 507,可以对照作者保留的387 分录像和507 分录像。只看两个数字会漏掉修改的理由:前一版活着但停滞,后一版有意改变球路。

扰动要在接球前收手

记录分数 这一步改了什么
387 能接球,但球路陷入重复
507 长时间无奖励时给落点加偏移,打破周期
839 针对高速低球,加入 fast_low_ball_lead_steps=3
864 后半场释放偏移,并补动作与挡板位置间的一步延迟

高速低球的问题在于,普通的落点追踪会让挡板提前过头。到 839 分以后,有些参数尝试没用,最后有效的一处修改在后半场:球离挡板还远时可以扰动,接近时逐渐释放偏移。原文摘出的核心三行是:

if score >= 432 and stuck_release_horizon_steps > 0:
release_ratio = clip(steps_to_paddle / stuck_release_horizon_steps, 0.0, 1.0)
offset *= release_ratio

steps_to_paddle 越小,偏移越小:

  • 预计剩余步数超出释放窗口时,比例取 1,偏移原样保留;
  • 进入窗口后,比例随剩余步数减小,到 0 时比例也为 0;
  • 分数没到 432,或窗口步数不大于 0,这行缩放不参与,偏移按原幅度给。

我喜欢这几行把“差不多该收手了”写成了一个能检查的条件。扰动帮球碰到新砖,到了接球前还继续偏,就会把挡板拉走。加上一步延迟补偿,最终记录到 864 分。代码和各阶段重跑命令都在原文附录。

这几行里的常量在附录 A.2 的参数表里都有名字:432 对应 --brick-balance-bias-min-score 432,释放窗口是 --stuck-release-horizon-steps 8,偏移幅度 --stuck-offset 12,无奖励 1024 步触发、每 256 步切换。一步延迟的补偿量是 --late-game-paddle-lag-px 2,也就是 2 像素。864 是这个游戏的上限,最终的 RAM 默认配置三局都是 864。

试过但没用的

原文没把失败藏起来。中文稿附录 A.1 里,Breakout 上死区、发球偏移、卡住偏移、砖块平衡偏置、前视步数,“很多方向都没用”。别的环境也一样:Ant 上大范围参数搜索打不过当时的节律策略,只好换表示;VizDoom 早期用过地图、object info 和种子特判,后来全删了;Montezuma 的状态图搜索把钥匙距离从 72 推到 28,奖励仍然是 0。

作者在那里写了一句我很认同的话:

低分没有解释力:它不知道是动作语义错了、状态检测错了、评测设置错了,还是策略结构本身不行。

这和 387 分那一版是同一件事。分数只告诉你卡住了,要靠看录像、读记录才知道卡在哪。

作者展示编码 Agent 读取反馈并维护策略软件的过程

配图来自 Jiayi Weng 的原文,版权归原作者,不是本站实验截图。

14,504 步从哪里开始算

后面把控制器从 RAM 状态读取迁到纯图像输入。几何控制、打破循环和后期释放偏移,已经在 RAM 版本里摸索过;图像版本接着替换状态读取层,用 RGB 检测球、挡板等信息。约 14,504 个环境步数对应的是这段局部迁移,不能写成从零发现整套策略的花费。

原文自己也这么说。附录 A.1 记了图像版的两级中间分,先 310 再 428,然后明确写着“不能写成纯图像从零 14.5K 步到满分”,“纯图像的 14.5K 是迁移预算”。另外,图像版把后期释放偏移的分数阈值下调了,让它全程生效。照上面那三行去复现图像版,432 这个门槛要改。

还有一笔账原文没算:附录 A.1 写明编码 Agent 读日志、写代码、看视频的开销没有折算进总计算成本。全文也没有 token、API 费用或墙钟时间。环境步数便宜,不代表整件事便宜。

387、507、839、864 也都是具体中间版本的记录,不是任意种子上的平均成绩。

普通程序出动作,语言模型改代码

慢循环里用了已训练语言模型的知识,所以“执行策略是普通程序”和“整个过程没用神经网络”差得很远。在环境里一步步出动作的是那份普通控制器,每个环境步出一次;语言模型在环境之外读记录、改代码,只在一轮运行结束后动手。

Breakout 之外,它没赢过 PPO

Breakout 只是一条线。附录 A.1 的 Atari57 小节里,作者批量跑了 57 个游戏、两种观测模式、各重复三次,共 342 条无人干预的搜索轨迹。人类归一化分数(HNS)的中位数,9.7M 步时图像输入是 0.81,RAM 是 0.59。

拿来对照的 PPO 基线,在 10M 步时大约是 0.88 和 0.92。原文直说,在 Atlantis、VideoPinball、UpNDown、Assault、RoadRunner、StarGunner 这六个游戏上 PPO 明显强得多。

批量实验的提示词约束得很紧:不训练神经网络,不读环境源码和隐藏状态,不许因为平台期就停,已知最好分只作参照。每次刷新最高分后,还得先简化代码,确认不掉分才保留。原文能留下各阶段代码和重跑命令,是这份提示词逼出来的。

所以 Breakout 的 864 是个漂亮的单点。整体看,编码 Agent 写的程序还在追 PPO,而且有一批游戏追不上。

有人在社交媒体上提过一个更尖锐的看法:如果简单到编码 Agent 就能写出的启发式能解掉一个游戏,说明这个基准本来就是“启发式形状”的,RL 在上面只会找到同一条捷径。照这个说法,这个结果暴露的是基准的问题,推翻不了 RL。我觉得这个质疑和上面六个游戏的对比放在一起看,挺能说明问题。

作者自己划的边界

原文对“下一个范式”的说法是部分解决。作者坦白想不出一个 Agent 用纯 Python、不用神经网络去解 ImageNet;也承认 Heuristic Learning 不自动解决持续学习,只长不压的系统会一直变复杂,直到超过维护能力。英文稿正文这几节都写得很直白。

Montezuma 的 400 分是个现成例子。附录 A.1 和 A.2 说这是一次无人干预跑出来的,回放其实是 86 个宏动作拼成的开环路线,不能当作通用策略。

这个方向后来有人接着做。AAArena 那篇论文以 Learning Beyond Gradients 为出发点,把它扩成对抗式的 Heuristic Learning,在真实竞赛游戏的天梯上和人类程序比。Opus5.5 加 Claude Code 在部分天梯拿了第一,其余的没能拿下,规则越复杂表现越弱。

如果要我挑一个最值得带走的判断:编码 Agent 迭代手写策略,在结构简单、录像能说明问题的环境里很好用;到了需要感知或长程探索的地方,代码的表达能力先撞墙。

原文留下了各阶段代码和重跑命令,可以对照那几行偏移释放,检查球接近挡板时偏移是不是真的减小了。

留下几句话 读者来信

读到这里,有什么想法?欢迎留下你的看法。