AIGC标识 OpenClaw 飞书多Agent配置实战

OpenClaw 飞书多Agent配置实战

本文基于我自己机器上跑的 openclaw@2026.6.11,配置文件就是那份 ~/.openclaw/openclaw.json。下面出现的 appId、token、open_id 全部脱敏过,你别直接抄。

适合谁看:第一次在自己电脑上把 OpenClaw 跑起来、还想接到飞书里挂多个 Agent 的同学。


一、OpenClaw 到底是个啥(顺便八一卦改名史)

项目最早叫 Clawdbot(Clawd + robot,灵感就是 Claude 那个龙虾爪的梗),2026 年初突然爆火。结果火得太大,Anthropic 注意到了,1 月 27 日直接发律师函,说 Clawd / Clawdbot 跟 Claude 太像了。项目当天紧急改名 Moltbot(Molt 是蜕壳的意思,吉祥物是只蜕壳的小龙虾 Molty 🦞),算是过渡。到了 1 月底,最终定名 OpenClaw,一直用到现在。所以你要是看到老文章里写 Clawdbot、Moltbot,别懵,都是同一个东西,旧命令 clawdbot 现在也还兼容。

作者是 Peter Steinberger,就是做 PSPDFKit 的那位,大佬出品。项目完全开源、跑在本地,地址在 github.com/openclaw/openclaw,中文文档在 docs.openclaw.ai/zh-CN

那它到底能干啥?一句话:它是个本地跑的多 Agent 编排网关

  • 把各种聊天渠道的消息(飞书、Slack、Discord、Telegram、邮件……)统一收到一个本地服务里;
  • bindings 这张路由表,把每条消息送到对应的 agent
  • 每个 agent 拿到消息后,去调大模型 → 决定该调哪些 skill / 工具 → 把结果发回原来的渠道。

整个运行时就一个进程(openclaw gateway),全靠 openclaw.json 这一份配置驱动。这点我觉得设计得挺干净,改配置基本等于改整个系统的行为

我这套环境的结构大概是这样:

[飞书 bot1(日常)] ─┐
[飞书 bot2(分析)] ─┼─→ [openclaw gateway :18789] ─→ [agent: main / aff / zhaochao]
[飞书 bot3(杂活)] ─┘            │                            │
                                 ├→ [skills]                   ├→ [大模型 provider]
                                 ├→ [plugins(feishu/acpx)]   ├→ [skills]
                                 └→ [hooks]                    └→ [channels: feishu]

二、配置文件在哪儿,长啥样

路径固定:~/.openclaw/openclaw.json(Windows 是 C:\Users\<你>\.openclaw\openclaw.json)。它其实是 JSON5,所以你可以写注释、尾逗号也无所谓,这点对人类挺友好。

如果你改过环境变量,位置可能不一样:OPENCLAW_CONFIG_PATH 能覆盖文件路径,OPENCLAW_STATE_DIR 能覆盖整个状态目录。但一般不用动。

我这份配置顶层一共 15 个 key,按字典序排:

Key 类型 一句话作用
acp dict Agent Client Protocol,接 Claude Code / Codex 这类编码 CLI
agents dict Agent 配置 + 列表(灵魂)
auth dict 大模型 provider 的鉴权 profile
bindings list 渠道 → Agent 的路由表(最容易踩坑)
channels dict 渠道配置(飞书、Slack……)
commands dict CLI 命令行为开关
gateway dict 本地 HTTP 服务配置
hooks dict 内部 hook(启动时跑那些)
meta dict 文件元数据(版本 / 改动时间)
models dict 大模型 provider + 模型目录
plugins dict 插件(feishu / memory-core / acpx……)
session dict session 复用策略
skills dict skill 的启用 / 禁用
tools dict 工具集策略(决定 Agent 能调哪些内置工具)
wizard dict 上次跑 openclaw doctor 之类的记录

下面一个一个说。


三、meta / wizard:这俩别手贱改

"meta": {
  "lastTouchedVersion": "2026.6.11",
  "lastTouchedAt": "2026-07-02T16:42:29.329Z"
},
"wizard": {
  "lastRunAt": "2026-07-02T16:42:29.228Z",
  "lastRunVersion": "2026.6.11",
  "lastRunCommand": "doctor",
  "lastRunMode": "local"
}

