Codex Goal 的技术原理分析

当前分析基于 2026 年 5 月 9 日 OpenAI Cookbook、当前 OpenAI Codex 文档/开源仓库,以及 2026 年 5–6 月 OpenAI Codex 官方 GitHub issues 的材料.

Codex/goal不是“给 agent 一个更长 prompt”,而是一个 thread-scoped completion contract:把一个长程任务绑定到当前线程,持久保存目标、预算、进度和状态,然后在安全边界上自动续跑,直到有证据证明完成、被暂停/清除、遇到阻塞或触达预算限制。对 Rudder 来说,最重要的判断是:不要把 Codex Goal 等同于 Rudder 当前的组织/项目 Goal;应该把它抽象成 issue/run 级的 Execution Objective,也就是一次 agent run loop 的可验证完成契约。

Rudder 自己的产品本体已经把Goal -> Issue -> Agent run -> Review -> Feedback -> Learning -> Better future runs定义为 agent work 复利循环,并强调 goals 解释为什么做、issues 让工作 durable、reviews/approvals 保持自治可治理、feedback/run history/skills 保存学习结果。 Codex/goal正好补的是其中更低一层:当某个 issue 已经进入执行阶段,agent 如何围绕一个明确完成条件持续推进,而不是每轮 prompt 完就停。

1. Codex Goal 的产品定义

OpenAI 官方 Cookbook 对 Goals 的定义很清楚:Goal 是 Codex 里的“persistent objective”,让一个 thread 在多轮之间持续朝着定义好的 outcome 工作;它不是无边界后台自治,而是一个 scoped、user-controlled 的 completion contract。用户需要给它 completion conditions,Codex 会在当前线程里持续对照这些条件推进。(OpenAI Developers)

它适合的不是一次性编辑,而是“比一个 prompt 大、但比开放式 backlog 小”的任务。OpenAI 文档给的典型场景包括 performance optimization、flaky test investigation、dependency migration、bug hunt、多步 refactor、benchmark-driven tuning、research task、deployment retry loop、实验循环等。(OpenAI Developers)

用户界面层非常轻:/goal <objective>设置目标,/goal查看状态,/goal pause暂停,/goal resume恢复,/goal clear清除;Goals 功能还需要通过 feature flag 启用,例如配置[features] goals = true或运行codex features enable goals。(OpenAI Developers)

OpenAI 对 good goal 的写法要求也很明确:要包括 outcome、verification surface、constraints、boundaries、iteration policy、blocked stop condition。也就是说,一个好 goal 不是“帮我优化一下”,而是“把 X 指标提高到 Y,用 Z 命令验证,不改 A/B,最多改这些文件,连续若干轮无进展就停下来报告阻塞”。(OpenAI Developers)

2. 核心机制:从 prompt 变成 completion contract

普通 Codex prompt 的模型是:

ask -> work -> result -> wait

Goal 模式变成:

objective -> work -> check evidence -> continue / complete / stop

OpenAI 文档强调,Goal 激活后,Codex 可以 inspect code、run relevant commands、make changes、test result,并持续执行,直到出现停止条件:成功、用户 pause/clear、中断、budget limit、blocker 等。(OpenAI Developers)

这里的关键不是“自动循环”,而是三件事叠在一起:

第一,目标持久化。Goal 被保存为 thread state,而不是只存在于 transcript 或系统 prompt 里。官方说明把它描述为 persisted thread state,不是 global memory,也不是 project instructions;它记录 objective、lifecycle、budget、progress accounting。(OpenAI Developers)

第二,续跑是事件驱动的。Codex 不是无限 while loop,而是在 safe boundaries 续跑:thread idle、goal active、budget 允许、没有用户中断、没有阻塞时才继续。OpenAI 文档也提到,plan-only 不触发 continuation,中断会暂停,resume 可以恢复,无 tool-call continuation 会抑制下一次自动续跑。(OpenAI Developers)

第三,完成必须基于 evidence audit。Codex continuation prompt 要求模型在判断完成前,重新把 objective 拆成 deliverables/success criteria,建立 checklist,检查文件、命令输出、测试结果、PR 状态、manifest/verifier/test suite 等证据;不能接受 proxy signal,不能把“差不多完成”当完成,不确定就视为未完成。只有 audit 显示 objective 已达成且没有 required work remaining,才调用update_goal标记 complete。(GitHub)

这就是 Codex Goal 最值得学的地方:它把“我觉得做完了”改造成“我能用具体证据证明完成了”。

3. 技术架构拆解

从公开源码和文档看,Codex Goal 至少有五层:state store、slash command/API、model tools、runtime continuation、prompt-level audit。

第一层是持久状态。官方源码里的GoalService提供get_thread_goalset_thread_goalclear_thread_goal,并且在 prepare/write window 期间持有 permit,避免 idle continuation 从 stale goal 启动。set 可以更新已有 goal,或者替换/插入 goal;clear 会删除 goal。(GitHub)

从官方 issue 暴露的 SQLite schema 看,Goal 的核心表大致是:

thread_goals( thread_id TEXT PRIMARY KEY, goal_id TEXT, objective TEXT, status TEXT CHECK ( status IN ( 'active', 'paused', 'blocked', 'usage_limited', 'budget_limited', 'complete' ) ), token_budget INTEGER, tokens_used INTEGER DEFAULT 0, time_used_seconds INTEGER DEFAULT 0, created_at_ms INTEGER, updated_at_ms INTEGER )

这个 schema 说明 Codex 采用的是one active goal per thread的设计,而不是一个 thread 里管理多个并行目标。(GitHub)

第二层是用户命令。/goal <objective>写入或替换当前线程 goal,/goal查询,pause/resume/clear由用户控制。官方 CLI 文档还提到 objective 必须非空,最多 4,000 字符;更长的说明应该写入文件,再让 goal 指向这个文件。(OpenAI Developers)

