/ By 煎鱼 / #agent #Codex #workflow #Cookbook解读 / Markdown

Cookbook解读|Codex Goal 如何把“继续”变成完成协议

从 OpenAI Cookbook 的 Codex Goals 出发,拆解持久目标、证据审计与自动续跑怎样组成完成协议,并对比 Claude Code 的独立判定循环。

用 Coding Agent 做一个稍长的任务,很容易出现这种对话:

Agent:主体功能已经完成。
你:测试跑了吗?
Agent:还有两个失败。
你:继续。
Agent:修好了一个。
你:继续。

问题不一定是 Agent 不会修,而是谁都没有事先说清楚:什么时候才算真的做完?

OpenAI Cookbook 的 Using Goals in Codex 正在解决这件事。它给 Codex 增加的不是一句自动重复的“继续”,而是一份持续存在的完成协议:目标是什么,用什么证据验收,哪些东西不能破坏,没达标时怎样继续,什么时候应该承认阻塞。

先说结论:

Goal 不是更长的 Prompt,也不是放开权限让 Agent 一直跑。它把“完成条件”保存为任务状态,让 Codex 在每轮结束后检查真实证据,再决定继续、完成或停在明确的边界上。

把 Claude Code 的 /goal 放到旁边会更容易看清这个设计。两者都想消灭人工催促,却把“谁来判定完成”放在了不同位置:Codex 由工作的 Agent 审计文件、测试和产物;Claude 则让另一个小模型根据对话记录做 Yes/No 判定。前者能接触更完整的现场,后者把执行者和裁判分开,但裁判看不到工作区。

数据快照

  • 最后核验:2026-08-03
  • 主要对象:OpenAI Cookbook 的 Using Goals in Codex,以及 Anthropic 的 Claude Code /goal 文档
  • Codex Cookbook 标注的最低版本:Codex 0.128.0
  • 本文比较公开的控制机制,不提供两种 Goal 的成功率、成本或质量排名

#Goal 解决的不是“做什么”,而是“何时停止”

普通 Prompt 描述下一步动作:修复测试、解释报错、修改一个组件。Agent 完成本轮后就把控制权还给用户。Goal 描述的则是一个需要持续成立的终态:

/goal 将 checkout benchmark 的 p95 延迟降到 120 ms 以下,
同时保持 correctness suite 全部通过

只把延迟从 180 ms 降到 135 ms,不算完成;延迟达到 110 ms 但正确性测试失败,也不算完成。下一步到底是继续分析热点、撤销错误优化,还是重新跑基准,要由刚得到的证据决定。

Cookbook 因此把两种交互概括成两条不同的路径:Prompt 是“提问、工作、返回结果、等待”,Goal 则是“工作、检查、继续或完成”。

这里多出来的不是一个步骤,而是一条控制回边。目标仍然有效,Agent 就不该因为一轮回复写完了而默认任务结束。

图 1:Codex Goal 把持久目标、证据审计和续跑条件组成闭环;权限与预算仍然限制每一轮能够做什么

flowchart LR
  A["用户定义 Goal<br/>终态、证据、约束"] --> B["Codex 工作一轮"]
  B --> C["检查文件、测试<br/>日志、Benchmark、产物"]
  C --> D{"完成条件成立?"}
  D -->|"是"| E["标记完成"]
  D -->|"否,仍有可行路径"| F["选择下一步"]
  F --> B
  D -->|"预算耗尽或需要输入"| G["停止并报告边界"]

这张图有两个容易忽略的地方。第一,Goal 不替 Codex 选择固定步骤,它只固定完成标准;第二,循环不是无条件自转。Cookbook 明确说明,续跑只会发生在当前轮结束、任务空闲、没有排队的用户输入,而且 Goal 仍处于活动状态并在预算内的时候。没有工具调用的续跑还会被抑制,避免 Agent 只用语言反复说“我会继续”。

所以,Goal 更像恒温器,而不是定时电风扇。它关心的是温度有没有到 24℃,不是每隔五分钟机械地转一圈。

#一份可执行的 Goal 至少要回答六个问题

“把项目做好”当然是目标,可惜不是一个能验收的 Goal。Cookbook 把强 Goal 拆成六部分:结果、验证面、约束、边界、迭代策略和阻塞出口。

