Signal Desk
返回Codex 教程

官方 Cookbook 与文章案例实验室2 / 2

官方中文知识库 · 09动手教程阅读约 17 分钟 · 实操约 41 分钟

官方长时任务与迭代修复案例:Review–Repair–Validate 闭环

把官方 repair loop 与 long-horizon 文章转译为有状态、有预算、有停止条件的修复系统。

先知道终点

做完你会得到
完成一个最多三轮、每轮都有新证据的自动修复实验
开始前只需要
有确定性测试或检查器;能把实现、review 与验证分开;实验不接触生产数据和不可逆动作
最后留下这些证据
每轮输入状态、finding、修改与验证;重试预算和重复失败停止记录;最终通过或诚实阻塞交接

内容校准于 2026-07-31 · 第 18 / 38 节已发布课程

跟着材料做,不只阅读

本节练习资料

建议先做,再看答案

修到第七轮,问题反而越来越多

第一轮 review 找到真实缺陷。修完以后,第二轮出现新回归。到了第七轮,列表里只剩风格建议,任务却仍然因为「还有发现」拒绝结束。

循环不会天然收敛。每次修复都会创造一个新候选状态。

Review–Repair–Validate 应该是一台有预算、有状态、有出口的机器。 这节课把官方长时案例拆成一张循环账本,重点看什么时候继续,什么时候回退,什么时候接受残余风险。

循环不是“继续,直到成功”

OpenAI Cookbook 的 iterative repair loop 可抽象为 Review、Repair、Validate:

  1. Review 读取当前状态并找具体问题;
  2. Repair 只修确认的问题;
  3. Validate 用独立检查器产生新证据;
  4. 根据证据决定完成、继续或停止。

长时任务文章进一步强调计划、执行、验证、修复和项目记忆。关键不是循环次数,而是每一轮必须缩小已知差距。没有新证据的重复不是进展。

一个闭环需要哪些状态

run-id:
iteration:
输入版本 / commit:
当前失败:
本轮 finding:
允许修改范围:
实际修改:
验证命令与结果:
与上轮差异:
剩余失败:
下一决策:

若缺少输入版本,下一轮可能基于已变化的状态却仍使用旧诊断。若缺少“与上轮差异”,循环可能重复同一修复。

Review:发现必须具体

Review 输出应该能触发:

  • 精确到文件和最小范围;
  • 说明输入条件;
  • 解释错误行为;
  • 指定可证伪的验证。

“代码可能有性能问题”不能直接进入 Repair。先建立可测量场景。Review 阶段默认不改代码,以免 finding 与工作树同时变化。

Repair:一次只修一个确认问题

Repair prompt:

只修复 finding F-02。
允许修改 [文件范围]。
保留 [公共行为与约束]。
不要顺便重构,不更新依赖,不处理其他 findings。
完成后展示最小 diff,并说明每处修改如何对应触发条件。

聚焦修改让下一步验证具有因果意义。如果一轮改十个无关问题,即使测试变绿也不知道真正原因。

Validate:独立于 agent 自述

验证器可以是测试、类型检查、schema、视觉比较、lint、数据对账或真实浏览器脚本。它应:

  • 可重复;
  • 对通过和失败有明确退出或结构化结果;
  • 尽量不依赖本轮 Repair 的自然语言总结;
  • 覆盖原触发条件与相邻回归;
  • 记录环境和输入版本。

“Codex 重新看了一遍,认为已经解决”不算 Validate。

停止条件与预算

在循环开始前定义:

  • 最多轮数或时间预算;
  • 同一失败重复几次后停止;
  • 失败集合不再缩小时停止;
  • 需要新权限、外部服务或产品决定时停止;
  • 变化超出允许文件或破坏基线时回退;
  • 所有目标验证通过且 review 无高优先级 finding 时完成。

示例:

最多三轮。
同一测试连续两轮以相同堆栈失败,停止并交接。
新增依赖、修改公开 schema 或联网均需人工批准。
每轮结束保存 diff、测试 JSON 和状态表。

Harness engineering 给出的环境启示

官方 Harness engineering 文章讨论了为 agent 设计工作环境:仓库要可读、worktree 可启动、验证可执行、浏览器可观察、重复流程可沉淀。修复循环的上限往往不只由模型决定,还由“能否快速启动、能否得到确定反馈、失败是否可恢复”决定。

改善 harness 的例子:

  • 提供一条可靠启动命令;
  • 让测试输出结构化;
  • 用 fixture 固定输入;
  • 为页面变化保存双视口截图;
  • 把项目规则写入 AGENTS.md;
  • 把稳定循环沉淀为 Skill;
  • 把 secrets、网络和生产动作隔离。

