Skip to main content

Codex Harness 开源解读:如何读懂 Agent Loop,并以 SDK 与 App Server 构建自己的应用

Rainy
雨落无声,代码成诗 —— 致力于技术与艺术的极致平衡
Rainy
17 MIN READ... VIEWS

开源 Codex Harness:应用、Harness 与执行环境的三层结构

2026 年 8 月 19 日,OpenAI 将 Codex 更清晰地定义为一个可供开发者构建产品的 开放 Agent Harness。这句话容易被误读成“Codex 模型开源了”,实际开放的是模型周围的运行时与集成面:会话、Agent Loop、工具执行、沙箱、审批、事件流、CLI、SDK 与 App Server。

用一句话概括:

模型决定下一步做什么,Harness 决定它能看到什么、可以怎样做、需要谁批准,以及整个过程如何被恢复和观察。

这篇文章会回答三个问题:

  1. openai/codex 到底开放了什么,没开放什么;
  2. 面对庞大的 Rust 工作区,应当怎样学习 Agent Harness 的原理;
  3. 如何选择 codex exec、Codex SDK 或 App Server,构建自己的应用。

一、先划清边界:开源的是 Harness,不是全部 Codex

根据 Codex Open Source 官方页面,当前主要开放组件包括:

组件位置用途
Codex CLIopenai/codex本地 Agent、终端 UI 与非交互执行入口
Codex SDKopenai/codex/sdk在 TypeScript 或 Python 应用中启动、继续和恢复 Codex Thread
Codex App Servercodex-rs/app-server面向富客户端的双向协议、事件与审批接口
Codex MCP ServerCodex CLI 能力将 Codex 作为更大 Agent 系统中的编码专家
Universal Cloud Environmentopenai/codex-universalCodex Cloud 使用的基础环境

主仓库采用 Apache-2.0 许可证。但需要注意:

  • 开源层是 Harness 与集成面;
  • 模型访问和托管服务是独立层;
  • IDE 扩展与 Codex Cloud 本身不在开源组件列表中;
  • 源码开放不等于你的产品自动获得模型、账户或服务权限。

因此,“Fork Codex”与“使用 Codex 模型”是两个不同问题。前者涉及运行时代码,后者仍受模型与服务的可用性、认证和条款约束。


二、Codex Harness 比一个 Prompt 多了什么

普通代码生成调用:

需求 + 代码上下文 → 模型 → 一段回答

Codex Harness 的实际闭环更接近:

任务
→ 建立或恢复 Thread
→ 装配指令、仓库上下文与工具
→ 模型推理
→ 发出命令 / 文件修改 / MCP 调用
→ 沙箱与审批策略判定
→ 执行并回传结果
→ 模型观察结果并继续
→ 流式发出 Items 与最终响应

OpenAI 官方将 Harness 的责任归纳为:管理对话状态、流式执行、使用工具、执行沙箱和审批策略、跨 Turn 延续工作。这里的关键不是“让模型不停循环”,而是让循环具备以下控制面:

  • 状态:知道过去发生了什么;
  • 工具:不只说怎么改,而是能检查、修改和验证;
  • 边界:文件、网络与命令不是默认无限开放;
  • 同意:高影响动作可以停下来请求用户;
  • 事件:UI 与自动化系统能看到进行中的工作;
  • 恢复:一次进程或客户端中断不必丢掉任务语境。

三、先看全景:应用、Harness、执行环境

上面的架构图可以拆成三层。

1. Your App:产品应该保留什么

你的应用仍然负责:

  • 业务界面:工单、仓库、告警、客户记录或任务队列;
  • 用户身份、租户和业务权限;
  • 把当前界面的实体与约束转换成 Agent 上下文;
  • 决定哪些动作必须人工批准;
  • 将最终结果写回业务系统。

最好的 Codex 应用通常不是“另一个通用聊天框”,而是把 Agent 放到用户原本就理解的工作流旁边。

2. Codex Harness:可复用的控制循环

