ACP:让 OpenClaw 操作 OpenCode 编写代码

一个半月前,我开始加入“养虾”大军,折腾 OpenClaw。当时我有一个念头:既然 OpenClaw 能调用工具,那能不能直接让它去操作 OpenCode / Claude Code 等编程智能体帮我写代码?
想法很自然,实际一上手,最早遇到的问题也很直接:卡住。
不是不能跑,而是有时命令像是发出去了,但没有任何响应,过一段时间我让 OpenClaw 去排查,它会说 OpenCode 卡在启动中了,没有正确运行。对一个偶尔改几行的小任务来说,这种状态还能忍;但只要真想把它拿来持续写代码,这就不算“能用”。
1. 为什么会卡住?
后面我慢慢意识到,问题不全在 OpenCode 本身,而在调用方式。
如果在 OpenClaw 里直接把 OpenCode 当成一条普通终端命令用 exec 来跑,那它就很容易卡在几个地方:终端交互、持续会话、确认输入、输出刷新。OpenCode 这类工具,本来就不是为“一次性吐一段文本然后结束”设计的。你用最朴素的方式去调用它,小任务能跑起来,长任务就很容易会遇到“卡住”的问题。
所以核心问题就是 OpenClaw 怎么把它跑顺。
2. Tmux
当时我先想到的办法是既然不能放在前台来跑,能不能用 nohpu 命令让 OpenCode 跑在后台?恰好看到辉哥在《从需求到发布:使用 OpenClaw + Ralph Loop 自动化开发 Nexus MCP Server》一文中也提到需要使用 tmux 实现后台运行,不要使用 nohup 模式。
tmux 是一个终端复用工具,可以让你在一个终端里开多个会话,每个会话可以独立运行,也可以随时切换,在主会话里,你也可以查询其他会话的运行状态和输出。
我自己也写了一个通过 tmux 去操作 Ralph + OpenCode 的 Skill。它做的事情并不复杂,就是把这条链路封装起来:
- 通过
tmux创建 Ralph + OpenCode 专用的 session# Create tmux session tmux -S /tmp/ralph-$(whoami).sock new-session -d -s ralph -c /path/to/project - 在 session 里启动 Ralph + OpenCode 并发送任务
# Run ralph tmux -S /tmp/ralph-$(whoami).sock send-keys -t ralph:0.0 -l 'ralph "<task>" --no-stream --allow-all --agent opencode --max-iterations <N>' tmux -S /tmp/ralph-$(whoami).sock send-keys -t ralph:0.0 Enter - 查看 session 状态和输出
# Watch live in tmux tmux -S /tmp/ralph-$(whoami).sock attach -t ralph
至少在当时,这个 Skill 让 OpenClaw 调 OpenCode 这件事,从“能跑但经常卡住”,变成了“虽然不优雅,但基本能用”。
当然,它的问题也很明显。tmux 更像是一种 Workaround ,不是 OpenClaw 原生支持 OpenCode 的能力,总觉得还差点意思。
3. OpenClaw ACP Agent
后来,偶然间看到 OpenClaw 在 2026.02.26 版本发布了一个名为 ACP Agents 的功能,可以让 OpenClaw 更顺滑地操作 OpenCode 之类的编程智能体,并且专门优化了异步调度和状态同步。也就是说使用 ACP + OpenCode 可以替代 tmux + OpenCode 的旧模式。
ACP 全称 Agent Client Protocol,设计的目的是给外部客户端或系统提供一套统一接口,用来接入和驱动 AI Agent。比如 OpenCode 在 IDE 中的插件,就是以 ACP 来实现的。
说到这,不妨对比一下 ACP 会话 、Sub-agent 任务、tmux 会话几个易混的概念:
| 维度 | ACP 会话 | Sub-agent 任务 | tmux 会话 |
|---|---|---|---|
| 运行时 | ACP backend 插件(例如 acpx) | OpenClaw 原生 sub-agent runtime | 终端多路复用工具,不是 OpenClaw runtime |
| 会话标识 | agent: |
agent: |
自己不产生 OpenClaw 会话标识 |
| 主要命令 | /acp … | /subagents … | tmux / tmux attach / tmux send-keys … |
| 启动方式 | sessions_spawn + runtime:“acp” | sessions_spawn(默认运行时) | exec + tmux |
| 主要作用 | 运行外部 coding agent | 运行 OpenClaw 原生后台代理任务 | 托住一个可恢复、可接管的终端进程 |
| 适合场景 | 正式接入 OpenCode/Codex/Claude Code | 通用任务的后台委派、做完回报 | 终端多路复用的通用工具,非原生方案 |
使用 ACP Agent,当你向 OpenClaw 发送一个需求 “使用 OpenCode 开发一个 H5 五子棋小游戏” 时,OpenClaw 的 Main Agent 就会通过 ACP Agent 与 OpenCode 建立一个会话,称之为 ACP Session (很重要,后面要考),然后把需求发过去,OpenCode 就会根据需求生成代码。当你需要查询任务进度、状态时,也是 Main Agent 与 ACP Session 进行交互,获取状态和输出。
那能不能用 Sub-agent 任务来跑 OpenCode 这类工具呢?答案也是不行的,除非你在 Sub-agent 中也通过使用 tmux 来实现,这就成套娃了。
如果说 tmux 像是让 OpenClaw 以外派项目的方式使用 OpenCode,那 ACP Agent 更像是让 OpenCode 正式“入职” OpenClaw。
开启 ACP Agent 的方式也很简单,只需要在 openclaw.json 中加入如下配置并重启 Gateway 即可:
核心配置大致是:
{
"acp": {
"enabled": true,
"backend": "acpx",
"defaultAgent": "opencode",
"allowedAgents": [
"opencode",
"codex",
"claude"
]
}
}此外还需要安装 acpx 插件,他是 ACP Agent 运行的底层实现:
openclaw plugins install acpx
openclaw config set plugins.entries.acpx.enabled true它的价值很明确:更原生、更正统。 OpenCode 不再只是一个外部命令,而是 OpenClaw 能正式调度的一类 Agent。
但可惜,由于 Ralph 本身不是一个 AI Agent,所以它不能直接使用 ACP Agent,只能通过 tmux 间接接入。而 Oh My OpenCode 虽然内置了 Ralph Loop 插件,但不支持非交互模式,所以还是期待 OpenCode 能像 Claude Code 那样原生支持非交互模式下的 loop 命令。
4. Thread-bound sessions
当然,OpenClaw 还在持续优化 ACP Agent 的能力,比如在 2026.03.01 版本里支持了 Discord 的 Thread binding 能力,随后在 2026.03.07-beta 版适配了 Telegram 。
吐个槽,OpenClaw 官方文档写的是 Thread-bound sessions ,Release Notes 里写的是 Thread binding 或 Thread bindings,所以到底叫啥,OpenClaw 能不能给个准信。
我们以文档为例,所谓 ACP Agent Thread-bound sessions ,就是把 ACP Session (还记得前文中要考的内容么) 绑定到某个聊天入口,跳过 Main Agent 的消息分发,让用户直接把需求发给 OpenCode。
我们先看看配置方式和使用效果:
4.1. Telegram 配置
目前 Thread-bound sessions 只支持 Discord 和 Telegram,以 Telegram 为例:
- 进入 OpenClaw Bot 与它对话,问它 “你的 chatid 是多少” ,并记录:

