外部智能体(ACP)
Chimera 可以把一次编码回合交给它没有编写的智能体 —— Claude Code、Gemini CLI,或任何讲 Agent Client Protocol 的适配器。对话记录、验证器、快照和撤销仍然属于 Chimera;干活的是别人。
为什么
Chimera 的主张从来不是它的循环是唯一好的循环,而是围绕循环的治理:污染台账、写入区域、回合前的快照、 回合后的裁决、说明真实发生了什么的回执。这些对任何执行者都成立。拒绝驱动一个你本就信任的执行者,等于 死守产品中最没意思的那一半。
什么有保证,什么没有
请在安装之前读这一节,因为它决定这个功能是否适合你。
ACP 智能体会声明它将使用客户端的哪些能力,而 Chimera 提供 fs/read_text_file 和
fs/write_text_file。提供不等于强制。 值得驱动的智能体都有自己的文件与终端工具:Claude Code 通过
Claude Agent SDK 写入,并没有义务先问我们。
具体地说:
| Chimera 自身的循环 | 外部智能体 | |
|---|---|---|
| 写入区域拒绝区域外的写入 | 总是 | 仅限经过我们的调用 |
| Shell 在配置的沙箱中运行 | 总是 | 智能体按自己的方式执行 |
| 污染台账触发危险工具闸门 | 总是 | 仅限我们中转的工具 |
| 回合前对工作区做快照 | 是 | 是 |
| 一键撤销整个回合 | 是 | 是 |
| 每次授予的权限都进回执 | — | 是 |
最后三行才是真正的保证,也正是选中外部智能体时「代码」界面那行状态所承诺的内容。它不再说「在
/project 内编辑,不执行命令」——那句话描述的是 Chimera 拥有的工具——而是说已经先做了一份副本,整个
回合可以撤销。保留更强说法的界面,就是在做一个这个回合无法兑现的承诺。
Chimera 还拒绝了 ACP 的终端能力。由我们托管的终端会成为沙箱之外的第二条执行路径,却没有沙箱的任何 规则。
安装
对 Chimera 已知的智能体无需配置:
npm i -g @agentclientprotocol/claude-agent-acp # Claude Code,需要 Node 22+
npm i -g @google/gemini-cli # Gemini CLI(其 ACP 模式在上游标记为实验性)
然后看看这台机器实际能跑什么:
chimera doctor
external_agents 会逐个报告 available: true/false,为 false 时还会给出解决它的那行命令。可用性是在
运行 sidecar 的那台机器上判定的 —— 对于打包好的桌面版,那是一台由 CI 组装、没人看过的机器。也就是说:
「它应该在那儿」不是证据。
桌面应用会在输入框上方显示一行由谁执行,列出 doctor 找到的项。当没有任何可运行的项时,这一行根本
不出现;「你还没有这个,装法如下」属于 doctor。
凭据
Chimera 启动的每个子进程拿到的环境都会剥掉 API_KEY / TOKEN / SECRET 变量,这样 shell 命令就无法
回显供应商密钥。而 ACP 智能体是一个整份工作都依赖密钥的程序,所以每个智能体按名字声明它需要的变量,
也只有这些会被放回去:
- Claude Code:
ANTHROPIC_API_KEY、ANTHROPIC_AUTH_TOKEN、ANTHROPIC_BASE_URL、CLAUDE_CONFIG_DIR - Gemini CLI:
GEMINI_API_KEY、GOOGLE_API_KEY、GOOGLE_APPLICATION_CREDENTIALS
直接透传整个环境更省事,也等于把机器上的每一把钥匙交给将来的每一个适配器。
自定义适配器
Codex 等通过本项目没有跑过的第三方适配器接入 ACP。与其列出一条未经验证的命令 —— 那会把「我们没检查」 变成「已支持」—— 不如把 Chimera 指向你手上的那个:
// POST /api/code/turn
{
"message": "修好那个失败的测试",
"provider": "custom",
"provider_command": "npx -y some-acp-adapter --flag"
}
命令按 shell 风格切分,但不经过 shell 执行,所以一个多余的管道符只是一个参数,而不是第二条命令。在
Windows 上,含有 cmd.exe 语法(& | < > ^ %)且会送到 .cmd 启动器的参数会被拒绝而不是转义:不同启动器
的引号规则并不相同,猜错就会执行你的机器,而不是机器上的某个程序。
工作原理
- 每个会话一个子进程,而不是每个回合一个。
session/prompt是智能体所保有的上下文中的一条消息; 每次都新起进程会让每个回合都变成第一回合。 - 同时最多四个存活,闲置一小时的会被关闭。每一个都是持有模型连接的进程。
- 进程在自己的进程组中启动,并按树杀死 —— 编码智能体是启动器,只杀掉我们持有的那个进程,会留下仍在跑的
工作进程和被占住的文件夹。
atexit收尸器覆盖了回合进行中退出应用的情况。 - 智能体的
session/update通知被翻译成原生循环发出的同一批事件,所以界面不需要第二套实现。思考片段 被丢弃而不是混入答案;diff块会变成对话记录本就渲染的统一 patch。 - 原生循环拥有而这里无法报告的数字 ——
steps、context_peak_tokens—— 以null而非0返回。零会 被读成「它什么都没做」。
局限
- 权限请求一律以
allow_once回应,并记入回执。拦下一个智能体本来就不必提出的请求是演戏;诚实的 做法是授予、记录,并依靠快照 —— 它同样覆盖那些从未询问过的写入。 - 融合、角色、记忆和仓库地图属于 Chimera 自身的循环。外部回合会报告
fused: false且没有记忆使用, 因为这些都没有发生。 - Gemini 的 ACP 模式在上游标记为实验性,其行为可能在版本之间变化。