OpenClaw + Claude Code:2 种模式 + 4 层架构

OpenClaw + Claude Code:2 种模式 + 4 层架构

图 1:OpenClaw + Claude Code 核心架构概览

你有没有遇到过这样的情况:用 Claude Code 写代码,聊着聊着上下文就爆了;运行 /clear 清空后,它又忘了项目背景;第二天打开新会话,之前讨论的架构决策全部归零。

这些问题的根源是同一个:AI 的记忆是临时的,没有持久化机制。

OpenClaw + Claude Code 的组合用职责分离的思路解决了这个问题:OpenClaw 负责会话管理和任务编排,Claude Code 专注代码执行。两个系统通过 ACP 协议通信,实现了真正可持续运行的开发工作流。

1. 架构本质:不是工具,是协作系统

ACP 协议:编排与执行的桥梁

根据 OpenClaw 官方文档的定义,ACP(Agent Client Protocol)是一个让外部编码工具接入的标准协议。支持的工具包括 Pi、Claude Code、Codex、OpenCode、Gemini CLI、Kimi 等。

核心定位是这样的:

代码语言:javascript

AI代码解释

OpenClaw(编排层)
    ↓ ACP 协议
Claude Code(执行层)

OpenClaw 不直接写代码,它负责:

  • 接收来自 Discord、Telegram、Slack 等渠道的任务
  • 管理会话的生命周期
  • 追踪任务进度
  • 处理异常和重试

Claude Code 也不关心会话管理,它只管:

  • 读取代码库
  • 编辑文件
  • 运行命令
  • 执行测试

这种分离的好处是各司其职。OpenClaw 可以同时管理多个 Claude Code 实例,每个实例处理不同项目;而 Claude Code 不需要操心"如何跟 Discord 通信"这种事,专注做好代码工作。

会话标识的设计

官方文档给出了清晰的会话标识格式:

类型

Session Key 格式

Sub-agent

agent:<agentId>:subagent:<uuid>

ACP session

agent:<agentId>:acp:<uuid>

这个设计让 OpenClaw 能精确追踪每个会话的状态,也方便后续通过命令行或 API 操作特定会话。

2. 会话管理:两种模式应对不同场景

ACP 会话有两种运行模式,官方文档把它们叫 persistentoneshot

persistent:持久化会话

这是长期运行任务的核心。持久化会话支持线程绑定——把 OpenClaw 的某个线程绑定到特定的 ACP 会话上,后续消息自动路由。

启动命令:

代码语言:javascript

AI代码解释

/acp spawn claude --mode persistent --thread auto --cwd /workspace/my-project

参数说明:

  • --mode persistent:持久化模式
  • --thread auto:自动绑定到当前线程
  • --cwd:指定工作目录

持久化会话适合这些场景:

  • 跨天的开发任务
  • 需要多轮对话的复杂需求
  • 团队协作(多人通过同一线程跟进进度)
oneshot:单次执行

简单直接:执行完任务就关闭会话,不留痕迹。

代码语言:javascript

AI代码解释

/acp spawn claude --mode oneshot --thread off

适合这些场景:

  • 快速代码审查
  • 一次性 bug 修复
  • 简单的文件查询

两种会话模式对比:持久化模式 vs 单次模式

两种会话模式对比:持久化模式 vs 单次模式

图 2:持久化模式与单次模式的特性对比

线程绑定机制

官方文档详细说明了线程绑定的行为:

  1. OpenClaw 将线程绑定到目标 ACP 会话
  2. 后续消息自动路由到绑定的会话
  3. ACP 的输出返回到同一线程
  4. Unfocus/Close/Archive/Idle-timeout 会移除绑定

支持的渠道包括:

  • Discord threads/channels
  • Telegram topics(包括群组话题和私聊话题)
  • 通过 Plugin channels 扩展的其他渠道

关键配置示例:

代码语言:javascript

AI代码解释

{
  session: {
    threadBindings: {
      enabled: true,
      idleHours: 24,      // 空闲 24 小时后自动关闭
      maxAgeHours: 0,     // 不限制最大存活时间
    },
  },

  channels: {
    discord: {
      threadBindings: {
        enabled: true,
        spawnAcpSessions: true,  // 允许线程绑定 ACP 会话
      },
    },
  },
}

