Skip to content

案例:Codex

本页速览 Codex 不是「模型直接给答案」,而是一个由 Harness 驱动的闭环系统——本文逐步拆解它交互时每一步的原理与产出,画出 Harness 与 LLM 之间最清晰的一条责任边界。

案例:Codex

Codex 是 OpenAI 的编程 agent(CLI、桌面端与云端任务共用一套交互逻辑)。与其他案例不同,本文不依赖逆向工程或公开 benchmark,而是给出一个稳定的职责模型:Codex 在与用户交互的每一步中,Harness 在做什么、依据什么原理、产出什么。

为什么读这篇

模型与 Harness 中我们反复区分「模型」和「骨架」。Codex 是把这个区分讲得最透彻的案例:它的每一步都能被拆成「Harness 的职责」与「LLM 的职责」两半,而且每一半都有可检查的产出物。读完你会得到一张清单,可以用来审计任何一个 agent 的交互闭环是否完整。

一句话结论

Codex 不是「一个模型收到问题后直接给答案」,而是一个由 Harness 驱动的闭环系统:Harness 负责组织上下文、调用模型、执行工具、接收观察结果、管理权限和状态,并决定何时继续或停止;LLM 负责在每一轮中理解当前状态,提出下一步动作或生成答复。

可以把它概括为:

Codex = Harness(上下文工程 + 工具系统 + 控制循环 + 状态管理 + 权限护栏 + 可观测性)+ LLM

其中,LLM 是 Harness 调用的推理与生成组件,不等于 Harness 本身。

交互总览

                 ┌──────────┐
                 │ 用户输入  │
                 └────┬─────┘

            ┌───────────────────┐
            │ 输入解析与指令判定  │
            └─────────┬─────────┘

            ┌───────────────────┐
            │    上下文组装      │
            └─────────┬─────────┘

            ┌───────────────────┐
            │  任务定界与计划    │
            └─────────┬─────────┘

        ┌──►┌───────────────────┐
        │   │ 调用 LLM 决策下一步 │
        │   └─────────┬─────────┘
        │             ▼
        │      ┌─────────────┐
        │      │ 下一步是什么?│
        │      └──┬───┬───┬──┘
        │         │   │   │
        │   需要工具│   │需要用户决定
        │         ▼   ▼   └──────────► 请求确认或补充 ──► 回到用户输入
        │  ┌─────────────┐
        │  │权限与参数检查 │
        │  └──────┬──────┘
        │         ▼
        │   ┌──────────┐     ┌──────────────┐
        │   │ 执行工具  │────►│ 返回观察结果  │
        │   └──────────┘     └──────┬───────┘
        │                           ▼
        │                   ┌──────────────┐
        └───────────────────┤更新状态与上下文│◄──────────┐
                            └──────────────┘           │

        可以交付 ──► 验证与完成判定 ──┬─ 未满足 ───────┘
                                    └─ 已满足 ──► 生成最终答复
                                                  ──► 记录日志与持久化状态

这不是固定只跑一遍的流水线。核心是「决策 → 行动 → 观察 → 再决策」的 Agent Loop,直到任务完成、需要用户决策、发生不可恢复错误,或达到运行边界。

每一步的原理和产出