这俩是 OpenClaw 自己写进去的:

  • meta:每次 OpenClaw 写配置时,顺手记一下版本号和 ISO 时间;
  • wizard:每次你跑 openclaw doctor / configure / onboard,它记一笔。

别手改,下次 OpenClaw 自己写配置会直接覆盖掉,白费劲。我一开始不知道,还手动把 lastTouchedAt 往前调过,想着能不能"骗"它,结果毫无卵用。


四、auth:API key 到底存哪了

先看配置里这段:

"auth": {
  "profiles": {
    "minimax-cn:default": { "provider": "minimax-cn", "mode": "api_key" },
    "minimax:cn":          { "provider": "minimax",    "mode": "api_key" }
  }
}

字段意思:

  • profiles 的 key 长这样 <provider>:<profile名>,后面那个名字纯粹是给你自己好认的;
  • provider 对应下面 models.providers 里的 provider id;
  • mode 目前只支持 api_key(OAuth 是预留的,还没开放)。

重点来了,也是我一开始最懵的地方:真正的 API key 根本不在这份 json 里。

网上有些老教程会让你把 apiKey 直接写在 models.providers.xxx 下面,那样确实能跑,但等于把 key 明文扔配置文件里了,不太安全。OpenClaw 实际的设计是:openclaw.json 只记"用哪个 provider + 哪个 profile",真正的凭证单独放在 Agent 的状态目录下:

~/.openclaw/agents/<agentId>/agent/auth-profiles.json

老版本的话在 ~/.openclaw/credentials/ 下。会话记录那些则在同目录的 openclaw-agent.sqlite 里。所以别在配置文件里找你的 key,找不到的

那怎么把 key 填进去?两条路:

# 方式一:配置向导,一步步选
openclaw configure
# 选 model providers → 选 minimax-cn → 粘贴 api_key

# 方式二:直接命令行登录
openclaw models auth setup-token

我比较推荐第二种,一行搞定,不用在向导里翻菜单。


五、models:怎么把大模型接进来

这段配的是"有哪些大模型可以用、走哪个端点"。我接的是 MiniMax:

"models": {
  "mode": "merge",
  "providers": {
    "minimax-cn": {
      "baseUrl": "https://api.minimaxi.com/anthropic",
      "api": "anthropic-messages",
      "authHeader": true,
      "models": [
        {
          "id": "MiniMax-M3",
          "name": "MiniMax M3",
          "reasoning": true,
          "input": ["text", "image"],
          "cost": {
            "input": 0.6,
            "output": 2.4,
            "cacheRead": 0.12,
            "cacheWrite": 0
          },
          "contextWindow": 1000000,
          "maxTokens": 131072
        }
      ]
    },
    "minimax": {
      "baseUrl": "https://api.minimaxi.com/anthropic"
      // ... 同上
    }
  }
}

挨个说:

  • mode: "merge":把你这里写的模型和 OpenClaw 内置的模型合并起来用,而不是覆盖。一般都填 merge;
  • providers.<名字>.baseUrl:provider 的 HTTP 端点;
  • providers.<名字>.api:API 协议风格。MiniMax 这个填 anthropic-messages——这里我专门查过,MiniMax 官方确实提供了 Anthropic 兼容端点 https://api.minimaxi.com/anthropic/v1/messages,M3 还支持 thinking 和工具调用,所以配成 anthropic 风格是没问题的;如果你接的是通义、Kimi 之类走 OpenAI 兼容的,就填 openai-chat-completions
  • providers.<名字>.authHeader: true:把 key 放在 x-api-key 头里(Anthropic 风格)。OpenAI 风格是 Authorization: Bearer ...,那种就不用开这个;
  • providers.<名字>.models[]:模型目录。

模型那一项里的字段:

  • id:模型的真实 id,调 API 时用的就是它;
  • name:界面上显示的名字,随你喜欢;
  • reasoning: true:这个模型支持扩展思考(思维链);
  • input:能吃 text / image / audio 哪几种输入;
  • cost:每 100 万 token 的价格(美元),OpenClaw 拿它来估算成本;
  • contextWindow:上下文窗口大小;
  • maxTokens:单次最多吐多少 token。

顺便解释个新手常见的疑惑:我这儿配了 minimax-cnminimax 两个 provider,baseUrl 还一模一样,这不是写错了吗?其实是历史遗留,最早一个走国内端点、一个走国际端点,后来 MiniMax 统一了,我也就没动。正常你留一个就行。多个 provider 的常见场景是:国内外端点不同、不同厂商(OpenAI / Anthropic / 自部署)、或者不同协议风格。


