第05章 ACP —— 如何对接外部 AI 客户端

如果你已经在本机装了 Codex、Claude Code、Gemini CLI、OpenCode 这类外部编码代理,OpenClaw 不需要重造一套运行时。它可以通过 ACP agents 把这些外部 harness 接进自己的会话体系里。

这一章只讲当前源码里的真实能力,不讲已经废弃或不存在的旧接口。

什么是 ACP

ACP 指的是 Agent Client Protocol。在 OpenClaw 里,它的作用很明确:

用 ACP 后,OpenClaw 可以把一个任务交给外部 agent runtime 去跑,同时仍然保留 OpenClaw 自己的会话、路由、线程绑定和结果回传。

和普通 sessions_spawn 的区别,不是“有没有子任务”,而是子任务到底跑在哪个 runtime 里:

  • 原生 sub-agent:跑在 OpenClaw 自己的 sub-agent runtime
  • ACP session:跑在 ACP backend 插件后面的外部 harness 里

会话长什么样

ACP 会话不是普通子会话。当前文档和源码约定的会话键形态是:

agent:<agentId>:acp:<uuid>

例如:

agent:codex:acp:9c2c2c7e-...
agent:claude:acp:4c3f9b1a-...

这意味着 ACP 会话也进入了 OpenClaw 的标准会话体系:

  • 可以被路由到正确线程
  • 可以有会话级状态
  • 可以被 /acp status、/acp close 之类命令管理

两种常见入口

1. 用 /acp 命令直接操作

这条路线适合人类操作员手动控制:

/acp spawn codex --mode persistent --thread auto
/acp status
/acp steer tighten logging and continue
/acp close

当前官方文档列出的常用命令包括:

  • /acp spawn
  • /acp cancel
  • /acp steer
  • /acp close
  • /acp status
  • /acp model
  • /acp permissions
  • /acp timeout
  • /acp sessions

2. 用 sessions_spawn 从智能体内部拉起 ACP 会话

这条路线适合让 OpenClaw 自己编排外部编码代理。

最关键的区别是:要显式设置 runtime: "acp"。

这里的字段里,ACP 相关的重点是:

  • runtime: "acp":告诉 OpenClaw 走 ACP runtime,而不是默认 sub-agent runtime
  • agentId:指定 ACP target harness,例如 codex、claude、gemini
  • thread + mode: "session":在支持线程绑定的渠道里,创建一个可持续对话的 ACP 会话

ACP 和普通 sub-agent 的区别

维度ACP session普通 sub-agent
运行时ACP backend 插件OpenClaw 原生 sub-agent runtime
会话键agent:<agentId>:acp:<uuid>agent:<agentId>:subagent:<uuid>
人类控制命令/acp .../subagents ...
典型用途调 Codex / Claude Code / Gemini CLIOpenClaw 内部多智能体协作

一句话说清楚:

  • 你要“调用外部编码代理”,用 ACP
  • 你要“让 OpenClaw 自己拆任务”,用原生 sub-agent

和 MCP 不是一回事

ACP 和 MCP 经常被混淆,但在 OpenClaw 里它们解决的是完全不同的问题:

  • ACP:把外部 agent runtime 接进来
  • MCP:给模型提供额外工具、资源或上下文

所以一个完整链路可能长这样:

OpenClaw -> ACP session -> Codex / Claude Code -> 调用其可用工具

ACP 负责“谁在干活”,不是“暴露哪些资源”。

当前源码里的配置基线

官方 ACP 文档给出的基础配置是:

{
  acp: {
    enabled: true,
    dispatch: { enabled: true },
    backend: "acpx",
    defaultAgent: "codex",
    allowedAgents: ["pi", "claude", "codex", "opencode", "gemini"],
    maxConcurrentSessions: 8,
    stream: {
      coalesceIdleMs: 300,
      maxChunkChars: 1200,
    },
    runtime: {
      ttlMinutes: 120,
    },
  },
}

这里最值得记住的是:

  • acp.enabled:总开关
  • acp.dispatch.enabled:允许正常会话消息被分发到 ACP runtime
  • acp.defaultAgent:省略 agentId 时的默认目标
  • acp.allowedAgents:允许使用哪些 ACP harness id

配置文件位置是当前工程使用的:

~/.openclaw/openclaw.json

线程绑定是另一层能力

ACP session 能不能“绑定到线程继续聊”,取决于渠道适配器是否支持 thread binding。

当前官方文档明确提到的内置支持重点是 Discord。示例配置:

{
  session: {
    threadBindings: {
      enabled: true,
      idleHours: 24,
      maxAgeHours: 0,
    },
  },
  channels: {
    discord: {
      threadBindings: {
        enabled: true,
        spawnAcpSessions: true,
      },
    },
  },
}

这层能力开启后,才有下面这种体验:

  1. /acp spawn codex --mode persistent --thread auto
  2. OpenClaw 自动创建或绑定一个线程
  3. 你后续在这个线程里说话,消息继续路由到同一个 ACP session

什么时候应该用 ACP

适合:

  • 你已经有 Codex、Claude Code、Gemini CLI 这类现成外部代理
  • 你希望保留这些工具自己的工作流和擅长领域
  • 你希望 OpenClaw 负责协调、路由、回传和线程绑定

不适合:

  • 你只是想在 OpenClaw 内部做普通多智能体拆分
  • 你不需要外部 harness,只要原生 sessions_spawn 就够

常见误区

误区 1:ACP 就是普通 sub-agent 的别名

不是。两者的 runtime、命令族和会话键都不同。

误区 2:只开 acp.enabled 就够了

不够。当前文档要求至少还要确认 acp.dispatch.enabled=true,线程场景还要看渠道 thread binding 开关。

误区 3:ACP 一定绑定线程

不是。--thread off 或 thread: false 时,ACP session 可以是非绑定的一次性会话。

本章小结

  • ACP agents 是 OpenClaw 接入外部编码代理的标准路径
  • ACP session 的会话键形态是 agent:<agentId>:acp:<uuid>
  • 人工操作走 /acp ...,智能体编排走 sessions_spawn + runtime: "acp"
  • 线程持续对话依赖渠道 thread binding 能力,不是 ACP 自动自带
  • 当前配置文件路径是 ~/.openclaw/openclaw.json

相关内容

如果这篇文章对你有帮助,欢迎请我喝杯咖啡 ☕
Cygnus Yang 支付宝支付宝
Cygnus Yang 微信微信