三轮实验

选择一个刻意带两个小错误的练习项目。运行最多三轮:

  1. 保存初始失败;
  2. Review 生成 findings;
  3. 人工确认一个 finding;
  4. Repair 最小范围;
  5. Validate;
  6. 更新状态并决定下一轮。

至少模拟一次停止:例如让一个检查器持续以相同错误失败,按规则交接而不是无限修。

失败交接格式

最后安全状态:
已通过验证:
仍失败验证:
重复模式:
已经排除:
需要的新信息或授权:
恢复命令:
未执行动作:

诚实阻塞是闭环的一种正确结果。伪造完成或无限重试才是失败。

完整案例:修复 47 个静态检查发现

一次 review 返回 47 条发现,其中有重复、误报、风格建议和真实缺陷。直接要求“全部修复”会让 repair 阶段扩大 diff,并可能为了消除告警改变行为。

第一轮先分类,不修改

类别处理
可复现缺陷建最小失败测试,进入修复
同根因重复项合并为一个修复单元
缺少上下文补调用链和运行证据
误报记录反证,不修改
风格或偏好与项目规则核对后再决定

Review 的输出是候选问题,不是自动授权的修改清单。

给每个修复窗口一个预算

本轮目标:修复 session 过期后仍返回缓存用户
允许文件:session-cache.ts、对应测试
基线:新增失败测试能稳定复现
停止条件:修复后原测试通过,相关缓存测试不回归
预算:不重构缓存接口,不处理其他 review 项

一次窗口只解决一个根因。这样 validate 失败时能知道是哪项变化造成。

Validate 不只是重跑同一检查器

三层验证:

  1. 原始反例:发现描述的行为不再出现;
  2. 相邻反例:有效 session、并发刷新和缓存失败仍正确;
  3. 独立检查:测试、类型、review 或真实运行从另一角度确认。

若只让同一个检查器从红变绿,可能只是迎合规则而没有修复用户问题。

识别修复振荡

典型振荡:

  • A 修复让 B 检查失败;
  • B 修复又恢复 A 的问题;
  • diff 越来越大,证据没有增加。

此时停止自动循环,比较两条规则的真实目的、优先级和共同约束。可能需要架构决定或人工裁决,而不是更多 repair。

长循环的状态记录

每轮保存:

发现 ID 与原始证据:
分类与优先级:
本轮假设:
修改范围:
验证结果:
新增风险:
剩余发现:
是否继续及理由:

这样任务被中断后可以从证据恢复,而不是重新扫描、重复修复。

什么时候交给人判断

以下情况不适合继续自动 repair:两条规则目标冲突、修复会改变公共契约、没有稳定复现、需要业务决定,或验证环境本身不可信。人工接管不意味着 agent 失败;它是循环设计中的明确出口。交接应包含最小复现、已排除假设、两种选项和各自风险,让人只判断真正不可自动决定的部分。

人工决定后要把结论写回状态记录,并明确哪些旧发现因此关闭、哪些修复窗口需要重新运行。否则下一轮仍会从过期假设开始。

故障诊所

现象原因恢复
发现数下降但 diff 暴涨追指标而非根因回退本轮,按根因重组
同一项反复出现修复未覆盖真实执行路径重建最小复现并追调用链
误报也被强行改代码缺少接受/拒绝标准保存反证并关闭该项
循环永不结束没有预算和停止条件设置轮次、范围与人工接管点

知识检查

Review 剩下两条低优先级风格建议时,Goal 是否必须继续到零发现?不一定。若它们不在验收范围、与项目规则无关或修改风险更高,应记录未处理原因并停止。

先写出口,再启动循环

为你的修复任务写下最大轮次、时间预算、必须清零的风险和允许保留的问题。每轮只对一个明确候选做 review、repair 和 validate。

没有出口的循环不是负责,它只是把停止决策推迟。能解释为什么结束,才算真正控制了长期任务。

完成检查

  • Review、Repair、Validate 三阶段分离
  • 每轮绑定输入版本和新证据
  • Repair 只处理确认 finding
  • 验证器独立、可重复、覆盖触发条件
  • 重试预算和停止条件在开始前定义
  • 最终通过或阻塞都留下可恢复状态

参考与校准来源

本文是官方资料的中文转译与教学重组,不是逐字翻译;产品能力、命令、默认值与安全边界以下列官方原文为准。