六、agents:整个配置的灵魂

多 Agent 的核心就在这一段。先看我配的三个:

"agents": {
  "defaults": {
    "model": { "primary": "minimax-cn/MiniMax-M3", "fallbacks": [] },
    "models": {
      "minimax-cn/MiniMax-M3": { "alias": "M3" },
      "minimax/MiniMax-M3":    { "alias": "Minimax" }
    },
    "workspace": "/Users/ajun/.openclaw/workspace"
  },
  "list": [
    {
      "id": "main",
      "tools": { "alsoAllow": ["message"] }
    },
    {
      "id": "aff",
      "name": "分析",
      "workspace": "/Users/ajun/projects/github/aff-data-analysis",
      "agentDir": "/Users/ajun/.openclaw/agents/aff/agent",
      "model": "minimax-cn/MiniMax-M3",
      "tools": { "alsoAllow": ["message"] }
    },
    {
      "id": "zhaochao",
      "name": "早朝官",
      "workspace": "/Users/ajun/.openclaw/workspace-zhaochao",
      "agentDir": "/Users/ajun/.openclaw/agents/zhaochao/agent",
      "model": "minimax-cn/MiniMax-M3",
      "tools": { "alsoAllow": ["message"] }
    }
  ]
}

defaults:所有 Agent 的默认值

  • model.primary:默认主模型,格式是 <provider>/<模型id>
  • model.fallbacks:主模型挂了的时候,依次往下试的备胎列表;
  • models.<主模型>.alias:模型在界面 / 提示词里的小名,方便看;
  • workspace:默认工作目录,Agent 就在这儿执行 shell、读写文件。

list[]:每个 Agent 的具体配置

  • id:唯一标识,后面 bindings 和命令行的 --agent 都靠它认人;
  • name:界面显示名;
  • workspace每个 Agent 可以有自己独立的工作目录,这点特别重要。比如我的 aff 这个分析 Agent,工作目录直接指到了 ~/projects/github/aff-data-analysis,这样它就能直接读改那个项目的代码,不用我再搬文件;main 默认用 ~/.openclaw/workspace
  • agentDir:OpenClaw 给这个 Agent 留的"私人小金库",存它的 session、模型配置、长期记忆;
  • model:覆盖 defaults.model.primary,让某个 Agent 单独换个模型;
  • tools.alsoAllow:在 tools.profile 基础上额外开几个工具。我给所有 Agent 都加了 ["message"],意思是允许它们主动给我发消息,不光是被动回消息——不然我的"早朝官"就做不到每天早上主动给我汇报了。

一个容易搞混的点:agentDir 不是 skill 目录

一开始我以为 agentDir 是放技能的地方,后来才发现不是。它存的是这个 Agent 的会话、记忆、凭证、模型注册表这些状态。

关于 skill 的加载,我得纠正一个网上常见的说法。有人(包括我自己一开始)以为"skill 全局共享、没法按 Agent 隔离",这其实不对。官方文档写得很清楚:

Skills 从每个 Agent 的工作区以及 ~/.openclaw/skills 共享根目录加载,然后按每个 Agent 的有效允许列表筛选。

也就是说,池子是共享的,但能上桌的菜可以按 Agent 限。用 agents.defaults.skills 设一个公共基线,再用 agents.list[].skills 给单个 Agent 开白名单 / 黑名单(注意:单个 Agent 里显式写的会替换默认值,不是合并,这点别踩)。

还有个配套设计:每个 Agent 可以有自己的 sandbox 和工具限制,比如给家庭群里那个 Agent 关掉 write / exec 这种危险工具:

{
  "id": "family",
  "sandbox": { "mode": "all", "scope": "agent" },
  "tools": {
    "allow": ["read"],
    "deny": ["exec", "write", "edit", "browser"]
  }
}

这点我觉得设计得很贴心,不同 Agent 给不同权限,不至于一个失控全家升天。


七、tools:给 Agent 发什么工具

"tools": {
  "profile": "coding"
}

OpenClaw 内置了几套工具集 profile,按场景打包好:

  • coding:编程场景(我用的就是这个),带 file_fetch / file_write / dir_list / pdf / tts 这些;
  • minimal:极简,只留最基本的消息类工具;
  • full:全开;
  • 其它 profile 看版本。