Harness 负责 Thread、Turn、Items、工具调用、流式事件、取消、恢复、沙箱与审批。它是产品与模型、执行环境之间的中间层。

3. Execution:副作用真正发生的地方

执行层包含:

  • 工作区文件与 Git;
  • Shell 命令和后台进程;
  • Apply Patch 等文件变更能力;
  • 本地或远程沙箱;
  • 通过 MCP 暴露的业务数据与动作。

安全问题几乎都发生在这一层,因此应用不能只关注“回答内容是否正确”,还要验证“副作用是否在授权范围内”。


四、如何读 openai/codex:不要从第一行读到最后一行

openai/codex 是一个不断演进的大型工作区。仓库根目录主要有:

codex-rs/ Rust 主实现:核心、CLI、TUI、App Server、协议、沙箱、工具
sdk/ TypeScript、Python SDK 与 Python runtime
codex-cli/ CLI 相关包与兼容层
docs/ 开发和功能文档
tools/ 仓库维护工具

codex-rs/ 下 crate 很多,不应该按字母顺序学习。更有效的办法是围绕一条用户请求,分五层阅读。

第 1 层:入口与表现层

先回答“用户从哪里进入”:

  • cli:命令分发;
  • tui:终端交互界面;
  • exec:非交互任务;
  • app-server:富客户端协议入口;
  • mcp-server:把 Codex 暴露为 MCP 服务。

这层不要深挖渲染细节,只追踪入口怎样把请求转换成核心可理解的配置与输入。

第 2 层:协议与状态词汇

接着理解几个稳定概念:

概念含义
Thread一段可持续、可恢复的 Agent 对话
Turn用户的一次请求以及随后发生的完整 Agent 工作
ItemTurn 中的输入或输出单元,如消息、命令、文件变更、工具调用
EventItem 与 Turn 的增量状态通知
Approval在副作用执行前暂停并等待宿主决定

对应阅读 protocolapp-server-protocolrolloutthread-store 等模块。先理解数据如何流动,再看实现细节。

第 3 层:Agent Loop 与核心状态机

再进入 corecore-api。这一层重点找四条链:

输入如何变成模型请求
模型输出如何被解析为 Item / Tool Call
工具结果如何回到下一轮模型上下文
何种条件让 Turn 完成、失败、中断或继续

不要把 Agent Loop 理解成一个简单 while。真正困难的是:并发事件、取消、超时、审批暂停、上下文压缩、历史持久化和工具部分失败同时存在时,状态仍要一致。

第 4 层:工具与执行边界

然后读:

  • tools:工具定义与分发;
  • shell-command / exec-server:命令执行;
  • apply-patch:结构化文件修改;
  • file-system / file-search:工作区能力;
  • codex-mcp / rmcp-client:MCP 集成。

阅读时为每个工具记录四项:输入 Schema、模型可见结果、真实副作用、审批点。这样才能看懂 Harness 如何把“模型意图”转换成“受控执行”。

第 5 层:沙箱、权限与宿主集成

最后看 sandboxinglinux-sandboxbwrapexecpolicyshell-escalationprocess-hardening。这些代码决定模型生成的命令到底在哪里运行,以及怎样越过边界。

很多 Agent Demo 只展示 Loop,却省略这一层;而生产系统真正的工程含量恰恰在这里。


五、用“一条任务”学习,比阅读目录更有效

建议选择一个小仓库,执行只读任务:

阅读项目结构,找到测试入口,并解释一个失败测试的可能原因。不要修改文件。

然后做四次追踪。

追踪 1:输入

从 CLI、SDK 或 App Server 的 turn/start 开始,记录:工作目录、模型、沙箱、审批策略和用户输入怎样进入核心。

追踪 2:事件

观察 turn/starteditem/started、消息 delta、命令或工具 Item、item/completedturn/completed。把事件时间线画出来。

追踪 3:副作用