idleHours: 24 是个合理的默认值——太短会频繁重建会话,太长会占用资源。根据你的任务特点调整。

线程绑定机制流程:从消息发送到结果返回的完整流程

线程绑定机制流程:从消息发送到结果返回的完整流程

图 3:线程绑定机制的完整工作流程

3. 权限配置:安全是底线

ACP 会话有个关键特点:非交互运行。官方文档说得清楚:

ACP sessions run non-interactively — there is no TTY to approve or deny file-write and shell-exec permission prompts.

这意味着你不能像在终端里那样,遇到权限提示时手动批准。必须在配置时就想清楚。

permissionMode 的三种级别

行为

风险

适用场景

approve-all

自动批准所有文件写入和 shell 命令

受信任的内部环境

approve-reads

仅自动批准读取操作,写入和执行需要提示

生产环境推荐

deny-all

拒绝所有权限提示

极度安全场景(但会阻塞任务)

生产环境建议用 approve-reads。它让 Claude Code 能自由读取代码,但写入和执行命令时会停下来等你确认。

配置命令:

代码语言:javascript

AI代码解释

# 设置权限模式
openclaw config set plugins.entries.acpx.config.permissionMode approve-reads
nonInteractivePermissions:权限冲突怎么办?

permissionMode 设置为 approve-reads 时,Claude Code 想写文件但没法交互确认,怎么办?

nonInteractivePermissions 决定了行为:

行为

fail

中止会话,抛出 AcpRuntimeError(默认)

deny

静默拒绝权限,任务继续(优雅降级)

代码语言:javascript

AI代码解释

# 设置非交互模式处理
openclaw config set plugins.entries.acpx.config.nonInteractivePermissions fail

fail 是更安全的选择——出问题时你会立刻知道,而不是让任务带着错误继续跑。

沙箱限制:一个重要的坑

官方文档明确指出:

ACP sessions currently run on the host runtime, not inside the OpenClaw sandbox.

这意味着:

  1. 如果请求者会话是沙箱化的,ACP spawns 会被阻止
  2. sessions_spawn with runtime: "acp" 不支持 sandbox: "require"
  3. 需要沙箱强制执行时,使用 runtime="subagent"

如果你遇到这个错误:

代码语言:javascript

AI代码解释

Sandboxed sessions cannot spawn ACP sessions because runtime="acp" runs on the host.
Use runtime="subagent" from sandboxed sessions.

解决方案是:要么从非沙箱会话启动 ACP,要么改用 runtime="subagent"

4. 四层架构:从需求到交付

基于官方配置示例,可以梳理出一个清晰的四层架构:

代码语言:javascript

AI代码解释

┌─────────────────────────────────────────────┐
│  第一层:任务入口层                          │
│  Discord / Telegram / Slack / GitHub        │
└─────────────────┬───────────────────────────┘
                  │
┌─────────────────▼───────────────────────────┐
│  第二层:编排层(OpenClaw)                  │
│  任务解析 / 状态追踪 / 异常处理              │
└─────────────────┬───────────────────────────┘
                  │ ACP 协议
┌─────────────────▼───────────────────────────┐
│  第三层:执行层(Claude Code)               │
│  代码读取 / 文件编辑 / 测试运行              │
└─────────────────┬───────────────────────────┘
                  │
┌─────────────────▼───────────────────────────┐
│  第四层:验收层                              │
│  lint / typecheck / 测试 / 通知              │
└─────────────────────────────────────────────┘

每一层有明确的职责边界:

入口层只负责接收需求,创建线程或话题。它不理解代码,只负责把消息传给编排层。

编排层是大脑。它解析任务意图,决定用哪个 agent,追踪执行状态,处理失败重试。

执行层是手脚。它不关心任务从哪来,只管按指令操作代码库。

验收层是质检。自动运行 lint、类型检查、单元测试,确保代码质量。

这种分层的好处是可替换性。执行层可以换成 Codex 或 Gemini CLI,入口层可以从 Discord 换成 Slack,编排层不需要改动。

四层架构图:从任务入口到验收的完整分层

四层架构图:从任务入口到验收的完整分层

图 4:四层架构的完整结构和职责边界

5. 实战配置:Discord 自动化工作流