你去看日志,经常能翻到这种:

[agents/tool-policy] tool policy removed 24 tool(s) via tools.profile (coding):
agents_list, browser, canvas, dir_fetch, ...

意思就是:这个 Agent 用了 coding 工具集,下面列出的这些工具被屏蔽掉了(OpenClaw 内部会按 Agent 类型再细分一遍)。第一次看到这行日志别慌,这不是报错,是正常的策略输出。


八、commands / session / hooks

这三个比较短,一起说。

commands

"commands": {
  "native": "auto",
  "nativeSkills": "auto",
  "restart": true,
  "ownerDisplay": "raw",
  "ownerAllowFrom": [
    "feishu:ou_24c83fff63626f2b627e43046160d6d0"
  ]
}
  • native: "auto":自动决定把哪些内置命令(/help/status 这种)暴露给模型;
  • nativeSkills: "auto":要不要把 skill 也当命令暴露;
  • restart: true:网关自愈开关,配合 launchd 的 KeepAlive 双保险;
  • ownerDisplay: "raw":owner 标识原样显示,不打码;
  • ownerAllowFromowner 白名单,只有这里的 user id 能调管理类命令。

这个白名单一定要配,不然理论上谁发消息都能调你的管理命令,那就裸奔了。后面那个 ou_24c83fff... 就是飞书里你自己的 open_id,去飞书管理后台能查到。

session

"session": {
  "dmScope": "per-channel-peer"
}

dmScope 决定私聊的 session 怎么复用,三种:

  • per-channel-peer:同一个(渠道, 用户)共享一个 session。推荐,我的 aff 用的就是这种,跟同一个人聊就一直有上下文;
  • global:所有消息共用一个 session,会串话,一般别用;
  • per-channel:同渠道所有人共用一个 session,也会串。

hooks

"hooks": {
  "internal": {
    "enabled": true,
    "entries": {
      "boot-md":               { "enabled": true },
      "bootstrap-extra-files": { "enabled": true },
      "command-logger":        { "enabled": true },
      "session-memory":        { "enabled": true }
    }
  }
}

这几个是 OpenClaw 启动时内部跑的 hook:

  • boot-md:启动时读 Agent 工作区里的 markdown,注入到 system prompt。它读的核心是 AGENTS.mdSOUL.mdUSER.md 这几个,完整的还有 MEMORY.mdHEARTBEAT.mdIDENTITY.mdBOOT.md这几个文件写得好不好,直接决定你的 Agent 好不好用,后面可以单开一篇细说;
  • bootstrap-extra-files:扫 agentDir 里的额外文件;
  • command-logger:所有命令行 / API 调用记日志,排查问题的时候特别香;
  • session-memory:把会话历史压缩进长期记忆,让它越用越懂你。

装的时候向导最后会让你勾选这几个,我建议都开,没坏处。


九、channels:飞书多 Bot 怎么挂

这段是接飞书的关键,我配了多账号结构:

"channels": {
  "feishu": {
    "enabled": true,
    "connectionMode": "websocket",
    "domain": "feishu",
    "groupPolicy": "open",
    "defaultAccount": "default",
    "accounts": {
      "default": {
        "enabled": true,
        "name": "default",
        "appId": "cli_a9315dd166789bb3",
        "appSecret": "<YOUR_LARK_APP_SECRET>",
        "connectionMode": "websocket",
        "domain": "feishu",
        "groupPolicy": "allowlist",
        "groupAllowFrom": ["ou_24c83fff63626f2b627e43046160d6d0"],
        "allowFrom":      ["ou_24c83fff63626f2b627e43046160d6d0"]
      },
      "bot2": { "name": "aff-bot", "appId": "...", "appSecret": "..." },
      "bot3": { "name": "bot3",    "appId": "...", "appSecret": "..." }
    }
  }
}

顶层几个字段

  • enabled:飞书集成的总开关;
  • connectionMode: "websocket"长连接模式,强烈推荐。本机直接和飞书服务器保持一条长连接,不需要公网 IP。另一个选项是 webhook,那个要公网回调地址,本地玩不转,别选;
  • domain: "feishu":国内飞书。境外 Lark 填 "lark"
  • groupPolicy: "open":群消息策略,顶层我开了 open;
  • defaultAccount: "default":匹配不到具体账号时的兜底。