找到工具执行前的策略判定、实际进程启动、stdout/stderr 回传与退出状态。确认拒绝、取消、超时分别走哪条路径。

追踪 4:恢复

结束客户端,重新 Resume Thread,再提交一个后续 Turn。检查历史从哪里加载,哪些运行时状态不会恢复。

这四次追踪完成以后,再读 crate 间抽象就不会悬空。


六、三种集成层:按产品复杂度选择

需求推荐方式原因
脚本、CI、一次性后台任务codex exec边界清晰,进程级集成简单
服务端应用启动/继续 Codex 任务Codex SDK省去底层协议处理,支持 Thread 生命周期
自定义 IDE、桌面端、运维控制台App Server直接控制事件、审批、历史与交互生命周期
Codex 是多 Agent 系统里的编码专家Codex MCP Server由更上层 Orchestrator 统一协调

选择原则是:能用高层 SDK 完成,就不要先绑定底层协议;只有产品体验需要完整事件和审批控制时,才使用 App Server。


七、基于 Codex SDK 构建自己的应用

官方 TypeScript SDK 适合服务端 Node.js 18+,可以启动、继续和恢复本地 Codex Thread。

1. 安装

npm install @openai/codex-sdk

2. 最小调用

import { Codex } from "@openai/codex-sdk";

const codex = new Codex();
const thread = codex.startThread();

const diagnosis = await thread.run(
"分析当前仓库的 CI 失败,只给出带文件证据的修复计划,不要修改文件。",
);

console.log(diagnosis.finalResponse);

const implementation = await thread.run(
"按照计划实现最小修复,并运行相关测试。",
);

console.log(implementation.finalResponse);

run() 再次调用同一 Thread 时会延续上下文。持久任务也可以由应用保存 Thread ID,稍后通过 resumeThread(threadId) 恢复。

3. 不要把 SDK 直接放进浏览器

SDK 控制的是本地 Codex Agent,应在服务端或受控 Worker 中运行:

Browser / Mobile
→ Your API(认证、业务权限、限流)
→ Job Queue
→ Isolated Worker + Codex SDK
→ Workspace / MCP / Artifact Store

否则浏览器无法安全持有运行时权限,也无法隔离不同用户的文件与进程。

4. 一个“代码修复队列”应怎样建模

type CodexJob = {
id: string;
threadId?: string;
repo: string;
revision: string;
workspaceId: string;
requestedBy: string;
phase: "queued" | "diagnosing" | "awaiting_approval" | "applying" | "done";
risk: "read" | "workspace-write" | "external-write";
};

应用先以只读阶段生成计划和证据,用户批准后再启动写入阶段。Thread 可以延续,但执行权限必须由宿主重新判定,不能因为模型“记得用户同意过”就跳过当前审批。


八、App Server:构建自定义界面的底层基座

Codex App Server:Initialize、Thread、Turn、Items、Approval 与事件 UI

Codex App Server 是 Codex 用来支持富客户端的接口。它适合需要下面能力的产品:

  • 展示实时推理与工具活动;
  • 管理多段对话历史;
  • 让用户批准或拒绝命令与文件变更;
  • 在任务运行中追加指令、打断或取消;
  • 将 Agent 嵌入已有业务面板,而不是只返回最终字符串。

1. 协议与传输

App Server 使用双向 JSON-RPC 风格消息,线上的 JSON 省略 "jsonrpc":"2.0" 字段。默认 stdio 使用一行一个 JSON 消息;也支持 Unix Socket。WebSocket 目前被官方标为实验性且不支持生产工作负载,应谨慎对待远程暴露。

2. 标准生命周期