- 通过 Telegram 的 BotFather 修改 OpenClaw Bot 的权限:
/mybots查询所有 Bot,选择 OpenClaw Bot ,进入Bot Settings。- 进入
Allow Groups点击Turn groups on,进入Group Privacy点击Turn off。
- 在 Telegram 中,创建一个新群组 Group,如
OpenClaw ACP,点击 Group 右上角的 “铅笔” 按钮进入设置:
- 开启 Topic 选项,注意确认 Group Type 是 Private ,以确保安全:

- 进入 Group, 将 OpenClaw Bot 添加到 Group 中。
- 进入 Group, 右上打开选项,点击 “Create topic”,输入名称,如
OpenCode:
4.2. OpenClaw 配置
先修改 openclaw.json ,如下:
{
"channels": {
"telegram": {
"enabled": true,
"dmPolicy": "pairing",
"botToken": "<bot_token>",
// 检查是否为 allowlist
"groupPolicy": "allowlist",
"streaming": "partial",
// 替换 <chatid>
"groupAllowFrom": [
"<chatid>"
]
}
}
}openclaw gateway restart 重启 Gateway 。
然后在 Telegram 中,进入 Group,进入 OpenCode Topic,@ OpenClaw Bot,说个 “Hi”。
再回到 Telegram 的 OpenClaw Bot 中,问它 “刚才你收到的来自 telegram topic 的会话, group_id 和topic_id 是多少?” ,并记录:

注意 group_id 前面有个 - 号,不要遗漏。
继续修改 openclaw.json ,如下:
{
"agents": {
// OpenCode ACP Agent 个性化配置
"list": [
{
"id": "opencode",
"runtime": {
"type": "acp",
"acp": {
"agent": "opencode",
"backend": "acpx",
"mode": "persistent",
// OpenCode 的工作目录
"cwd": "/root/.openclaw/workspace/projects"
}
}
}
]
},
// 将 OpenCode ACP 绑定到 Telegram Topic
"bindings": [
{
"type": "acp",
"agentId": "opencode",
"match": {
"channel": "telegram",
"accountId": "default",
// 替换 <group_id> 和 <topic_id>
"peer": {
"kind": "group",
"id": "<group_id>:topic:<topic_id>"
}
}
}
],
"channels": {
"telegram": {
"enabled": true,
"dmPolicy": "pairing",
"botToken": "<bot_token>",
"groupPolicy": "allowlist",
"streaming": "partial",
// 开启 Thread binding
"threadBindings": {
"enabled": true,
"spawnAcpSessions": true
},
// 上一步已替换 <chatid>
"groupAllowFrom": [
"<chatid>"
],
// 如果不想每次都 @ OpenClaw Bot,可以设置 requireMention 为 false
"groups": {
"<group_id>": {
"topics": {
"<topic_id>": {
"requireMention": false
}
}
}
}
}
}
}重启 Gateway 后,你就可以直接在 Telegram 的 OpenCode Topic 中,直接说 “开发一个 H5 五子棋小游戏” ,它就会直接调用 OpenCode 生成代码了。

最终我在 Telegram 中的对话窗口就变成这样:
---- Telegram
|__ OpenClaw Bot (DM) —— 主对话窗口
|__ OpenClaw ACP (Group)
|__ OpenCode (Topic) —— OpenCode 专属对话窗口
|__ OpenClaw Bot4.3. 效果和缺点
这样做的好处是:
- 不用每次跟 OpenClaw 说 “使用 OpenCode 开发 xxxx” ,直接进入 Topic 说 “开发 xxxx” 就行,这个 Topic 相当于 OpenCode 的专属对话窗口。
- 你在这个 Topic 中的上下文只有 OpenCode 这个 ACP Session 知道,它不受 OpenClaw Bot 主对话窗口的其他上下文干扰。
- 如果你还有 Claude Code, Codex 等其他 ACP Agent,你也可以分别建 Topic,让它们各司其职。
ACP Thread-bound sessions 看上去一切皆美好,但它不是没有缺点。因为它是一个 Session,不是一个 Agent,意味着它只能一条路跑到底,成功或失败,过程中你没办法再在这个对话窗口中干涉它的状态,它是阻塞的。
就像把 OpenCode 跑在 CI/CD 流水线中,你只能等它结束。除非回到 OpenClaw Bot 的主对话窗口,问它 “OpenCode ACP Session 的进度如何” ,或者让 OpenClaw Main Agent 来帮你暂停、关闭这个 Session。
所以我觉得它依然不是最优解,在 OpenClaw 这类智能体中再去调用编程智能体,应该还需要一个更好的调度方案或实现方式。
5. 开发进度和状态反馈
在 OpenCode 中,不管是使用 tmux、ACP Agent,还是 ACP Thread-bound sessions,最后都会遇到同一个现实问题:
任务启动了,OpenClaw 不会主动告诉你开发进度和任务状态。
这件事底层机制比较复杂,但结论是:
| 类别 | 任务完成通知 | 任务过程通知 |
|---|---|---|
| tmux | 需配置 OpenClaw Cron | 需配置 OpenClaw Cron |
| ACP Agent | 需配置 OpenClaw Cron | 需配置 OpenClaw Cron |
| ACP Thread-bound sessions | 自动通知 | Topic 中无法实现,须在 Main Agent 对话窗口中配置 OpenClaw Cron |
所以,目前 OpenCode 的开发进度和状态反馈,只能通过 OpenClaw Cron 来实现,这又涉及到 “虾友” 经常反馈的另一个问题 —— OpenClaw 定时任务没通知。
为此我也专门写过一篇文章《OpenClaw 定时任务没通知,你应该这样做》 详细分析问题原因。解决的方式很简单,我自己已经封装了一个 Skill OpenClaw Msg Delivery Guide ,安装即可。
6. 总结
折腾了一圈,遗憾的是到最后我也没解决全部问题,但我至少明白了 OpenClaw 的各种 Agent 和 Session 机制,以及它们之间的关系。
目前我还是倾向以 ACP Thread-bound sessions 的方式来在 OpenClaw 中使用 OpenCode,因为是单线程会话,它至少会自动把结果通知给我。如果需要查看进度,再回到 Main Agent 对话窗口,使用 OpenClaw Cron 的方式来解决。
此外,如上文所述,OpenClaw 这样的个人智能体在接入编程智能体以及其他工具上,还有较多的问题有待解决。不过按照它目前的迭代速度,我相信不会等太久。