Appearance
Multica 调用链
一句话结论
Multica 没有用 ACP 来接 Codex 和 Claude Code。它在 Go 里自己做了两套 backend:
Claude Code:直接拉claudeCLI,消费stream-jsonCodex:直接拉codex app-server,消费 JSON-RPC over stdio
Multica 的总体位置
它不是 IDE,也不是纯 provider gateway,而是本地 daemon。
text
Multica web app
->
Multica backend
->
local daemon on your machine
->
Claude Code / Codex所以它关心的是:
- 本机 runtime 探测
- 本地工作目录隔离
- daemon 自动执行
- 流式回报任务消息
它怎么发现可用 agent
daemon 启动时会探测本机 claude、codex、opencode 是否在 PATH 上。
text
MULTICA_CLAUDE_PATH=claude
MULTICA_CODEX_PATH=codex
MULTICA_OPENCODE_PATH=opencode只要 exec.LookPath(...) 成功,就把它登记为可用 runtime。
Claude Code 路线
实际调用方式
text
Multica daemon -> claude --output-format stream-json ... -p <prompt>它会附加:
--verbose--permission-mode bypassPermissions- 可选
--model - 可选
--max-turns - 可选
--append-system-prompt - 可选
--resume <session>
为什么这样做
因为 Claude 这边给 daemon 最直接、最薄的机器接口就是 CLI JSON 事件流。
它怎么处理输出
daemon 逐行读取 stdout 的 JSON,把它统一翻译成自己的消息类型:
textthinkingtool-usetool-resultstatuslog
如果收到 control_request,它会自动回 allow,让 daemon 模式能无人工继续运行。
Codex 路线
实际调用方式
text
Multica daemon -> codex app-server --listen stdio://然后通过 JSON-RPC 走完整生命周期:
text
initialize
initialized
thread/start
turn/start
... item / turn notifications ...为什么不是 codex exec --json
因为 Multica 需要的是“宿主控制权”,而不只是“一条命令跑完再给我结果”。
它要自己掌控:
- thread 创建
- turn 启动
- 当前工作目录
- sandbox 设定
- 审批响应
- 工具调用流
这更像 server integration,而不是命令包装。
它怎么处理审批
当 app-server 发来 JSON-RPC server request:
- 命令执行审批
- 文件变更审批
Multica 会直接回 accept,以支撑 daemon 自动执行。
它怎么处理事件
它兼容两类 Codex 通知:
- 旧的
codex/event - 新的
turn/*、item/*
然后再映射成自己的统一消息流。
工作目录和运行时注入
Multica 对每个任务都会准备隔离环境:
text
workspace root
-> task env root
-> workdir
-> logs
-> output
-> codex-home (only for codex)它不会预先 clone repo,而是让 agent 在运行时通过 multica repo checkout <url> 自己拉。
为 Claude 和 Codex 注入什么
Claude
它在 workdir 写 CLAUDE.md,告诉 Claude:
- 如何通过
multicaCLI 读 issue - 如何发 comment
- 如何改 issue status
- 如何 checkout repo
Codex
它在 workdir 写 AGENTS.md,并且额外给每个任务准备一个独立 CODEX_HOME:
auth.json共享config.json/config.toml/instructions.md拷贝隔离- skill 写进 task 专属
CODEX_HOME/skills
这使得 Codex 能以接近原生方式发现自己的配置和技能,但又不会把所有任务互相污染。
一个很关键的判断
Multica 不是在“统一上游协议”,而是在“统一自己的宿主抽象”。
它上层统一的是:
text
Backend.Execute() -> Session.Messages -> Result所以底层完全可以同时存在:
Claude的 CLI JSON 流Codex的 app-server JSON-RPC
只要最后都被翻译成同一套消息类型就行。
当前实现的一个现实差异
Claude 路线已经把 session resume 接起来了,因为上游会明确给出 session_id。
Codex 路线虽然能拿到 thread_id,但 Multica 当前实现里还没有把这件事打通成完整 resume 能力,所以它更接近“每次新建 thread 再跑一轮”。