本节看 Codex 这一侧。关键问题是:为什么 companion 要接 app-server、thread、turn,而不是自己实现 agent loop。

Codex app-server 是什么位置?

在这套桥里,Codex app-server 是目标 runtime 的入口。Claude 和 Node companion 都不直接执行 agent 推理,真正的任务执行交给 Codex app-server。

flowchart TD
  A[Node companion] --> B[connect Codex app-server]
  B --> C{是否 resume?}
  C -->|否| D[thread/start]
  C -->|是| E[thread/resume]
  D --> F[turn/start]
  E --> F
  F --> G[Codex agent loop]
  G --> H[工具调用 / 文件读写 / 命令执行]
  H --> I[finalMessage]

Thread 和 Turn 要怎么理解?

可以用聊天软件类比:

概念类比在这里的作用
thread一个持续会话保存 Codex 对某个任务的上下文
turn会话里的一次输入输出执行一次新的任务请求
finalMessage本轮最终回复返回给 companion,再回到 Claude
threadId会话 ID用于后续 resume
turnId本轮 ID用于日志和追踪

为什么 resume 必须依赖 threadId?

因为真正保存 Codex 上下文的是 Codex thread,不是 Claude 的聊天记录。--resume 的核心不是“把上一轮文本复制一遍”,而是找到之前任务留下的 threadId,然后让 Codex app-server 继续那个 thread。

flowchart LR
  A["/codex:rescue --resume"] --> B[companion 查找最近 job]
  B --> C[取出 threadId]
  C --> D[thread/resume]
  D --> E[turn/start 新请求]

sandbox 为什么放在 Codex 侧?

进入 Codex runtime 后,读写文件、跑命令、是否能改 workspace,主要由 Codex 自己的 sandbox 和权限策略决定。Claude Code 层只是发起者,不应该假定自己的权限规则自动覆盖 Codex。

flowchart TD
  A[Claude Code settings] --> B[约束 Claude 自己的工具]
  C[Codex config / sandbox] --> D[约束 Codex runtime]
  B -.不是同一层.-> D

这也是 --write 重要的原因:它会把任务从偏只读调查切换成允许 workspace 写入的 Codex 执行模式。

app-server 方案的收益

接 app-server 带来的收益:

  • 可以复用 Codex 已有登录态。
  • 可以复用 Codex config.toml。
  • 可以复用 Codex 的 thread/turn 语义。
  • 可以让任务天然支持 resume。
  • 可以让插件不必重写 agent loop。

这就是低侵入设计:桥不复制 Codex,只把请求送到 Codex 已有入口。


相关笔记