每个飞书账号

  • appId / appSecret:去 open.feishu.cn/app 建个自建应用,凭证页面就能拿到。App Secret 跟密码一样,别泄露
  • name:给人看的名(aff-bot、bot3 之类);
  • groupPolicy:群消息策略(open / allowlist / closed);
  • groupAllowFrom / allowFrom:群消息 / 私聊的白名单,放 user open_id。

如果你的场景简单(就挂一个 bot),其实不用这么复杂,写成顶层的扁平结构也行:

"channels": {
  "feishu": {
    "enabled": true,
    "appId": "cli_xxx",
    "appSecret": "xxx",
    "connectionMode": "websocket"
  }
}

多账号到底图啥

一句话:一机多 Agent,用不同飞书 bot 隔离开

  • 飞书 default 这个 bot → 绑 main Agent(日常聊天);
  • 飞书 bot2 = aff-bot → 绑 aff Agent(数据分析);
  • 飞书 bot3 → 绑 zhaochao Agent(杂活汇报)。

这样同一台机器上,三个 Agent 互不打扰,各自有自己的记忆、各自的飞书入口。对外的体验就是:我在飞书里跟不同 bot 说话,就是在跟不同的"员工"派活。

配对(pairing)这个坎儿

接飞书还有一步新手特别容易卡:配对。机器人刚加上不会马上回消息,得先走配对流程,相当于加个好友验证。

# 看谁在请求配对
openclaw pairing list feishu

# 批准(CODE 换成实际的配对码)
openclaw pairing approve feishu <CODE>

我当时就是没配对,对着机器人发了半天消息没反应,还以为是配置错了,查半天日志。记住:机器人不回消息,先 openclaw pairing list 看看是不是卡在配对上。


十、gateway:本地这个 HTTP 服务

"gateway": {
  "port": 18789,
  "mode": "local",
  "bind": "loopback",
  "auth": {
    "mode": "token",
    "token": "<YOUR_GATEWAY_TOKEN>"
  },
  "tailscale": {
    "mode": "off",
    "resetOnExit": false
  }
}
  • port: 18789:本地 HTTP 端口,这是默认值。网页控制台(Control UI)和 ACP 后端都挂在它上面。访问 http://127.0.0.1:18789/ 就是管理界面;
  • mode: "local":本地模式(另一个是 "tailscale",走 Tailscale 网络);
  • bind: "loopback":只监听 127.0.0.1,安全。想从外网访问得用 Tailscale、ngrok 或者反向代理,别图省事直接 bind 到 0.0.0.0;
  • auth.mode: "token":用静态 token 鉴权;
  • tailscale.mode: "off":我没用 Tailscale,关掉。

token 自己生成一个就行:

openssl rand -hex 32   # 生成 64 位 hex

端口被占了怎么办:这是最常见的启动失败原因。先查一下端口:

# macOS / Linux
lsof -i :18789
# 或者
ps aux | grep openclaw

# Windows
netstat -ano | findstr 18789

确认是旧进程没退干净就 kill 掉,或者干脆换个端口。要换端口的话,除了改 gateway.port,launchd 那边如果有显式端口绑定也得同步改。

另外提一个很实用的点:配置改完怎么生效。第一选择永远是这条:

openclaw gateway restart

跨平台、官方推荐。改完配置记得先校验 JSON 没写错再重启:

# 校验配置合法性(这命令救过我好几回)
openclaw config validate

# 重启
openclaw gateway restart

macOS 上如果你是手动装的守护进程,也可以用 launchctl 那一套(但能用 openclaw gateway restart 就别折腾 launchctl 了):

launchctl unload ~/Library/LaunchAgents/ai.openclaw.gateway.plist
launchctl load   ~/Library/LaunchAgents/ai.openclaw.gateway.plist

OpenClaw 还有个热重载机制,默认 hybrid 模式——能热加载的就热加载(不中断连接),必须重启的才重启。所以有些小改动其实不用手动 restart。但新手老老实实 restart 最稳。


十一、plugins:插件加载

"plugins": {
  "load": {
    "paths": [
      "/Users/ajun/.openclaw/npm/projects/openclaw-feishu-.../node_modules/@openclaw/feishu"
    ]
  },
  "entries": {
    "feishu":       { "enabled": true },
    "minimax":      { "enabled": true },
    "memory-core":  { "config": { "dreaming": { "enabled": true } }, "enabled": true }
  }
}
  • load.paths:从哪些本地路径加载插件,一般是 npm 全局装完后的真实路径;
  • entries.<插件名>.enabled:插件开关;
  • memory-core.dreaming:memory-core 插件的"梦境"配置,后台会周期性跑叙事生成、整理记忆,让它记得更牢。