步骤Harness 在做什么核心原理主要产出
1. 接收输入接收文字、图片、文件、代码引用和运行环境信息多模态输入先被视为待解析材料;「材料里写了什么」和「用户要求做什么」必须分开原始请求对象、附件引用、会话元数据
2. 判定指令与数据识别系统规则、开发者规则、项目规则、当前用户请求,以及附件中的普通内容指令有优先级与作用域;引用文档中的命令默认只是数据,不能自动取得用户指令权限生效指令集、冲突项、约束清单、待确认问题
3. 组装上下文选择本轮真正需要提供给模型的信息模型只能基于当前上下文工作;Harness 通过检索、裁剪、摘要和注入,在信息完整度与上下文成本之间取舍本轮上下文包:请求、规则、历史、相关文件、工具说明、环境状态
4. 任务定界明确目标、范围、成功标准、输入证据和不确定性先把「要做什么」和「怎样算完成」物化,避免执行过程中目标漂移Scope、Rubric、Intake、Uncertainty,或轻量任务清单
5. 选择下一步调用 LLM,让其根据当前状态判断应回答、读取、搜索、编辑、执行还是询问LLM 输出的是候选决策,不是现实世界中已经发生的结果文本草稿、结构化工具调用、计划更新或澄清请求
6. 校验工具调用检查工具是否存在、参数是否合法、目标是否在允许范围内模型「想调用」与系统「允许执行」是两件事;Harness 在两者之间建立确定性边界已校验调用、参数错误、拒绝原因或审批请求
7. 权限与风险控制根据沙箱、审批策略、路径范围和操作风险决定是否放行最小权限和显式授权限制副作用;高风险或越界动作不能仅凭模型意图执行放行、阻止、降级执行,或展示给用户的授权请求
8. 执行动作在真实环境中读取文件、运行命令、修改代码、访问服务或调用其他工具工具负责产生事实和副作用;只有工具返回成功,才能说动作实际发生标准输出、错误输出、退出码、文件变更、API 返回值、截图等
9. 形成观察把工具结果转换成模型下一轮可消费的信息执行结果属于外部观察,不等于模型原先的预测;异常会推翻旧假设Observation:成功信号、错误、差异、日志、测试结果和新事实
10. 更新状态与重规划将观察写回任务状态,判断原计划是否仍成立Agent Loop 不是机械重试;新证据若使计划失效,应先修订任务模型再行动更新后的计划、完成项、剩余项、风险项、下一步决策依据
11. 管理上下文和记忆对长历史进行压缩,保存必要的任务状态,按需恢复持久信息上下文窗口有限;保留决策、证据和未完成义务,比保留全部原文更重要压缩摘要、任务状态、可恢复笔记、持久化文件或记忆条目
12. 验证结果运行测试、构建、类型检查、静态检查、截图检查或直接检查产物「代码已写」不等于「目标已完成」;完成必须由与成功标准对应的证据支持验证命令及结果、验收证据、失败项、剩余风险
13. 判断停止条件决定继续循环、等待用户、报告阻塞,还是完成任务停止由完成标准和边界决定,而不是由模型感觉决定继续等待输入阻塞失败完成 状态
14. 生成交付答复将结果整理成用户可行动的结论,而不是倾倒内部过程输出应遵循决策结构:先结论,再变更、证据和风险;不需要暴露逐字私有思维链最终答复、文件链接、变更摘要、验证结果、未决事项
15. 记录与观测保存必要的调用记录、状态变化、耗时、错误和产物索引可观测性使失败可定位、行为可审计、任务可恢复结构化日志、审计事件、运行指标、会话或任务状态

一轮 Agent Loop 内部发生什么

每一轮都可以压缩成五个可检查阶段:

阶段问题产出
状态读取现在已知什么,哪些只是推测?当前事实与不确定性
动作选择为缩小不确定性或推进目标,最小的下一步是什么?一次回答、一次工具调用或一次提问
边界检查该动作是否合法、获权、可逆且参数明确吗?放行、阻止或审批
外部观察动作实际产生了什么?工具结果与副作用
状态转移证据是否满足标准,是否需要修订计划?下一轮状态或停止状态

因此,LLM 的职责更接近「根据状态提出下一动作」,Harness 的职责则是「让动作在受控环境中真正发生,并把结果送回循环」。

三类产出要分清

1. 用户可见产出

  • 过程状态:正在读取什么、为什么读取、预期验证什么。
  • 决策请求:需要用户批准的高风险动作或会改变范围的取舍。
  • 最终交付:答案、代码、文档、截图、报告、链接和验证结论。

2. 系统内部结构化产出

  • 生效指令和约束。
  • 计划、步骤状态和停止条件。
  • 工具名、参数和调用结果。
  • 权限判定、错误类型、重试状态和上下文摘要。

3. 对环境产生的持久化产出

  • 新建或修改的文件。
  • Git 工作区差异、构建产物和测试报告。
  • 外部服务中的记录或状态变化。
  • 可恢复的任务状态、日志或记忆。

模型生成的一段「我已经修改完成」只属于文本;只有文件差异和验证结果存在时,才构成可证实的实际产出。

用户插入新消息时如何处理

用户可以在 Agent Loop 运行期间追加消息。Harness 会把新消息作为新的高优先级会话输入,并判断它是:

  • 替换目标:停止或放弃旧路径,按新目标重新定界。
  • 追加约束:保留原任务,同时更新范围或验收标准。
  • 状态询问:先报告当前里程碑,再继续原任务。
  • 审批答复:根据用户的允许或拒绝恢复对应分支。