第三层是模型工具。官方源码里可以看到get_goalcreate_goalupdate_goal工具定义。get_goal返回当前 goal 状态、budget、token usage、elapsed/remaining 等;create_goal需要 objective,并且只有在用户/系统/开发者明确要求时才允许创建,不应该从普通任务中自行推断;update_goal允许模型把 goal 标记为completeblocked,但不能让模型自己 pause/resume/clear/budget-limit。(GitHub)

这体现了一个很重要的 authority boundary:模型可以证明完成或报告阻塞,但 pause/resume/clear/budget-limit 属于用户或系统控制面。blocked也不是随便用;源码说明要求同一个 blocker 至少连续出现在多个 goal turns 中,才可以标记为 blocked。(GitHub)

第四层是 runtime continuation。官方源码里的GoalRuntimeHandle会在外部 goal mutation 后更新当前/idle goal 状态,注入 objective update steering;如果线程 idle 且 goal active,则可以调用try_start_turn_if_idle继续执行。它会检查 goal tools 是否可见、thread 是否 live、goal status 是否 Active。(GitHub)

第五层是预算和会计。Goal runtime 会记录 turn、wall clock、token usage,并序列化 progress accounting。预算耗尽时,budget limit prompt 明确要求模型不要开始新的 substantive work,只总结有用进展、剩余工作、阻塞和下一步;除非实际上完成,否则不能调用update_goal标记 complete。(GitHub)

4. 状态机

可以把 Codex Goal 抽象成这个状态机:

none └─ /goal <objective> -> active active ├─ evidence audit passed -> complete ├─ repeated blocker -> blocked ├─ token budget reached -> budget_limited ├─ usage limit reached -> usage_limited ├─ user /goal pause or interruption -> paused └─ user /goal clear -> none paused ├─ user /goal resume -> active └─ user /goal clear -> none complete / blocked / budget_limited / usage_limited └─ user clear or new explicit goal flow -> none / active

公开文档重点描述的是 active、paused、complete、budget-limited 这些用户可理解状态;源码和官方 issues 显示实际实现还覆盖 blocked、usage_limited 等状态。(OpenAI Developers)

这个状态机的产品含义很强:Codex Goal 的完成不是 chat 文本,而是状态转移;状态转移又必须由明确权限触发。用户控制方向,系统控制资源边界,模型控制“我是否有证据证明完成/是否被阻塞”。

5. prompt 设计里的关键安全点

Codex continuation prompt 有一个非常值得 Rudder 学的细节:objective 被放在<untrusted_objective>中,明确说明它是 user-provided data,是任务内容,不是更高优先级指令。(GitHub)

这解决的是 prompt injection 和 authority confusion:用户的 goal 可以要求“完成某项任务”,但不能通过 objective 改写系统层规则、工具权限或安全约束。

Completion audit prompt 也非常硬:它要求模型把 objective 拆成 checklist,并用 concrete evidence 逐条核对;不能接受“测试通过”这种 proxy signal,除非测试本身覆盖了 objective;不能因为预算快没了、工作接近完成、或者 stopping 而标记 complete。(GitHub)

这实际上把 Codex Goal 的 prompt 设计分成两类:

Continuation prompt: 继续朝 active goal 工作,但先尊重预算、状态、工具权限和 objective untrusted 边界。 Completion audit prompt: 在宣称完成前,把目标转成 checklist,用证据逐项验证。

这比普通“你是一个认真负责的 agent,请完成任务”强得多,因为它把完成判断变成一个 protocol。

6. Codex Goal 已暴露的工程风险

Codex Goal 设计很好,但公开 issues 也暴露出几个实现上必须警惕的问题。

第一,goal state 和 UI/state machine 容易不同步。有 issue 反馈 backend 已经 complete,但 UI goal chip 仍显示 active。对 Rudder 来说,这说明 goal status 必须有单一 source of truth,UI 只能订阅状态事件,不能自己推断。(GitHub)

第二,工具可见性和 feature flag 容易错配。有 issue 反馈 goals enabled 但模型工具get_goal/create_goal/update_goal没有暴露,导致 goal stuck。对 Rudder 来说,这意味着 run 启动前必须做 capability handshake:scheduler 认为可以 goal-continuation,不代表 runtime/model tools 真的可用。(GitHub)

第三,DB migration / process schema mismatch 会让 goal runtime 崩掉。有 issue 提到从state_5.sqlite.thread_goals迁移到goals_1.sqlite.thread_goals后,runtime 仍期待旧表,出现 “no such table: thread_goals”。对 Rudder 来说,goal 这种 scheduler-critical state 不能只靠 lazy migration;启动时必须做 schema compatibility check。(GitHub)

第四,pause 语义容易被用户误解。有 issue 反馈用户在 chat 里 STOP 后,active goal 可能仍继续调度,因为真正暂停需要/goal pause状态转移;模型本身没有 pause tool。另一个 issue 也指出 schema/runtime 支持 paused,但 agent tool contract 可能让 agent 误称无法暂停。对 Rudder 来说,停止/暂停必须是显式控制面动作,不能靠自然语言“stop”在 transcript 里被模型自行理解。(GitHub)

第五,compaction 会丢失 goal 语义或 audit 要求。有 issue 描述中途压缩后,新 agent 没有正确继承 active goal,导致缺少 completion audit、过早标记 complete。对 Rudder 来说,目标状态不能只存在 prompt/transcript summary 里;必须作为 run context snapshot 的结构化输入重新注入。(GitHub)

这些风险说明:Codex Goal 的难点不是/goal命令本身,而是状态持久化、工具契约、调度器、UI、预算、上下文压缩之间的一致性