OpenAI 的 Codex as a platform 文章把 Codex CLI 的可复用部分称为 open agent harness。这里的重点不是把 CLI 换个名字,而是把一整套 Agent 工程能力从产品 UI 中拆出来:线程、turn、事件、工具、审批、沙箱、MCP 和 SDK。
本文以 openai/codex rust-v0.156.1 和当前主线为参照。仓库公开的是本地 runtime、app-server、协议和 SDK;桌面应用、托管模型服务和云端产品不等于开源仓库本身。
01 Harness 的平台边界
传统集成是:
应用 -> 模型 API -> 自己实现 prompt、tool loop、审批、状态和恢复
Codex Harness 则把中间层抽出来:
宿主应用
-> app-server / SDK
-> Thread / Turn / Item
-> Agent Loop + context
-> shell / patch / MCP / dynamic tool
-> approval + sandbox + environment
-> JSON-RPC events
宿主仍负责产品 UI、业务状态、业务工具和用户身份,Harness 负责受治理的 Agent 执行。
02 Thread、Turn、Item:三层状态模型
Thread 是可恢复的对话和工作空间上下文;Turn 是一次模型执行;Item 是事件级事实,例如用户消息、assistant 文本、tool call、tool result、审批请求和计划更新。
这三层分开后,宿主可以订阅一个 turn 的流,也可以恢复整个 thread;工具结果不会被误当作 UI 文本,审批请求可以暂停 turn 而不丢失 thread。
一次执行可以写成:
thread
-> start turn
-> stream item
-> tool / approval / sandbox
-> more item
-> turn result
-> thread remains resumable
03 app-server:双向 JSON-RPC 是产品接缝
app-server 不只是把 CLI 包成 HTTP。它需要处理初始化、能力协商、请求/通知区分、双向消息、流事件、背压、取消和连接关闭。
宿主可以发送 thread/start、turn/start、approval response 等请求,server 则持续发出 item/started、item/updated、tool events、turn/completed 等通知。双向协议很重要,因为 Agent 可能在一次请求之后很久才需要用户批准或输入。
背压也不能被忽略。宿主 UI 变慢时,事件是排队、丢弃、合并还是阻塞执行,都会影响状态一致性。协议必须定义可重放或可恢复的边界。
04 一次请求的执行链路
一次 turn 大致经过:宿主创建或恢复 Thread,发送用户输入,Core session 组装 prompt、历史、工具和环境,模型流产生文本或 tool call,policy 判断是否需要审批,sandbox 执行,工具结果写回 transcript,并最终完成、暂停、失败或取消。
真正可复用的是模型调用和副作用执行之间的边界,让宿主可以接管审批和产品体验。
05 工具、审批和沙箱
Codex 的工具执行至少有三层:
tool schema -> approval policy -> execution environment
schema 负责参数形状,approval policy 负责用户或组织是否同意,environment 负责文件、命令、网络和进程边界。三者不能互相替代。
审批请求必须是协议事实,不能只显示在 CLI 上。宿主应用可能要把它渲染成按钮、企业策略或自动批准规则;用户决定也需要回写 server,保证 turn 可以继续或终止。
06 MCP 与业务工具
MCP 使 Codex Harness 可以发现和调用外部工具、资源和 prompt。宿主需要负责 server 配置、认证、连接生命周期、工具过滤和结果大小。
外部工具不能因为被发现就自动可信。推荐把 MCP server 看成独立供应链:记录来源、版本、能力、请求参数和返回值,并在每次调用前重新应用 workspace 与 policy 约束。
07 持久化:Rollout、Thread History 与 Compaction
Codex 需要同时保存完整 rollout 和面向当前执行的 thread history。完整事件用于审计、resume 和 debugging,压缩后的 context 用于控制 token 成本。
compaction 不应改变已经发生的事实,只改变下一次模型看到的投影。fork 和 rollback 也应生成新的线程或分支,而不是静默覆盖历史。
08 Multi-Agent、Goal、Plan 与 Skills
多 Agent 的核心不是多开几个模型,而是把父 Thread、子 Thread、任务边界、工具权限和结果回传联系起来。子 Agent 应拥有独立 session 和预算,父 Agent 只消费明确的结果或证据。
Goal、Plan、Skills 和 Plugins 位于不同层:Goal 管长期目标,Plan 管当前任务拆解,Skill 管可复用方法,Plugin 管能力和生命周期。把它们都写成 prompt,会失去状态、版本和权限边界。
09 SDK 与 app-server:三种集成层
| 方式 | 适合场景 | 宿主责任 |
|---|---|---|
| exec | 一次性任务函数 | 进程、输出和错误 |
| SDK | 程序化运行 Agent | thread、事件和产品状态 |
| app-server | Agent 是产品的一部分 | 双向协议、审批、UI 和多会话 |
Python SDK 和 TypeScript/CLI 生态共享同一协议语义,但版本必须锁定。SDK 不是远程模型 API,它依赖兼容的本地 runtime 和 app-server。
10 与 DeepSeek Harness 和 Pi Agent 对比
| 维度 | Codex Harness | DeepSeek Harness | Pi Agent |
|---|---|---|---|
| 中心抽象 | app-server 协议与 Thread/Turn/Item | Cordis 插件与 Profile | Agent Core 与 Extension |
| 组合方式 | SDK、MCP、宿主工具 | Bundle、Patch、Preset | package、extension、harness |
| 状态 | rollout、thread history、turn | durable event、projection、team task | session tree、repository、operation |
| 安全 | approval policy + sandbox | plugin/config ownership + runtime | 宿主定义 execution policy |
| 产品定位 | 可嵌入 Agent backend | 可组装 Agent 产品 runtime | 极简可编程底座 |
Codex 的平台接缝最清晰,DeepSeek Harness 的插件组合更深入,Pi 的核心最小且更偏用户定制。选型取决于你希望平台替你承担多少治理。
11 宿主集成的三个原则
第一,先做只读或低权限工具,确认事件、恢复和审批语义,再开放写文件和命令。第二,锁定 CLI、app-server、SDK 版本和 schema,不要依赖浮动的 experimental protocol。第三,把审批、取消、连接断开和进程退出当成正常状态,而不是异常分支。
12 最后的判断
Codex Harness 的价值是把 Agent 工程从“应用团队各写一遍”变成一个协议化运行时:Thread 保存工作,Turn 推进执行,Item 传递事实,Policy 控制副作用,Environment 提供边界,宿主决定产品体验。