装插件用命令,别手动往 paths 里塞:

openclaw plugins list                          # 看装了啥
openclaw plugins install @openclaw/voice-call  # 装官方插件
openclaw plugins enable feishu                 # 启用
openclaw gateway restart                       # 装完记得重启

十二、skills:技能开关

"skills": {
  "entries": {
    "api-gateway":   { "enabled": false },
    "gog":           { "enabled": false },
    "summarize":     { "enabled": false }
  }
}

这里有个反直觉的点,我愣了一会儿才反应过来:这里出现的,都是默认禁用的 skill;已经启用的反而不在这里出现(默认就是启用)。

所以你想彻底关掉某个 skill,就往这儿加一条 "enabled": false

技能的来源,新手我强烈推荐走 ClawHub(官方技能市场,clawhub.ai,国内有镜像 skillhub.tencent.com),别随便从野路子装,风险很大

# 装 clawhub 工具(推荐 npx,不用全局装)
npx clawhub@latest --version

# 搜技能
clawhub search "postgres backups"

# 装一个
clawhub install my-skill-pack

# 批量更新
clawhub update --all

装完看一眼状态:

openclaw skills list      # 列出所有技能
openclaw skills info <名字>  # 看详情

skills list 输出里,技能状态分几种:

  • ✓ ready:环境齐了,Agent 能直接用;
  • △ Needs setup:缺环境变量,得去 service-env/*.env 里补;
  • disabled:被 skills.entries 关了;
  • 啥都没有:文件在,但元数据不够,OpenClaw 认不出来。

十三、bindings:消息路由表(最容易踩坑)

⭐ 这一段是整个系统里最关键的部分:一条飞书消息到底该送给哪个 Agent。

"bindings": [
  { "agentId": "main",     "match": { "channel": "feishu", "accountId": "default" } },
  { "agentId": "aff",      "match": { "channel": "feishu", "accountId": "bot2" } },
  { "agentId": "zhaochao", "match": { "channel": "feishu", "accountId": "bot3" } }
]

bindings 是个有序数组,从上往下匹配,第一条命中的生效

  • default 飞书账号 → main Agent;
  • bot2 = aff-botaff Agent;
  • bot3zhaochao Agent。

几个匹配规则,必须记住

  1. 顺序就是优先级。把最具体的规则放前面,最宽的放后面。顺序错了,就会出现"明明发给 bot2 的消息被 main 收了"这种鬼故事;
  2. 多个字段是 AND 关系。一条 binding 里同时写了 peerguildId,那必须俩都匹配才生效;
  3. 省略 accountId 只匹配默认账号,不是匹配所有账号。要"渠道级兜底"用 accountId: "*"
  4. 对端(peer)匹配永远优先于渠道级规则。想给某个特定的人 / 群单独路由,就用 match.peer,把它写在前面。

举个高级点的例子——WhatsApp 一个号,按发件人拆给不同 Agent:

"bindings": [
  { "agentId": "alex", "match": { "channel": "whatsapp", "peer": { "kind": "direct", "id": "+15551230001" } } },
  { "agentId": "mia",  "match": { "channel": "whatsapp", "peer": { "kind": "direct", "id": "+15551230002" } } }
]

加一个新 Agent 的标准三连

# 1. 创建 Agent
openclaw agents add myagent --workspace /path/to/project

# 2. 手动在 channels.feishu.accounts 加一个 bot 账号(比如 bot4)
#    填上对应的 appId / appSecret

# 3. bindings 加一条
# { "agentId": "myagent", "match": { "channel": "feishu", "accountId": "bot4" } }

# 然后验证一下
openclaw agents list --bindings
openclaw channels status --probe

最后别忘了 openclaw gateway restart


十四、acp:让 Claude Code 给你打黑工

这一段我最开始理解错了,得重点纠正一下。

"acp": {
  "enabled": true,
  "backend": "acpx",
  "defaultAgent": "claude",
  "allowedAgents": ["claude", "codex", "cursor", "gemini", "qwen", "copilot"],
  "maxConcurrentSessions": 4,
  "stream": {
    "coalesceIdleMs": 300,
    "maxChunkChars": 1200
  },
  "runtime": {
    "ttlMinutes": 120
  }
}

先说 ACP 是什么。我以前以为它是 Anthropic 家的协议,后来查了才搞明白:ACP 全称 Agent Client Protocol,是一个开放协议(规范在 agentclientprotocol.com),不是哪一家私有的。在 OpenClaw 里,它通过 acpx 插件实现,作用是把本地那些命令行编码 Agent——Claude Code、Codex、Gemini CLI、Cursor、OpenCode——统一接进来当"执行层"。

说白了,架构是分层的:

你(在飞书发消息)
   ↓
OpenClaw Agent(决策层:理解你要干嘛)
   ↓ 通过 ACP
acpx(中层:管 session、任务队列、上下文)
   ↓
Claude Code / Codex / Gemini CLI(执行层:真去改代码、跑 git)

这样我在飞书里说一句"把登录接口加上限流",OpenClaw 的 Agent 就能 spawn 一个 Claude Code 去真改代码、提交,完全不用我开终端

字段意思:

  • backend: "acpx":用 acpx 这个实现,它是 openclaw/acpx 这个仓库,headless CLI 客户端;
  • defaultAgent: "claude":默认 spawn claude(Claude Code);
  • allowedAgents白名单,只允许这里列的 CLI 被 spawn,防止 Agent 乱拉进程;
  • maxConcurrentSessions: 4:同时最多 4 个 ACP session;
  • stream.coalesceIdleMs:流式输出的合并间隔,减少飞书卡片刷新次数(飞书卡片更新太频繁会限流);
  • stream.maxChunkChars:单个 chunk 最大字符数,也是为了迁就飞书卡片限制;
  • runtime.ttlMinutes: 120:ACP session 的缓存时间,两小时。

一个必填项,我踩过坑

acpx 装好之后,还有一个配置特别容易漏:因为 ACP 会话是非交互式的(没人坐在那儿点同意),所以必须把权限模式设成全部放行,不然 Claude Code 卡在那儿等批准,一直没动静:

// 在对应 Agent 或 acpx 配置里
"permissionMode": "approve-all"

装 acpx 插件本身:

openclaw plugins install @openclaw/acpx
openclaw gateway restart

弄好之后,让 Agent 内部调 acp spawn claude,OpenClaw 就会自动拉起 Claude Code 去干活。普通用户到这一步就够了,ACP 底层的 WebSocket 细节完全不用管,它自己跑。


十五、几个常见改动场景

把上面零碎的字段串一下,挑几个最常干的事。

场景 A:加个新飞书 bot + 新 Agent

# 1. 建 Agent
openclaw agents add devops \
    --name "DevOps" \
    --workspace ~/projects/devops-scripts

# 2. 手动编辑 openclaw.json,在 channels.feishu.accounts 下加 bot4
#    (填从飞书开放平台拿到的 appId / appSecret)

# 3. bindings 加一条
#    { "agentId": "devops", "match": { "channel": "feishu", "accountId": "bot4" } }

# 4. 校验 + 重启
openclaw config validate
openclaw gateway restart

场景 B:换个默认模型

models.providers.<名字>.models[].id 改成新模型,然后在 agents.defaults.model.primary<provider>/<模型id> 引用也同步更新。别只改一半,会出现"模型没配置"的提示。

场景 C:禁掉某个 skill

"skills": {
  "entries": {
    "summarize": { "enabled": false }
  }
}

场景 D:换 gateway 端口

gateway.port,launchd 那边如果有显式端口绑定也要一起改,然后重启。


十六、新机器第一次配置清单

换台机器从头配,按这个顺序走基本能起来:

  1. 装本体。一行命令(macOS / Linux):curl -fsSL https://openclaw.ai/install.sh | bash;Windows PowerShell:iwr -useb https://openclaw.ai/install.ps1 | iex。或者 npm i -g openclaw(要 Node.js ≥ 22);
  2. 跑引导:openclaw onboard --install-daemon--install-daemon 让它开机自启);
  3. 配模型:向导里选 provider、填 key,或者后面 openclaw models auth setup-token
  4. 接飞书:openclaw channels add 选 Feishu,填 appId / appSecret;
  5. 建 Agent:openclaw agents add
  6. bindings 路由;
  7. 检查:openclaw agents list --bindingsopenclaw skills list
  8. 健康检查:openclaw doctor(支持 --deep);
  9. 看环境变量齐不齐:openclaw config get 或者直接翻 ~/.openclaw/service-env/ 下的 env 文件;
  10. 重启 + 测试:openclaw gateway restart,然后飞书发条消息,记得先 openclaw pairing list / pairing approve 走配对。

跑顺了之后,日常就靠这几个命令活着:

openclaw status           # 整体状态
openclaw gateway status   # 网关进程状态
openclaw logs --follow    # 实时日志,排查必备
openclaw dashboard        # 浏览器打开控制台( http://127.0.0.1:18789/ )
openclaw tui              # 终端里直接聊,SSH 进服务器也能用

十七、我踩过的坑(按时间顺序)

现象 解法
webhook 模式收不到消息 本机怎么都不回 改用 connectionMode: "websocket",长连接不需要公网
没配 ownerAllowFrom 谁都能调管理命令 填自己的 feishu:ou_xxx
忘了配对 机器人死活不回消息 openclaw pairing list feishu 看请求,再 pairing approve
bindings 顺序乱 发给 bot2 的消息被 main 收了 调顺序,具体规则在前,兜底在后
acp.allowedAgents 没配 ACP 默认啥都不让 spawn "claude" / "codex" 加进白名单
ACP 没设 permissionMode Claude Code 卡住不干活 设成 "approve-all"(非交互式必需)
模型没填 id openclaw skills info 显示模型未配置 补上 id 字段
改完配置没生效 新配置像没起作用 openclaw config validate 校验 → openclaw gateway restart
端口冲突起不来 gateway 启动失败 lsof -i :18789 查占用,kill 掉或换端口
以为 skill 全局共享没法隔离 给敏感 Agent 配了危险工具 agents.list[].skillstools.allow/deny 按 Agent 限权

十八、字段速查表(收藏用)

按字母序排,方便以后翻:

字段 类型 默认 备注
acp.allowedAgents list 白名单 CLI 名
acp.backend str "acpx" ACP 实现
acp.defaultAgent str 默认 spawn 哪个
acp.enabled bool false 总开关
acp.maxConcurrentSessions int 4 并发上限
acp.runtime.ttlMinutes int 120 session 缓存分钟
agents.defaults.model.primary str <provider>/<模型>
agents.defaults.skills dict 共享 skill 基线
agents.list[].agentDir path Agent 私有状态目录
agents.list[].skills dict 每 Agent 的 skill 允许列表(替换默认值)
agents.list[].workspace path Agent 工作目录
auth.profiles dict <provider>:<名字> → profile
bindings[].agentId str 必须对上 agents.list[].id
bindings[].match.accountId str 必须对上 channels.<渠道>.accounts 的 key,"*" 表示渠道兜底
bindings[].match.channel str "feishu"
channels.feishu.accounts dict 每个 account = 一个飞书 bot
channels.feishu.connectionMode str 推荐 "websocket"
commands.ownerAllowFrom list owner 白名单
gateway.auth.token str 随机 hex token
gateway.bind str "loopback" "loopback" / "all"
gateway.port int 18789 本地端口
models.providers[].api str "anthropic-messages" / "openai-chat-completions"
models.providers[].baseUrl url 大模型端点
models.providers[].models[].id str 模型真实 id
models.providers[].models[].reasoning bool 支不支持 thinking
session.dmScope str "per-channel-peer" / "global"
skills.entries dict 显式禁用某些 skill
tools.profile str coding / minimal / full

小结

OpenClaw 这份 openclaw.json 看着字段多,其实顺着"渠道进来 → bindings 路由 → agents 处理 → models 出答案 → tools/skills 打辅助 → acp 接外部编码 CLI"这条线捋一遍,就清楚了。

真正卡人的就那几个地方:飞书用 websocket 别用 webhook、bindings 顺序、pairing 配对、acp 的 allowedAgents 和 permissionMode、改完记得 restart。这几个坎过了,剩下就是按需调参。

要是你也在折腾 OpenClaw 接飞书,欢迎评论区交流。下一篇我打算写写那几个 workspace 里的 markdown(SOUL.mdAGENTS.mdUSER.mdMEMORY.md),那几个文件才是决定 Agent "好不好用、像不像你想要的那个人"的关键。


参考资料

posted @ 2026-07-22 22:52  AJun816  阅读(19)  评论(0)    收藏  举报