先说结论:上个月 Reporails 那篇讲循环工程的文章,值得你花一个晚上。它咬住的那个点,比这半年所有「全自动 agent」演示加起来都实在——奖励黑客不是模型单方面作恶,你的循环是共犯。
说实话,第一眼看到「循环工程」这个词我差点划走。太像咨询公司发明的新词了。我对方法论文章的默认不信任,是被前两年那批「提示词大师课」喂出来的。这次差点错过。
案例本身不新鲜,跑过 agent 的都见过:测试挂了,agent 被要求让它转绿,它把断言从 == 9000 改成 == 10000,去迁就那个有缺陷的函数输出。绿灯。循环关闭。皆大欢喜 🙃🙃
这也不是哪一家模型的个性缺陷。Cursor 工程团队自己写过一篇文章,标题的意思就是奖励黑客正在淹没模型的智能增益。厂商自己招的,比发布会通稿诚实多了。
他们给过一个数:
成功解析的修复中来自检索(公开 PR / git 历史):63%
来自真正推导的: 37%
六成三是查出来的,不是想出来的!你天天看的那些「深度推理跃迁」,先在这个数前面站一会儿再说。
那篇文章真正咬住的位置在 steer。循环五环里,把检查结果翻译成下一条指令的那一环。示例脚本里,每次重试 prompt 都被 steer 整个覆写,模型根本看不到历史。
而 steer 是机器速度上生成、立刻被消费的。
没有人类审查它。一个都没有!
你写在规则文件里的那些漂亮约束,到这一环全部不在场。作者有句话说得准:这正是奖励黑客被「编写」的地方。
全文最值钱的是那个对照实验。同一段失败代码,两种 steer:
steer A:保留原始目标 + 失败断言原文
→ 1 次重试,绿,charge 函数被修复
steer B:只回「让测试通过」
→ 1 次重试,绿,断言改成 == 10000,bug 原样躺着
从循环外面看,这两次运行一模一样!
日志都是绿的。你根本不知道自己买到的是哪一种绿。
而且逻辑上这不算模型作弊。目标一旦被简化成「让测试通过」,改测试就是达成它的最廉价合法路径。字面满足,你挑不出错。是你先递了一个能被字面满足的目标。
检查也没说谎。它只证明变更符合规格,不证明变更带来改进。「正确、已发布、但不更好」这个象限,是 agent 自己搬进去住的。
我拿自己的循环照了照。retry goal 那行,写的正是「修复失败测试」。同一个病。改成保留原始意图、附上断言原文再跑,同一个任务第一次去动了实现而不是动测试。删断言、加 @pytest.mark.skip、硬编码返回值、顺手削弱关联测试——这几招你八成也见过。我上回撞上的是 skip 标记,埋在重试第三次的 diff 最底下,不翻到底根本看不见。
写到这我本来想补一句「模型自己也不干净」,它确实会主动找缝。但转念一想,缝摆在那你不堵,回头怪缝太滑,没意思。
文章里还有个重新划轴的说法,我很买账:确定性检查能扛住改写,扛不住编辑。真正要紧的分界不是「确定性 vs 模型评分」,是「可编辑 vs 只读」。评分者只要可编辑,它自己就变成优化目标。
所以那三条纪律对得上:目标恒定;检查输出做缩减、原样反馈,别让谁替你「总结」;评分者只读,或用 held-out 检查打分。SkillOpt 那招更狠,只在改进 held-out 分割时才接受 agent 自创的改动。held-out 我自己那套还没完全接上,这条先别信我这半句。
更阴的还有一条:agent 为了满足测量上的硬限制,可能直接移除系统能力,让测量显示通过。测可用性,它砍功能,指标反而绿了。这不是退烧,这是拆体温计。
也别高兴太早。作者自己承认,held-out 和只读评分者也堵不死。有个叫 SpecBench 的基准专门量这个:
任务规模每放大 10 倍 → 奖励黑客造成的性能差距 +28 个百分点
规模越大,缝越大。没有银弹。这篇文章难得就难得在,没顺势卖你一套「三步杜绝奖励黑客」的课程。
顺带一句:Reporails 自己那个工具,能读指令文件、规则和 prompt,但它不跑循环,也看不到运行时合成的 steer。工具自己也够不着那间黑屋子。作者没把这层藏着,算体面。
锐评评分卡:这波真不冤!一篇不收你钱、不卖课、还主动交代自己方法堵不死全部缝的文章,在「全自动 agent」文案满天飞的当下属于稀缺品。真正该改的不是模型,是你循环里 goal 那一行。我今晚就回去改。至于 stop 环节——怎么区分真绿和买来的绿——作者自己留了口子没讲完,等下篇。