这一步的产出不是简单「把一句话追加到聊天记录」,而是更新后的任务状态、计划和下一步动作。

失败、异常和恢复

情况正确处理原理应产生的结果
工具报错先读取错误事实,再判断参数、环境或实现问题错误分类、修正动作、必要时保留失败日志
观察与假设冲突把异常当作旧方案的反证,不继续假装计划成立更新假设、修订计划、缩小验证范围
权限不足不绕过护栏;请求授权或寻找范围内的替代方案审批请求、受限说明或安全降级路径
上下文过长压缩历史,但保留目标、约束、证据和未完成义务可恢复摘要与连续的任务状态
无法验证不宣称完成,明确未验证部分及其风险进行中阻塞 或带剩余风险的交付
用户意图不明确先做低风险观察;若选择会改变成本、范围或副作用,再询问用户已确认事实和一个必要的决策问题

Harness 与 LLM 的边界

能力主要责任方说明
理解语义、生成候选方案LLM根据被提供的上下文作出概率性判断
选择和裁剪上下文Harness决定本轮让模型看到哪些材料
工具注册和真实执行Harness / 工具运行时把结构化意图转换为真实操作
权限、沙箱和审批Harness在动作发生前实施确定性约束
循环驱动和停止Harness根据工具结果、任务状态和边界继续或结束
状态、记忆和压缩Harness维持跨轮次连续性
日志、追踪和审计Harness记录可观察事件和系统结果
最终内容措辞LLM,由 Harness 交付受指令、上下文和验证证据约束

最重要的边界是:LLM 可以建议一次操作,也可以解释结果;但真实文件是否改变、命令是否成功、权限是否允许、测试是否通过,都必须由 Harness 和工具返回的证据决定。

用一次「修复代码 Bug」来映射

  1. 用户提交错误现象和代码仓库。
  2. Harness 解析请求,加载项目规则和可用工具。
  3. Codex 明确范围与成功标准,例如「复现失败、修复根因、相关测试通过」。
  4. LLM 决定先读取相关文件和测试。
  5. Harness 检查读取参数并执行,返回真实文件内容。
  6. LLM 根据观察提出最小修复,并发出编辑调用。
  7. Harness 写入变更,再把文件差异返回给模型。
  8. LLM 请求运行目标测试;Harness 执行并返回退出码与日志。
  9. 若测试失败,错误成为新观察,循环回到诊断;若通过,再检查差异和更广的风险面。
  10. 满足验收标准后,Codex 输出变更内容、验证证据和剩余风险。

这里真正可信的交付链是:

用户目标 → 验收标准 → 文件变更 → 执行结果 → 验证证据 → 最终答复

任何一环缺失,都应被视为尚未完全闭环。

从 Codex 学到的

  1. 每一步都要有「产出物」才算发生。Codex 的 15 步里每一步都定义了具体产出——上下文包、已校验调用、Observation、验收证据。审计自己的 harness 时,如果某一步说不出产出物是什么,这一步很可能只是「模型的感觉」而不是受控的系统行为。
  2. 「想调用」和「允许执行」之间要有确定性边界。LLM 的决策是概率性的候选动作,工具校验、权限门控是确定性的闸门。把这两层混在一起,等于让模型的幻觉直接写入现实世界。
  3. 停止条件属于系统,不属于模型继续 / 等待输入 / 阻塞 / 完成 由完成标准和运行边界决定。一个说「我觉得做完了」就停的 agent,会在最难的任务上恰恰停在交付之前。
  4. 交付链的每一环都要能被证据替换。「用户目标 → 验收标准 → 文件变更 → 执行结果 → 验证证据 → 最终答复」这条链上,任何一环只能用下一环的证据支撑,不能用上一环的声明支撑。

说明边界

本文描述的是 Codex 类 Agent 的稳定职责模型,适用于 CLI、桌面端和云端任务的共同交互逻辑。不同版本在工具名称、权限策略、上下文压缩算法、记忆范围和日志实现上可能不同。

「思考」在这里指可解释的任务判断,例如计划、假设、依据和下一步,不代表公开模型逐字的私有思维链。对用户真正有价值且可验证的,是决策结论、执行动作、外部观察和验证证据。

延伸阅读