Appearance
ACP 与适配器
ACP 是什么
ACP 更像一套宿主和 agent 之间的会话协议,而不是一个单独产品。它适合表达:
- 初始化
- 新建会话
- 发 prompt
- 流式消息
- 工具调用
- 权限审批
- 取消
- 恢复历史会话
所以 ACP 解决的是“把 agent 嵌进另一个产品”的问题。
codex exec 为什么不等于 ACP
codex exec 是 one-shot non-interactive 命令。它适合:
- shell automation
- CI job
- 一次性任务
但 ACP 需要的是宿主对 agent 生命周期的持续控制。两者差别主要在:
| 维度 | codex exec | ACP |
|---|---|---|
| 控制方式 | 一次启动,一次结束 | 宿主持续控制 |
| 会话模型 | 单次任务为主 | 多轮 session 为主 |
| UI 交互 | 偏命令输出 | 可渲染审批、工具、diff、terminal |
| 集成目标 | 人或脚本直接用 | IDE / 网关 / 编排系统接入 |
为什么 Codex 往往需要 adapter
因为宿主想要的是 ACP,但 Codex 并不是天然暴露一个 ACP 端点。于是中间要有一层 adapter。
典型链路:
text
Zed / ACP host -> codex-acp -> codex runtime这层 adapter 的职责是:
- 把 ACP 请求翻译成 Codex runtime 操作
- 把 Codex 事件翻译成 ACP 更新
- 把审批、工具调用、终端输出、历史恢复映射到宿主语义
codex-acp 怎么拿到“内部状态”
关键不是抓取终端,而是直接链接 runtime。
根据 zed-industries/codex-acp 的实现:
- 它通过
stdin/stdout跟宿主说 ACP。 - 但在进程内部,它直接依赖
codex-core、codex-login、codex-exec-server、codex-protocol等 crate。 - 它不是简单 shell out 到
codex exec,而是创建ThreadManager,再启动或恢复线程。
因此它能拿到的是:
- 结构化线程对象
- 结构化事件流
- rollout / history
- 配置与认证对象
而不是“CLI 屏幕上的字符”。
Claude Code 为什么经常不用单独 ACP adapter
不是说它不能有 adapter,而是很多宿主产品直接拿到了一个更薄、更实用的机器接口:
text
claude CLI -> stream-json如果一个产品的目标是 daemon 或后台任务系统,而不是 IDE 级深度嵌入,那么直接消费这条 JSON 流往往已经足够。
但在 Zed 这种 IDE 宿主里,Claude 也同样会通过专门 adapter 接进 ACP。