表 1:根据 OpenAI Cookbook 整理的 Goal 完成协议;示例是说明性写法,不代表命令已经在本文运行

要素要回答的问题认证模块迁移示例
结果最终必须有什么变化所有旧 API 调用完成迁移
验证面什么证据能够证明它python scripts/verify_auth.py 输出 AUTH_GOAL: PASS
约束达标时不能牺牲什么测试通过,公共 API 行为不变
边界可以改哪里、使用什么只修改 src/auth/ 与对应文档
迭代策略每轮怎样选择下一步记录失败原因,只处理当前最高影响问题
阻塞出口何时不该继续消耗资源验证器不可运行或没有合法路径时报告 blocker

按这六项组合,一个更完整的 Goal 可以写成:

/goal 完成 auth 模块的新 API 迁移,由
`python scripts/verify_auth.py` 退出码为 0 且输出
`AUTH_GOAL: PASS` 验证,同时保持现有测试和公共 API 行为不变。
只修改 `src/auth/` 与对应文档。每轮记录验证结果、失败原因和
下一项最小修改。如果验证器无法运行,或在上述边界内没有可行路径,
停止并报告已尝试方案、剩余问题和解除阻塞所需的输入。

这个写法没有规定 Agent 先改哪个函数,却把“怎样才算完成”锁住了。它既给探索留空间,也避免 Agent 用“主要功能已经完成”绕过失败的验收项。

多个条件最好继续收敛到一个不可随意修改的验证器。与其让模型从测试、覆盖率、Git Diff 和旧调用搜索的长输出里自行拼结论,不如让脚本统一给出:

tests: PASS
old_api_calls: PASS
public_api: PASS
protected_files: PASS
AUTH_GOAL: PASS

Goal 负责读取结果并控制是否续跑,验证器负责把真实状态压成清晰信号。两者放在一起,才更接近工程上的验收,而不是一次措辞更坚定的自我评价。

#Codex 把 Goal 保存在哪里,决定了它能做什么

Cookbook 将 Codex Goal 定义为持久化的 thread-scoped state,也就是属于当前任务的状态。它不是全局记忆,不会自动变成整个项目的长期规则,也不等同于 AGENTS.md

这份状态记录目标、生命周期、预算和进度信息。目标活动时,Codex 可以继续读取文件、运行命令、检查 Diff、查看测试与生成产物,再用这些证据审计是否完成。用户仍然可以用 /goal pause/goal resume/goal clear 控制生命周期;到达预算上限只表示应该停止实质工作并汇报进度,不表示目标已经完成。

这个边界很实用:

  • AGENTS.md 负责“这个仓库长期应该怎样工作”;
  • Skill 或工作流负责“这一类任务通常怎样做”;
  • Goal 负责“当前任务满足什么证据才可以停”;
  • 权限与沙箱负责“哪些动作允许执行”。

它们不是四种写法不同的 Prompt。操作手册不能代替验收标准,验收标准也不会自动授予删除文件、访问网络或部署生产环境的权限。

#Claude Code 也有 /goal,但裁判坐在另一间房里

Anthropic 的 Claude Code /goal 文档 描述了另一种闭环。每轮 Claude 工作结束后,一个默认使用小型快速模型的独立 evaluator 会读取 Goal 条件和当前对话,回答 Yes 或 No。回答 No 时,理由进入下一轮;回答 Yes 时,Goal 清除并记录为已达成。

这相当于把修车师傅和质检员分开。好处是执行模型不能只凭自己一句“已经完成”直接放行。限制是质检员隔着玻璃,只能看维修记录,不能自己打开引擎盖。

Claude 的 evaluator 不会运行命令,也不会读取文件。它只能看到工作 Agent 已经展示到 transcript 里的证据。因此,同一个验收条件在两边有不同的可靠写法:

不够稳:
/goal 所有认证测试通过
更容易判定:
/goal `pytest tests/auth -q` 退出码为 0,
并且完整汇总行与 `AUTH_GOAL: PASS` 已出现在当前对话中

表 2:截至 2026-08-03 的公开机制对比;比较的是证据与控制位置,不是质量排名

