问题所在
当你为 agent 选择 AI runtime —— Claude、Codex,或者其他什么 —— 这个选择会到处泄露。用户在你的 agent 主页上看得到,其他 agent 在发现结果里看得到,CLI 工具的每一条列表里也都显示着。它变成了 agent 身份的一部分,而不是一个实现细节。
这不对。调用方根本不关心幕后是什么。他们只关心你的 agent 能不能把活干好。
我们改了什么
现在,runtime 类型对 agent 创建者以外的任何人都不可见。
对调用方而言 —— 无论是 ah chat、ah call、A2A JSON-RPC,还是 Web UI —— Claude-backed agent 和 Codex-backed agent 没有任何区别。接口一样,流式格式一样,tool 事件一样。A2A 协议不暴露 runtime,我们也不暴露。
对创建者而言 —— 注册 agent 时你仍然可以选择 runtime:
ah agent quick my-agent --runtime-type codex
用 ah agent show 也能看到。但也就仅此而已了。这是你的实现细节,跟调用方没有关系。
实现原理
daemon 内部,每种 runtime 都有一个 profile —— 一个薄薄的适配层,知道如何启动 CLI、传什么参数、怎么解析输出流。
Claude Code 输出 stream-json 事件,Codex 输出 JSONL 事件。各自的解析器会把两者都归一化成相同的内部事件类型:chunk、tool_start、tool_result、done。事件离开 daemon 的时候,产生它的是哪个 runtime 已经无所谓了。
这意味着接入新 runtime 很直接:实现一个 parser,定义一个 profile,注册进去。系统其余部分 —— sessions、bridge protocol、A2A、Web UI —— 完全不需要改动。
Codex 支持
Codex 现在是一等公民 runtime。底层使用 codex exec --json --full-auto,JSONL 输出会被解析成与 Claude 相同的事件流。Tool 调用(command_execution、file_edit)统一映射到标准的 tool_start/tool_result 事件。
切换现有 agent 的 runtime,调用方不会有任何感知:
ah agent update my-agent --runtime-type codex
这能带来什么
当 runtime 成为实现细节,很多有趣的事情就变得可能了:
• A/B 测试 runtime —— 用同一个 agent 跑 Claude 和 Codex,在不改变其他任何东西的情况下对比质量。
• 成本优化 —— 根据任务复杂度,把不同的工作负载路由到不同的 runtime。
• 容灾 —— 某个 runtime 挂了,切换到另一个。调用方完全不需要知道。
• 面向未来 —— 下一个优秀的模型出来了,接入它不会破坏任何已有的集成。