来看一个完整的配置示例,展示如何在 Discord 上实现任务自动化。

完整配置文件

代码语言:javascript

AI代码解释

{
  // Discord 渠道配置
  channels: {
    discord: {
      enabled: true,
      token: "${DISCORD_TOKEN}",  // 从环境变量读取
      threadBindings: {
        enabled: true,
        spawnAcpSessions: true,
      },
    },
  },

  // Agent 配置
  agents: {
    list: [
      {
        id: "claude",
        runtime: {
          type: "acp",
          acp: {
            agent: "claude",
            backend: "acpx",
            mode: "persistent",
            cwd: "/workspace/my-project",
          },
        },
      },
    ],
  },

  // 会话管理
  session: {
    threadBindings: {
      enabled: true,
      idleHours: 24,
    },
  },

  // ACP 基础配置
  acp: {
    enabled: true,
    dispatch: { enabled: true },
    backend: "acpx",
    defaultAgent: "claude",
    allowedAgents: ["pi", "claude", "codex", "opencode", "gemini", "kimi"],
    maxConcurrentSessions: 8,
  },

  // 权限配置
  plugins: {
    entries: {
      acpx: {
        config: {
          permissionMode: "approve-reads",
          nonInteractivePermissions: "fail",
        },
      },
    },
  },
}
通过 API 启动会话

除了命令行,还可以通过 sessions_spawn API 启动会话:

代码语言:javascript

AI代码解释

{
  "task": "Review the PR and fix any failing tests",
  "runtime": "acp",
  "agentId": "claude",
  "thread": true,
  "mode": "session",
  "cwd": "/workspace/my-project"
}

参数说明:

  • task:发送给 ACP 会话的初始提示
  • runtime:必须设置为 "acp"
  • agentId:目标工具 id(不填则用默认 agent)
  • thread:是否请求线程绑定
  • moderun(单次)或 session(持久化)
恢复已有会话

如果会话中断了,可以用 resumeSessionId 恢复:

代码语言:javascript

AI代码解释

{
  "task": "Continue fixing the remaining test failures",
  "runtime": "acp",
  "agentId": "claude",
  "resumeSessionId": "agent:claude:acp:a1b2c3d4-..."
}
常用命令速查

命令

功能

/acp spawn

创建 ACP 会话

/acp status

查看会话状态

/acp steer

向运行中的会话发送调整指令

/acp cancel

取消当前轮次(不关闭会话)

/acp close

关闭会话并解除线程绑定

/acp sessions

列出最近的 ACP 会话

/acp doctor

检查后端健康状态

你在项目中用过类似的自动化方案吗?是走 Discord 还是其他渠道?评论区聊聊你的实践经验。

6. 故障排查:常见错误和解决方案

官方文档的 Troubleshooting 章节列出了常见问题,这里整理几个高频场景:

错误信息

原因

解决方案

ACP runtime backend is not configured

后端插件缺失

运行 /acp doctor 检查,安装 acpx 插件

ACP is disabled by policy

ACP 全局禁用

设置 acp.enabled=true

ACP agent "<id>" is not allowed

Agent 不在白名单

更新 acp.allowedAgents 列表

Sandboxed sessions cannot spawn ACP

沙箱限制

改用 runtime="subagent" 或从非沙箱会话启动

Permission prompt unavailable in non-interactive mode

权限模式阻止操作

检查 permissionMode 配置

排查流程建议:

  1. 先跑 /acp doctor这个命令会检查后端健康状态和能力
  2. 查看 /acp sessions确认会话状态和 key 是否正确
  3. 检查配置项acp.enabledacp.dispatch.enabledacp.allowedAgents
  4. 看沙箱设置:确认是否在沙箱化会话中尝试启动 ACP

总结:什么时候用,什么时候不用

OpenClaw + Claude Code 的组合适合这些场景:

  • ✅ 需要跨天运行的长期开发任务
  • ✅ 团队协作,多人通过同一线程跟进进度
  • ✅ 多渠道接入(Discord、Telegram 等)

不太适合这些场景:

  • ❌ 简单的一次性代码查询(直接用 Claude Code 更快)
  • ❌ 需要严格沙箱隔离的环境(ACP 目前跑在宿主机)
  • ❌ 没有多渠道接入需求的个人项目

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