连接进程
→ initialize
→ initialized
→ thread/start 或 thread/resume
→ turn/start
→ 持续读取 item/* 与 turn/* 通知
→ 处理 approval request
→ turn/completed 或 turn/interrupt

App Server 的三个核心原语是:

  • Thread:包含多个 Turn 的对话;
  • Turn:一次用户请求及 Agent 随后的工作;
  • Item:消息、命令、文件变更、工具调用等最小可展示单元。

3. 最小协议客户端

下面的 TypeScript 片段展示进程与握手,字段与官方示例一致:

import { spawn } from "node:child_process";
import readline from "node:readline";

const proc = spawn("codex", ["app-server"], {
stdio: ["pipe", "pipe", "inherit"],
});

const lines = readline.createInterface({ input: proc.stdout });

const send = (message: unknown) => {
proc.stdin.write(`${JSON.stringify(message)}\n`);
};

let threadId: string | null = null;

lines.on("line", (line) => {
const message = JSON.parse(line);
console.log("event:", message);

if (message.id === 1 && message.result?.thread?.id && !threadId) {
threadId = message.result.thread.id;
send({
method: "turn/start",
id: 2,
params: {
threadId,
input: [{ type: "text", text: "只读分析这个仓库。" }],
},
});
}
});

send({
method: "initialize",
id: 0,
params: {
clientInfo: {
name: "repo_inspector",
title: "Repo Inspector",
version: "0.1.0",
},
},
});

send({ method: "initialized", params: {} });
send({ method: "thread/start", id: 1, params: {} });

真正的产品还必须补上:请求 ID 映射、进程退出、协议错误、消息背压、超时、取消、审批响应、版本能力协商与持久状态。

4. 事件 UI 不应该只显示“思考中”

建议把 Item 映射成明确的产品状态:

Item / EventUI 表达
Agent message delta流式说明
Command execution命令、工作目录、状态与输出摘要
File change可审阅 diff
MCP tool工具名、参数摘要与数据来源
Approval request影响范围、允许一次/拒绝操作
Turn completed最终结果、验证证据、剩余风险

透明不等于把所有原始日志倾倒给用户。UI 应优先展示“发生了什么、为什么需要注意、用户现在能做什么”。


九、实战架构:构建一个带审批的发布故障助手

假设目标是:在部署失败后自动检查仓库、CI 日志和服务状态,提出修复;任何写代码、重跑流水线或创建工单的动作都要审批。

1. 产品拥有业务语境

Incident UI
├─ 服务、版本、负责人、告警与最近部署
├─ “开始诊断”业务按钮
├─ Agent Event Timeline
└─ Approval Drawer

用户不必从空白 Prompt 开始。点击“开始诊断”时,应用自动传入当前 incident ID、仓库 revision、日志引用与组织规则。

2. MCP 提供业务数据与动作

将能力拆成读写不同的工具:

只读:get_incident、get_deploy、query_logs、read_runbook
写入:rerun_pipeline、create_ticket、rollback_release

读工具也要最小授权;写工具必须由应用确认当前用户、当前对象与当前动作,而不是只相信模型参数。

3. Codex 负责 Agent Loop 和工作区执行

App Server 维持 Thread,Codex 在隔离工作区读取代码、运行检查、调用 MCP,并把进度作为 Items 流给 UI。

4. 宿主负责审批与事实写回

模型建议 rollback_release(release-42)
→ Harness 发出审批请求
→ UI 展示服务、版本、影响与理由
→ 用户批准一次
→ 宿主重新校验权限与资源版本
→ MCP Server 执行动作
→ 业务视图从系统记录重新拉取

审批不能只是一个“允许”按钮。它必须与准确的工具、参数、资源版本和授权主体绑定,避免审批后状态已经改变。


十、SDK 还是 App Server:一个更实际的决策树

只需要一次任务和最终结果?
└─ 是 → codex exec

应用代码需要启动、继续或恢复任务?
└─ 是 → Codex SDK

需要实时 Item UI、审批、打断、历史列表和自定义客户端?
└─ 是 → App Server

Codex 只是多 Agent 系统中的一个专家?
└─ 是 → Codex MCP Server + 上层 Orchestrator

不要为了“更底层、更灵活”过早选择 App Server。协议意味着更多生命周期、兼容性与错误恢复责任。


十一、Fork 源码前先问:我真的需要修改 Harness 吗?

大多数业务需求可以通过以下方式完成:

  • AGENTS.md 与配置定义仓库规则;
  • Skills 封装可复用工作流;
  • MCP 接入业务数据与动作;
  • SDK 控制 Thread;
  • App Server 自定义界面与审批;
  • 沙箱和执行策略控制边界。

只有当需求落在这些扩展面之外,例如必须改变核心 Turn 状态机、工具调度语义或新平台沙箱实现时,才值得维护源码分支。

Fork 的隐性成本包括:

  • 上游高频变更与冲突;
  • 协议、SDK 和 App Server 版本绑定;
  • 安全修复同步;
  • Session 与配置格式迁移;
  • 不同平台的执行与沙箱测试。

“能改源码”不等于“应该改源码”。开源更重要的价值常常是可检查、可验证和可贡献,而不是每个团队都维护一套私有 Harness。


十二、生产应用必须补齐的六层护栏

1. 输入边界

仓库文件、Issue、网页、日志与 MCP 返回都可能包含提示注入。外部文本是数据,不是更高优先级指令。

2. 工具边界

工具 Schema 要窄,读写工具分开;危险动作接受结构化参数,避免把任意 Shell 当作业务 API。

3. 执行边界

每个任务使用独立工作区或容器,限制文件、网络、CPU、内存、进程数与运行时间。

4. 审批边界

审批绑定具体动作、参数、主体和资源版本;批准一次不等于给 Thread 永久提权。

5. 状态边界

恢复 Thread 时验证仓库 revision、身份、租户和工作区租约。历史上下文不能替代当前事实。

6. 评估边界

不仅评文本答案,还要评:

  • 是否改了允许的文件;
  • 是否运行了正确验证;
  • 是否遗漏审批;
  • 是否在预算内停止;
  • 是否能从工具失败恢复;
  • 最终结论是否有可核验证据。

十三、五天学习路线

Day 1:把 Codex 当用户使用

运行 CLI,分别完成只读分析与小修复,观察命令、diff、审批和恢复。

Day 2:理解协议词汇

阅读 App Server 的 Thread、Turn、Item、Event 与 Approval。自己记录一次事件时间线。

Day 3:沿入口追核心

execapp-server 追到 core,只追一条任务,不发散到所有 crate。

Day 4:研究执行与安全

选择 Shell 或 Apply Patch,追踪从模型工具调用到沙箱执行、审批和结果回传的完整链。

Day 5:用 SDK 做一个垂直原型

不要复制 Codex UI。选择一个小场景,例如失败测试诊断、依赖升级评估或 PR 证据检查,把业务上下文、Agent Loop 和审批分层实现。

完成这个原型后,再判断是否需要 App Server 或源码级扩展。


十四、总结:学习 Harness,重点不是复刻一个聊天框

Codex Harness 展示了一种更成熟的 Agent 工程分层:

业务应用拥有语境、界面、权限与结果
Codex Harness 拥有会话、循环、事件与受控工具执行
模型提供推理能力
沙箱和 MCP 将推理连接到真实环境

对于开发者,最值得学习的不是某一个 Prompt,而是:

  1. 如何把持续任务建模为 Thread / Turn / Item;
  2. 如何让工具结果安全地回到下一轮推理;
  3. 如何在执行前插入沙箱和人工同意;
  4. 如何通过事件流让过程可见、可打断、可恢复;
  5. 如何让产品保留业务控制权,而 Harness 专注通用 Agent Loop。

构建自己的应用时,从 SDK 开始,把任务做小、权限做窄、状态做实;只有 UI 与生命周期确实需要深度控制时,再进入 App Server。这样才能真正利用开源 Harness,而不是把复杂度搬进自己的代码库。


参考资料

Logo
RainLib

Exploring the frontiers of technology, design, and distributed systems. Building tools for the future developers.

Suggestions & Feedback

© 2026 RainLib. Built for the Future.
All rights reserved.
System Normal