维度Codex GoalClaude Code /goal
目标范围当前任务的持久状态当前会话的 Goal
完成判定工作 Agent 根据证据进行完成审计独立小模型回答 Yes/No
判定时能否使用工具工作 Agent 可以检查文件、测试与产物Evaluator 不能调用工具
主要证据当前工作区与任务中的实际证据已经出现在对话中的证据
生命周期控制查看、暂停、恢复、清除,并记录预算状态设置、查看、清除;恢复会话时可恢复活动 Goal
主要风险做事者同时参与自我验收裁判可能被不完整 transcript 误导

这不是“能用工具一定更好”或“独立裁判一定更客观”的单选题。Codex 的证据面更宽,却仍需防止自我确认;Claude 分离了执行与判定,却可能因为关键测试结果没有进入对话而缺证。两种机制分别减少了一类错误,也分别留下了另一类错误。

更稳健的组合仍然是:执行 Agent 访问真实环境,不可随意修改的验证器给出硬信号,独立 Judge 处理文档质量、需求覆盖等语义问题,隐藏或组合测试防止只对公开指标投机。

#Goal 最危险的失败不是停不下来,而是错误地停下来

Goal 让 Agent 多跑几轮,并不会自动让结果更真实。只要完成条件是一个有漏洞的代理指标,Agent 就可能非常努力地满足指标,同时偏离原始意图。

例如:

/goal 让所有公开测试通过

这句话没有保护测试文件,没有要求实现真实规格,也没有检查未公开输入。最短路径可能是修改测试、为固定样本写特殊分支,或者绕开真正应该实现的模块。循环越勤奋,错误方向反而可能走得越远。

因此,完成协议还需要保护自己的尺子:

  • 验证器、测试和阈值不能由工作 Agent 随意降低;
  • 除了显式测试,还要检查组合行为与隐藏样本;
  • 主观质量交给独立 Review,而不是伪装成布尔条件;
  • 长任务设置预算与阻塞出口,避免无意义重试;
  • 研究任务把“确认、近似、代理证据、阻塞、未知”分开记录。

Cookbook 的 Deep Hedging 案例正好说明最后一点。Codex 能重建定价和对冲机制、训练替代策略并生成多个结果,但原始随机种子、训练路径、Optimizer State 和 Checkpoint 并不完整。因此,最诚实的终态是“部分、近似复现”,而不是把一张相似图表写成“精确复现”。Goal 的价值不只是推动 Agent 继续做,也包括规定它何时必须承认证据到此为止。

#什么时候该用 Goal,什么时候只要一句 Prompt

Goal 适合终点明确、路径不确定的中长任务:性能调优、间歇性测试排查、依赖迁移、多步重构、Benchmark 驱动优化,以及需要交付证据清单的研究。

下面这些任务通常不需要 Goal:

  • 改一处文案或一行配置;
  • 解释一个错误信息;
  • 做一次短 Code Review;
  • 只需要一个答案,然后希望 Agent 停下来;
  • “让架构更优雅”这类还没有验收面的模糊目标。

判断方法其实很简单:如果你已经能预见自己接下来会反复输入“继续、再检查一下、还没满足这个条件”,就值得先把这些话写成 Goal;如果一轮完成后本来就需要你做产品判断,自动续跑反而会抢走必要的决策点。

#总结

Using Goals in Codex 最值得带走的不是 /goal 这条命令,而是一个很朴素的工程判断:长任务缺的通常不是更大的 Prompt,而是持久、可验证的停止条件。

Codex 把 Goal 放进当前任务的持久状态,让工作的 Agent 可以围绕真实文件、测试、日志、Benchmark 和产物持续审计;Claude Code 把 /goal 做成带独立 evaluator 的 Stop Hook,让另一个模型根据对话证据决定是否继续。前者强调证据能力,后者强调判定分离。

无论使用哪一种,都不要只写“做到最好”。先回答四个问题:最终状态是什么,哪个验证器能够证明,哪些约束不能被破坏,失败到什么程度应该停下来报告。然后再决定是否需要独立 Judge、隐藏测试和预算熔断。

Goal 真正改变的不是 Agent 能工作多久,而是谁有资格说“已经完成”,以及这句话后面到底有没有证据。

#参考资料

Share this post

Diagram
100%