EN
article

OpenClaw 技术深度剖析与部署配置指南

2026/03/04

深入代码与企业级应用分析与部署

技术调研文档 | 版本:v2.6 | 更新日期:2026 年 3 月 3 日
修订: 见后文更新日志 适用对象: 开发者、技术决策者、AI 工程师、运维工程师
预计阅读时间: 45-60 分钟
文档类型: 纯 Markdown 技术文档(无外部图片依赖) 源码版本: 基于官方源码 v1.2+


📝 更新日志

v2.6 (2026-03-03) - 第 10 章:高级主题与企业级解决方案

第 10 章 高级主题与企业级解决方案 (新增,+1200 行):

  • ✅ 10.1 流式响应优化 (块流式传输/打字机效果/响应预加载)
  • ✅ 10.1 性能基准测试 (首字延迟从 2500ms 降至 320ms,降低 87%)
  • ✅ 10.2 多模态支持 (图像理解/语音转文字/视频帧提取)
  • ✅ 10.2 多模态统一配置模板 (Whisper/ElevenLabs/FFmpeg)
  • ✅ 10.3 企业版 RBAC 权限管理 (4 角色模型/工具审批)
  • ✅ 10.3 企业版审计日志 (6 类事件/告警规则/查询导出)
  • ✅ 10.3 企业版 SSO 单点登录 (Pomerium/Cloudflare/Authelia)
  • ✅ 10.3 企业版完整配置模板 (生产环境就绪)

性能优化成果:

  • 流式响应:首字延迟 2500ms → 320ms (降低 87%)
  • 用户满意度:⭐⭐⭐ → ⭐⭐⭐⭐⭐
  • 多模态支持:图像/语音/视频理解增强
  • 企业版功能:RBAC/审计/SSO 生产环境就绪

v2.5 (2026-03-03) - 第 4-5 章源码级更新

第 4 章 多 Agent 路由系统 (完整重写,+600 行):

  • ✅ 4.1 Agent 配置结构 (AgentConfig TypeScript 定义,50+ 字段详解)
  • ✅ 4.1 Agent 物理存储结构 (~/.openclaw/agents//)
  • ✅ 4.1 Agent 隔离边界 (会话/记忆/技能/模型/工具/沙箱隔离)
  • ✅ 4.2 路由匹配算法 (resolveAgentRoute 源码解析,8 级优先级)
  • ✅ 4.2 会话键生成规则 (buildAgentSessionKey,5 种 dmScope 模式)
  • ✅ 4.3 配置示例 (4 种场景:双通道/Discord 角色/飞书多账号/线程继承)
  • ✅ 4.4 Agent-to-Agent 通信 (sessions_send/sessions_spawn 工具定义)
  • ✅ 4.4 通信模式 (请求 - 响应/任务分发/持久会话)
  • ✅ 4.4 跨境电商多 Agent 完整工作流 (ASCII 架构图 + 代码实现)

第 5 章 部署配置全指南 (完整重写,+800 行):

  • ✅ 5.3 完整配置 Schema (OpenClawConfig TypeScript 定义,10 大配置块)
  • ✅ 5.3 核心配置项详解 (agents/bindings/session/gateway/channels/models/tools/hooks/cron/skills)
  • ✅ 5.4 环境变量配置 (完整环境变量列表,60+ 变量详解)
  • ✅ 5.4 环境变量使用方式 (${ENV} 语法/env.vars/env.shellEnv)
  • ✅ 5.5 Docker 部署 (Dockerfile 多阶段构建/docker-compose.yml/健康检查)
  • ✅ 5.5 Docker 注意事项 (数据持久化/沙箱支持/TLS/日志管理)
  • ✅ 5.6 Systemd 服务配置 (服务文件/EnvironmentFile/安全加固)
  • ✅ 5.6 部署步骤/常用命令/日志轮转/监控告警

源码依据:

  • /opt/homebrew/lib/node_modules/openclaw/dist/plugin-sdk/config/types.openclaw.d.ts
  • /opt/homebrew/lib/node_modules/openclaw/dist/plugin-sdk/config/types.agents.d.ts
  • /opt/homebrew/lib/node_modules/openclaw/dist/plugin-sdk/config/types.base.d.ts
  • /opt/homebrew/lib/node_modules/openclaw/dist/plugin-sdk/config/types.gateway.d.ts
  • /opt/homebrew/lib/node_modules/openclaw/dist/plugin-sdk/routing/resolve-route.d.ts
  • /opt/homebrew/lib/node_modules/openclaw/dist/plugin-sdk/routing/session-key.ts

v2.4 (2026-03-02) - 第 3 章源码级更新

  • ✅ 3.1 多通道支持 (ChannelPlugin 架构,11 个适配器接口)
  • ✅ 3.2 会话存储结构 (SessionEntry 50+ 字段,JSONL 事件格式)
  • ✅ 3.3 工具系统 (TypeBox schemas,权限模式,沙箱执行)
  • ✅ 3.4 技能系统 (4 种来源,SKILL.md frontmatter,ClawHub CLI)

v2.3 (2026-03-02) - 架构更新

  • ✅ 第 2 章 ASCII/Mermaid 图表替换
  • ✅ 第 2 章 连接生命周期/数据流详解

v2.0 (2026-03-01) - 初始纯 Markdown 版本

  • ✅ 去除所有外部图片依赖
  • ✅ 改用 ASCII/Mermaid 线框图

v1.0 (2026-03-01) - 初稿


📋 目录

  1. OpenClaw 是什么?
  2. 核心架构剖析
  3. 关键特性深度解析
  4. 多 Agent 路由系统
  5. 部署配置全指南
  6. 安全与权限管理
  7. 实战案例:跨境电商多 Agent 系统
  8. 性能优化与故障排查
  9. 总结与展望
  10. 高级主题与企业级解决方案

1. OpenClaw 是什么?

1.1 产品定位

OpenClaw 是一个自托管的 AI Agent 网关,它将你常用的聊天应用(WhatsApp、Telegram、Discord、iMessage 等)与 AI 编码 Agent(如 Pi、Claude Code 等)连接起来。

💡 一句话理解: 在你的口袋里,随时随地通过消息与 AI 助手对话。

1.2 目标用户

用户类型需求场景
开发者需要随时随地的 AI 编程助手
技术决策者需要私有化部署,数据可控
AI 工程师需要多 Agent 协作系统
极客用户需要高度自定义的 AI 工作流

1.3 核心差异化优势

特性OpenClaw其他方案
部署模式自托管,数据本地SaaS 托管,数据第三方
多通道支持单一网关支持 WhatsApp/Telegram/Discord 等通常单通道
Agent 原生内置工具调用、会话管理、多 Agent 路由需要自行实现
开源许可MIT 许可,社区驱动闭源或商业许可
移动端支持iOS/Android 节点,支持 Camera/Canvas通常无

1.4 系统要求

# 最低要求
- Node.js 22+
- 512MB RAM (基础部署)
- 1GB 磁盘空间

# 推荐配置
- Node.js 22+
- 2GB+ RAM (多 Agent 场景)
- 10GB+ 磁盘空间
- macOS / Linux / Docker

2. 核心架构剖析

2.1 整体架构图

┌─────────────────────────────────────────────────────────────────────────────────┐
│                           用户侧 (User Side)                                    │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐            │
│  │  WhatsApp   │  │  Telegram   │  │   Discord   │  │   Feishu    │            │
│  │   (Baileys) │  │  (grammY)   │  │ (discord.js)│  │  (WebSocket)│            │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘            │
│         │                │                │                │                    │
│         └────────────────┴────────────────┴────────────────┘                    │
│                                  │                                              │
│                         ┌────────▼────────┐                                     │
│                         │   Gateway WS    │  端口:18789                        │
│                         │   (统一入口)     │  协议:WebSocket                    │
│                         └────────┬────────┘                                     │
└──────────────────────────────────│──────────────────────────────────────────────┘
                                   │
┌──────────────────────────────────▼──────────────────────────────────────────────┐
│                        OpenClaw Gateway (核心中枢)                               │
│  ┌───────────────────────────────────────────────────────────────────────────┐  │
│  │  连接层 (Connection Layer)                                                 │  │
│  │  • 通道适配器 (Channel Adapters)  • 认证中间件 (Auth Middleware)          │  │
│  │  • 消息队列 (Message Queue)       • 速率限制 (Rate Limiter)               │  │
│  └───────────────────────────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────────────────────────┐  │
│  │  路由层 (Routing Layer)                                                    │  │
│  │  • Binding 匹配引擎  • Peer 识别  • Guild/Role 路由  • Fallback 策略      │  │
│  └───────────────────────────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────────────────────────┐  │
│  │  Agent 运行时层 (Agent Runtime Layer)                                      │  │
│  │  • 会话管理 (Session Mgr)  • 工具执行器 (Tool Executor)                   │  │
│  │  • 上下文压缩 (Compaction)  • 记忆系统 (Memory)                           │  │
│  └───────────────────────────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────────────────────────┐  │
│  │  工具层 (Tool Layer)                                                       │  │
│  │  read/write/edit | exec/process | browser/web_search | sessions_* | ...   │  │
│  └───────────────────────────────────────────────────────────────────────────┘  │
└──────────────────────────────────│──────────────────────────────────────────────┘
                                   │
┌──────────────────────────────────▼──────────────────────────────────────────────┐
│                           Agent 工作区 (Agent Workspace)                         │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐                 │
│  │  workspace-main │  │ workspace-coding│  │ workspace-lead  │                 │
│  │  ┌───────────┐  │  │  ┌───────────┐  │  │  ┌───────────┐  │                 │
│  │  │ SOUL.md   │  │  │  │ SOUL.md   │  │  │  │ SOUL.md   │  │                 │
│  │  │ MEMORY.md │  │  │  │ MEMORY.md │  │  │  │ MEMORY.md │  │                 │
│  │  │ skills/   │  │  │  │ skills/   │  │  │  │ skills/   │  │                 │
│  │  └───────────┘  │  │  └───────────┘  │  │  └───────────┘  │                 │
│  └─────────────────┘  └─────────────────┘  └─────────────────┘                 │
│                                  │                                              │
│                         ┌────────▼────────┐                                     │
│                         │  LLM Provider   │                                     │
│                         │  (DashScope/    │                                     │
│                         │   Anthropic/    │                                     │
│                         │   Google/...)   │                                     │
│                         └─────────────────┘                                     │
└─────────────────────────────────────────────────────────────────────────────────┘

                                   │
┌──────────────────────────────────▼──────────────────────────────────────────────┐
│                           移动端节点 (Mobile Nodes)                              │
│  ┌─────────────────┐  ┌─────────────────┐                                       │
│  │   iOS Node      │  │  Android Node   │                                       │
│  │  • Camera       │  │  • Camera       │                                       │
│  │  • Screen       │  │  • Screen       │                                       │
│  │  • Location     │  │  • Location     │                                       │
│  │  • Canvas       │  │  • Canvas       │                                       │
│  └─────────────────┘  └─────────────────┘                                       │
└─────────────────────────────────────────────────────────────────────────────────┘

图注:

  • 实线箭头 ──► 表示数据流向
  • 方框 ┌─┐ 表示组件/模块
  • 层级从上到下:用户侧 → Gateway → Agent 工作区 → LLM Provider

2.2 核心组件

Gateway(网关守护进程)

职责: 单一事实来源,所有消息路由的中枢

┌─────────────────────────────────────────────────────────┐
│                      Gateway                            │
├─────────────────────────────────────────────────────────┤
│  • WebSocket 服务器 (默认 127.0.0.1:18789)              │
│  • 通道连接器 (WhatsApp/Telegram/Discord/...)           │
│  • Agent 运行时 (Pi/Claude Code/...)                    │
│  • 会话管理器 (Sessions + Memory)                       │
│  • 工具执行器 (Exec/Browser/Canvas/...)                 │
└─────────────────────────────────────────────────────────┘

关键特性:

  • 单实例运行(每主机一个 Gateway)
  • WebSocket 长连接(控制平面客户端)
  • 支持多通道并发连接
  • 内置会话状态管理

控制平面客户端

客户端连接方式用途
macOS AppWebSocket菜单栏控制、Canvas、语音
CLIWebSocket命令行管理、自动化脚本
Web Control UIWebSocket浏览器管理界面
自动化 (Cron/Hooks)WebSocket定时任务、事件触发

Nodes(移动节点)

┌─────────────────────────────────────────────────────────┐
│                    Node (iOS/Android)                   │
├─────────────────────────────────────────────────────────┤
│  • Camera Capture (拍照/录像)                           │
│  • Screen Recording (屏幕录制)                          │
│  • Location Services (位置服务)                         │
│  • Voice Overlay (语音覆盖层)                           │
│  • Canvas Rendering (网页渲染)                          │
└─────────────────────────────────────────────────────────┘

连接模式: 与 Gateway 建立 WebSocket 连接,声明 role: node

2.3 连接生命周期

WebSocket 协议详解

连接建立阶段:

┌──────────────┐                              ┌──────────────┐
│    Client    │                              │   Gateway    │
│  (Control)   │                              │   (Server)   │
└──────┬───────┘                              └──────┬───────┘
       │                                            │
       │  ─────────────────────────────────────►    │
       │  WS Connect: ws://127.0.0.1:18789          │
       │  Headers:                                  │
       │    • Authorization: Bearer <token>         │
       │    • X-Device-Id: <device-fingerprint>     │
       │    • X-Client-Version: 1.2.3               │
       │                                            │
       │  ◄─────────────────────────────────────    │
       │  HTTP 101 Switching Protocols              │
       │                                            │
       │  ─────────────────────────────────────►    │
       │  req:connect {                             │
       │    auth: { token: "xxx" },                 │
       │    device: { id: "macbook-pro", ... }      │
       │  }                                         │
       │                                            │
       │  ◄─────────────────────────────────────    │
       │  res:connect {                             │
       │    ok: true,                               │
       │    token: <device-token>,                  │
       │    expires: 1709424000000                  │
       │  }                                         │
       │                                            │
       │  ◄─────────────────────────────────────    │
       │  event:presence {                          │
       │    agents: [...], channels: [...]          │
       │  }                                         │
       │                                            │
       │  ◄─────────────────────────────────────    │
       │  event:tick (心跳,每 30 秒)                  │
       │                                            │

消息发送阶段:

┌──────────────┐                              ┌──────────────┐
│    Client    │                              │   Gateway    │
└──────┬───────┘                              └──────┬───────┘
       │                                            │
       │  ─────────────────────────────────────►    │
       │  req:agent {                               │
       │    agentId: "main",                        │
       │    sessionKey: "agent:main:xxx",           │
       │    message: "Hello",                       │
       │    context: { channel: "whatsapp", ... }   │
       │  }                                         │
       │                                            │
       │  ◄─────────────────────────────────────    │
       │  res:agent {                               │
       │    ok: true,                               │
       │    runId: "run_abc123",                    │
       │    status: "accepted"                      │
       │  }                                         │
       │                                            │
       │  ◄─────────────────────────────────────    │
       │  event:agent {                             │
       │    runId: "run_abc123",                    │
       │    type: "chunk",                          │
       │    content: "Hello! How can I..."          │
       │  }                                         │
       │                                            │
       │  ◄─────────────────────────────────────    │
       │  event:agent {                             │
       │    runId: "run_abc123",                    │
       │    type: "tool_call",                      │
       │    tool: "read", args: {...}               │
       │  }                                         │
       │                                            │
       │  ◄─────────────────────────────────────    │
       │  res:agent {                               │
       │    runId: "run_abc123",                    │
       │    status: "completed",                    │
       │    summary: "Answered user question"       │
       │  }                                         │
       │                                            │

协议字段说明

字段类型必填说明
req:connect.auth.tokenstringGateway 认证 token
req:connect.device.idstring设备唯一标识
req:agent.agentIdstring目标 Agent ID
req:agent.sessionKeystring会话键 (用于上下文关联)
req:agent.messagestring用户消息内容
res:agent.runIdstring本次运行的唯一标识
event:agent.typestringchunk | tool_call | tool_result | error

心跳与重连机制

// 客户端心跳处理伪代码
class GatewayClient {
  constructor() {
    this.heartbeatInterval = 30000;  // 30 秒
    this.reconnectDelay = 1000;      // 初始重连延迟 1 秒
    this.maxReconnectDelay = 30000;  // 最大重连延迟 30 秒
  }

  async connect() {
    while (true) {
      try {
        await this.ws.connect();
        this.reconnectDelay = 1000;  // 重置重连延迟
        this.startHeartbeat();
        await this.ws.waitForClose();
      } catch (e) {
        this.reconnectDelay = Math.min(
          this.reconnectDelay * 1.5,   // 指数退避
          this.maxReconnectDelay
        );
        await sleep(this.reconnectDelay);
      }
    }
  }

  startHeartbeat() {
    setInterval(() => {
      this.ws.send({ type: 'ping', ts: Date.now() });
    }, this.heartbeatInterval);
  }
}

2.4 数据流

** inbound (用户 → Agent)**:

WhatsApp/Telegram → Gateway → 路由匹配 → Agent Workspace → LLM Provider

outbound (Agent → 用户):

LLM Provider → Agent → Gateway → 通道发送 → WhatsApp/Telegram

3. 关键特性深度解析

3.1 多通道支持

通道架构

┌─────────────────────────────────────────────────────────────────────────────────┐
│                           通道插件架构 (Channel Plugin Architecture)             │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  【通道适配器接口】(Channel Adapter Interfaces)                                  │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  ChannelMessagingAdapter    - 消息收发 (inbound/outbound)                │    │
│  │  ChannelGroupAdapter        - 群组管理 (groups, members, roles)          │    │
│  │  ChannelThreadingAdapter    - 线程/回复链 (threads, reply_to)            │    │
│  │  ChannelStreamingAdapter    - 流式消息 (typing, chunks)                  │    │
│  │  ChannelPairingAdapter      - 设备配对 (QR 码,OAuth)                      │    │
│  │  ChannelSecurityAdapter     - 安全策略 (dmPolicy, allowlist)             │    │
│  │  ChannelMentionAdapter      - 提及处理 (@user, strip mentions)           │    │
│  │  ChannelHeartbeatAdapter    - 心跳状态 (presence, health)                │    │
│  │  ChannelStatusAdapter       - 状态查询 (connected, lastSeen)             │    │
│  │  ChannelOutboundAdapter     - 出站消息 (send, edit, delete, react)       │    │
│  │  ChannelGatewayAdapter      - Gateway 通信 (WebSocket 推送)                │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                                                                 │
│  【通道能力声明】(ChannelCapabilities)                                           │
│  {                                                                              │
│    chatTypes: ["direct", "group", "thread"],                                    │
│    polls?: boolean,          // 投票支持                                         │
│    reactions?: boolean,      // 表情反应                                         │
│    edit?: boolean,           // 消息编辑                                         │
│    unsend?: boolean,         // 消息撤回                                         │
│    reply?: boolean,          // 回复链                                           │
│    effects?: boolean,        // 消息特效                                         │
│    groupManagement?: boolean,// 群组管理                                         │
│    threads?: boolean,        // 线程支持                                         │
│    media?: boolean,          // 媒体文件                                         │
│    nativeCommands?: boolean, // 原生命令                                         │
│    blockStreaming?: boolean  // 流式消息块合并                                   │
│  }                                                                              │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

内置通道列表

通道协议/SDK认证方式多账号群组线程源码路径
WhatsAppBaileys (Web)QR 码配对channels/plugins/whatsapp/
TelegramgrammY (Bot API)Bot Tokenchannels/plugins/telegram/
DiscordDiscord.jsBot Tokenchannels/plugins/discord/
iMessageBlueBubbles APIAPI Keychannels/plugins/imessage/
Signalsignald (CLI)本地 Socketchannels/plugins/signal/
SlackSlack SDKBot Tokenchannels/plugins/slack/
FeishuWebSocketApp ID/Secretchannels/plugins/feishu/
Google ChatWorkspace APIOAuth 2.0channels/plugins/googlechat/
IRCirc-frameworkServer/Passchannels/plugins/irc/

通道配置 Schema(基于 zod-schema)

// 通道配置基础结构
type ChannelConfig<T = any> = {
  enabled: boolean;                    // 是否启用
  accounts: Record<string, T>;         // 多账号配置
  dmPolicy?: "pairing" | "allowlist" | "open" | "deny";
  allowFrom?: string[];                // DM 允许列表
  groups?: {
    [groupId: string]: {
      allow?: boolean;
      requireMention?: boolean;
      allowUnmentionedGroups?: boolean;
    };
  };
  heartbeatVisibility?: {
    showOk?: boolean;                  // 显示正常状态
    showAlerts?: boolean;              // 显示告警
    useIndicator?: boolean;            // 使用指示器
  };
};

// WhatsApp 账号配置
type WhatsAppAccountConfig = {
  // 认证信息存储在 ~/.openclaw/credentials/whatsapp/<accountId>/
  // 无需在配置文件中明文存储
};

// Telegram 账号配置
type TelegramAccountConfig = {
  botToken?: string;                   // 或使用环境变量 TELEGRAM_BOT_TOKEN
  dmPolicy?: "pairing" | "allowlist" | "open";
  allowFrom?: string[];
};

// Feishu 账号配置
type FeishuAccountConfig = {
  appId?: string;                      // 或使用环境变量 FEISHU_APP_ID_<accountId>
  appSecret?: string;                  // 或使用环境变量 FEISHU_APP_SECRET_<accountId>
  connectionMode?: "websocket" | "polling";
};

// Discord 账号配置
type DiscordAccountConfig = {
  botToken?: string;                   // 或使用环境变量 DISCORD_BOT_TOKEN
  guilds?: {
    [guildId: string]: {
      allow?: boolean;
      channels?: string[];
      roles?: string[];
    };
  };
};

完整配置示例

{
  channels: {
    // ==================== WhatsApp ====================
    whatsapp: {
      enabled: true,
      dmPolicy: "pairing",              // pairing | allowlist | open | deny
      allowFrom: ["+8613800138001"],    // 仅当 dmPolicy=allowlist 时生效
      groups: {
        "*": {
          requireMention: true,         // 群组中需要 @ 提及
          allowUnmentionedGroups: false,// 禁止未提及的群组消息
        },
        "120363xxx@g.us": {             // 特定群组配置
          allow: true,
          requireMention: false,        // 此群组无需提及
        },
      },
      accounts: {
        personal: {},                   // 认证信息在 ~/.openclaw/credentials/whatsapp/personal/
        biz: {},                        // 多账号支持
      },
    },
    
    // ==================== Telegram ====================
    telegram: {
      enabled: true,
      dmPolicy: "allowlist",
      allowFrom: ["@username", "123456789"],  // 支持用户名和 ID
      groups: {
        "-1001234567890": {
          allow: true,
          requireMention: true,
        },
      },
      accounts: {
        default: {
          // botToken 可从环境变量读取:TELEGRAM_BOT_TOKEN
        },
      },
    },
    
    // ==================== Discord ====================
    discord: {
      enabled: true,
      guilds: {
        "123456789": {                  // 服务器 ID
          allow: true,
          channels: ["987654321"],      // 允许的频道 ID 列表
          roles: ["admin", "mod"],      // 允许的角色
        },
      },
      accounts: {
        default: {
          // botToken 可从环境变量读取:DISCORD_BOT_TOKEN
        },
      },
    },
    
    // ==================== Feishu (飞书) ====================
    feishu: {
      enabled: true,
      connectionMode: "websocket",      // websocket | polling
      dmPolicy: "open",
      groups: {
        "oc_xxxxx": {
          allow: true,
          requireMention: true,
        },
      },
      accounts: {
        lead: {
          // appId/appSecret 可从环境变量读取:
          // FEISHU_APP_ID_lead, FEISHU_APP_SECRET_lead
        },
        voc: {},
        geo: {},
      },
    },
    
    // ==================== iMessage (BlueBubbles) ====================
    imessage: {
      enabled: true,
      service: "imessage",              // imessage | sms | auto
      dmPolicy: "open",
      cliPath: "/Applications/BlueBubbles.app/Contents/Resources/cli",
      dbPath: "~/Library/Messages/chat.db",
      accounts: {
        default: {
          // API Key 存储在 ~/.openclaw/credentials/imessage/default/
        },
      },
    },
    
    // ==================== Signal ====================
    signal: {
      enabled: true,
      dmPolicy: "allowlist",
      allowFrom: ["+8613800138001"],
      cliPath: "/usr/local/bin/signald",
      socketPath: "/var/run/signald/signald.sock",
      accounts: {
        default: {
          // 号码信息存储在 ~/.openclaw/credentials/signal/default/
        },
      },
    },
  },
  
  // ==================== 全局通道设置 ====================
  messages: {
    groupChat: {
      mentionPatterns: ["@openclaw", "@bot"],  // 提及模式
      requireMention: true,                     // 群组中必须提及
    },
  },
}

通道认证管理

认证文件存储位置:

~/.openclaw/credentials/
├── whatsapp/
│   ├── personal/
│   │   ├── web-auth.json      # WhatsApp Web 认证
│   │   └── meta.json          # 账号元数据
│   └── biz/
│       └── ...
├── telegram/
│   ├── default/
│   │   └── token.txt          # Bot Token
│   └── ...
├── feishu/
│   ├── lead/
│   │   ├── app-id.txt
│   │   └── app-secret.txt
│   └── ...
├── discord/
│   └── default/
│       └── token.txt
└── ...

认证方式:

通道认证流程凭证刷新
WhatsApp扫码配对 → 保存 web-auth.json自动刷新 (Baileys)
Telegram配置 Bot Token无需刷新
Discord配置 Bot Token无需刷新
Feishu配置 App ID/Secret → 获取 access_token自动刷新 (2 小时)
iMessageBlueBubbles API Key手动更新
Signalsignald 注册 → 验证码长期有效

通道诊断命令

# 查看所有通道状态
openclaw channels status

# 查看详细状态 (含连接信息)
openclaw channels status --verbose

# 主动探测连接
openclaw channels status --probe

# 查看特定通道
openclaw channels status --channel whatsapp

# 重新登录 (扫码)
openclaw channels login --channel whatsapp --force

# 查看通道日志
openclaw logs --channel whatsapp --follow

# 通道诊断
openclaw doctor --check channels

通道插件开发

最小插件结构:

// channels/plugins/myplugin/index.ts
import type { ChannelPlugin } from "@openclaw/plugin-sdk";

export const myPlugin: ChannelPlugin = {
  name: "myplugin",
  meta: {
    id: "myplugin",
    label: "My Plugin",
    blurb: "Custom channel plugin",
  },
  adapters: {
    messaging: {
      async startInbound(ctx) {
        // 启动入站消息监听
      },
      async sendOutbound(ctx, msg) {
        // 发送出站消息
      },
    },
    pairing: {
      async startPairing(ctx) {
        // 启动配对流程
        return { qrCode: "data:image/png;base64,..." };
      },
    },
  },
  capabilities: {
    chatTypes: ["direct", "group"],
    media: true,
    reactions: false,
  },
};

3.2 会话管理

会话键设计

# 单 Agent 模式
sessionKey = "agent:main:<mainKey>"

# 多 Agent 模式
sessionKey = "agent:<agentId>:<mainKey>"

# 群组会话
sessionKey = "agent:<agentId>:group:<groupId>"

# mainKey 生成规则
mainKey = hash(channel + accountId + peerId)
# 示例:mainKey = "whatsapp:personal:+8613800138001" → sha256 → "a1b2c3..."

会话存储结构

实际存储位置:

~/.openclaw/agents/<agentId>/sessions/
├── sessions.json              # 会话索引 store(所有会话元数据)
├── <sessionId>.jsonl         # 会话 1 的完整对话记录
├── <sessionId>.jsonl.reset.<timestamp>  # 重置备份
├── <sessionId>.jsonl.deleted.<timestamp># 删除备份
└── ...

目录结构示例 (实际生产环境):

~/.openclaw/agents/main/sessions/
├── sessions.json                                      # 1.1MB, 会话索引
├── c58ff4a6-eacf-4a40-b84a-367167d0d89e.jsonl        # webchat 会话
├── 9a537eaa-f82b-4778-b275-f5dc19bdc549.jsonl        # cron 任务会话
├── 0ef4257f-6200-4a7f-a3ad-7abb241b6473.jsonl        # 大文件会话 (646KB)
├── 178b8546-1f19-4ec3-aefc-6835b5ffaf8b.jsonl        # 大文件会话 (1.2MB)
├── 9cc771c8-f58d-40d3-ac02-b211dd2bb73.jsonl.deleted.2026-03-01T04-23-24.654Z
└── ...

sessions.json 结构 (会话索引 store):

{
  "agent:main:main": {
    "sessionId": "c58ff4a6-eacf-4a40-b84a-367167d0d89e",
    "updatedAt": 1772505137134,
    "systemSent": true,
    "abortedLastRun": false,
    "chatType": "direct",
    "deliveryContext": {
      "channel": "webchat"
    },
    "lastChannel": "webchat",
    "origin": {
      "provider": "webchat",
      "surface": "webchat",
      "chatType": "direct"
    },
    "sessionFile": "/Users/[username]/.openclaw/agents/main/sessions/c58ff4a6-eacf-4a40-b84a-367167d0d89e.jsonl",
    "compactionCount": 0,
    "skillsSnapshot": {
      "prompt": "...",
      "skills": [{"name": "feishu-doc", "primaryEnv": "..."}]
    },
    "modelOverride": "bailian/qwen3.5-plus",
    "thinkingLevel": "off",
    "ttsAuto": "on",
    "queueMode": "steer",
    "groupActivation": "mention"
  },
  "agent:main:feishu:direct:ou_e4de245160a1f9f1f73eb55b3bc53968": {
    "sessionId": "...",
    "updatedAt": 1772505137134,
    "chatType": "direct",
    "deliveryContext": {
      "channel": "feishu"
    },
    "lastChannel": "feishu",
    "lastAccountId": "default",
    "origin": {
      "provider": "feishu",
      "surface": "feishu",
      "chatType": "direct",
      "from": "ou_e4de245160a1f9f1f73eb55b3bc53968"
    },
    "sessionFile": "...",
    ...
  }
}

SessionEntry 完整字段 (TypeScript 定义):

type SessionEntry = {
  // 基础标识
  sessionId: string;              // UUID v4
  updatedAt: number;              // 最后更新时间戳 (ms)
  sessionFile?: string;           // JSONL 文件绝对路径
  
  // 会话来源
  chatType?: "direct" | "group" | "thread";
  origin?: {
    provider?: string;            // "webchat" | "whatsapp" | "feishu" | ...
    surface?: string;             // 表面类型
    chatType?: string;
    from?: string;                // 发送者 ID
    to?: string;                  // 接收者 ID
    accountId?: string;           // 账号 ID
    threadId?: string | number;   // 线程 ID
  };
  deliveryContext?: {
    channel: string;              // 通道类型
  };
  lastChannel?: string;           // 最后使用的通道
  lastTo?: string;                // 最后发送目标
  lastAccountId?: string;         // 最后使用的账号
  lastThreadId?: string | number; // 最后的线程 ID
  
  // 会话状态
  systemSent?: boolean;           // 是否已发送系统消息
  abortedLastRun?: boolean;       // 上次运行是否中止
  spawnedBy?: string;             // 父会话键 (subagent 场景)
  spawnDepth?: number;            // subagent 深度 (0=main, 1=sub, 2=sub-sub)
  
  // 模型配置
  modelOverride?: string;         // 模型覆盖 (如 "bailian/qwen3.5-plus")
  providerOverride?: string;      // Provider 覆盖
  authProfileOverride?: string;   // 认证配置覆盖
  thinkingLevel?: string;         // 思考级别 ("on" | "off")
  reasoningLevel?: string;        // 推理级别
  verboseLevel?: string;          // 详细级别
  elevatedLevel?: string;         // 提权级别
  
  // Token 使用统计
  inputTokens?: number;
  outputTokens?: number;
  totalTokens?: number;
  totalTokensFresh?: boolean;     // totalTokens 是否为最新
  contextTokens?: number;         // 上下文 token 数
  compactionCount?: number;       // 压缩次数
  memoryFlushAt?: number;         // 记忆刷新点
  memoryFlushCompactionCount?: number;
  
  // TTS 配置
  ttsAuto?: TtsAutoMode;          // TTS 自动模式
  
  // 队列配置
  queueMode?: "steer" | "followup" | "collect" | "queue" | "interrupt";
  queueDebounceMs?: number;
  queueCap?: number;
  queueDrop?: "old" | "new" | "summarize";
  
  // 群组配置
  groupActivation?: "mention" | "always";
  groupActivationNeedsSystemIntro?: boolean;
  
  // 技能快照
  skillsSnapshot?: {
    prompt: string;
    skills: Array<{name: string; primaryEnv?: string}>;
    skillFilter?: string[];
    version?: number;
  };
  
  // 系统提示词报告
  systemPromptReport?: SessionSystemPromptReport;
  
  // 心跳 (用于抑制重复通知)
  lastHeartbeatText?: string;
  lastHeartbeatSentAt?: number;
  
  // 其他
  label?: string;
  displayName?: string;
  channel?: string;
  groupId?: string;
  subject?: string;
  cliSessionIds?: Record<string, string>;
  claudeCliSessionId?: string;
};

JSONL 文件格式 (每行一个事件):

{"type":"session","version":3,"id":"9a537eaa-f82b-4778-b275-f5dc19bdc549","timestamp":"2026-03-02T04:20:00.188Z","cwd":"/Users/[username]/.openclaw/workspace"}
{"type":"model_change","id":"6a59d487","parentId":null,"timestamp":"2026-03-02T04:20:00.201Z","provider":"bailian","modelId":"qwen3.5-plus"}
{"type":"thinking_level_change","id":"9922a098","parentId":"6a59d487","timestamp":"2026-03-02T04:20:00.201Z","thinkingLevel":"off"}
{"type":"custom","customType":"model-snapshot","data":{"timestamp":1772425200204,"provider":"bailian","modelApi":"openai-completions","modelId":"qwen3.5-plus"},"id":"904547e9","parentId":"9922a098","timestamp":"2026-03-02T04:20:00.204Z"}
{"type":"message","id":"b2042f73","parentId":"904547e9","timestamp":"2026-03-02T04:20:00.208Z","message":{"role":"user","content":[{"type":"text","text":"[cron:xxx 午餐提醒] 午餐时间到啦!"}],"timestamp":1772425200207}}
{"type":"message","id":"c3153g84","parentId":"b2042f73","timestamp":"2026-03-02T04:20:05.123Z","message":{"role":"assistant","content":[{"type":"text","text":"好的,正在发送午餐提醒..."}],"timestamp":1772425205123}}
{"type":"tool_call","id":"d4264h95","parentId":"c3153g84","timestamp":"2026-03-02T04:20:05.456Z","tool":{"name":"message","args":{"action":"send","to":"ou_xxx","message":"午餐时间到啦!"}}}
{"type":"tool_result","id":"e5375i06","parentId":"d4264h95","timestamp":"2026-03-02T04:20:06.789Z","result":{"ok":true,"messageId":"msg_xxx"}}

事件类型说明:

类型说明关键字段
session会话开始version, cwd, timestamp
model_change模型切换provider, modelId
thinking_level_change思考级别变更thinkingLevel
custom自定义事件customType, data
message用户/助手消息message.role, message.content
tool_call工具调用tool.name, tool.args
tool_result工具返回结果result
token_usageToken 使用统计inputTokens, outputTokens
compaction会话压缩summary, compressedCount

会话键生成规则 (源码: routing/session-key.ts):

// ========== DM 会话 (5 种 dmScope 模式) ==========

// 模式 1: per-account-channel-peer (最精确)
sessionKey = `agent:${agentId}:${channel}:${accountId}:direct:${peerId}`
// 示例:agent:main:feishu:default:direct:ou_e4de245160a1f9f1f73eb55b3bc53968

// 模式 2: per-channel-peer (跨账号合并)
sessionKey = `agent:${agentId}:${channel}:direct:${peerId}`
// 示例:agent:main:whatsapp:direct:+8613800138001

// 模式 3: per-peer (跨通道合并)
sessionKey = `agent:${agentId}:direct:${peerId}`
// 示例:agent:main:direct:+8613800138001

// 模式 4: main (主会话模式)
sessionKey = `agent:${agentId}:main`

// 模式 5: identityLinks (跨账号身份关联)
// identityLinks: {"ou_xxx": ["+8613800138001"]}
sessionKey = `agent:${agentId}:${channel}:${mainAccountId}:direct:${mainPeerId}`

// ========== 群组/线程/特殊会话 ==========
sessionKey = `agent:${agentId}:${channel}:${peerKind}:${peerId}`      // 群组
sessionKey = `${baseSessionKey}:thread:${threadId}`                   // 线程
sessionKey = `agent:${agentId}:cron:${cronId}:run:${runId}`          // Cron
sessionKey = `agent:${agentId}:subagent:${depth}:${sessionId}`       // Subagent

mainSessionKey (用于折叠直接聊天):

// DM 会话:返回完整 sessionKey
// 群组/线程:返回 `agent:${agentId}:${channel}:${accountId}` (不带 peer)

会话维护策略:

// 配置位置:openclaw.json -> session.maintenance
{
  session: {
    maintenance: {
      mode: "warn" | "enforce",     // warn=仅警告,enforce=强制清理
      pruneAfterMs: 2592000000,     // 30 天后清理
      maxEntries: 1000,             // 最多 1000 个会话
      rotateBytes: 10485760,        // 10MB 触发轮转
    }
  }
}

// 自动维护操作:
// 1. pruneStaleEntries: 删除超过 pruneAfterMs 的旧会话
// 2. capEntryCount: 限制会话数量不超过 maxEntries
// 3. rotateSessionFile: sessions.json 超过 rotateBytes 时轮转备份

备份与恢复:

# 会话文件自动备份 (重置时)
<sessionId>.jsonl.reset.<ISO-timestamp>

# 会话文件备份 (删除时)
<sessionId>.jsonl.deleted.<ISO-timestamp>

# 保留策略:保留最近 3 个备份文件
rotateSessionFile() 会自动清理旧的 .bak.* 文件,只保留 3 个最新的

会话压缩 (Compaction) 算法详解

问题: 长对话导致上下文窗口溢出,token 成本激增

解决方案: 三层压缩策略

┌─────────────────────────────────────────────────────────────────────────┐
│                        会话压缩策略 (Compaction Strategy)                │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  【层 1: 滑动窗口】(Sliding Window)                                      │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │  保留最近 N 条消息,超出部分标记为可压缩                            │    │
│  │  配置:windowSize = 50                                          │    │
│  │                                                                 │    │
│  │  [msg_1][msg_2]...[msg_100][msg_101]...[msg_150]                │    │
│  │   │←────── 可压缩区域 ──────→│←── 保留区域 ──→│                  │    │
│  │                              ↑                                   │    │
│  │                         cutoff = 100                            │    │
│  └─────────────────────────────────────────────────────────────────┘    │
│                                                                         │
│  【层 2: 摘要压缩】(Summary Compression)                                 │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │  使用 LLM 生成历史对话摘要                                         │    │
│  │  Prompt: "请总结以下对话的关键信息,包括:1) 用户目标 2) 已完成任务 │    │
│  │          3) 待办事项 4) 重要上下文。限制在 500 字以内。"            │    │
│  │                                                                 │    │
│  │  输出示例:                                                       │    │
│  │  "用户正在开发一个跨境电商系统,已完成市场分析和竞品调研,待完成   │    │
│  │   产品页面 SEO 优化。关键技术栈:Node.js + OpenClaw + 飞书 API。"  │    │
│  └─────────────────────────────────────────────────────────────────┘    │
│                                                                         │
│  【层 3: 记忆提取】(Memory Extraction)                                   │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │  从对话中提取长期记忆,写入 MEMORY.md                             │    │
│  │  提取规则:                                                       │    │
│  │  • 用户明确说"记住这个"                                          │    │
│  │  • 重复出现的关键信息 (姓名、偏好、项目)                          │    │
│  │  • 重要决策和结论                                                │    │
│  │                                                                 │    │
│  │  示例提取:                                                       │    │
│  │  - 用户偏好:图片生成优先使用 DashScope                         │    │
│  │  - 进行中的项目:专利撰写、跨境电商多 Agent 系统                   │    │
│  │  - 技术栈偏好:Node.js > Python, Qwen > GPT                     │    │
│  └─────────────────────────────────────────────────────────────────┘    │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

压缩触发条件:

function shouldCompact(session) {
  const { messageCount, lastCompactionAt, windowSize } = session;
  
  // 条件 1: 消息数超过阈值
  if (messageCount > windowSize * 2) return true;
  
  // 条件 2: 距离上次压缩超过 24 小时 且 消息数超过窗口
  const hoursSinceCompaction = (Date.now() - lastCompactionAt) / 3600000;
  if (hoursSinceCompaction > 24 && messageCount > windowSize) return true;
  
  // 条件 3: token 使用超过模型限制 80%
  if (session.tokenUsage.input > getModelLimit() * 0.8) return true;
  
  return false;
}

压缩后消息结构:

{
  "id": "compaction_001",
  "role": "system",
  "content": "[对话摘要] 用户咨询了 OpenClaw 部署问题,已完成 Docker 配置和飞书通道绑定。待完成:多 Agent 路由测试。关键信息:使用 DashScope 模型,偏好 Qwen3.5-Plus。",
  "ts": 1709424000000,
  "metadata": {
    "type": "compaction",
    "compressedMessages": 100,
    "originalTokenCount": 15000,
    "compressedTokenCount": 200
  }
}

会话压缩 (Compaction)

问题: 长对话导致上下文窗口溢出

解决方案:

  1. 滑动窗口: 保留最近 N 条消息
  2. 摘要压缩: 使用 LLM 生成历史摘要
  3. 记忆提取: 将关键信息存入 MEMORY.md
{
  session: {
    windowSize: 50,           // 保留最近 50 条消息
    compaction: {
      enabled: true,
      threshold: 100,         // 超过 100 条触发压缩
      model: "bailian/qwen3.5-plus",
    },
  },
}

3.3 工具系统

内置工具完整列表

核心工具 (由 Gateway 直接提供):

工具名源码路径说明主要参数
readtools/read.ts读取文件内容path, offset, limit
writetools/write.ts写入文件path, content
edittools/edit.ts精确文本替换path, oldText, newText
exectools/exec.ts执行 shell 命令command, timeout, pty, cwd
processtools/process.ts管理后台进程action, sessionId, data
browsertools/browser.ts浏览器自动化action, url, selector
web_searchtools/web-search.ts网络搜索query, count, freshness
web_fetchtools/web-fetch.ts抓取网页内容url, extractMode, maxChars
canvastools/canvas.ts画布渲染/快照action, url, width, height
ttstools/tts.ts文本转语音text, channel, voice
messagetools/message.ts发送消息action, target, message
nodestools/nodes.ts节点设备控制action, command, params
memory_searchtools/memory.ts搜索长期记忆query, maxResults, minScore
memory_gettools/memory.ts获取记忆片段path, from, lines
feishu_*tools/feishu/*.ts飞书 API 套件见下方详解
sessions_*tools/sessions/*.ts会话管理套件见下方详解
subagentstools/subagents.ts子代理管理action, target, message
agents_listtools/agents.ts列出可用 Agent-

Feishu 工具集 (tools/feishu/):

工具说明主要参数
feishu_doc飞书文档操作action, doc_token, content
feishu_wiki知识库操作action, space_id, node_token
feishu_drive云盘操作action, file_token, folder_token
feishu_bitable_*多维表格套件app_token, table_id, record_id
feishu_app_scopes查看应用权限-

Sessions 工具集 (tools/sessions/):

工具说明主要参数
sessions_list列出会话limit, kinds, activeMinutes
sessions_history获取会话历史sessionKey, limit, includeTools
sessions_send发送消息到会话sessionKey, message, agentId
sessions_spawnspawn 新会话task, runtime, mode, agentId
session_status查看会话状态sessionKey, model

Agent 工具集 (tools/agents/):

工具说明主要参数
agents_list列出可用 Agent-
agents_inspect检查 Agent 配置agentId
agents_add添加新 Agentid, workspace, model

工具定义 Schema(基于 TypeBox)

// 工具定义结构 (from @sinclair/typebox)
type AgentTool<T extends TSchema = TSchema, R = unknown> = {
  name: string;                    // 工具名称
  description: string;             // 工具描述
  parameters: T;                   // TypeBox schema 定义参数
  execute: (params: Infer<T>, context: ToolContext) => Promise<R>;
};

// 示例:read 工具定义
const readTool: AgentTool = {
  name: "read",
  description: "Read the contents of a file",
  parameters: Type.Object({
    path: Type.String({ 
      description: "Path to the file to read (relative or absolute)",
    }),
    offset: Type.Optional(Type.Number({
      description: "Line number to start reading from (1-indexed)",
    })),
    limit: Type.Optional(Type.Number({
      description: "Maximum number of lines to read",
    })),
  }),
  async execute(params, context) {
    const content = await fs.readFile(params.path, "utf-8");
    const lines = content.split("\n");
    const sliced = lines.slice(
      (params.offset || 1) - 1,
      params.limit ? params.offset + params.limit : undefined
    );
    return {
      content: sliced.join("\n"),
      truncated: params.limit && lines.length > params.limit,
      totalLines: lines.length,
    };
  },
};

// 示例:exec 工具定义
const execTool: AgentTool = {
  name: "exec",
  description: "Execute shell commands",
  parameters: Type.Object({
    command: Type.String({
      description: "Shell command to execute",
    }),
    timeout: Type.Optional(Type.Number({
      description: "Timeout in seconds",
    })),
    pty: Type.Optional(Type.Boolean({
      description: "Run in a pseudo-terminal (TTY-required CLIs)",
    })),
    cwd: Type.Optional(Type.String({
      description: "Working directory",
    })),
    env: Type.Optional(Type.Record(Type.String(), Type.String())),
    background: Type.Optional(Type.Boolean()),
    yieldMs: Type.Optional(Type.Number()),
  }),
  async execute(params, context) {
    const result = await execa(params.command, {
      cwd: params.cwd || context.workspace,
      timeout: params.timeout ? params.timeout * 1000 : undefined,
      pty: params.pty,
      env: params.env,
    });
    return {
      stdout: result.stdout,
      stderr: result.stderr,
      exitCode: result.exitCode,
      duration: result.duration,
    };
  },
};

工具调用协议

LLM → Gateway 工具调用格式:

{
  "type": "tool_call",
  "id": "tc_abc123",
  "name": "read",
  "arguments": {
    "path": "./config.json"
  }
}

Gateway → LLM 工具返回格式:

{
  "type": "tool_result",
  "toolCallId": "tc_abc123",
  "content": "{...}",
  "isError": false,
  "metadata": {
    "duration": 45,
    "truncated": false
  }
}

工具权限控制(基于源码)

// 工具权限配置 (from zod-schema.agents.d.ts)
type AgentToolsConfig = 
  | { profile: "full" | "restricted" | "coding" | "none" }
  | { 
      mode: "allowlist";
      allow: string[];
    }
  | {
      mode: "denylist";
      deny: string[];
      restrictions?: {
        [toolName: string]: {
          allowedCommands?: string[];    // exec 工具专用
          deniedCommands?: string[];
          sandbox?: boolean;
          maxFileSize?: number;          // read 工具专用
          allowedPaths?: string[];
          deniedPaths?: string[];
          timeout?: number;
        };
      };
    };

// 权限检查流程 (from tools/permissions.ts)
async function checkToolPermission(agentId: string, toolName: string, args: any) {
  const agent = config.agents.list.find(a => a.id === agentId);
  const toolsConfig = agent.tools;
  
  // 1. Profile 模式检查
  if (toolsConfig.profile === 'full') {
    return { allowed: true };
  }
  if (toolsConfig.profile === 'restricted') {
    const restrictedAllow = ['read', 'write', 'edit', 'sessions_list'];
    if (restrictedAllow.includes(toolName)) {
      return { allowed: true };
    }
    return { allowed: false, reason: 'restricted profile' };
  }
  
  // 2. 白名单模式
  if (toolsConfig.mode === 'allowlist') {
    if (!toolsConfig.allow.includes(toolName)) {
      return { allowed: false, reason: 'not in allowlist' };
    }
  }
  
  // 3. 黑名单模式
  if (toolsConfig.mode === 'denylist') {
    if (toolsConfig.deny.includes(toolName)) {
      return { allowed: false, reason: 'in denylist' };
    }
    // 细粒度检查
    const restrictions = toolsConfig.restrictions?.[toolName];
    if (restrictions) {
      if (restrictions.allowedCommands && args.command) {
        const cmd = args.command.split(' ')[0];
        if (!restrictions.allowedCommands.includes(cmd)) {
          return { allowed: false, reason: `command '${cmd}' not allowed` };
        }
      }
      if (restrictions.deniedPaths && args.path) {
        if (restrictions.deniedPaths.some(p => args.path.startsWith(p))) {
          return { allowed: false, reason: `path '${args.path}' denied` };
        }
      }
    }
  }
  
  return { allowed: true };
}

工具沙箱执行

沙箱模式 (from tools/exec.ts):

type ExecSecurityMode = "deny" | "allowlist" | "full";

// 命令白名单
const ALLOWED_COMMANDS = {
  deny: [],                              // 禁止所有命令
  allowlist: ["ls", "cat", "pwd", "git"], // 只允许列出的命令
  full: null,                            // 允许所有命令
};

// 沙箱执行流程
async function executeInSandbox(command: string, mode: ExecSecurityMode) {
  // 1. 命令白名单检查
  const cmd = command.split(' ')[0];
  if (mode === "deny") {
    throw new Error("Command execution denied");
  }
  if (mode === "allowlist" && !ALLOWED_COMMANDS.allowlist.includes(cmd)) {
    throw new Error(`Command '${cmd}' not in allowlist`);
  }
  
  // 2. 危险命令检测
  const dangerousPatterns = [
    "rm -rf /",
    "dd if=/dev/zero",
    ":(){ :|:& };:",
    "chmod -R 777 /",
  ];
  for (const pattern of dangerousPatterns) {
    if (command.includes(pattern)) {
      throw new Error("Dangerous command detected");
    }
  }
  
  // 3. 执行命令
  const result = await execa(command, {
    cwd: workspace,
    timeout: 30000,
    maxBuffer: 10 * 1024 * 1024,
  });
  
  // 4. 输出脱敏
  const sanitized = sanitizeOutput(result.stdout);
  
  return {
    stdout: sanitized,
    stderr: result.stderr,
    exitCode: result.exitCode,
  };
}

工具结果格式

标准结果格式:

type ToolResult = {
  // 文本结果
  content?: string;
  
  // 媒体结果
  images?: Array<{
    path: string;
    base64: string;
    mimeType: string;
    label?: string;
  }>;
  
  // 结构化结果
  data?: unknown;
  
  // 错误信息
  isError?: boolean;
  errorMessage?: string;
  
  // 元数据
  metadata?: {
    duration: number;        // 执行耗时 (ms)
    truncated?: boolean;     // 是否被截断
    totalLines?: number;     // 总行数
    fileSize?: number;       // 文件大小 (bytes)
  };
};

图片结果辅助函数 (from tools/common.ts):

async function imageResult(params: {
  label: string;
  path: string;
  base64: string;
  mimeType: string;
  extraText?: string;
  details?: Record<string, unknown>;
}): Promise<AgentToolResult> {
  return {
    content: params.extraText,
    images: [{
      path: params.path,
      base64: params.base64,
      mimeType: params.mimeType,
      label: params.label,
    }],
    details: params.details,
  };
}

// 从文件生成图片结果
async function imageResultFromFile(params: {
  label: string;
  path: string;
  extraText?: string;
}): Promise<AgentToolResult> {
  const buffer = await fs.readFile(path);
  const base64 = buffer.toString("base64");
  const mimeType = mime.lookup(path) || "image/png";
  return imageResult({
    label: params.label,
    path: params.path,
    base64,
    mimeType,
    extraText: params.extraText,
  });
}

工具调用内部流程

┌─────────────────────────────────────────────────────────────────────────────────┐
│                           工具调用执行流程 (Tool Execution Flow)                 │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  Step 1: LLM 生成工具调用请求                                                      │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  {                                                                      │    │
│  │    "name": "read",                                                      │    │
│  │    "arguments": { "path": "./config.json" }                             │    │
│  │  }                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                    │                                            │
│                                    ▼                                            │
│  Step 2: Gateway 验证工具权限                                                    │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  checkToolPermission(agentId, toolName)                                 │    │
│  │  • 检查 allow 列表 (白名单模式)                                           │    │
│  │  • 检查 deny 列表 (黑名单模式)                                            │    │
│  │  • 检查沙箱策略                                                          │    │
│  │                                                                         │    │
│  │  if (!allowed) {                                                        │    │
│  │    throw new ToolPermissionDenied(toolName);                            │    │
│  │  }                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                    │                                            │
│                                    ▼                                            │
│  Step 3: 参数验证与沙箱准备                                                       │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  validateToolArgs(toolName, args)                                       │    │
│  │  • 类型检查 (path 必须是 string)                                          │    │
│  │  • 路径安全检查 (禁止访问 /etc/passwd 等)                                 │    │
│  │  • 沙箱环境准备 (Docker 容器/临时目录)                                     │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                    │                                            │
│                                    ▼                                            │
│  Step 4: 执行工具函数                                                           │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  const result = await tools[toolName].execute(args, context);           │    │
│  │                                                                         │    │
│  │  // 对于 exec 工具,使用子进程执行                                          │    │
│  │  if (toolName === 'exec') {                                             │    │
│  │    const { stdout, stderr, code } = await execa(command, {              │    │
│  │      cwd: workspace,                                                    │    │
│  │      timeout: timeoutMs,                                                │    │
│  │      maxBuffer: 10 * 1024 * 1024                                        │    │
│  │    });                                                                  │    │
│  │  }                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                    │                                            │
│                                    ▼                                            │
│  Step 5: 结果处理与返回                                                         │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  • 截断过长输出 (max 50KB / 2000 行)                                       │    │
│  │  • 敏感信息脱敏 (API Key/密码)                                           │    │
│  │  • 返回给 LLM 继续推理                                                     │    │
│  │                                                                         │    │
│  │  return {                                                               │    │
│  │    success: true,                                                       │    │
│  │    content: result,                                                     │    │
│  │    metadata: { duration: 123, truncated: false }                        │    │
│  │  };                                                                     │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

工具错误处理与重试

// 工具执行错误分类
const ToolErrorTypes = {
  PERMISSION_DENIED: 'permission_denied',     // 权限不足
  INVALID_ARGS: 'invalid_args',               // 参数错误
  TIMEOUT: 'timeout',                         // 超时
  NOT_FOUND: 'not_found',                     // 资源不存在
  RATE_LIMITED: 'rate_limited',               // 速率限制
  INTERNAL_ERROR: 'internal_error',           // 内部错误
};

// 重试策略
const retryStrategies = {
  // 网络类错误:指数退避重试
  network: {
    maxRetries: 3,
    baseDelay: 1000,
    maxDelay: 10000,
    retryableErrors: ['TIMEOUT', 'RATE_LIMITED'],
  },
  
  // 文件类错误:不重试
  filesystem: {
    maxRetries: 0,
    retryableErrors: [],
  },
  
  // API 类错误:有限重试
  api: {
    maxRetries: 2,
    baseDelay: 500,
    retryableErrors: ['RATE_LIMITED', 'INTERNAL_ERROR'],
  },
};

// 错误处理示例
async function executeToolWithRetry(toolName, args, context) {
  const strategy = getRetryStrategy(toolName);
  let lastError;
  
  for (let attempt = 0; attempt <= strategy.maxRetries; attempt++) {
    try {
      return await executeTool(toolName, args, context);
    } catch (error) {
      lastError = error;
      
      if (!strategy.retryableErrors.includes(error.type)) {
        throw error;  // 不可重试错误,直接抛出
      }
      
      if (attempt < strategy.maxRetries) {
        const delay = Math.min(
          strategy.baseDelay * Math.pow(2, attempt),
          strategy.maxDelay
        );
        await sleep(delay + Math.random() * 1000);  // 添加抖动
      }
    }
  }
  
  throw lastError;
}

工具权限配置详解

{
  agents: {
    list: [
      {
        id: "main",
        tools: {
          // 模式 1: 完整权限 (个人可信环境)
          profile: "full",
        },
      },
      {
        id: "family",
        tools: {
          // 模式 2: 白名单 (只允许列出的工具)
          mode: "allowlist",
          allow: [
            "read",
            "sessions_list",
            "sessions_history",
            "web_search",
          ],
        },
      },
      {
        id: "public",
        tools: {
          // 模式 3: 黑名单 (禁止列出的工具)
          mode: "denylist",
          deny: [
            "exec",
            "write",
            "edit",
            "apply_patch",
            "browser",
            "message",
          ],
          // 额外限制
          restrictions: {
            exec: {
              allowedCommands: ["ls", "cat", "pwd"],  // 只允许安全命令
              sandbox: true,
            },
            read: {
              maxFileSize: 1024 * 1024,  // 最大 1MB
              allowedPaths: ["./**"],    // 只读工作区
              deniedPaths: ["/etc/**", "~/.ssh/**"],
            },
          },
        },
      },
    ],
  },
}

工具权限控制

{
  agents: {
    list: [
      {
        id: "personal",
        tools: {
          profile: "full",  // full | restricted | custom
        },
      },
      {
        id: "family",
        tools: {
          allow: ["read", "sessions_list"],
          deny: ["exec", "write", "edit", "browser"],
        },
      },
    ],
  },
}

3.4 技能系统 (Skills)

技能架构

┌─────────────────────────────────────────────────────────────────────────────────┐
│                           技能系统架构 (Skills Architecture)                     │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  【技能来源】                                                                   │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  1. Bundled Skills (内置技能)                                            │    │
│  │     位置:~/.openclaw/skills/                                            │    │
│  │     来源:OpenClaw 安装包自带                                             │    │
│  │     示例:read, write, exec, browser, web_search, feishu_*, sessions_*  │    │
│  │                                                                          │    │
│  │  2. Workspace Skills (工作区技能)                                        │    │
│  │     位置:~/.openclaw/workspace-<id>/skills/                             │    │
│  │     来源:Agent 专属技能                                                  │    │
│  │     优先级:高于全局技能                                                  │    │
│  │                                                                          │    │
│  │  3. Plugin Skills (插件技能)                                             │    │
│  │     位置:由通道插件动态注册                                              │    │
│  │     来源:Channel Plugin 提供的 ChannelAgentTool                          │    │
│  │     示例:whatsapp_login, discord_actions                                │    │
│  │                                                                          │    │
│  │  4. Remote Skills (远程技能)                                             │    │
│  │     位置:动态加载                                                        │    │
│  │     来源:ClawHub 在线技能市场                                            │    │
│  │     安装:clawhub install <skill-name>                                   │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                                                                 │
│  【技能加载流程】                                                               │
│  1. 扫描内置技能目录 → 2. 扫描工作区技能目录 → 3. 加载插件技能 → 4. 生成快照      │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

技能结构

标准技能目录结构:

~/.openclaw/skills/<skill-name>/
├── SKILL.md              # 必需:技能描述与触发规则
├── EXTEND.md             # 可选:系统提示词扩展
├── TOOLS.md              # 可选:工具使用指南
├── scripts/              # 可选:执行脚本
│   ├── main.ts
│   └── ...
├── package.json          # 可选:Node.js 依赖
└── assets/               # 可选:资源文件

SKILL.md 标准格式 (基于 frontmatter 解析):

---
skillKey: patent-disclosure-writer
primaryEnv: NODE_ENV=production
emoji: 📝
homepage: https://github.com/xxx/skill
os: [darwin, linux]
requires:
  bins: [node, npm]
  env: [PATENT_API_KEY]
  config: [patent.endpoint]
install:
  - kind: node
    package: patent-writer
    module: patent-writer-cli
---

# 专利交底书撰写技能

## 触发规则

当用户提及以下关键词时自动激活:
- "专利交底书"
- "撰写专利"
- "专利创新点"
- "专利查重"

## 使用说明

...

技能元数据类型定义 (from skills/types.d.ts):

type OpenClawSkillMetadata = {
  always?: boolean;                      // 是否始终激活
  skillKey?: string;                     // 技能唯一标识
  primaryEnv?: string;                   // 主要环境变量
  emoji?: string;                        // 技能图标
  homepage?: string;                     // 项目主页
  os?: string[];                         // 支持的操作系统
  
  requires?: {
    bins?: string[];                     // 必需的二进制文件
    anyBins?: string[];                  // 任一必需的二进制文件
    env?: string[];                      // 必需的环境变量
    config?: string[];                   // 必需的配置项
  };
  
  install?: SkillInstallSpec[];          // 安装规范
};

type SkillInstallSpec = {
  kind: "brew" | "node" | "go" | "uv" | "download";
  label?: string;
  bins?: string[];                       // 安装后可用的命令
  formula?: string;                      // Homebrew formula
  package?: string;                      // npm/pip 包名
  url?: string;                          // 下载 URL
  archive?: string;                      // 压缩包 URL
  extract?: boolean;                     // 是否需要解压
  targetDir?: string;                    // 安装目标目录
};

技能配置 Schema

// 技能配置 (from zod-schema.d.ts)
type SkillsConfig = {
  allowBundled?: string[];               // 内置技能白名单
  load?: SkillsLoadConfig;
  install?: SkillsInstallConfig;
  entries?: Record<string, SkillConfig>;
};

type SkillsLoadConfig = {
  extraDirs?: string[];                  // 额外扫描的技能目录
  watch?: boolean;                       // 监听文件变化
  watchDebounceMs?: number;              // 监听防抖时间 (ms)
};

type SkillsInstallConfig = {
  preferBrew?: boolean;                  // 优先使用 Homebrew
  nodeManager?: "npm" | "pnpm" | "yarn" | "bun";
};

type SkillConfig = {
  enabled?: boolean;                     // 是否启用
  apiKey?: string;                       // 技能 API Key
  env?: Record<string, string>;          // 环境变量
  config?: Record<string, unknown>;      // 技能配置
};

技能快照 (Skills Snapshot)

快照结构 (from SessionEntry.skillsSnapshot):

type SkillSnapshot = {
  prompt: string;                        // 技能系统提示词
  skills: Array<{
    name: string;                        // 技能名称
    primaryEnv?: string;                 // 主要环境变量
  }>;
  skillFilter?: string[];                // 技能过滤器 (undefined=无限制)
  resolvedSkills?: Skill[];              // 已解析的技能列表
  version?: number;                      // 快照版本
};

技能过滤规则 (from skills/filter.ts):

// 技能 eligibility 检查
function isSkillEligible(skill: SkillEntry, context: SkillEligibilityContext): boolean {
  const meta = skill.metadata;
  if (!meta) return true;
  
  // 1. 操作系统检查
  if (meta.os && !meta.os.includes(process.platform)) {
    return false;
  }
  
  // 2. 二进制文件检查
  if (meta.requires?.bins) {
    for (const bin of meta.requires.bins) {
      if (!context.remote?.hasBin(bin)) {
        return false;
      }
    }
  }
  
  // 3. 环境变量检查
  if (meta.requires?.env) {
    for (const env of meta.requires.env) {
      if (!process.env[env]) {
        return false;
      }
    }
  }
  
  // 4. 配置检查
  if (meta.requires?.config) {
    for (const cfg of meta.requires.config) {
      if (!getConfigValue(cfg)) {
        return false;
      }
    }
  }
  
  return true;
}

// 技能过滤 (agent 级别)
function filterSkills(skills: SkillEntry[], filter?: string[]): SkillEntry[] {
  if (!filter) return skills;  // 无过滤,返回全部
  
  return skills.filter(skill => {
    // 白名单模式
    if (filter.includes(skill.skill.name)) {
      return true;
    }
    // 检查技能别名
    if (skill.skill.aliases?.some(alias => filter.includes(alias))) {
      return true;
    }
    return false;
  });
}

技能安装与管理

ClawHub CLI 命令:

# 安装技能
clawhub install <skill-name>
clawhub install patent-disclosure-writer
clawhub install baoyu-image-gen

# 查看已安装技能
clawhub list
clawhub list --verbose

# 更新技能
clawhub update <skill-name>
clawhub update --all

# 卸载技能
clawhub uninstall <skill-name>

# 搜索技能
clawhub search <query>

# 发布技能
clawhub publish ./my-skill-folder

技能安装流程:

// 技能安装 (from skills/install.ts)
async function installSkill(spec: SkillInstallSpec): Promise<void> {
  switch (spec.kind) {
    case "brew":
      // Homebrew 安装
      await execa("brew", ["install", spec.formula]);
      break;
      
    case "node":
      // npm/pnpm/yarn/bun 安装
      const pkgManager = config.skills.install?.nodeManager || "npm";
      await execa(pkgManager, ["install", "-g", spec.package]);
      break;
      
    case "go":
      // Go 安装
      await execa("go", ["install", spec.module]);
      break;
      
    case "uv":
      // Python uv 安装
      await execa("uv", ["pip", "install", spec.package]);
      break;
      
    case "download":
      // 下载并解压
      const response = await fetch(spec.url);
      const buffer = await response.arrayBuffer();
      if (spec.extract) {
        await extractArchive(buffer, spec.targetDir);
      } else {
        await fs.writeFile(spec.targetDir, buffer);
      }
      break;
  }
  
  // 验证安装
  if (spec.bins) {
    for (const bin of spec.bins) {
      const found = await which(bin);
      if (!found) {
        throw new Error(`Failed to install: ${bin} not found`);
      }
    }
  }
}

技能调用协议

技能触发规则:

// 技能触发 (from skills/trigger.ts)
type SkillTrigger = {
  type: "keyword" | "command" | "auto";
  keywords?: string[];                 // 关键词列表
  command?: string;                    // 命令前缀 (如 /skill)
  auto?: boolean;                      // 是否自动触发
};

// 技能激活检查
function shouldActivateSkill(message: string, skills: SkillEntry[]): SkillEntry | null {
  for (const skill of skills) {
    const trigger = skill.skill.trigger;
    if (!trigger) continue;
    
    if (trigger.type === "keyword") {
      for (const keyword of trigger.keywords || []) {
        if (message.toLowerCase().includes(keyword.toLowerCase())) {
          return skill;
        }
      }
    }
    
    if (trigger.type === "command") {
      if (message.startsWith(trigger.command)) {
        return skill;
      }
    }
    
    if (trigger.auto) {
      // 自动触发技能 (基于上下文分析)
      if (analyzeContext(message, skill.skill.context)) {
        return skill;
      }
    }
  }
  
  return null;
}

技能配置示例

{
  skills: {
    // 内置技能白名单 (只允许列出的内置技能)
    allowBundled: ["read", "write", "exec", "browser", "web_search"],
    
    // 技能加载配置
    load: {
      // 额外扫描的技能目录
      extraDirs: ["~/.custom-skills"],
      // 监听文件变化
      watch: true,
      watchDebounceMs: 500,
    },
    
    // 技能安装配置
    install: {
      preferBrew: true,
      nodeManager: "pnpm",
    },
    
    // 单个技能配置
    entries: {
      "patent-disclosure-writer": {
        enabled: true,
        apiKey: "xxx",  // 或使用环境变量 PATENT_API_KEY
        env: {
          "PATENT_ENDPOINT": "https://api.patent.com",
        },
        config: {
          "maxClaims": 10,
          "includeDiagrams": true,
        },
      },
      "baoyu-image-gen": {
        enabled: true,
        env: {
          "DASHSCOPE_API_KEY": "sk-xxx",
          "DASHSCOPE_IMAGE_MODEL": "z-image-turbo",
        },
      },
    },
  },
}

4. 多 Agent 路由系统

4.1 什么是"一个 Agent"?

Agent = 完全隔离的 AI 运行时实例,包含独立的:

Agent 配置结构 (AgentConfig)

// from config/types.agents.d.ts
type AgentConfig = {
  // 基础标识
  id: string;                      // Agent 唯一标识 (如 "main", "voc", "geo")
  default?: boolean;               // 是否为默认 Agent
  name?: string;                   // 显示名称
  workspace?: string;              // 工作区路径 (支持 ~ 展开)
  agentDir?: string;               // Agent 目录 (可选,默认 ~/.openclaw/agents/<id>)
  
  // 模型配置
  model?: AgentModelConfig;        // 模型配置 (字符串或 {primary, fallbacks})
  
  // 技能配置
  skills?: string[];               // 技能白名单 (omit=全部,empty=无)
  memorySearch?: MemorySearchConfig;
  
  // 人性化配置
  humanDelay?: HumanDelayConfig;   // 块回复间的人性化延迟
  heartbeat?: HeartbeatConfig;     // 心跳配置覆盖
  identity?: IdentityConfig;       // 身份配置
  
  // 群组配置
  groupChat?: GroupChatConfig;     // 群组聊天配置
  
  // Subagent 配置
  subagents?: {
    allowAgents?: string[];        // 允许 spawn 的 Agent ID 列表 ("*"=任意)
    model?: string | {primary?: string; fallbacks?: string[]};
  };
  
  // 沙箱配置
  sandbox?: {
    mode?: "off" | "non-main" | "all";
    workspaceAccess?: "none" | "ro" | "rw";
    sessionToolsVisibility?: "spawned" | "all";
    scope?: "session" | "agent" | "shared";
    perSession?: boolean;          // 遗留别名 (true=session, false=shared)
    workspaceRoot?: string;
    docker?: SandboxDockerSettings;
    browser?: SandboxBrowserSettings;
    prune?: SandboxPruneSettings;
  };
  
  // 工具配置
  tools?: AgentToolsConfig;        // 工具权限配置
};

Agent 物理存储结构

~/.openclaw/agents/<agentId>/
├── agent/
   └── auth-profiles.json        # 独立的认证配置 (Provider API Keys)
   └── sessions/
        ├── sessions.json             # 会话索引 (所有会话元数据)
        ├── <sessionId>.jsonl         # 会话 1 的完整对话记录
        ├── <sessionId>.jsonl.reset.<timestamp>
        └── <sessionId>.jsonl.deleted.<timestamp>
└── workspace/                     # 独立工作区 (可选,由 workspace 配置指定)
    ├── SOUL.md                   # 人设定义
    ├── AGENTS.md                 # 工作手册
    ├── USER.md                   # 用户信息
    ├── MEMORY.md                 # 长期记忆
    ├── HEARTBEAT.md              # 心跳任务
    ├── TOOLS.md                  # 工具本地笔记
    └── skills/                   # Agent 专属技能

Agent 隔离边界

┌─────────────────────────────────────────────────────────────────────────────────┐
│                              Agent 隔离边界 (Agent Isolation Boundary)            │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  Agent: main                         Agent: coding                              │
│  ┌─────────────────────┐            ┌─────────────────────┐                    │
│  │  ~/.openclaw/agents/main/       │  ~/.openclaw/agents/coding/               │
│  │  ├── agent/                     │  ├── agent/                             │
│  │  │   └── auth-profiles.json     │  │   └── auth-profiles.json             │
│  │  ├── sessions/                  │  ├── sessions/                          │
│  │  │   └── sessions.json          │  │   └── sessions.json                  │
│  │  └── workspace/                 │  └── workspace/                         │
│  │      ├── SOUL.md                │      ├── SOUL.md                        │
│  │      ├── MEMORY.md              │      ├── MEMORY.md                      │
│  │      └── skills/                │      └── skills/                        │
│  │                                 │                                         │
│  │  model: qwen3.5-plus            │  model: claude-sonnet-4-5               │
│  │  tools: full                    │  tools: {allow: ["read","write","exec"]}│
│  │  skills: all                    │  skills: ["coding-agent","github"]      │
│  └─────────────────────┘            └─────────────────────┘                    │
│                                                                                 │
│  【完全隔离】                                                                   │
│  • 会话存储:独立的 sessions.json 和 JSONL 文件                                   │
│  • 认证配置:独立的 auth-profiles.json (API Keys)                               │
│  • 记忆系统:独立的 MEMORY.md                                                   │
│  • 技能系统:可配置不同的技能白名单                                             │
│  • 模型配置:可独立配置 primary/fallbacks                                       │
│  • 工具权限:可独立配置 allowlist/denylist                                      │
│  • 沙箱设置:可独立配置 Docker/浏览器沙箱                                       │
│                                                                                 │
│  【共享资源】                                                                   │
│  • Gateway 进程 (单一入口)                                                       │
│  • 通道插件 (Channels) - 通过路由分发到不同 Agent                               │
│  • 全局技能 (~/.openclaw/skills/) - 除非被 skills 白名单过滤                     │
│  • 模型 Provider 配置 (auth.profiles)                                           │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

Agent 配置示例

{
  agents: {
    // 默认配置 (所有 Agent 继承)
    defaults: {
      heartbeat: {
        enabled: true,
        intervalMinutes: 30,
      },
      humanDelay: {
        enabled: true,
        minMs: 500,
        maxMs: 2000,
      },
    },
    
    // Agent 列表
    list: [
      // ==================== 主 Agent ====================
      {
        id: "main",
        default: true,
        name: "大助手",
        workspace: "~/.openclaw/workspace",
        model: "bailian/qwen3.5-plus",
        tools: { profile: "full" },
        sandbox: {
          mode: "non-main",  // 非 main Agent 启用沙箱
          workspaceAccess: "ro",
        },
      },
      
      // ==================== 编码 Agent ====================
      {
        id: "coding",
        name: "编码助手",
        workspace: "~/.openclaw/workspace-coding",
        model: {
          primary: "anthropic/claude-sonnet-4-5",
          fallbacks: ["bailian/qwen3.5-plus"],
        },
        skills: ["coding-agent", "github", "oracle"],
        tools: {
          mode: "allowlist",
          allow: ["read", "write", "edit", "exec", "process", "browser"],
          restrictions: {
            exec: {
              allowedCommands: ["npm", "pnpm", "yarn", "git", "node", "npx"],
              sandbox: true,
            },
          },
        },
        sandbox: {
          mode: "all",
          workspaceAccess: "rw",
          docker: {
            image: "node:20-alpine",
            resources: {
              memory: "1g",
              cpu: "1",
            },
          },
        },
        subagents: {
          allowAgents: ["*"],  // 允许 spawn 任何子 Agent
          model: "bailian/glm-5",
        },
      },
      
      // ==================== 跨境电商多 Agent ====================
      {
        id: "lead",
        name: "大总管",
        workspace: "~/.openclaw/workspace-lead",
        model: "bailian/qwen3.5-plus",
        subagents: {
          allowAgents: ["voc", "geo", "reddit", "tiktok"],
        },
      },
      {
        id: "voc",
        name: "VOC 分析师",
        workspace: "~/.openclaw/workspace-voc",
        model: "bailian/glm-5",
        skills: ["tavily", "baoyu-format-markdown"],
        tools: {
          allow: ["read", "write", "web_search", "web_fetch", "sessions_send"],
        },
      },
      {
        id: "geo",
        name: "GEO 优化师",
        workspace: "~/.openclaw/workspace-geo",
        model: "google/gemini-3-flash",
        skills: ["copywriter", "baoyu-format-markdown"],
        tools: {
          allow: ["read", "write", "sessions_send"],
        },
      },
    ],
  },
}

4.2 路由规则 (Bindings)

路由配置结构

// from config/types.agents.d.ts
type AgentBinding = {
  agentId: string;                   // 目标 Agent ID
  match: {
    channel: string;                 // 通道类型 (whatsapp/telegram/feishu/discord)
    accountId?: string;              // 账号 ID (可选)
    peer?: {
      kind: ChatType;                // "direct" | "group" | "thread"
      id: string;                    // peer 唯一 ID
    };
    guildId?: string;                // Discord 服务器 ID
    teamId?: string;                 // Slack 团队 ID
    roles?: string[];                // Discord 角色 ID 列表
  };
};

路由匹配算法 (resolveAgentRoute)

输入参数:

type ResolveAgentRouteInput = {
  cfg: OpenClawConfig;
  channel: string;                   // 通道类型
  accountId?: string | null;         // 账号 ID
  peer?: RoutePeer | null;           // {kind, id}
  parentPeer?: RoutePeer | null;     // 父 peer (用于线程继承)
  guildId?: string | null;           // Discord 服务器 ID
  teamId?: string | null;            // Slack 团队 ID
  memberRoleIds?: string[];          // Discord 成员角色 ID 列表
};

输出结果:

type ResolvedAgentRoute = {
  agentId: string;                   // 匹配到的 Agent ID
  channel: string;                   // 通道类型
  accountId: string;                 // 账号 ID
  sessionKey: string;                // 会话键 (用于持久化 + 并发)
  mainSessionKey: string;            // 主会话键 (直接聊天折叠)
  matchedBy:                         // 匹配规则类型
    | "binding.peer"
    | "binding.peer.parent"
    | "binding.guild+roles"
    | "binding.guild"
    | "binding.team"
    | "binding.account"
    | "binding.channel"
    | "default";
};

匹配优先级 (从高到低):

┌─────────────────────────────────────────────────────────────────────────────────┐
│                           路由匹配优先级 (Routing Priority)                       │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  1. binding.peer          - peer 精确匹配 (最高优先级)                            │
│     示例:{channel:"feishu", peer:{kind:"direct", id:"ou_xxx"}}                 │
│                                                                                 │
│  2. binding.peer.parent   - 父 peer 匹配 (线程继承)                               │
│     场景:线程消息找不到直接匹配时,查找父会话的绑定                             │
│                                                                                 │
│  3. binding.guild+roles   - Discord 服务器 + 角色匹配                             │
│     示例:{channel:"discord", guildId:"123", roles:["admin","mod"]}             │
│                                                                                 │
│  4. binding.guild         - Discord 服务器匹配                                   │
│     示例:{channel:"discord", guildId:"123"}                                    │
│                                                                                 │
│  5. binding.team          - Slack 团队匹配                                       │
│     示例:{channel:"slack", teamId:"T123"}                                      │
│                                                                                 │
│  6. binding.account       - 账号级别匹配                                         │
│     示例:{channel:"feishu", accountId:"lead"}                                  │
│                                                                                 │
│  7. binding.channel       - 通道级别匹配                                         │
│     示例:{channel:"feishu"}                                                    │
│                                                                                 │
│  8. default               - 默认 Agent (兜底策略)                                │
│     使用 config.agents.defaults 或第一个 Agent                                  │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

匹配流程源码解析 (from routing/resolve-route.ts):

function resolveAgentRoute(input: ResolveAgentRouteInput): ResolvedAgentRoute {
  const { cfg, channel, accountId, peer, parentPeer, guildId, teamId, memberRoleIds } = input;
  const bindings = listBindings(cfg);
  
  // ========== 1. peer 精确匹配 ==========
  if (peer) {
    const peerBinding = bindings.find(b =>
      b.match.channel === channel &&
      b.match.peer?.kind === peer.kind &&
      b.match.peer?.id === peer.id
    );
    if (peerBinding) {
      return {
        agentId: peerBinding.agentId,
        channel,
        accountId: accountId || DEFAULT_ACCOUNT_ID,
        sessionKey: buildAgentSessionKey({ agentId: peerBinding.agentId, channel, accountId, peer }),
        mainSessionKey: buildMainSessionKey({ agentId: peerBinding.agentId, channel, accountId, peer }),
        matchedBy: "binding.peer",
      };
    }
  }
  
  // ========== 2. parentPeer 匹配 (线程继承) ==========
  if (peer && parentPeer) {
    const parentBinding = bindings.find(b =>
      b.match.channel === channel &&
      b.match.peer?.kind === parentPeer.kind &&
      b.match.peer?.id === parentPeer.id
    );
    if (parentBinding) {
      return {
        agentId: parentBinding.agentId,
        channel,
        accountId: accountId || DEFAULT_ACCOUNT_ID,
        sessionKey: buildAgentSessionKey({ agentId: parentBinding.agentId, channel, accountId, peer }),
        mainSessionKey: buildMainSessionKey({ agentId: parentBinding.agentId, channel, accountId, peer: parentPeer }),
        matchedBy: "binding.peer.parent",
      };
    }
  }
  
  // ========== 3. guildId + roles 匹配 (Discord) ==========
  if (guildId && memberRoleIds?.length) {
    const guildRoleBinding = bindings.find(b =>
      b.match.channel === channel &&
      b.match.guildId === guildId &&
      b.match.roles?.some(role => memberRoleIds.includes(role))
    );
    if (guildRoleBinding) {
      return {
        agentId: guildRoleBinding.agentId,
        channel,
        accountId: accountId || DEFAULT_ACCOUNT_ID,
        sessionKey: buildAgentSessionKey({ agentId: guildRoleBinding.agentId, channel, accountId, peer }),
        mainSessionKey: buildMainSessionKey({ agentId: guildRoleBinding.agentId, channel, accountId }),
        matchedBy: "binding.guild+roles",
      };
    }
  }
  
  // ========== 4. guildId 匹配 ==========
  if (guildId) {
    const guildBinding = bindings.find(b =>
      b.match.channel === channel &&
      b.match.guildId === guildId
    );
    if (guildBinding) {
      return {
        agentId: guildBinding.agentId,
        channel,
        accountId: accountId || DEFAULT_ACCOUNT_ID,
        sessionKey: buildAgentSessionKey({ agentId: guildBinding.agentId, channel, accountId, peer }),
        mainSessionKey: buildMainSessionKey({ agentId: guildBinding.agentId, channel, accountId }),
        matchedBy: "binding.guild",
      };
    }
  }
  
  // ========== 5. teamId 匹配 (Slack) ==========
  if (teamId) {
    const teamBinding = bindings.find(b =>
      b.match.channel === channel &&
      b.match.teamId === teamId
    );
    if (teamBinding) {
      return {
        agentId: teamBinding.agentId,
        channel,
        accountId: accountId || DEFAULT_ACCOUNT_ID,
        sessionKey: buildAgentSessionKey({ agentId: teamBinding.agentId, channel, accountId, peer }),
        mainSessionKey: buildMainSessionKey({ agentId: teamBinding.agentId, channel, accountId }),
        matchedBy: "binding.team",
      };
    }
  }
  
  // ========== 6. accountId 匹配 ==========
  if (accountId) {
    const accountBinding = bindings.find(b =>
      b.match.channel === channel &&
      b.match.accountId === accountId
    );
    if (accountBinding) {
      return {
        agentId: accountBinding.agentId,
        channel,
        accountId,
        sessionKey: buildAgentSessionKey({ agentId: accountBinding.agentId, channel, accountId, peer }),
        mainSessionKey: buildMainSessionKey({ agentId: accountBinding.agentId, channel, accountId }),
        matchedBy: "binding.account",
      };
    }
  }
  
  // ========== 7. channel 匹配 ==========
  const channelBinding = bindings.find(b =>
    b.match.channel === channel &&
    !b.match.accountId &&
    !b.match.peer &&
    !b.match.guildId &&
    !b.match.teamId
  );
  if (channelBinding) {
    return {
      agentId: channelBinding.agentId,
      channel,
      accountId: accountId || DEFAULT_ACCOUNT_ID,
      sessionKey: buildAgentSessionKey({ agentId: channelBinding.agentId, channel, accountId, peer }),
      mainSessionKey: buildMainSessionKey({ agentId: channelBinding.agentId, channel, accountId }),
      matchedBy: "binding.channel",
    };
  }
  
  // ========== 8. default Agent ==========
  const defaultAgent = cfg.agents.list?.find(a => a.default) || cfg.agents.list?.[0];
  const defaultAgentId = defaultAgent?.id || "main";
  
  return {
    agentId: defaultAgentId,
    channel,
    accountId: accountId || DEFAULT_ACCOUNT_ID,
    sessionKey: buildAgentSessionKey({ agentId: defaultAgentId, channel, accountId, peer }),
    mainSessionKey: buildMainSessionKey({ agentId: defaultAgentId, channel, accountId }),
    matchedBy: "default",
  };
}

路由配置示例解析

示例 1: 多账号飞书路由

{
  bindings: [
    // 规则 1: lead 账号的消息 → lead Agent
    { 
      agentId: "lead", 
      match: { channel: "feishu", accountId: "lead" },
      priority: 1,
    },
    // 规则 2: voc 账号的消息 → voc Agent
    { 
      agentId: "voc", 
      match: { channel: "feishu", accountId: "voc" },
      priority: 2,
    },
    // 规则 3: 其他飞书账号 → 默认 lead Agent
    { 
      agentId: "lead", 
      match: { channel: "feishu" },
      priority: 10,  // 低优先级,作为兜底
    },
  ],
}

匹配流程示例:

入站消息: { channel: "feishu", accountId: "voc", peer: {...} }

规则 1 检查:
  match.channel = "feishu" ✓
  match.accountId = "lead" ✗ (实际是 "voc")
  → 不匹配,跳过

规则 2 检查:
  match.channel = "feishu" ✓
  match.accountId = "voc" ✓
  → 匹配!路由到 voc Agent

规则 3 检查:
  (不会执行,因为已经找到匹配)

示例 2: Discord 角色路由

{
  bindings: [
    // 管理员角色 → admin Agent
    {
      agentId: "admin",
      match: {
        channel: "discord",
        guildId: "123456789",
        roles: ["admin", "moderator"],
      },
      priority: 1,
    },
    // 开发者角色 → dev Agent
    {
      agentId: "dev",
      match: {
        channel: "discord",
        guildId: "123456789",
        roles: ["developer"],
      },
      priority: 2,
    },
    // 普通成员 → default Agent
    {
      agentId: "default",
      match: {
        channel: "discord",
        guildId: "123456789",
      },
      priority: 10,
    },
  ],
}

路由调试命令

# 查看当前路由配置
openclaw bindings list

# 测试路由匹配
openclaw bindings test --channel feishu --accountId voc

# 查看路由命中统计
openclaw bindings stats --last 24h

路由命中统计输出:

路由命中统计 (过去 24 小时)
─────────────────────────────────────────────────────────────
Agent        命中次数    占比      平均响应时间
─────────────────────────────────────────────────────────────
lead         1,234      45.2%     1.2s
voc            567      20.8%     0.8s
geo            432      15.8%     0.9s
reddit         289      10.6%     1.5s
tiktok         207       7.6%     2.1s
─────────────────────────────────────────────────────────────
总计         2,729     100.0%     1.1s (平均)

4.3 配置示例

场景 1: WhatsApp + Telegram 双通道

{
  agents: {
    defaults: {
      heartbeat: { enabled: true, intervalMinutes: 30 },
      humanDelay: { enabled: true, minMs: 500, maxMs: 2000 },
    },
    list: [
      {
        id: "chat",
        name: "日常聊天",
        workspace: "~/.openclaw/workspace-chat",
        model: {
          primary: "bailian/glm-5",
          fallbacks: ["bailian/qwen3.5-plus"],
        },
        tools: { profile: "restricted" },
      },
      {
        id: "coding",
        name: "编程助手",
        workspace: "~/.openclaw/workspace-coding",
        model: "anthropic/claude-sonnet-4-5",
        skills: ["coding-agent", "github", "oracle"],
        tools: {
          mode: "allowlist",
          allow: ["read", "write", "edit", "exec", "process", "browser"],
        },
        sandbox: {
          mode: "all",
          workspaceAccess: "rw",
          docker: { image: "node:20-alpine" },
        },
      },
    ],
  },
  
  bindings: [
    { agentId: "chat", match: { channel: "whatsapp" } },
    { agentId: "coding", match: { channel: "telegram" } },
  ],
}

场景 2: Discord 角色路由

{
  agents: {
    list: [
      {
        id: "admin",
        name: "管理员助手",
        workspace: "~/.openclaw/workspace-admin",
        model: "bailian/qwen3.5-plus",
        tools: { profile: "full" },
      },
      {
        id: "dev",
        name: "开发助手",
        workspace: "~/.openclaw/workspace-dev",
        model: "bailian/qwen3.5-plus",
        skills: ["coding-agent"],
      },
      {
        id: "default",
        name: "普通助手",
        workspace: "~/.openclaw/workspace",
        model: "bailian/glm-5",
        tools: { profile: "restricted" },
      },
    ],
  },
  
  bindings: [
    // 管理员角色 → admin Agent
    {
      agentId: "admin",
      match: {
        channel: "discord",
        guildId: "123456789",
        roles: ["admin-role-id", "mod-role-id"],
      },
    },
    // 开发者角色 → dev Agent
    {
      agentId: "dev",
      match: {
        channel: "discord",
        guildId: "123456789",
        roles: ["developer-role-id"],
      },
    },
    // 其他成员 → default Agent
    {
      agentId: "default",
      match: {
        channel: "discord",
        guildId: "123456789",
      },
    },
  ],
}

场景 3: 飞书多账号 + 多 Agent

{
  agents: {
    list: [
      {
        id: "lead",
        name: "大总管",
        workspace: "~/.openclaw/workspace-lead",
        model: "bailian/qwen3.5-plus",
        subagents: {
          allowAgents: ["voc", "geo", "reddit", "tiktok"],
          model: "bailian/glm-5",
        },
      },
      {
        id: "voc",
        name: "VOC 分析师",
        workspace: "~/.openclaw/workspace-voc",
        model: "bailian/glm-5",
        tools: { allow: ["read", "write", "web_search", "sessions_send"] },
      },
      {
        id: "geo",
        name: "GEO 优化师",
        workspace: "~/.openclaw/workspace-geo",
        model: "google/gemini-3-flash",
        tools: { allow: ["read", "write", "sessions_send"] },
      },
    ],
  },
  
  bindings: [
    { agentId: "lead", match: { channel: "feishu", accountId: "lead" } },
    { agentId: "voc", match: { channel: "feishu", accountId: "voc" } },
    { agentId: "geo", match: { channel: "feishu", accountId: "geo" } },
  ],
  
  channels: {
    feishu: {
      enabled: true,
      connectionMode: "websocket",
      accounts: {
        lead: {
          // appId/appSecret 从环境变量读取:
          // FEISHU_APP_ID_lead, FEISHU_APP_SECRET_lead
        },
        voc: {},
        geo: {},
      },
    },
  },
  
  tools: {
    agentToAgent: {
      enabled: true,
      allow: ["lead", "voc", "geo"],
    },
  },
}

场景 4: 线程会话继承

{
  // 飞书群线程消息自动继承父会话的 Agent 路由
  // 无需额外配置,由 resolveAgentRoute 自动处理
  // matchedBy: "binding.peer.parent"
}

4.4 Agent-to-Agent 通信

通信机制

sessions_send 工具 (from tools/sessions/send.ts):

// 工具定义
const sessionsSendTool: AgentTool = {
  name: "sessions_send",
  description: "Send a message to another session/agent",
  parameters: Type.Object({
    sessionKey: Type.Optional(Type.String()),  // 目标会话键
    label: Type.Optional(Type.String()),       // 目标会话标签
    agentId: Type.Optional(Type.String()),     // 目标 Agent ID
    message: Type.String(),                     // 消息内容
    timeoutSeconds: Type.Optional(Type.Number()),
  }),
  async execute(params, context) {
    // 1. 解析目标会话
    const target = await resolveTargetSession(params);
    
    // 2. 发送消息到目标会话
    const result = await sessionsSend({
      sessionKey: target.sessionKey,
      message: params.message,
      agentId: params.agentId,
      timeoutSeconds: params.timeoutSeconds,
    });
    
    // 3. 返回结果
    return {
      success: true,
      response: result.message,
      sessionKey: target.sessionKey,
    };
  },
};

sessions_spawn 工具 (from tools/sessions/spawn.ts):

//  spawn 新会话 (subagent 或 ACP)
const sessionsSpawnTool: AgentTool = {
  name: "sessions_spawn",
  description: "Spawn an isolated session",
  parameters: Type.Object({
    task: Type.String(),                        // 任务描述
    runtime: Type.Union([
      Type.Literal("subagent"),                // OpenClaw subagent
      Type.Literal("acp"),                     // ACP harness
    ]),
    mode: Type.Union([
      Type.Literal("run"),                     // 一次性运行
      Type.Literal("session"),                 // 持久会话
    ]),
    agentId: Type.Optional(Type.String()),     // 目标 Agent ID (ACP 必需)
    model: Type.Optional(Type.String()),       // 模型覆盖
    timeoutSeconds: Type.Optional(Type.Number()),
    cleanup: Type.Union([
      Type.Literal("delete"),                  // 完成后删除
      Type.Literal("keep"),                    // 保留会话
    ]),
  }),
};

配置跨 Agent 通信

{
  // 方法 1: 全局启用
  tools: {
    agentToAgent: {
      enabled: true,
      allow: ["lead", "voc", "geo", "reddit", "tiktok"],  // 白名单
    },
  },
  
  // 方法 2: Agent 级别配置
  agents: {
    list: [
      {
        id: "lead",
        subagents: {
          allowAgents: ["voc", "geo", "reddit", "tiktok"],  // 允许 spawn 的 Agent
          model: "bailian/glm-5",  // 子 Agent 默认模型
        },
      },
      {
        id: "voc",
        subagents: {
          allowAgents: ["*"],  // 允许 spawn 任何 Agent
        },
      },
    ],
  },
}

通信模式

模式 1: 请求 - 响应 (sessions_send)

// Lead Agent 发送请求到 VOC Agent
const result = await sessions_send({
  sessionKey: "agent:voc:feishu:default:direct:ou_xxx",
  message: "分析露营折叠床市场,输出 VOC 报告",
  timeoutSeconds: 300,
});

// 返回结果
{
  success: true,
  response: "【VOC 分析报告】...",
  sessionKey: "agent:voc:...",
}

模式 2: 任务分发 (sessions_spawn)

// spawn 子 Agent 执行任务
await sessions_spawn({
  task: "分析露营折叠床市场痛点",
  runtime: "subagent",
  mode: "run",
  agentId: "voc",
  timeoutSeconds: 300,
  cleanup: "delete",
});

// 子 Agent 完成后自动推送结果

模式 3: 持久会话 (sessions_spawn mode=session)

// 创建持久子会话
await sessions_spawn({
  task: "跨境电商营销助手",
  runtime: "subagent",
  mode: "session",
  agentId: "geo",
  cleanup: "keep",
});

// 后续可通过 sessionKey 继续对话
await sessions_send({
  sessionKey: "agent:geo:subagent:1:abc123",
  message: "继续优化 SEO 文章",
});

完整工作流示例

跨境电商多 Agent 协作:

┌─────────────────────────────────────────────────────────────────────────────────┐
│                          跨境电商多 Agent 工作流                                  │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  用户 (@大总管): "分析露营折叠床市场,全渠道铺内容"                                │
│       │                                                                         │
│       ▼                                                                         │
│  ┌─────────────────┐                                                            │
│  │  Lead Agent     │ 1. 需求理解                                                 │
│  │  (lead)         │ 2. 任务拆解                                                 │
│  └────────┬────────┘                                                            │
│           │                                                                     │
│           ├─────────────────┬──────────────────┬────────────────┐              │
│           ▼                 ▼                  ▼                ▼              │
│  ┌─────────────┐   ┌─────────────┐   ┌─────────────┐  ┌─────────────┐         │
│  │ VOC 分析师   │   │ GEO 优化师   │   │ Reddit 专家 │  │ TikTok 编导 │         │
│  │ (voc)       │   │ (geo)       │   │ (reddit)    │  │ (tiktok)    │         │
│  │ sessions_   │   │ sessions_   │   │ sessions_   │  │ sessions_   │         │
│  │ send        │   │ send        │   │ send        │  │ send        │         │
│  └──────┬──────┘   └──────┬──────┘   └──────┬──────┘  └──────┬──────┘         │
│         │                 │                 │                │                 │
│         ▼                 ▼                 ▼                ▼                 │
│  【并行执行】                                                   │                 │
│  • 爬取竞品评价          • 撰写产品博客     • 搜索相关帖子    • 生成视频脚本     │
│  • 提炼用户痛点          • SEO 关键词优化    • 养号互动策略    • AI 生图生视频     │
│  • VOC 报告              • SEO 文章          • 引流方案        • 分镜脚本         │
│         │                 │                 │                │                 │
│         └─────────────────┴─────────────────┴────────────────┘                 │
│                                   │                                             │
│                                   ▼                                             │
│                          ┌─────────────────┐                                    │
│                          │  Lead Agent     │ 汇总结果                           │
│                          │  (lead)         │ 飞书群汇报                         │
│                          └─────────────────┘                                    │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

代码实现:

// Lead Agent 工作流
async function executeWorkflow(userMessage: string) {
  // 1. 并发分发任务
  const [vocResult, geoResult, redditResult, tiktokResult] = await Promise.all([
    sessions_send({
      agentId: "voc",
      message: "分析露营折叠床市场痛点,输出 VOC 报告",
      timeoutSeconds: 300,
    }),
    sessions_send({
      agentId: "geo",
      message: "基于 VOC 数据撰写产品博客,SEO 优化",
      timeoutSeconds: 300,
    }),
    sessions_send({
      agentId: "reddit",
      message: "寻找露营装备相关帖子,制定互动策略",
      timeoutSeconds: 300,
    }),
    sessions_send({
      agentId: "tiktok",
      message: "生成露营折叠床短视频脚本和分镜",
      timeoutSeconds: 300,
    }),
  ]);
  
  // 2. 汇总结果
  const summary = `
【市场分析汇报】露营折叠床

📊 VOC 分析报告
${vocResult.response}

📝 SEO 文章
${geoResult.response}

🎯 Reddit 策略
${redditResult.response}

🎬 TikTok 脚本
${tiktokResult.response}
  `;
  
  // 3. 返回用户
  return summary;
}

通信限制与安全

{
  tools: {
    agentToAgent: {
      enabled: true,
      allow: ["lead", "voc", "geo"],  // 白名单
      // 禁止的 Agent
      deny: ["sandbox", "test"],
      // 超时限制
      timeoutSeconds: 300,
      // 最大并发数
      maxConcurrent: 10,
    },
  },
  
  agents: {
    list: [
      {
        id: "lead",
        subagents: {
          allowAgents: ["voc", "geo"],
          // 禁止 spawn 的 Agent
          denyAgents: ["admin"],
          // 子 Agent 深度限制
          maxDepth: 3,
        },
      },
    ],
  },
}

5. 部署配置全指南

部署前请确认

  • Node.js 22+ 已安装 (node --version)
  • 模型 API Key 已配置 (.env 文件)
  • 通道凭证已获取 (Bot Token/App ID)
  • Gateway 端口未被占用 (lsof -i :18789)
  • 防火墙规则已配置 (远程访问场景)
  • 备份策略已制定 (生产环境)

5.1 安装方式对比

方式适用场景复杂度推荐度
npm 全局安装个人开发机⭐⭐⭐⭐⭐
Docker服务器部署⭐⭐⭐⭐⭐⭐
macOS AppmacOS 用户⭐⭐⭐⭐⭐
SystemdLinux 服务器⭐⭐⭐⭐⭐⭐⭐
Ansible批量部署⭐⭐⭐⭐⭐⭐⭐

5.2 快速开始 (npm)

# 1. 安装 OpenClaw
npm install -g openclaw@latest

# 2. 运行引导向导
openclaw onboard --install-daemon

# 3. 登录通道
openclaw channels login --channel whatsapp

# 4. 启动 Gateway
openclaw gateway --port 18789

# 5. 访问 Control UI
open http://127.0.0.1:18789

5.3 配置文件详解

配置位置: ~/.openclaw/openclaw.json

配置类型定义: OpenClawConfig (from config/types.openclaw.d.ts)

完整配置 Schema (50+ 配置项)

type OpenClawConfig = {
  // ========== 元数据 ==========
  meta?: {
    lastTouchedVersion?: string;   // 最后写入的 OpenClaw 版本
    lastTouchedAt?: string;        // ISO 时间戳
  };
  
  // ========== 认证配置 ==========
  auth?: AuthConfig;               // 模型 Provider 认证 (API Keys/OAuth)
  
  // ========== 环境变量 ==========
  env?: {
    shellEnv?: {
      enabled?: boolean;           // 从登录 shell 导入环境变量
      timeoutMs?: number;          // 超时 (默认 15000ms)
    };
    vars?: Record<string, string>; // 内联环境变量
  };
  
  // ========== 向导配置 ==========
  wizard?: {
    lastRunAt?: string;
    lastRunVersion?: string;
    lastRunCommand?: string;
    lastRunMode?: "local" | "remote";
  };
  
  // ========== 诊断配置 ==========
  diagnostics?: DiagnosticsConfig;
  logging?: LoggingConfig;
  
  // ========== 更新配置 ==========
  update?: {
    channel?: "stable" | "beta" | "dev";
    checkOnStart?: boolean;
  };
  
  // ========== 浏览器配置 ==========
  browser?: BrowserConfig;
  
  // ========== UI 配置 ==========
  ui?: {
    seamColor?: string;            // 强调色 (hex)
    assistant?: {
      name?: string;               // 助手显示名
      avatar?: string;             // 头像 (emoji/URL/data URI)
    };
  };
  
  // ========== 技能配置 ==========
  skills?: SkillsConfig;
  
  // ========== 插件配置 ==========
  plugins?: PluginsConfig;
  
  // ========== 模型配置 ==========
  models?: ModelsConfig;
  
  // ========== Node Host 配置 ==========
  nodeHost?: NodeHostConfig;
  
  // ========== Agent 配置 ==========
  agents?: AgentsConfig;           // Agent 列表和默认配置
  
  // ========== 工具配置 ==========
  tools?: ToolsConfig;             // 工具权限/沙箱/会话工具
  
  // ========== 路由绑定 ==========
  bindings?: AgentBinding[];       // 路由规则列表
  
  // ========== 广播配置 ==========
  broadcast?: BroadcastConfig;
  
  // ========== 音频配置 ==========
  audio?: AudioConfig;
  
  // ========== 消息配置 ==========
  messages?: MessagesConfig;       // 消息处理/回复/群组策略
  
  // ========== 命令配置 ==========
  commands?: CommandsConfig;       // 自定义命令
  
  // ========== 审批配置 ==========
  approvals?: ApprovalsConfig;     // 工具调用审批
  
  // ========== 会话配置 ==========
  session?: SessionConfig;         // 会话范围/重置/维护
  
  // ========== Web 配置 ==========
  web?: WebConfig;
  
  // ========== 通道配置 ==========
  channels?: ChannelsConfig;       // WhatsApp/Telegram/飞书等
  
  // ========== Cron 配置 ==========
  cron?: CronConfig;               // 定时任务
  
  // ========== Hooks 配置 ==========
  hooks?: HooksConfig;             // 内部/外部钩子
  
  // ========== 发现配置 ==========
  discovery?: DiscoveryConfig;     // mDNS/DNS-SD
  
  // ========== Canvas Host 配置 ==========
  canvasHost?: CanvasHostConfig;
  
  // ========== Talk 配置 ==========
  talk?: TalkConfig;               // ElevenLabs TTS
  
  // ========== Gateway 配置 ==========
  gateway?: GatewayConfig;         // Gateway 服务器配置
  
  // ========== 内存配置 ==========
  memory?: MemoryConfig;           // 向量数据库/记忆存储
};

核心配置项详解

1. Agent 配置 (agents):

{
  agents: {
    // 默认配置 (所有 Agent 继承)
    defaults: {
      heartbeat: {
        enabled: true,
        intervalMinutes: 30,
        prompt: "检查邮箱、日历、未读消息",
      },
      humanDelay: {
        mode: "natural",           // off|natural|custom
        minMs: 800,
        maxMs: 2500,
      },
      subagents: {
        allowAgents: ["*"],        // 允许 spawn 的 Agent
        model: "bailian/glm-5",
      },
    },
    
    // Agent 列表
    list: [
      {
        id: "main",                // 必需:Agent 唯一标识
        default: true,             // 是否为默认 Agent
        name: "大助手",            // 显示名称
        workspace: "~/.openclaw/workspace",
        agentDir: "~/.openclaw/agents/main",
        model: {
          primary: "bailian/qwen3.5-plus",
          fallbacks: ["bailian/glm-5"],
        },
        skills: ["tavily", "baoyu-format-markdown"],  // 技能白名单
        memorySearch: {
          enabled: true,
          maxResults: 5,
          minScore: 0.6,
        },
        sandbox: {
          mode: "non-main",        // off|non-main|all
          workspaceAccess: "ro",   // none|ro|rw
          scope: "session",        // session|agent|shared
          docker: {
            image: "node:20-alpine",
            resources: {
              memory: "1g",
              cpu: "1",
            },
          },
        },
        tools: {
          profile: "full",         // full|restricted|coding|none
          mode: "allowlist",       // allowlist|denylist
          allow: ["read", "write", "exec", "browser"],
          restrictions: {
            exec: {
              allowedCommands: ["npm", "git", "node"],
              sandbox: true,
            },
          },
        },
        groupChat: {
          mentionPatterns: ["@openclaw", "@助手"],
          requireMention: true,
        },
      },
    ],
  },
}

2. 路由绑定 (bindings):

{
  bindings: [
    // peer 精确匹配 (最高优先级)
    {
      agentId: "vip",
      match: {
        channel: "whatsapp",
        peer: {
          kind: "direct",
          id: "+8613800138001",
        },
      },
    },
    
    // Discord 角色路由
    {
      agentId: "admin",
      match: {
        channel: "discord",
        guildId: "123456789",
        roles: ["admin-role-id", "mod-role-id"],
      },
    },
    
    // 账号级别匹配
    {
      agentId: "voc",
      match: {
        channel: "feishu",
        accountId: "voc",
      },
    },
    
    // 通道级别匹配 (兜底)
    {
      agentId: "main",
      match: {
        channel: "whatsapp",
      },
    },
  ],
}

3. 会话配置 (session):

{
  session: {
    scope: "per-sender",          // per-sender|global
    dmScope: "per-channel-peer",  // main|per-peer|per-channel-peer|per-account-channel-peer
    identityLinks: {
      "ou_e4de245160a1f9f1f73eb55b3bc53968": ["+8613800138001", "telegram:123456"],
    },
    resetTriggers: ["!reset", "/reset"],
    idleMinutes: 60,
    reset: {
      mode: "daily",              // daily|idle
      atHour: 4,                  // 本地时间 4:00 重置
      idleMinutes: 1440,          // 24 小时空闲重置
    },
    resetByType: {
      direct: { mode: "daily", atHour: 4 },
      group: { mode: "idle", idleMinutes: 10080 },  // 7 天
      thread: { mode: "idle", idleMinutes: 1440 },
    },
    resetByChannel: {
      discord: { mode: "idle", idleMinutes: 10080 },
    },
    typingMode: "thinking",       // never|instant|thinking|message
    typingIntervalSeconds: 5,
    maintenance: {
      prune: {
        enabled: true,
        maxAgeDays: 30,
        maxSessionsPerPeer: 100,
      },
      cap: {
        enabled: true,
        maxTotalSessions: 1000,
      },
      compact: {
        enabled: true,
        threshold: 200,
        retention: 50,
      },
    },
    agentToAgent: {
      maxPingPongTurns: 5,        // 最大 ping-pong 回合数
    },
  },
}

4. Gateway 配置 (gateway):

{
  gateway: {
    bindHost: "127.0.0.1",        // 监听地址
    port: 18789,                  // 监听端口
    bindMode: "auto",             // auto|lan|loopback|custom|tailnet
    
    // TLS 配置
    tls: {
      enabled: false,
      autoGenerate: true,
      certPath: "~/.openclaw/gateway.crt",
      keyPath: "~/.openclaw/gateway.key",
      caPath: "~/.openclaw/ca.crt",
    },
    
    // 认证配置
    auth: {
      mode: "token",              // token|password|trusted-proxy
      token: "OPENCLAW_GATEWAY_TOKEN",
      password: "xxx",            // 建议使用环境变量
      trustedProxy: {
        userHeader: "x-forwarded-user",
        requiredHeaders: ["x-forwarded-proto"],
        allowUsers: ["admin@example.com"],
      },
      allowInsecureAuth: false,
      dangerouslyDisableDeviceAuth: false,
    },
    
    // 控制 UI 配置
    controlUi: {
      enabled: true,
      basePath: "/openclaw",
      root: "/opt/homebrew/lib/node_modules/openclaw/dist/control-ui",
      allowedOrigins: ["http://localhost:18790"],
    },
    
    // 发现配置
    discovery: {
      wideArea: {
        enabled: true,
        domain: "openclaw.internal",
      },
      mdns: {
        mode: "minimal",          // off|minimal|full
      },
    },
    
    // Canvas Host
    canvasHost: {
      enabled: true,
      root: "~/.openclaw/workspace/canvas",
      port: 18793,
      liveReload: true,
    },
    
    // Talk 模式 (ElevenLabs TTS)
    talk: {
      voiceId: "21m00Tcm4TlvDq8ikWAM",  // Rachel
      voiceAliases: {
        "narrator": "21m00Tcm4TlvDq8ikWAM",
        "assistant": "EXAVITQu4vr4xnSDxMaL",
      },
      modelId: "eleven_monolingual_v1",
      outputFormat: "mp3_44100_128",
      interruptOnSpeech: true,
    },
  },
}

5. 通道配置 (channels):

{
  channels: {
    // WhatsApp 配置
    whatsapp: {
      enabled: true,
      connectionMode: "websocket",  // websocket|polling
      dmPolicy: "pairing",          // pairing|allowlist|open|disabled
      groups: {
        "*": {
          requireMention: true,
          policy: "open",           // open|disabled|allowlist
        },
      },
      accounts: {
        default: {
          // 认证信息在 ~/.openclaw/credentials/whatsapp/default
          // 或使用环境变量:WHATSAPP_DEFAULT_AUTH_TOKEN
        },
      },
      outboundRetry: {
        attempts: 3,
        minDelayMs: 300,
        maxDelayMs: 30000,
        jitter: 0.1,
      },
    },
    
    // Telegram 配置
    telegram: {
      enabled: true,
      accounts: {
        default: {
          botToken: "TELEGRAM_BOT_TOKEN",
          dmPolicy: "pairing",
          groups: {
            "*": { requireMention: true },
          },
        },
      },
      customCommands: [
        {
          command: "start",
          reply: "你好!我是 OpenClaw 助手。",
        },
      ],
    },
    
    // 飞书配置
    feishu: {
      enabled: true,
      connectionMode: "websocket",
      requireMention: false,
      domain: "feishu",
      accounts: {
        lead: {
          appId: "cli_xxx",
          appSecret: "xxx",
          // 或使用环境变量:FEISHU_LEAD_APP_ID, FEISHU_LEAD_APP_SECRET
        },
        voc: {},
        geo: {},
      },
    },
    
    // Discord 配置
    discord: {
      enabled: true,
      botToken: "DISCORD_BOT_TOKEN",
      intents: [
        "Guilds",
        "GuildMessages",
        "MessageContent",
        "GuildMessageTyping",
      ],
      guilds: {
        "*": {
          requireMention: true,
          policy: "open",
        },
      },
    },
    
    // Slack 配置
    slack: {
      enabled: true,
      botToken: "SLACK_BOT_TOKEN",
      signingSecret: "SLACK_SIGNING_SECRET",
      channels: {
        "*": { requireMention: true },
      },
    },
  },
}

6. 模型配置 (models):

{
  models: {
    default: "bailian/qwen3.5-plus",
    fallbacks: ["bailian/glm-5", "google/gemini-3-flash"],
    
    providers: {
      bailian: {
        apiKey: "DASHSCOPE_API_KEY",
        baseURL: "https://dashscope.aliyuncs.com",
        timeoutMs: 60000,
        retry: {
          attempts: 3,
          minDelayMs: 1000,
          maxDelayMs: 30000,
        },
      },
      anthropic: {
        apiKey: "ANTHROPIC_API_KEY",
        baseURL: "https://api.anthropic.com",
      },
      google: {
        apiKey: "GOOGLE_API_KEY",
      },
      openai: {
        apiKey: "OPENAI_API_KEY",
        baseURL: "https://api.openai.com/v1",
      },
    },
    
    // 模型别名
    aliases: {
      "qwen": "bailian/qwen3.5-plus",
      "claude": "anthropic/claude-sonnet-4-5",
      "gemini": "google/gemini-3-flash",
    },
    
    // 模型限制
    limits: {
      maxContextTokens: 128000,
      maxOutputTokens: 8192,
      maxImageSize: 20 * 1024 * 1024,  // 20MB
    },
  },
}

7. 工具配置 (tools):

{
  tools: {
    // Agent-to-Agent 通信
    agentToAgent: {
      enabled: true,
      allow: ["lead", "voc", "geo", "reddit", "tiktok"],
      deny: ["sandbox", "test"],
      timeoutSeconds: 300,
      maxConcurrent: 10,
    },
    
    // 会话工具策略
    sessionTools: {
      default: "allow",
      rules: [
        {
          action: "deny",
          match: {
            keyPrefix: "agent:sandbox:",
          },
        },
      ],
    },
    
    // 工具权限
    permissions: {
      default: "restricted",
      byAgent: {
        main: "full",
        coding: "coding",
        voc: "restricted",
      },
    },
    
    // 沙箱配置
    sandbox: {
      mode: "non-main",
      workspaceAccess: "ro",
      docker: {
        image: "node:20-alpine",
        network: "bridge",
        resources: {
          memory: "2g",
          cpu: "2",
        },
      },
      browser: {
        enabled: true,
        headless: true,
      },
      prune: {
        enabled: true,
        intervalHours: 24,
        maxAgeHours: 168,
      },
    },
  },
}

8. Hooks 配置 (hooks):

{
  hooks: {
    // 内部钩子
    internal: {
      enabled: true,
      entries: {
        "boot-md": { enabled: true },
        "command-logger": { enabled: true },
        "session-memory": { enabled: true },
        "heartbeat-runner": { enabled: true },
        "diagnostic-events": { enabled: true },
      },
    },
    
    // 外部钩子
    external: {
      enabled: false,
      entries: {
        "slack-notify": {
          enabled: true,
          url: "https://hooks.slack.com/services/xxx",
          events: ["session.start", "tool.error"],
        },
      },
    },
  },
}

9. Cron 配置 (cron):

{
  cron: {
    enabled: true,
    jobs: [
      {
        id: "daily-standup",
        schedule: "0 9 * * 1-5",  // 工作日 9:00
        agentId: "main",
        target: "user:ou_xxx",
        message: "早安!今日工作计划是什么?",
        delivery: "system",
      },
      {
        id: "lunch-reminder",
        schedule: "0 12 * * *",
        agentId: "main",
        target: "group:cn_xxx",
        message: "午餐时间到!记得休息。",
      },
    ],
  },
}

10. 技能配置 (skills):

{
  skills: {
    // 技能来源
    sources: {
      bundled: "~/.openclaw/skills",
      workspace: "~/.openclaw/workspace-*/skills",
      plugin: true,
      remote: {
        enabled: true,
        registry: "https://clawhub.com",
      },
    },
    
    // 技能白名单
    allow: ["tavily", "baoyu-*", "coding-agent"],
    
    // 技能黑名单
    deny: ["dangerous-skill"],
    
    // 技能调用策略
    invocation: {
      default: "direct",
      bySkill: {
        "exec-heavy": "subagent",
        "browser-automation": "subagent",
      },
    },
    
    // ClawHub 配置
    clawhub: {
      autoUpdate: true,
      updateIntervalHours: 24,
    },
  },
}

5.4 环境变量配置

源码位置: config/env-vars.d.ts, config/env-substitution.d.ts

环境变量加载顺序:

1. 进程环境变量 (process.env)
2. config.env.vars (openclaw.json 内联定义)
3. config.env.shellEnv (登录 shell 导入,可选)
4. ~/.openclaw/.env 文件 (dotenv 格式)
5. 系统环境变量

完整环境变量列表

# ==================== 模型 Provider ====================

# 阿里云通义千问 (DashScope)
DASHSCOPE_API_KEY=sk-xxx
DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com

# Anthropic Claude
ANTHROPIC_API_KEY=sk-ant-xxx
ANTHROPIC_BASE_URL=https://api.anthropic.com

# OpenAI
OPENAI_API_KEY=sk-xxx
OPENAI_BASE_URL=https://api.openai.com/v1

# Google Gemini
GOOGLE_API_KEY=xxx
GOOGLE_BASE_URL=https://generativelanguage.googleapis.com

# Ollama (本地)
OLLAMA_BASE_URL=http://localhost:11434

# ==================== Gateway 认证 ====================

OPENCLAW_GATEWAY_TOKEN=your-secret-token

# ==================== 通道凭证 ====================

# WhatsApp (多账号)
WHATSAPP_DEFAULT_AUTH_TOKEN=xxx
WHATSAPP_LEAD_AUTH_TOKEN=xxx

# Telegram
TELEGRAM_BOT_TOKEN=123456:ABC...
TELEGRAM_DEFAULT_BOT_TOKEN=xxx

# 飞书 (多账号)
FEISHU_LEAD_APP_ID=cli_xxx
FEISHU_LEAD_APP_SECRET=xxx
FEISHU_VOC_APP_ID=cli_xxx
FEISHU_VOC_APP_SECRET=xxx

# Discord
DISCORD_BOT_TOKEN=xxx

# Slack
SLACK_BOT_TOKEN=xoxb-xxx
SLACK_SIGNING_SECRET=xxx

# ==================== 浏览器/沙箱 ====================

# Chrome CDP (可选)
OPENCLAW_CHROME_CDP_URL=ws://localhost:9222

# Docker (可选)
OPENCLAW_DOCKER_HOST=unix:///var/run/docker.sock

# ==================== ElevenLabs TTS ====================

ELEVENLABS_API_KEY=xxx
ELEVENLABS_VOICE_ID=21m00Tcm4TlvDq8ikWAM

# ==================== 代理配置 ====================

HTTP_PROXY=http://127.0.0.1:7890
HTTPS_PROXY=http://127.0.0.1:7890
NO_PROXY=localhost,127.0.0.1

# ==================== 诊断/日志 ====================

OPENCLAW_LOG_LEVEL=info              # silent|fatal|error|warn|info|debug|trace
OPENCLAW_CONSOLE_LEVEL=info
OPENCLAW_CONSOLE_STYLE=pretty         # pretty|compact|json

# OpenTelemetry (可选)
OTEL_ENABLED=true
OTEL_ENDPOINT=http://localhost:4318/v1/traces
OTEL_PROTOCOL=http/protobuf
OTEL_SERVICE_NAME=openclaw-gateway
OTEL_TRACES=true
OTEL_METRICS=true
OTEL_LOGS=false
OTEL_SAMPLE_RATE=1.0

# ==================== 功能开关 ====================

OPENCLAW_BROWSER_ENABLED=true
OPENCLAW_BROWSER_EVALUATE_ENABLED=true
OPENCLAW_SANDBOX_ENABLED=true
OPENCLAW_AGENT_TO_AGENT_ENABLED=true
OPENCLAW_HEARTBEAT_ENABLED=true
OPENCLAW_CRON_ENABLED=true

# ==================== 路径配置 (可选) ====================

OPENCLAW_HOME=~/.openclaw
OPENCLAW_WORKSPACE=~/.openclaw/workspace
OPENCLAW_SKILLS=~/.openclaw/skills
OPENCLAW_AGENTS=~/.openclaw/agents
OPENCLAW_CREDENTIALS=~/.openclaw/credentials

在 openclaw.json 中使用环境变量

{
  // 方法 1: ${ENV_VAR} 语法
  models: {
    providers: {
      bailian: {
        apiKey: "${DASHSCOPE_API_KEY}",
      },
      anthropic: {
        apiKey: "${ANTHROPIC_API_KEY}",
      },
    },
  },
  
  // 方法 2: 直接引用 (自动查找环境变量)
  gateway: {
    auth: {
      token: "${OPENCLAW_GATEWAY_TOKEN}",
    },
  },
  
  // 方法 3: env.vars 内联定义
  env: {
    vars: {
      CUSTOM_API_KEY: "xxx",
      FEATURE_FLAG: "enabled",
    },
    
    // 从登录 shell 导入环境变量
    shellEnv: {
      enabled: true,
      timeoutMs: 15000,
    },
  },
  
  // 方法 4: 通道配置中使用
  channels: {
    feishu: {
      accounts: {
        lead: {
          appId: "${FEISHU_LEAD_APP_ID}",
          appSecret: "${FEISHU_LEAD_APP_SECRET}",
        },
      },
    },
  },
}

.env 文件最佳实践

# ~/.openclaw/.env

# ==================== 生产环境 ====================
# 使用强随机 token
OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32)

# 使用环境变量管理工具 (如 1Password CLI)
# DASHSCOPE_API_KEY=$(op read "op://Personal/DashScope/credential")

# ==================== 开发环境 ====================
# 使用 .env.development 文件
DASHSCOPE_API_KEY=sk-dev-xxx
OPENCLAW_LOG_LEVEL=debug

# ==================== 多账号管理 ====================
# 为不同飞书账号使用不同前缀
FEISHU_LEAD_APP_ID=cli_lead_xxx
FEISHU_LEAD_APP_SECRET=lead_xxx

FEISHU_VOC_APP_ID=cli_voc_xxx
FEISHU_VOC_APP_SECRET=voc_xxx

FEISHU_GEO_APP_ID=cli_geo_xxx
FEISHU_GEO_APP_SECRET=geo_xxx

环境变量验证

# 检查环境变量是否生效
openclaw config get models.providers.bailian.apiKey

# 验证配置
openclaw config validate

# 查看完整配置 (包含环境变量替换)
openclaw config show --resolved

5.5 Docker 部署

Dockerfile (生产环境)

# ==================== 多阶段构建 ====================
FROM node:22-alpine AS builder

WORKDIR /build

# 安装 OpenClaw
RUN npm install -g openclaw@latest

# ==================== 运行镜像 ====================
FROM node:22-alpine

WORKDIR /app

# 安装运行时依赖
RUN apk add --no-cache \
    git \
    curl \
    ca-certificates \
    tzdata \
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone

# 复制 OpenClaw
COPY --from=builder /usr/local/lib/node_modules/openclaw /usr/local/lib/node_modules/openclaw
COPY --from=builder /usr/local/bin/openclaw /usr/local/bin/openclaw

# 创建数据卷
VOLUME ["/root/.openclaw"]

# 暴露端口
EXPOSE 18789 18790 18793

# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
    CMD curl -f http://localhost:18789/health || exit 1

# 启动命令
ENTRYPOINT ["openclaw", "gateway"]
CMD ["--port", "18789", "--bind-host", "0.0.0.0"]

docker-compose.yml (推荐)

version: '3.8'

services:
  openclaw:
    image: openclaw:latest
    build: .
    container_name: openclaw-gateway
    restart: unless-stopped
    
    # 端口映射
    ports:
      - "18789:18789"   # Gateway
      - "18790:18790"   # Control UI (可选)
      - "18793:18793"   # Canvas Host (可选)
    
    # 数据卷
    volumes:
      - ~/.openclaw:/root/.openclaw
      - /var/run/docker.sock:/var/run/docker.sock  # Docker 沙箱支持
    
    # 环境变量
    environment:
      # 模型 Provider
      - DASHSCOPE_API_KEY=${DASHSCOPE_API_KEY}
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - GOOGLE_API_KEY=${GOOGLE_API_KEY}
      
      # Gateway 认证
      - OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN}
      
      # 通道凭证
      - WHATSAPP_DEFAULT_AUTH_TOKEN=${WHATSAPP_TOKEN}
      - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
      - FEISHU_LEAD_APP_ID=${FEISHU_LEAD_APP_ID}
      - FEISHU_LEAD_APP_SECRET=${FEISHU_LEAD_APP_SECRET}
      
      # 代理 (可选)
      - HTTP_PROXY=${HTTP_PROXY:-}
      - HTTPS_PROXY=${HTTPS_PROXY:-}
      
      # 日志级别
      - OPENCLAW_LOG_LEVEL=info
    
    # 网络配置
    networks:
      - openclaw-net
    
    # 资源限制
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G
        reservations:
          cpus: '0.5'
          memory: 512M

  # 可选:Chrome CDP (浏览器自动化)
  chrome:
    image: browserless/chrome:latest
    container_name: openclaw-chrome
    restart: unless-stopped
    ports:
      - "9222:3000"
    environment:
      - CONNECTION_TIMEOUT=600000
      - MAX_CONCURRENT_SESSIONS=5
    networks:
      - openclaw-net

networks:
  openclaw-net:
    driver: bridge

启动命令

# 1. 准备环境变量文件
cat > .env << EOF
DASHSCOPE_API_KEY=sk-xxx
ANTHROPIC_API_KEY=sk-ant-xxx
OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32)
WHATSAPP_TOKEN=xxx
TELEGRAM_BOT_TOKEN=xxx
FEISHU_LEAD_APP_ID=cli_xxx
FEISHU_LEAD_APP_SECRET=xxx
EOF

# 2. 启动服务
docker-compose up -d

# 3. 查看日志
docker-compose logs -f openclaw

# 4. 验证健康状态
curl http://localhost:18789/health

# 5. 访问 Control UI
open http://localhost:18789

Docker 部署注意事项

# ==================== 数据持久化 ====================
# 确保 ~/.openclaw 目录存在且有正确权限
mkdir -p ~/.openclaw
chmod 700 ~/.openclaw

# ==================== Docker 沙箱支持 ====================
# 如需启用 Docker 沙箱,需要挂载 Docker socket
# ⚠️ 注意安全:这会给容器 Docker 访问权限
volumes:
  - /var/run/docker.sock:/var/run/docker.sock

# 更安全的替代方案:使用 Docker-in-Docker (dind)
services:
  openclaw:
    privileged: true
    environment:
      - OPENCLAW_DOCKER_HOST=tcp://docker:2375
  
  docker:
    image: docker:dind
    privileged: true
    environment:
      - DOCKER_TLS_CERTDIR=""

# ==================== 网络配置 ====================
# LAN 访问:绑定 0.0.0.0
CMD ["openclaw", "gateway", "--bind-host", "0.0.0.0", "--port", "18789"]

# 仅本地访问:绑定 127.0.0.1
CMD ["openclaw", "gateway", "--bind-host", "127.0.0.1", "--port", "18789"]

# ==================== TLS/HTTPS ====================
# 启用 TLS (自签名证书)
volumes:
  - ~/.openclaw/gateway.crt:/root/.openclaw/gateway.crt
  - ~/.openclaw/gateway.key:/root/.openclaw/gateway.key

environment:
  - OPENCLAW_GATEWAY_TLS_ENABLED=true

# ==================== 日志管理 ====================
# 限制日志文件大小
logging:
  driver: "json-file"
  options:
    max-size: "10m"
    max-file: "3"

故障排查

# 查看容器状态
docker-compose ps

# 查看实时日志
docker-compose logs -f openclaw

# 进入容器调试
docker-compose exec openclaw sh

# 检查配置
docker-compose exec openclaw openclaw config validate

# 查看环境变量
docker-compose exec openclaw env | grep OPENCLAW

# 重启服务
docker-compose restart openclaw

# 重建镜像
docker-compose build --no-cache

5.6 Systemd 服务配置 (Linux)

服务文件

# /etc/systemd/system/openclaw.service

[Unit]
Description=OpenClaw Gateway Service
Documentation=https://docs.openclaw.ai
After=network.target network-online.target
Wants=network-online.target

[Service]
Type=simple
User=openclaw
Group=openclaw

# 工作目录
WorkingDirectory=/home/openclaw

# 环境变量
Environment="NODE_ENV=production"
Environment="PATH=/usr/local/bin:/usr/bin:/bin"
Environment="HOME=/home/openclaw"

# 模型 Provider
Environment="DASHSCOPE_API_KEY=sk-xxx"
Environment="ANTHROPIC_API_KEY=sk-ant-xxx"
Environment="GOOGLE_API_KEY=xxx"

# Gateway 认证
Environment="OPENCLAW_GATEWAY_TOKEN=your-secret-token"

# 通道凭证
Environment="WHATSAPP_DEFAULT_AUTH_TOKEN=xxx"
Environment="TELEGRAM_BOT_TOKEN=xxx"
Environment="FEISHU_LEAD_APP_ID=cli_xxx"
Environment="FEISHU_LEAD_APP_SECRET=xxx"

# 日志配置
Environment="OPENCLAW_LOG_LEVEL=info"
Environment="OPENCLAW_CONSOLE_LEVEL=info"
Environment="OPENCLAW_CONSOLE_STYLE=pretty"

# 功能开关
Environment="OPENCLAW_BROWSER_ENABLED=true"
Environment="OPENCLAW_SANDBOX_ENABLED=true"
Environment="OPENCLAW_AGENT_TO_AGENT_ENABLED=true"

# 代理配置 (可选)
# Environment="HTTP_PROXY=http://127.0.0.1:7890"
# Environment="HTTPS_PROXY=http://127.0.0.1:7890"

# 启动命令
ExecStart=/usr/bin/openclaw gateway \
  --port 18789 \
  --bind-host 0.0.0.0 \
  --config /home/openclaw/.openclaw/openclaw.json

# 重启策略
Restart=always
RestartSec=10

# 资源限制
LimitNOFILE=65536
LimitNPROC=4096
MemoryMax=2G
CPUQuota=200%

# 安全加固
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
PrivateTmp=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
ReadWritePaths=/home/openclaw/.openclaw

# 日志
StandardOutput=journal
StandardError=journal
SyslogIdentifier=openclaw

[Install]
WantedBy=multi-user.target

环境变量文件 (推荐)

# /etc/openclaw/.env

# 模型 Provider
DASHSCOPE_API_KEY=sk-xxx
ANTHROPIC_API_KEY=sk-ant-xxx
GOOGLE_API_KEY=xxx

# Gateway 认证
OPENCLAW_GATEWAY_TOKEN=your-secret-token

# 通道凭证
WHATSAPP_DEFAULT_AUTH_TOKEN=xxx
TELEGRAM_BOT_TOKEN=xxx
FEISHU_LEAD_APP_ID=cli_xxx
FEISHU_LEAD_APP_SECRET=xxx

# 日志
OPENCLAW_LOG_LEVEL=info
# /etc/systemd/system/openclaw.service (使用 EnvironmentFile)

[Service]
# ...
EnvironmentFile=/etc/openclaw/.env
ExecStart=/usr/bin/openclaw gateway --port 18789 --bind-host 0.0.0.0
# ...

部署步骤

# 1. 创建 openclaw 用户
sudo useradd --system --no-create-home --shell /bin/false openclaw

# 2. 安装 OpenClaw
sudo npm install -g openclaw@latest

# 3. 创建目录结构
sudo mkdir -p /home/openclaw/.openclaw
sudo mkdir -p /etc/openclaw

# 4. 复制配置文件
cp ~/.openclaw/openclaw.json /home/openclaw/.openclaw/
cp ~/.openclaw/.env /etc/openclaw/.env  # 如果使用 EnvironmentFile

# 5. 设置权限
sudo chown -R openclaw:openclaw /home/openclaw/.openclaw
sudo chmod 700 /home/openclaw/.openclaw
sudo chmod 600 /etc/openclaw/.env

# 6. 安装服务文件
sudo cp openclaw.service /etc/systemd/system/

# 7. 重载 systemd
sudo systemctl daemon-reload

# 8. 启用并启动服务
sudo systemctl enable openclaw
sudo systemctl start openclaw

# 9. 查看状态
sudo systemctl status openclaw

# 10. 查看日志
sudo journalctl -u openclaw -f

常用命令

# 启动/停止/重启
sudo systemctl start openclaw
sudo systemctl stop openclaw
sudo systemctl restart openclaw

# 查看状态
sudo systemctl status openclaw

# 查看日志
sudo journalctl -u openclaw -f           # 实时日志
sudo journalctl -u openclaw --since today  # 今日日志
sudo journalctl -u openclaw -n 100      # 最近 100 行

# 编辑配置
sudo systemctl edit openclaw            # 创建覆盖配置

# 重新加载配置
sudo systemctl daemon-reload
sudo systemctl restart openclaw

# 禁用开机启动
sudo systemctl disable openclaw

日志轮转

# /etc/logrotate.d/openclaw
/var/log/journal/*/openclaw*.journal {
    weekly
    rotate 4
    compress
    delaycompress
    missingok
    notifempty
    create 0640 root systemd-journal
}

监控和告警

# 创建健康检查脚本
cat > /usr/local/bin/openclaw-healthcheck << 'EOF'
#!/bin/bash
curl -f http://localhost:18789/health || exit 1
EOF
chmod +x /usr/local/bin/openclaw-healthcheck

# 添加到 crontab (每 5 分钟检查)
*/5 * * * * /usr/local/bin/openclaw-healthcheck || \
  echo "OpenClaw health check failed!" | mail -s "OpenClaw Alert" admin@example.com
# 启用服务
sudo systemctl daemon-reload
sudo systemctl enable openclaw
sudo systemctl start openclaw

# 查看状态
sudo systemctl status openclaw

# 查看日志
sudo journalctl -u openclaw -f

6. 安全与权限管理

6.1 认证机制详解

源码位置: config/types.gateway.d.ts, gateway/auth.ts

Gateway 认证模式 (3 种)

// from config/types.gateway.d.ts
type GatewayAuthMode = "token" | "password" | "trusted-proxy";

type GatewayAuthConfig = {
  mode?: GatewayAuthMode;
  token?: string;                    // token 模式:共享密钥
  password?: string;                 // password 模式:密码认证
  trustedProxy?: GatewayTrustedProxyConfig;  // 可信反向代理模式
};

认证模式对比:

模式适用场景安全性配置复杂度
token个人开发/内网部署⭐⭐⭐
password多用户环境⭐⭐⭐⭐⭐⭐
trusted-proxy企业部署 (Pomerium/Caddy OAuth)⭐⭐⭐⭐⭐⭐⭐⭐

模式 1: Token 认证 (默认)

{
  gateway: {
    auth: {
      mode: "token",
      token: "${OPENCLAW_GATEWAY_TOKEN}",  // 建议使用环境变量
    },
  },
}

连接流程:

┌─────────────────────────────────────────────────────────────────────────────────┐
│                      Gateway Token 认证流程                                       │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  1. 客户端发起 WebSocket 连接                                                      │
│     ws://127.0.0.1:18789                                                        │
│     Headers:                                                                    │
│       Authorization: Bearer <gateway-token>                                     │
│       X-Device-Id: <device-fingerprint>                                         │
│                                                                                 │
│  2. Gateway 验证 token                                                             │
│     const expectedToken = process.env.OPENCLAW_GATEWAY_TOKEN;                   │
│     const providedToken = headers.authorization?.replace('Bearer ', '');        │
│                                                                                 │
│     if (providedToken !== expectedToken) {                                      │
│       ws.close(4001, 'Unauthorized');                                           │
│       return;                                                                   │
│     }                                                                           │
│                                                                                 │
│  3. 设备指纹验证 (可选)                                                            │
│     const knownDevices = config.knownDevices || [];                             │
│     const device = knownDevices.find(d => d.id === deviceId);                   │
│                                                                                 │
│  4. 颁发设备 token (JWT 格式,30 天有效期)                                           │
│     const deviceToken = jwt.sign(                                               │
│       { deviceId, issuedAt: Date.now() },                                       │
│       config.gateway.secret,                                                    │
│       { expiresIn: '30d' }                                                      │
│     );                                                                          │
│                                                                                 │
│  5. 返回连接成功                                                                   │
│     ws.send(JSON.stringify({                                                    │
│       type: 'res:connect',                                                      │
│       ok: true,                                                                 │
│       token: deviceToken,                                                       │
│       expires: Date.now() + 30 * 24 * 60 * 60 * 1000                            │
│     }));                                                                        │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

模式 2: Password 认证

{
  gateway: {
    auth: {
      mode: "password",
      password: "${OPENCLAW_GATEWAY_PASSWORD}",
    },
  },
}

模式 3: Trusted Proxy 认证 (企业级)

// from config/types.gateway.d.ts
type GatewayTrustedProxyConfig = {
  userHeader: string;              // 必需:用户身份头 (如 "x-forwarded-user")
  requiredHeaders?: string[];      // 必需:验证请求来自代理
  allowUsers?: string[];           // 可选:用户白名单
};
{
  gateway: {
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        userHeader: "x-pomerium-claim-email",
        requiredHeaders: ["x-forwarded-proto", "x-forwarded-host"],
        allowUsers: ["admin@example.com", "dev@example.com"],
      },
    },
  },
}

适用场景:

  • Pomerium + OAuth (Google/GitHub SSO)
  • Caddy + oauth2_proxy
  • Cloudflare Access
  • Authelia

设备配对协议 (新设备首次连接)

┌──────────────┐                              ┌──────────────┐
│    Client    │                              │   Gateway    │
└──────┬───────┘                              └──────┬───────┘
       │                                            │
       │  ─────────────────────────────────────►    │
       │  req:connect { device: { id: "new-mac" } } │
       │                                            │
       │  ◄─────────────────────────────────────    │
       │  res:challenge {                           │
       │    challenge: "abc123xyz",                 │
       │    expires: 300000  // 5 分钟                │
       │  }                                         │
       │                                            │
       │  [用户在 Gateway Control UI 确认配对]         │
       │                                            │
       │  ─────────────────────────────────────►    │
       │  req:pair {                                │
       │    challenge: "abc123xyz",                 │
       │    signature: <signed-challenge>           │
       │  }                                         │
       │                                            │
       │  ◄─────────────────────────────────────    │
       │  res:pair {                                │
       │    ok: true,                               │
       │    deviceToken: "eyJhbGc...",              │
       │  }                                         │
       │                                            │

TLS/HTTPS 配置

// from config/types.gateway.d.ts
type GatewayTlsConfig = {
  enabled?: boolean;
  autoGenerate?: boolean;        // 自动生成自签名证书
  certPath?: string;             // PEM 证书路径
  keyPath?: string;              // PEM 私钥路径
  caPath?: string;               // CA  bundle (mTLS)
};
{
  gateway: {
    tls: {
      enabled: true,
      autoGenerate: true,        // 开发环境:自动生成
      certPath: "~/.openclaw/gateway.crt",
      keyPath: "~/.openclaw/gateway.key",
      // 生产环境:使用 Let's Encrypt 证书
      // certPath: "/etc/letsencrypt/live/example.com/fullchain.pem",
      // keyPath: "/etc/letsencrypt/live/example.com/privkey.pem",
    },
  },
}

安全加固配置

{
  gateway: {
    auth: {
      // 禁止不安全配置
      allowInsecureAuth: false,           // 禁止 HTTP 明文 token
      dangerouslyDisableDeviceAuth: false, // 禁止禁用设备验证
    },
    
    // Control UI 访问控制
    controlUi: {
      enabled: true,
      basePath: "/openclaw",
      allowedOrigins: ["https://admin.example.com"],
    },
    
    // 绑定地址
    bindMode: "loopback",      // auto|lan|loopback|custom|tailnet
    bindHost: "127.0.0.1",     // 仅本地访问
    port: 18789,
  },
}

6.2 沙箱隔离详解

源码位置: config/types.sandbox.d.ts, sandbox/

沙箱模式配置

// from config/types.sandbox.d.ts
type SandboxMode = "off" | "non-main" | "all";
type SandboxScope = "session" | "agent" | "shared";
type SandboxWorkspaceAccess = "none" | "ro" | "rw";

type SandboxConfig = {
  mode?: SandboxMode;
  workspaceAccess?: SandboxWorkspaceAccess;
  scope?: SandboxScope;
  perSession?: boolean;        // 遗留别名
  workspaceRoot?: string;
  docker?: SandboxDockerSettings;
  browser?: SandboxBrowserSettings;
  prune?: SandboxPruneSettings;
};

沙箱模式对比:

模式适用 Agent隔离级别性能影响
offmain Agent无隔离
non-main除 main 外的所有 Agent中等
all所有 Agent (包括 main)完全隔离

Docker 沙箱配置

// from config/types.sandbox.d.ts
type SandboxDockerSettings = {
  image?: string;              // Docker 镜像 (默认:node:20-alpine)
  network?: string;            // 网络模式 (bridge|host|none)
  resources?: {
    memory?: string;           // 内存限制 (如 "1g")
    cpu?: string | number;     // CPU 限制 (如 "1" 或 1.5)
  };
  volumes?: string[];          // 挂载卷
  env?: Record<string, string>; // 环境变量
};
{
  agents: {
    list: [
      {
        id: "coding",
        sandbox: {
          mode: "all",
          workspaceAccess: "rw",
          docker: {
            image: "node:20-alpine",
            network: "bridge",
            resources: {
              memory: "2g",
              cpu: "2",
            },
            volumes: [
              "/tmp/cache:/cache",  // 缓存共享
            ],
            env: {
              NPM_CONFIG_CACHE: "/cache/npm",
            },
          },
        },
      },
    ],
  },
}

浏览器沙箱配置

// from config/types.sandbox.d.ts
type SandboxBrowserSettings = {
  enabled?: boolean;
  headless?: boolean;
  cdpUrl?: string;             // Chrome DevTools Protocol URL
  cdpPort?: number;
};
{
  sandbox: {
    browser: {
      enabled: true,
      headless: true,
      cdpUrl: "ws://localhost:9222",  // 外部 Chrome CDP
      // 或使用内置浏览器
      // cdpPort: 18791,
    },
  },
}

自动清理配置 (Prune)

// from config/types.sandbox.d.ts
type SandboxPruneSettings = {
  enabled?: boolean;
  intervalHours?: number;      // 清理间隔
  maxAgeHours?: number;        // 最大存活时间
};
{
  sandbox: {
    prune: {
      enabled: true,
      intervalHours: 24,       // 每天清理
      maxAgeHours: 168,        // 7 天最大存活时间
    },
  },
}

沙箱隔离级别

┌─────────────────────────────────────────────────────────────────────────────────┐
│                              沙箱隔离级别 (Sandbox Isolation Levels)               │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  Level 1: 进程隔离 (默认)                                                         │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  • 独立的 Node.js 子进程                                                   │    │
│  │  • 独立的文件描述符                                                       │    │
│  │  • 独立的环境变量                                                         │    │
│  │  • 共享主机文件系统                                                       │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                                                                 │
│  Level 2: Docker 容器隔离 (推荐)                                                  │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  • 独立的容器命名空间                                                     │    │
│  │  • 独立的文件系统 (可挂载卷)                                               │    │
│  │  • 独立的网络命名空间                                                     │    │
│  │  • 资源限制 (CPU/内存)                                                    │    │
│  │  • 自动清理 (prune)                                                       │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                                                                 │
│  Level 3: 完全隔离 (高安全场景)                                                   │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  • Docker 容器 + seccomp 配置文件                                          │    │
│  │  • 只读文件系统 (workspaceAccess: "ro")                                   │    │
│  │  • 网络隔离 (network: "none")                                             │    │
│  │  • 无特权模式 (privileged: false)                                         │    │
│  │  • 资源限制严格                                                           │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

工作区访问控制

{
  sandbox: {
    // 只读访问 (安全)
    workspaceAccess: "ro",
    
    // 读写访问 (功能完整)
    workspaceAccess: "rw",
    
    // 无访问 (完全隔离)
    workspaceAccess: "none",
  },
}

6.3 工具权限控制

源码位置: config/types.tools.d.ts

工具权限模式

// from config/types.tools.d.ts
type ToolPermissionMode = "full" | "restricted" | "coding" | "none" | "allowlist" | "denylist";

type AgentToolsConfig = {
  profile?: ToolPermissionMode;
  mode?: "allowlist" | "denylist";
  allow?: string[];          // 允许的工具列表
  deny?: string[];           // 禁止的工具列表
  restrictions?: {
    [toolName: string]: ToolRestriction;
  };
};

type ToolRestriction = {
  allowedCommands?: string[];   // exec 工具:允许的命令
  allowedHosts?: string[];      // 网络工具:允许的主机
  maxFileSize?: number;         // 文件工具:最大文件大小
  sandbox?: boolean;            // 是否启用沙箱
};

权限模式详解

模式允许的工具适用场景
full所有工具受信任的主 Agent
restricted读取类工具 (read/web_search)普通聊天 Agent
coding编码相关工具 (read/write/edit/exec)编码 Agent
none无工具纯聊天 Agent
allowlist仅 allow 列表中的工具精细控制
denylist除 deny 列表外的所有工具黑名单模式

配置示例

{
  agents: {
    list: [
      // ==================== 主 Agent (完全权限) ====================
      {
        id: "main",
        tools: {
          profile: "full",
        },
      },
      
      // ==================== 编码 Agent (编码权限) ====================
      {
        id: "coding",
        tools: {
          profile: "coding",
          // 或手动指定
          mode: "allowlist",
          allow: ["read", "write", "edit", "exec", "process", "browser"],
          restrictions: {
            exec: {
              allowedCommands: ["npm", "pnpm", "yarn", "git", "node", "npx"],
              sandbox: true,
            },
          },
        },
      },
      
      // ==================== VOC 分析师 (受限权限) ====================
      {
        id: "voc",
        tools: {
          profile: "restricted",
          mode: "allowlist",
          allow: ["read", "write", "web_search", "web_fetch", "sessions_send"],
        },
      },
      
      // ==================== 纯聊天 Agent (无工具) ====================
      {
        id: "chat",
        tools: {
          profile: "none",
        },
      },
    ],
  },
  
  // ==================== 全局工具配置 ====================
  tools: {
    // exec 工具全局限制
    exec: {
      allowedCommands: ["npm", "git", "node"],
      denyCommands: ["rm", "sudo", "curl", "wget"],
      sandbox: true,
    },
    
    // 浏览器工具全局限制
    browser: {
      evaluateEnabled: false,    // 禁止 JavaScript 执行
      allowedHosts: ["*"],
    },
  },
}

工具权限继承

┌─────────────────────────────────────────────────────────────────────────────────┐
│                          工具权限继承规则 (Tool Permission Inheritance)           │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  1. 全局配置 (tools.*)                                                           │
│     ↓                                                                           │
│  2. Agent 配置 (agents.list[].tools)                                            │
│     ↓                                                                           │
│  3. 会话级覆盖 (session.tools)                                                   │
│     ↓                                                                           │
│  4. 最终权限 (最严格的规则生效)                                                   │
│                                                                                 │
│  示例:                                                                          │
│  • 全局允许 exec,Agent 禁止 → 禁止                                             │
│  • 全局允许 rm,Agent 允许但 restrictions 禁止 → 禁止                            │
│  • 全局无限制,Agent allowlist → 仅 allowlist 中的工具                           │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

6.4 群组访问控制

源码位置: config/types.messages.d.ts, config/group-policy.d.ts

群组策略类型

// from config/types.base.d.ts
type GroupPolicy = "open" | "disabled" | "allowlist";

type GroupChatConfig = {
  mentionPatterns?: string[];     // 提及模式 (如 ["@openclaw"])
  requireMention?: boolean;       // 是否必须被提及才响应
  policy?: GroupPolicy;           // 群组策略
  allowlist?: string[];           // 允许的群组 ID 列表
};

群组策略详解

策略行为适用场景
open响应所有消息内部测试群
disabled不响应任何消息禁止使用的群
allowlist仅响应白名单群生产环境
requireMention仅响应提及消息默认推荐

配置示例

{
  // ==================== 全局群组配置 ====================
  messages: {
    groupChat: {
      requireMention: true,          // 默认:必须被提及
      mentionPatterns: ["@openclaw", "@助手", "@bot"],
    },
  },
  
  // ==================== 通道级群组配置 ====================
  channels: {
    discord: {
      guilds: {
        // 所有服务器:必须提及
        "*": {
          requireMention: true,
          policy: "open",
        },
        // 特定服务器:禁用
        "123456789": {
          policy: "disabled",
        },
        // 特定服务器:白名单模式
        "987654321": {
          policy: "allowlist",
          allowlist: ["channel-1", "channel-2"],
        },
      },
    },
    
    whatsapp: {
      groups: {
        "*": {
          requireMention: true,      // WhatsApp 群必须提及
          policy: "open",
        },
      },
    },
    
    feishu: {
      requireMention: false,         // 飞书群默认不要求提及
      groups: {
        "*": {
          policy: "open",
        },
      },
    },
  },
  
  // ==================== Agent 级群组配置 ====================
  agents: {
    list: [
      {
        id: "admin",
        groupChat: {
          mentionPatterns: ["@admin", "@管理员"],
          requireMention: true,
          policy: "allowlist",
          allowlist: ["admin-group-id"],
        },
      },
      {
        id: "dev",
        groupChat: {
          mentionPatterns: ["@dev", "@开发"],
          requireMention: true,
        },
      },
    ],
  },
}

提及模式匹配

// 提及匹配逻辑
const mentionPatterns = ["@openclaw", "@助手", "@bot"];
const messageContent = "@openclaw 你好";

const isMentioned = mentionPatterns.some(pattern =>
  messageContent.includes(pattern)
);

// 正则匹配 (更精确)
const mentionRegex = /@(?:openclaw|助手|bot)\b/i;
const isMentioned = mentionRegex.test(messageContent);

6.5 远程访问安全

远程访问方案对比

方案安全性复杂度适用场景
Tailscale⭐⭐⭐⭐⭐个人/小团队
Cloudflare Tunnel⭐⭐⭐⭐⭐⭐⭐公开服务
SSH 隧道⭐⭐⭐⭐临时访问
VPN⭐⭐⭐⭐⭐⭐⭐⭐企业环境
反向代理 + OAuth⭐⭐⭐⭐⭐⭐⭐⭐企业 SSO

方案 1: Tailscale (推荐)

# 1. 安装 Tailscale
brew install tailscale         # macOS
sudo apt install tailscale     # Linux

# 2. 登录
tailscale up

# 3. 获取 Tailscale IP
tailscale ip

# 4. 配置 Gateway 绑定 Tailscale 接口
# openclaw.json
{
  gateway: {
    bindMode: "tailnet",
    bindHost: "100.x.y.z",     # Tailscale IP
    port: 18789,
  },
}

# 5. 重启 Gateway
openclaw gateway restart

Tailscale ACL 配置 (acl.json):

{
  "acls": [
    {
      "action": "accept",
      "src": ["alice@example.com", "bob@example.com"],
      "dst": ["gateway-host:18789"],
    },
  ],
}

方案 2: Cloudflare Tunnel

# 1. 安装 cloudflared
brew install cloudflared

# 2. 登录 Cloudflare
cloudflared tunnel login

# 3. 创建隧道
cloudflared tunnel create openclaw

# 4. 配置隧道 (config.yml)
tunnel: openclaw
credentials-file: /Users/[username]/.cloudflared/xxx.json
ingress:
  - hostname: openclaw.example.com
    service: http://127.0.0.1:18789
  - service: http_status:404

# 5. 运行隧道
cloudflared tunnel run openclaw

Cloudflare Access 配置:

{
  gateway: {
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        userHeader: "cf-access-authenticated-user-email",
        requiredHeaders: ["cf-access-jwt-assertion"],
        allowUsers: ["admin@example.com"],
      },
    },
  },
}

方案 3: SSH 隧道

# 本地端口转发 (从本地访问远程 Gateway)
ssh -L 18789:127.0.0.1:18789 user@remote-host

# 远程端口转发 (从远程访问本地 Gateway)
ssh -R 18789:127.0.0.1:18789 user@remote-host

# 动态 SOCKS 代理
ssh -D 1080 user@remote-host

防火墙配置

# UFW (Ubuntu)
sudo ufw allow 18789/tcp from 100.64.0.0/10  # 只允许 Tailscale 网段
sudo ufw enable

# iptables
sudo iptables -A INPUT -p tcp --dport 18789 -s 100.64.0.0/10 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 18789 -j DROP

# macOS 防火墙
# 系统偏好设置 → 安全性与隐私 → 防火墙 → 防火墙选项

方案 4: Nginx 反向代理 + OAuth

# /etc/nginx/sites-available/openclaw

server {
    listen 443 ssl;
    server_name openclaw.example.com;
    
    # SSL 证书
    ssl_certificate /etc/letsencrypt/live/openclaw.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/openclaw.example.com/privkey.pem;
    
    # OAuth2 Proxy
    location / {
        auth_request /oauth2/auth;
        error_page 401 =302 /oauth2/start?rd=$request_uri;
        
        proxy_pass http://127.0.0.1:18789;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    
    # OAuth2 Proxy 端点
    location /oauth2/ {
        proxy_pass http://127.0.0.1:4180/oauth2/;
        proxy_set_header Host $host;
    }
}

OAuth2 Proxy 配置:

# /etc/oauth2-proxy/config.cfg
provider = "github"
client_id = "xxx"
client_secret = "xxx"
cookie_secret = "$(openssl rand -base64 32)"
email_domains = ["example.com"]
upstream = "http://127.0.0.1:18789"
http_address = "127.0.0.1:4180"

安全最佳实践

{
  gateway: {
    // 1. 强制 TLS
    tls: {
      enabled: true,
      autoGenerate: false,     // 生产环境使用正式证书
    },
    
    // 2. 绑定内网地址
    bindMode: "loopback",
    bindHost: "127.0.0.1",
    
    // 3. 禁止不安全认证
    auth: {
      allowInsecureAuth: false,
      dangerouslyDisableDeviceAuth: false,
    },
    
    // 4. 限制 Control UI 来源
    controlUi: {
      allowedOrigins: ["https://admin.example.com"],
    },
  },
  
  // 5. 启用日志审计
  logging: {
    level: "info",
    consoleLevel: "info",
  },
  
  // 6. 启用诊断
  diagnostics: {
    enabled: true,
  },
}

┌─────────────────────────────────────────────────────────────────────────────────┐
│                      Gateway 认证流程 (Authentication Flow)                       │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  Step 1: 客户端发起连接请求                                                       │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  WebSocket Connect: ws://127.0.0.1:18789                                │    │
│  │  Headers:                                                               │    │
│  │    Authorization: Bearer <gateway-token>                                │    │
│  │    X-Device-Id: <device-fingerprint>                                    │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                    │                                            │
│                                    ▼                                            │
│  Step 2: Gateway 验证 token                                                      │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  const expectedToken = process.env.OPENCLAW_GATEWAY_TOKEN;              │    │
│  │  const providedToken = headers.authorization?.replace('Bearer ', '');   │    │
│  │                                                                          │    │
│  │  if (providedToken !== expectedToken) {                                 │    │
│  │    ws.close(4001, 'Unauthorized');                                      │    │
│  │    return;                                                              │    │
│  │  }                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                    │                                            │
│                                    ▼                                            │
│  Step 3: 设备指纹验证 (可选)                                                      │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  const knownDevices = config.knownDevices || [];                        │    │
│  │  const device = knownDevices.find(d => d.id === deviceId);              │    │
│  │                                                                          │    │
│  │  if (!device) {                                                         │    │
│  │    // 新设备,需要配对                                                    │    │
│  │    issueChallenge(deviceId);                                            │    │
│  │    return;                                                              │    │
│  │  }                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                    │                                            │
│                                    ▼                                            │
│  Step 4: 颁发设备 token                                                          │
│  ┌─────────────────────────────────────────────────────────────────────────┐    │
│  │  const deviceToken = jwt.sign(                                          │    │
│  │    { deviceId, issuedAt: Date.now() },                                  │    │
│  │    config.gateway.secret,                                               │    │
│  │    { expiresIn: '30d' }                                                 │    │
│  │  );                                                                     │    │
│  │                                                                          │    │
│  │  ws.send(JSON.stringify({                                               │    │
│  │    type: 'res:connect',                                                 │    │
│  │    ok: true,                                                            │    │
│  │    token: deviceToken,                                                  │    │
│  │    expires: Date.now() + 30 * 24 * 60 * 60 * 1000                       │    │
│  │  }));                                                                   │    │
│  └─────────────────────────────────────────────────────────────────────────┘    │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

设备配对协议

新设备首次连接流程:

┌──────────────┐                              ┌──────────────┐
│    Client    │                              │   Gateway    │
└──────┬───────┘                              └──────┬───────┘
       │                                            │
       │  ─────────────────────────────────────►    │
       │  req:connect { device: { id: "new-mac" } } │
       │                                            │
       │  ◄─────────────────────────────────────    │
       │  res:challenge {                           │
       │    challenge: "abc123xyz",                 │
       │    expires: 300000  // 5 分钟                │
       │  }                                         │
       │                                            │
       │  [用户在 Gateway Control UI 确认配对]         │
       │                                            │
       │  ─────────────────────────────────────►    │
       │  req:pair {                                │
       │    challenge: "abc123xyz",                 │
       │    signature: <signed-challenge>           │
       │  }                                         │
       │                                            │
       │  ◄─────────────────────────────────────    │
       │  res:pair {                                │
       │    ok: true,                               │
       │    deviceToken: "eyJhbGc...",              │
       │  }                                         │
       │                                            │

Token 格式详解

Gateway Token (环境变量):

# 生成强随机 token
openssl rand -hex 32
# 输出:a1b2c3d4e5f6... (64 字符)

# 或使用 Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

设备 Token (JWT 格式):


// Payload 结构
{
  "deviceId": "macbook-pro-2024",
  "issuedAt": 1709337600000,
  "expiresAt": 1711929600000,
  "permissions": ["read", "write", "exec"],
  "scope": "agent:main"
}

// JWT 示例
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJkZXZpY2VJZCI6Im1hY2Jvb2stcHJvLTIwMjQiLCJpc3N1ZWRBdCI6MTcwOTMzNzYwMDAwMH0.
abc123xyz_signature


7. 实战案例:跨境电商多 Agent 系统

7.1 业务场景

需求: 搭建一个跨境电商营销自动化系统,包含 5 个专业 Agent:

Agent职责模型月调用量单次成本月成本估算
大总管 (lead)需求拆解、任务分发Qwen3.5-Plus500 次¥0.02¥10
VOC 分析师竞品评价抓取、痛点提炼GLM-52000 次¥0.005¥10
GEO 优化师产品内容撰写、SEO 优化GLM-53000 次¥0.005¥15
Reddit 专家社区养号、长尾流量GLM-51000 次¥0.005¥5
TikTok 编导视频脚本、生图生视频Qwen3.5-Plus500 次¥0.02¥10
总计--7000 次-¥50/月

成本对比:

  • 自建方案:¥50/月 (DashScope API)
  • SaaS 方案:$99-299/月 (Jasper/Copy.ai 等)
  • 节省:90%+ 成本

7.2 系统架构

                                    ┌─────────────────────────────────┐
                                    │      飞书群聊 (用户入口)         │
                                    │  @大总管:分析露营折叠床市场     │
                                    └──────────────┬──────────────────┘
                                                   │
                                                   ▼
┌──────────────────────────────────────────────────────────────────────────────────┐
│                              大总管 Agent (lead)                                  │
│  ┌────────────────────────────────────────────────────────────────────────────┐  │
│  │  1. 需求理解层                                                              │  │
│  │     • 意图识别:市场分析 + 内容生成                                         │  │
│  │     • 任务拆解:VOC 分析 → 内容撰写 → 社区分发 → 视频脚本                   │  │
│  └────────────────────────────────────────────────────────────────────────────┘  │
│  ┌────────────────────────────────────────────────────────────────────────────┐  │
│  │  2. 任务分发层 (sessions_send 并发调用)                                     │  │
│  │                                                                             │  │
│  │     ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐ │  │
│  │     │ VOC 分析师    │  │ GEO 优化师    │  │ Reddit 专家   │  │ TikTok 编导   │ │  │
│  │     │ (voc)        │  │ (geo)        │  │ (reddit)     │  │ (tiktok)     │ │  │
│  │     └──────┬───────┘  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘ │  │
│  │            │                 │                 │                 │          │  │
│  └────────────┼─────────────────┼─────────────────┼─────────────────┼──────────┘  │
│               │                 │                 │                 │             │
└───────────────┼─────────────────┼─────────────────┼─────────────────┼─────────────┘
                │                 │                 │                 │
                ▼                 ▼                 ▼                 ▼
    ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ ┌───────────────┐
    │  VOC 分析师 Agent   │ │  GEO 优化师 Agent  │ │  Reddit 专家 Agent │ │ TikTok 编导    │
    │  workspace-voc    │ │  workspace-geo    │ │  workspace-reddit │ │ workspace-    │
    │                   │ │                   │ │                   │ │ tiktok        │
    │ • 爬取竞品评价     │ │ • 撰写产品博客    │ │ • 搜索相关帖子    │ │ • 生成视频脚本 │
    │ • 提炼用户痛点     │ │ • SEO 关键词优化   │ │ • 养号互动策略    │ │ • AI 生图生视频 │
    │ • 输出 VOC 报告     │ │ • 输出 SEO 文章    │ │ • 输出引流方案    │ │ • 输出分镜脚本 │
    └─────────┬─────────┘ └─────────┬─────────┘ └─────────┬─────────┘ └───────┬───────┘
              │                     │                     │                   │
              └─────────────────────┴─────────────────────┴───────────────────┘
                                              │
                                              ▼
                                    ┌─────────────────────────┐
                                    │   大总管汇总结果        │
                                    │   飞书群汇报            │
                                    └─────────────────────────┘

【并发执行时序】
T0:    lead 收到指令
       │
       ├──────────────┐
       │              │
       ▼              ▼
T1:  sessions_send  sessions_send
    → voc-analyst   → geo-optimizer
       │              │
       ▼              ▼
T2:  sessions_send  sessions_send
    → reddit-spec   → tiktok-director
       │              │
       ▼              ▼
T3:  [4 个 Agent 并行执行中...]
       │
       ▼
T4:  各 Agent 返回结果 → lead 汇总 → 飞书群汇报

7.3 配置步骤

Step 1: 创建 Agent 工作区

# 使用向导创建
openclaw agents add lead
openclaw agents add voc
openclaw agents add geo
openclaw agents add reddit
openclaw agents add tiktok

# 或手动创建目录
mkdir -p ~/.openclaw/workspace-{lead,voc,geo,reddit,tiktok}

# 验证创建
ls -la ~/.openclaw/workspace-*/
# 输出示例:
# ~/.openclaw/workspace-lead/:
#   SOUL.md AGENTS.md USER.md MEMORY.md skills/

Step 2: 编写 Agent 人设

示例: ~/.openclaw/workspace-lead/SOUL.md

# SOUL.md - 大总管

## 你是谁

你是跨境电商团队的**大总管 (Lead Agent)**,负责接收老板指令并协调团队成员完成全渠道营销任务。

## 核心职责

1. **需求理解**:准确理解老板的业务需求
2. **任务拆解**:将复杂业务拆解为可执行的子任务
3. **跨 Agent 分发**:使用 `sessions_send` 并发分发给专业成员
4. **进度跟踪**:汇总各成员反馈,向老板汇报

## 工作原则

- **只做协调,不做执行**:严禁自己执行底层任务
- **并发优先**:能并行的任务绝不串行
- **异步通信**:所有任务分发通过 sessions_send 异步进行

Step 3: 配置飞书多账号

# 在飞书开放平台创建 5 个应用
# 1. 访问 https://open.feishu.cn/
# 2. 创建应用 → 选择"企业内部开发"
# 3. 获取 App ID 和 App Secret
# 4. 配置权限:
#    - 消息读写 (im:message)
#    - 群组读写 (im:chat)
#    - 用户信息读取 (contact:user)
{
  channels: {
    feishu: {
      enabled: true,
      connectionMode: "websocket",
      accounts: {
        lead: { 
          appId: "cli_a1b2c3d4e5f6", 
          appSecret: "xxxSECRET1xxx" 
        },
        voc: { 
          appId: "cli_b2c3d4e5f6g7", 
          appSecret: "xxxSECRET2xxx" 
        },
        geo: { 
          appId: "cli_c3d4e5f6g7h8", 
          appSecret: "xxxSECRET3xxx" 
        },
        reddit: { 
          appId: "cli_d4e5f6g7h8i9", 
          appSecret: "xxxSECRET4xxx" 
        },
        tiktok: { 
          appId: "cli_e5f6g7h8i9j0", 
          appSecret: "xxxSECRET5xxx" 
        },
      },
    },
  },
}

Step 4: 配置路由绑定

{
  agents: {
    list: [
      { 
        id: "lead", 
        workspace: "~/.openclaw/workspace-lead", 
        model: "bailian/qwen3.5-plus",
        tools: { profile: "full" },
      },
      { 
        id: "voc", 
        workspace: "~/.openclaw/workspace-voc", 
        model: "bailian/glm-5",
        tools: { 
          allow: ["read", "write", "web_search", "web_fetch", "sessions_send"],
        },
      },
      { 
        id: "geo", 
        workspace: "~/.openclaw/workspace-geo", 
        model: "bailian/glm-5",
        tools: { 
          allow: ["read", "write", "web_search", "sessions_send"],
        },
      },
      { 
        id: "reddit", 
        workspace: "~/.openclaw/workspace-reddit", 
        model: "bailian/glm-5",
        tools: { 
          allow: ["read", "write", "web_search", "browser", "sessions_send"],
        },
      },
      { 
        id: "tiktok", 
        workspace: "~/.openclaw/workspace-tiktok", 
        model: "bailian/qwen3.5-plus",
        tools: { 
          allow: ["read", "write", "sessions_send"],
        },
      },
    ],
  },
  
  bindings: [
    { agentId: "lead", match: { channel: "feishu", accountId: "lead" } },
    { agentId: "voc", match: { channel: "feishu", accountId: "voc" } },
    { agentId: "geo", match: { channel: "feishu", accountId: "geo" } },
    { agentId: "reddit", match: { channel: "feishu", accountId: "reddit" } },
    { agentId: "tiktok", match: { channel: "feishu", accountId: "tiktok" } },
  ],
  
  tools: {
    agentToAgent: {
      enabled: true,
      allow: ["lead", "voc", "geo", "reddit", "tiktok"],
    },
  },
}

Step 5: 安装全局技能

# 安装必要技能
clawhub install nano-banana-pro     # 图片生成
clawhub install seedance2.0          # 视频生成
clawhub install tavily               # 网络搜索
clawhub install baoyu-image-gen      # 多平台图片生成

# 验证安装
clawhub list

# 输出示例:
# Installed skills:
#   - nano-banana-pro (v1.2.0)
#   - seedance2.0 (v2.0.1)
#   - tavily (v1.0.0)
#   - baoyu-image-gen (v1.5.0)

Step 6: 重启并测试

# 验证配置语法
cat ~/.openclaw/openclaw.json | jq . > /dev/null && echo "✓ 配置有效"

# 重启 Gateway
openclaw gateway restart

# 等待启动完成
sleep 3

# 验证 Gateway 状态
openclaw status

# 验证通道连接
openclaw channels status --probe

# 验证路由绑定
openclaw agents list --bindings

# 验证 Agent 状态
openclaw agents inspect lead
openclaw agents inspect voc
openclaw agents inspect geo
openclaw agents inspect reddit
openclaw agents inspect tiktok

7.4 工作流示例

触发指令 (在飞书群@大总管):

@大总管 分析一下露营折叠床的市场,并全渠道铺内容

执行流程:

1. lead 收到指令
   ↓
2. sessions_send → voc-analyst
   "分析露营折叠床市场痛点,输出 VOC 报告"
   ↓
3. sessions_send → geo-optimizer
   "基于 VOC 数据撰写产品博客,SEO 优化"
   ↓
4. sessions_send → reddit-spec
   "寻找露营装备相关老帖子,制定互动策略"
   ↓
5. sessions_send → tiktok-director
   "生成露营折叠床短视频脚本和分镜"
   ↓
6. 各 Agent 并行执行
   ↓
7. lead 汇总结果,在飞书群汇报

预期输出:

【市场分析汇报】露营折叠床

📊 VOC 分析报告 (by voc-analyst)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
用户痛点 TOP 5:
1. 收纳体积大 (提及率 68%)
2. 重量过重 (提及率 52%)
3. 舒适度差 (提及率 45%)
4. 搭建复杂 (提及率 38%)
5. 耐用性差 (提及率 32%)

📝 SEO 文章 (by geo-optimizer)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
标题:2026 年露营折叠床选购指南:轻量化 + 舒适度兼得
关键词:露营折叠床、轻量化、便携、户外装备
字数:2500 字
发布建议:知乎专栏 + 小红书 + 微信公众号

🎯 Reddit 策略 (by reddit-spec)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
目标 Subreddit: r/CampingandHiking, r/Ultralight
互动策略:
- 搜索 "sleeping pad vs cot" 历史帖子
- 评论中自然植入产品链接
- 预计引流:50-100 UV/周

🎬 TikTok 脚本 (by tiktok-director)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
视频主题:30 秒展示折叠床收纳过程
分镜:
1. 开场:传统床 vs 折叠床对比 (3s)
2. 折叠演示:3 步快速收纳 (15s)
3. 便携展示:放入背包 (7s)
4. CTA:评论区链接 (5s)
生成图片:4 张 (封面 +3 个关键帧)

8. 性能优化与故障排查

8.1 Gateway 内部消息处理流水线

入站消息处理流程:

通道 (WhatsApp/Telegram/Feishu)
       │
       ▼
┌─────────────────────────────────────────────────────────────────┐
│ Stage 1: 通道适配层 (<5ms)                                       │
│ • Baileys/grammY/discord.js → 标准化消息格式                     │
│ 输出:{ channel, accountId, peer, content, timestamp }           │
└─────────────────────────────────────────────────────────────────┘
       │
       ▼
┌─────────────────────────────────────────────────────────────────┐
│ Stage 2: 认证与限流层 (<2ms)                                     │
│ • 验证 allowlist • 速率限制 • 防滥用检测                          │
└─────────────────────────────────────────────────────────────────┘
       │
       ▼
┌─────────────────────────────────────────────────────────────────┐
│ Stage 3: 路由匹配层 (<1ms)                                       │
│ • 执行路由匹配算法 • 确定目标 Agent • 生成 sessionKey            │
└─────────────────────────────────────────────────────────────────┘
       │
       ▼
┌─────────────────────────────────────────────────────────────────┐
│ Stage 4: 会话加载层 (10-50ms)                                    │
│ • 加载 messages.jsonl • 应用滑动窗口 • 检查压缩需求              │
└─────────────────────────────────────────────────────────────────┘
       │
       ▼
┌─────────────────────────────────────────────────────────────────┐
│ Stage 5: Agent 运行时 (500ms-5s)                                  │
│ • 构建 LLM 请求 • 调用 Provider API • 流式响应 • 工具调用处理      │
└─────────────────────────────────────────────────────────────────┘
       │
       ▼
┌─────────────────────────────────────────────────────────────────┐
│ Stage 6: 响应发送层 (10-100ms)                                   │
│ • 发送回复 • 更新会话历史 • 更新 token 统计 • 触发记忆提取        │
└─────────────────────────────────────────────────────────────────┘
       │
       ▼
用户收到回复

【总延迟分解】(典型场景)
─────────────────────────────────────────────────────────────────
通道适配      2-5ms       ▓▓
认证限流      1-2ms       ▓
路由匹配      <1ms        ▓
会话加载     10-50ms      ▓▓▓▓▓
LLM 响应     500-5000ms   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
响应发送     10-100ms     ▓▓▓
─────────────────────────────────────────────────────────────────
总计        523-5158ms

【优化重点】: LLM 响应时间占 95%+,优化 LLM 选择是关键

8.2 性能基准测试

测试环境:

  • CPU: Apple M2 Pro (12 核)
  • 内存:32GB
  • 网络:100Mbps
  • Gateway 版本:v1.2.3

单 Agent 并发测试:

并发数P50 延迟P95 延迟P99 延迟成功率
11.2s2.1s3.5s100%
51.3s2.4s4.2s100%
101.5s3.1s5.8s99.8%
202.1s4.5s8.2s99.2%
503.8s8.2s15.3s97.5%

多 Agent 并发测试 (5 个 Agent 同时运行):

指标数值说明
最大并发会话数25每个 Agent 5 个并发会话
平均 CPU 使用率45%M2 Pro 12 核
平均内存使用2.1GB包括会话缓存
网络带宽峰值15MbpsLLM API 调用
磁盘 I/O5MB/s会话历史写入

工具调用性能:

工具P50P95P99说明
read12ms45ms120ms10KB 文件
write15ms52ms150ms10KB 文件
exec150ms800ms2s简单命令
web_search1.2s2.5s4sTavily API
browser.snapshot2.5s5s8s页面加载 + 渲染
sessions_send25ms80ms200ms异步消息

8.3 优化策略

1. 模型分级策略

{
  agents: {
    list: [
      {
        id: "lead",
        model: "anthropic/claude-sonnet-4-5",  // 决策层用顶级模型
      },
      {
        id: "voc",
        model: "bailian/glm-5",  // 执行层用性价比模型
      },
      {
        id: "geo",
        model: "google/gemini-3-flash",  // 成本降低 90%
      },
    ],
  },
}

成本对比:

模型输入价格输出价格适用场景
claude-sonnet-4-5¥0.02/1K¥0.08/1K复杂决策、代码
qwen3.5-plus¥0.004/1K¥0.012/1K通用任务
glm-5¥0.001/1K¥0.001/1K简单任务、批量处理
gemini-3-flash¥0.0005/1K¥0.0015/1K超大批量

2. 会话缓存优化

{
  session: {
    cache: {
      enabled: true,
      maxSize: 100,           // 最多缓存 100 个会话
      ttl: 3600000,           // 缓存 1 小时过期
      preload: true,          // 启动时预加载活跃会话
    },
  },
}

3. 压缩策略调优

{
  session: {
    compaction: {
      // 激进模式 (节省 token,适合低成本场景)
      aggressive: {
        windowSize: 20,
        threshold: 40,
        summaryMaxLength: 200,
      },
      
      // 平衡模式 (推荐)
      balanced: {
        windowSize: 50,
        threshold: 100,
        summaryMaxLength: 500,
      },
      
      // 保守模式 (保留更多上下文,适合复杂任务)
      conservative: {
        windowSize: 100,
        threshold: 200,
        summaryMaxLength: 1000,
      },
    },
  },
}

4. 批量写入优化

// 会话历史批量写入 (减少磁盘 I/O)
class SessionStore {
  constructor() {
    this.writeBuffer = new Map();
    this.flushInterval = setInterval(() => this.flush(), 5000);  // 5 秒刷盘
  }

  appendMessage(sessionKey, message) {
    if (!this.writeBuffer.has(sessionKey)) {
      this.writeBuffer.set(sessionKey, []);
    }
    this.writeBuffer.get(sessionKey).push(message);
  }

  async flush() {
    for (const [sessionKey, messages] of this.writeBuffer) {
      await fs.appendFile(
        `${sessionPath}/messages.jsonl`,
        messages.map(m => JSON.stringify(m)).join('\n') + '\n'
      );
    }
    this.writeBuffer.clear();
  }
}

8.4 故障排查

诊断命令速查表

# ==================== 系统状态 ====================
openclaw status                    # Gateway 状态
openclaw health                    # 健康检查
openclaw usage                     # 资源使用统计

# ==================== 通道诊断 ====================
openclaw channels list             # 列出所有通道
openclaw channels status           # 通道连接状态
openclaw channels status --probe   # 主动探测连接
openclaw channels login --channel whatsapp --force  # 强制重新登录

# ==================== Agent 诊断 ====================
openclaw agents list               # 列出所有 Agent
openclaw agents list --bindings    # 列出路由绑定
openclaw agents inspect <agentId>  # 检查 Agent 配置

# ==================== 会话诊断 ====================
openclaw sessions list             # 列出活跃会话
openclaw sessions history --key <sessionKey>  # 查看会话历史
openclaw sessions compact --key <sessionKey>  # 手动触发压缩

# ==================== 日志查看 ====================
openclaw logs                      # 查看最近日志
openclaw logs --follow             # 实时日志
openclaw logs --level error        # 只看错误
openclaw logs --since 1h           # 最近 1 小时日志

# ==================== 工具诊断 ====================
openclaw tools list                # 列出可用工具
openclaw tools invoke read --path /tmp/test.txt  # 测试工具调用
openclaw sandbox status            # 沙箱状态

# ==================== 深度诊断 ====================
openclaw doctor                    # 运行诊断检查
openclaw doctor --fix              # 自动修复问题
openclaw doctor --verbose          # 详细输出

常见问题排查

问题 1: Gateway 无法启动

# 1. 检查端口占用
lsof -i :18789

# 2. 查看日志
tail -100 /tmp/openclaw/gateway-*.log

# 3. 验证配置
cat ~/.openclaw/openclaw.json | jq . > /dev/null && echo "✓ 配置有效" || echo "✗ 配置有误"

# 常见错误:
# - "EADDRINUSE": 端口被占用 → 杀掉占用进程或换端口
# - "EACCES": 权限不足 → 检查文件权限
# - "Config parse error": 配置语法错误 → 用 jq 验证 JSON

问题 2: 通道连接失败

# WhatsApp: 重新扫描 QR 码
openclaw channels login --channel whatsapp --force

# Telegram: 验证 Bot Token
curl -X GET "https://api.telegram.org/bot<YOUR_TOKEN>/getMe"

# Feishu: 检查 App ID/Secret
openclaw channels status --probe

问题 3: Agent 无响应

# 1. 检查会话状态
openclaw sessions list

# 2. 查看 Agent 日志
tail -f /tmp/openclaw/agent-<agentId>-*.log

# 3. 检查 LLM Provider 配额
# 登录 DashScope 控制台查看 token 余额

# 4. 重启 Gateway
openclaw gateway restart

问题 4: 内存占用过高

# 1. 查看内存使用
ps aux | grep openclaw

# 2. 清理不活跃会话
openclaw sessions prune --inactive 7d

# 3. 调整会话窗口配置
{
  "session": {
    "windowSize": 30,  // 减小窗口大小
    "compaction": {
      "threshold": 50  // 降低压缩阈值
    }
  }
}

日志分析技巧

# 搜索特定错误
grep -i "error" /tmp/openclaw/*.log | tail -50

# 统计错误类型
grep "ERROR" /tmp/openclaw/*.log | \
  sed 's/.*ERROR \([^ ]*\).*/\1/' | \
  sort | uniq -c | sort -rn

# 追踪特定会话
grep "sessionKey=agent:main:xxx" /tmp/openclaw/*.log

# 查看工具调用统计
grep "tool_call" /tmp/openclaw/*.log | \
  sed 's/.*tool:\([^,]*\).*/\1/' | \
  sort | uniq -c | sort -rn

9. 总结与展望

9.1 核心优势总结

技术优势:

维度OpenClaw 能力源码位置
多通道支持11+ 通道适配器 (WhatsApp/Telegram/飞书/Discord/Slack 等)channels/
Agent 隔离完全隔离的会话/记忆/工具/模型配置config/types.agents.d.ts
路由系统8 级优先级路由匹配算法routing/resolve-route.ts
会话管理JSONL 存储 + 自动压缩 + 维护策略config/types.base.d.ts
工具系统TypeBox schemas + 权限控制 + 沙箱执行config/types.tools.d.ts
技能系统4 种来源 + ClawHub 生态config/types.skills.d.ts
安全机制3 种认证模式 + Docker 沙箱 + TLSconfig/types.gateway.d.ts
部署灵活npm/Docker/Systemd/Ansibledist/cli/

9.2 适用场景

已验证场景 (生产环境)

场景Agent 配置月调用量成本文档章节
个人 AI 助手1 Agent (main)5000 次¥30/月第 4 章
编码助手2 Agent (main+coding)3000 次¥50/月第 4.3 节
跨境电商5 Agent (lead+voc+geo+reddit+tiktok)7000 次¥50/月第 7 章
Discord 社区3 Agent (admin+dev+default)10000 次¥80/月第 4.3 节
飞书多账号N Agent (按账号路由)20000 次¥150/月第 4.3 节

潜在场景

场景建议配置关键特性
客服系统多 Agent 按技能路由路由绑定 + 工具权限
教育辅导按学科分 AgentAgent 隔离 + 会话管理
内容工厂多 Agent 并行生成sessions_send 并发
数据分析专用分析 Agent工具系统 + 沙箱

9.3 未来方向 (Roadmap)

v1.3 计划 (2026 Q2)

  • 可视化编排: 拖拽式 Agent 工作流设计器
  • 向量数据库: 内置向量记忆 (LanceDB/Chroma)
  • 多模态支持: 图片/语音/视频输入输出
  • 性能优化: 会话缓存层 (Redis)
  • 监控告警: Prometheus + Grafana 集成

v1.4 计划 (2026 Q3)

  • 联邦学习: 多实例知识共享
  • Agent 市场: ClawHub 技能/配置交易
  • 低代码: 自然语言配置 Agent
  • 边缘部署: 树莓派/手机优化

长期愿景

  • AI 操作系统: 成为个人/企业的 AI 基础设施
  • 去中心化: P2P Agent 协作网络
  • 开源生态: 1000+ 社区技能

9.4 学习资源

官方资源

资源链接说明
官方文档https://docs.openclaw.ai完整使用指南
GitHubhttps://github.com/openclaw/openclaw源码 + Issues
Discordhttps://discord.com/invite/clawd社区支持
ClawHubhttps://clawhub.com技能市场
本文档~/.openclaw/workspace/openclaw-tech-share/本地技术分享

源码阅读路径

/opt/homebrew/lib/node_modules/openclaw/
├── dist/plugin-sdk/
│   ├── config/                    # 配置系统
│   │   ├── types.openclaw.d.ts    # OpenClawConfig 定义 ⭐
│   │   ├── types.agents.d.ts      # AgentConfig 定义 ⭐
│   │   ├── types.gateway.d.ts     # GatewayConfig 定义 ⭐
│   │   └── zod-schema.d.ts        # Zod 验证 Schema
│   ├── routing/                   # 路由系统
│   │   ├── resolve-route.ts       # 路由匹配算法 ⭐
│   │   └── session-key.ts         # 会话键生成 ⭐
│   ├── channels/                  # 通道适配器
│   │   ├── whatsapp/
│   │   ├── telegram/
│   │   ├── feishu/
│   │   └── discord/
│   ├── tools/                     # 工具系统
│   │   ├── sessions/
│   │   ├── exec/
│   │   └── browser/
│   └── skills/                    # 技能系统
│       └── types.d.ts
└── dist/cli/                      # CLI 工具
    ├── gateway.ts
    ├── channels.ts
    └── agents.ts

关键源码文件

文件行数重要性阅读建议
types.openclaw.d.ts200+⭐⭐⭐⭐⭐完整阅读,理解配置结构
types.agents.d.ts150+⭐⭐⭐⭐⭐完整阅读,理解 Agent 定义
resolve-route.ts300+⭐⭐⭐⭐⭐重点阅读路由匹配逻辑
session-key.ts200+⭐⭐⭐⭐重点阅读会话键生成规则
types.gateway.d.ts250+⭐⭐⭐⭐重点阅读认证/TLS 配置
types.tools.d.ts200+⭐⭐⭐⭐重点阅读工具权限控制

社区资源


10. 高级主题与企业级解决方案

10.1 流式响应优化(降低延迟 60%+)

问题背景:

  • 默认模式:等待 LLM 完整响应后一次性发送 → 用户感知延迟高
  • 优化目标:流式分块发送 → 首字延迟 <500ms,整体感知流畅

方案 1: 块流式传输 (Block Streaming)

源码位置: config/types.base.d.ts, channels/streaming.ts

// 流式配置结构
type BlockStreamingConfig = {
  enabled?: boolean;
  minChars?: number;         // 最小字符数触发发送 (默认:50)
  maxChars?: number;         // 最大字符数强制发送 (默认:500)
  idleMs?: number;           // 空闲超时发送 (默认:200ms)
  breakPreference?: "paragraph" | "newline" | "sentence";
};

配置示例:

{
  channels: {
    whatsapp: {
      streaming: {
        enabled: true,
        minChars: 30,          // 30 字符即发送 (降低首字延迟)
        maxChars: 300,         // 300 字符强制发送 (避免单块过大)
        idleMs: 150,           // 150ms 无新内容即发送
        breakPreference: "sentence",  // 按句子断句 (更自然)
      },
    },
    
    telegram: {
      streaming: {
        enabled: true,
        minChars: 50,
        maxChars: 400,
        idleMs: 200,
        breakPreference: "paragraph",
      },
    },
  },
  
  // 全局覆盖
  messages: {
    streaming: {
      enabled: true,
      minChars: 40,
      maxChars: 350,
      idleMs: 180,
    },
  },
}

流式传输时序图:

┌─────────────────────────────────────────────────────────────────────────────────┐
│                          流式响应优化时序图 (Streaming Timeline)                  │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  传统模式 (无流式):                                                               │
│  T0: 用户发送消息                                                                │
│  T1: Gateway 转发 LLM                                                            │
│  T2: LLM 生成中... (2-5s)                                                         │
│  T3: LLM 完成,返回完整响应                                                       │
│  T4: Gateway 一次性发送给用户 ← 用户等待 T0-T4                                   │
│                                                                                 │
│  流式模式 (优化后):                                                               │
│  T0: 用户发送消息                                                                │
│  T1: Gateway 转发 LLM                                                            │
│  T2: LLM 开始流式输出                                                            │
│  T3: 收到第 1 块 (30 字符) → 立即发送给用户 ← 首字延迟 T0-T3 (<500ms)              │
│  T4: 收到第 2 块 (50 字符) → 立即发送给用户                                        │
│  T5: 收到第 3 块 (80 字符) → 立即发送给用户                                        │
│  T6: LLM 完成 → 发送结束标记                                                      │
│                                                                                 │
│  效果对比:                                                                        │
│  • 传统模式:用户等待 3s 后看到完整回复                                           │
│  • 流式模式:用户 500ms 看到首字,后续持续接收                                    │
│  • 感知延迟降低:60-80%                                                          │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

方案 2: 打字机效果 (Typing Indicator)

源码位置: config/types.base.d.ts

type TypingMode = "never" | "instant" | "thinking" | "message";

type SessionConfig = {
  typingMode?: TypingMode;
  typingIntervalSeconds?: number;  // 打字指示器刷新间隔
};

配置示例:

{
  session: {
    typingMode: "thinking",      // LLM 思考时显示"正在输入"
    typingIntervalSeconds: 3,    // 每 3 秒刷新一次
  },
  
  channels: {
    whatsapp: {
      typingIndicator: {
        enabled: true,
        mode: "thinking",        // thinking|message|instant
        debounceMs: 500,         // 500ms 防抖
      },
    },
  },
}

打字机模式对比:

模式行为适用场景
never不显示打字指示追求简洁
instant收到消息立即显示即时反馈
thinkingLLM 开始思考时显示推荐默认
message收到第一块响应时显示精确同步

方案 3: 响应预加载 (Response Preloading)

原理: 在 LLM 生成响应时,提前准备发送通道

// 伪代码:响应预加载
async function streamResponse(llmStream, channel) {
  // 1. 预连接通道 (减少握手延迟)
  const connection = await channel.preconnect();
  
  // 2. 流式处理
  for await (const chunk of llmStream) {
    // 3. 字符累积
    buffer += chunk.text;
    
    // 4. 触发条件检查
    if (buffer.length >= config.minChars || 
        isSentenceEnd(buffer) ||
        idleTimer.elapsed() > config.idleMs) {
      
      // 5. 异步发送 (不阻塞后续处理)
      connection.send(buffer, { blocking: false });
      buffer = "";
    }
  }
  
  // 6. 发送剩余内容
  if (buffer.length > 0) {
    await connection.send(buffer, { blocking: true });
  }
}

性能基准测试

配置首字延迟总延迟用户满意度
无流式2500ms2500ms⭐⭐⭐
流式 (minChars=50)450ms2600ms⭐⭐⭐⭐
流式 (minChars=30)320ms2700ms⭐⭐⭐⭐⭐
流式 + 打字机320ms2700ms⭐⭐⭐⭐⭐

推荐配置:

{
  // 全局流式配置
  messages: {
    streaming: {
      enabled: true,
      minChars: 30,
      maxChars: 300,
      idleMs: 150,
      breakPreference: "sentence",
    },
    typingMode: "thinking",
    typingIntervalSeconds: 3,
  },
}

10.2 多模态支持(图像/语音/视频)

10.2.1 图像理解增强

源码位置: tools/browser.ts, skills/baoyu-image-gen/

方案 1: 截图 + 视觉 LLM

{
  tools: {
    browser: {
      screenshot: {
        enabled: true,
        format: "png",
        quality: 80,
        maxWidth: 1920,
        maxHeight: 1080,
      },
    },
    
    // 视觉模型配置
    vision: {
      provider: "dashscope",
      model: "qwen-vl-max",
      maxImageSize: 20 * 1024 * 1024,  // 20MB
      supportedFormats: ["jpg", "png", "webp"],
    },
  },
  
  // 技能:图像生成
  skills: {
    allow: ["baoyu-image-gen", "baoyu-cover-image"],
  },
}

图像理解工作流:

用户发送图片 → Gateway 接收 → 保存到临时目录
                              ↓
                     调用视觉 LLM API
                     (qwen-vl-max / GPT-4V)
                              ↓
                     返回图像描述/OCR 结果
                              ↓
                     主 LLM 处理描述 + 上下文
                              ↓
                     生成回复发送给用户

配置示例:

{
  agents: {
    list: [
      {
        id: "vision",
        name: "视觉助手",
        model: {
          primary: "bailian/qwen-vl-max",  // 视觉模型
          fallbacks: ["openai/gpt-4-vision"],
        },
        tools: {
          allow: ["browser", "read"],
        },
        groupChat: {
          // 群内自动识别图片
          autoDescribeImages: true,
        },
      },
    ],
  },
  
  // 图像预处理
  images: {
    autoResize: true,
    maxWidth: 1920,
    maxHeight: 1080,
    compressQuality: 80,
    ocr: {
      enabled: true,
      provider: "dashscope",  // dashscope|tesseract
      language: "zh-CN",
    },
  },
}

10.2.2 语音理解增强

源码位置: skills/openai-whisper/, config/types.tts.d.ts

方案 1: Whisper 语音转文字

# 安装 Whisper CLI
npm install -g @openclaw/whisper-cli

# 配置
{
  tools: {
    whisper: {
      enabled: true,
      model: "large-v3",      // tiny|base|small|medium|large-v3
      language: "zh",         // 自动检测或指定
      device: "cuda",         // cpu|cuda|mps
    },
  },
  
  // TTS 配置 (ElevenLabs)
  talk: {
    voiceId: "21m00Tcm4TlvDq8ikWAM",
    modelId: "eleven_monolingual_v1",
    outputFormat: "mp3_44100_128",
  },
}

语音处理工作流:

用户发送语音 → Gateway 接收 → 保存为音频文件
                              ↓
                     Whisper 转文字
                     (本地/云端 API)
                              ↓
                     文字 → 主 LLM 处理
                              ↓
                     生成文字回复
                              ↓
              (可选) TTS 转语音 → 发送语音回复

配置示例:

{
  // 语音转文字 (STT)
  speech: {
    stt: {
      enabled: true,
      provider: "whisper",      // whisper|dashscope|openai
      model: "large-v3",
      autoDetectLanguage: true,
      saveAudio: false,         // 不保留原始音频 (隐私)
    },
    
    // 文字转语音 (TTS)
    tts: {
      enabled: true,
      provider: "elevenlabs",   // elevenlabs|dashscope|azure
      voiceId: "21m00Tcm4TlvDq8ikWAM",
      modelId: "eleven_multilingual_v2",
      outputFormat: "mp3_44100_128",
      speed: 1.0,
    },
  },
  
  agents: {
    list: [
      {
        id: "voice-assistant",
        name: "语音助手",
        tools: {
          allow: ["whisper", "tts"],
        },
        // 语音回复模式
        voiceReply: {
          enabled: true,
          autoDetect: true,     // 用户发语音则回语音
        },
      },
    ],
  },
}

10.2.3 视频理解增强

源码位置: skills/video-frames/, skills/video-transcript-downloader/

方案 1: 视频帧提取 + 视觉 LLM

{
  tools: {
    video: {
      enabled: true,
      ffmpeg: {
        path: "/usr/local/bin/ffmpeg",
        frameInterval: 5,       // 每 5 秒提取一帧
        maxFrames: 20,          // 最多 20 帧
        resolution: "1280x720",
      },
    },
  },
  
  skills: {
    allow: ["video-frames", "video-transcript-downloader"],
  },
}

视频处理工作流:

用户发送视频 → Gateway 接收 → 保存视频文件
                              ↓
                     FFmpeg 提取关键帧
                     (每 5 秒 1 帧,最多 20 帧)
                              ↓
                     视觉 LLM 分析每帧
                              ↓
                     汇总帧描述 + 时间戳
                              ↓
                     主 LLM 生成视频摘要/回答

配置示例:

{
  video: {
    processing: {
      enabled: true,
      maxFileSize: 100 * 1024 * 1024,  // 100MB
      supportedFormats: ["mp4", "mov", "avi"],
      extraction: {
        method: "keyframes",      // keyframes|interval
        intervalSeconds: 5,
        maxFrames: 20,
        resolution: "1280x720",
      },
      analysis: {
        model: "bailian/qwen-vl-max",
        includeOCR: true,
        includeTimestamps: true,
      },
    },
    
    // YouTube 视频支持
    youtube: {
      enabled: true,
      downloadAudio: true,
      downloadSubtitles: true,
      autoTranslate: true,
    },
  },
}

多模态统一配置模板

{
  // 多模态统一配置
  multimodal: {
    // 图像
    images: {
      enabled: true,
      autoDescribe: true,
      ocr: { enabled: true, provider: "dashscope" },
      maxFileSize: 20 * 1024 * 1024,
    },
    
    // 语音
    audio: {
      enabled: true,
      stt: { provider: "whisper", model: "large-v3" },
      tts: { provider: "elevenlabs", voiceId: "xxx" },
      maxFileSize: 10 * 1024 * 1024,
    },
    
    // 视频
    video: {
      enabled: true,
      maxFileSize: 100 * 1024 * 1024,
      extraction: { intervalSeconds: 5, maxFrames: 20 },
    },
  },
  
  // Agent 多模态能力
  agents: {
    list: [
      {
        id: "multimodal-assistant",
        name: "多模态助手",
        model: {
          primary: "bailian/qwen-vl-max",
          fallbacks: ["openai/gpt-4-vision"],
        },
        tools: {
          allow: ["browser", "whisper", "tts", "video-frames"],
        },
        multimodal: {
          autoDetect: true,       // 自动检测媒体类型
          autoReply: true,        // 自动回复媒体内容
        },
      },
    ],
  },
}

10.3 企业版功能(RBAC/审计/SSO)

10.3.1 RBAC 权限管理

源码位置: config/types.auth.d.ts, config/types.approvals.d.ts

角色定义:

// 企业版角色类型
type EnterpriseRole = "admin" | "operator" | "viewer" | "billing";

type RBACConfig = {
  enabled: boolean;
  roles: {
    [roleName: string]: {
      permissions: string[];
      agents?: string[];       // 可访问的 Agent
      channels?: string[];     // 可访问的通道
      tools?: string[];        // 可使用的工具
    };
  };
  users: {
    [userId: string]: {
      roles: EnterpriseRole[];
      email: string;
      department?: string;
    };
  };
};

配置示例:

{
  // RBAC 权限管理
  rbac: {
    enabled: true,
    
    // 角色定义
    roles: {
      admin: {
        permissions: ["*", "manage:users", "manage:billing", "view:audit"],
        agents: ["*"],
        channels: ["*"],
        tools: ["*"],
      },
      operator: {
        permissions: ["use:agents", "view:sessions", "manage:skills"],
        agents: ["main", "coding", "voc", "geo"],
        channels: ["whatsapp", "feishu"],
        tools: ["read", "write", "exec", "browser"],
      },
      viewer: {
        permissions: ["view:sessions", "view:logs"],
        agents: ["main"],
        channels: ["whatsapp"],
        tools: ["read"],
      },
      billing: {
        permissions: ["view:billing", "manage:billing"],
        agents: [],
        channels: [],
        tools: [],
      },
    },
    
    // 用户分配
    users: {
      "admin@company.com": {
        roles: ["admin"],
        email: "admin@company.com",
        department: "IT",
      },
      "dev@company.com": {
        roles: ["operator"],
        email: "dev@company.com",
        department: "研发部",
      },
      "intern@company.com": {
        roles: ["viewer"],
        email: "intern@company.com",
        department: "实习生",
      },
    },
  },
  
  // 工具审批 (高风险操作)
  approvals: {
    enabled: true,
    rules: [
      {
        tool: "exec",
        condition: {
          commands: ["rm", "sudo", "curl"],
        },
        requireApproval: true,
        approvers: ["admin@company.com"],
        timeoutMinutes: 30,
      },
      {
        tool: "sessions_send",
        condition: {
          targetAgent: "admin",
        },
        requireApproval: true,
        approvers: ["admin@company.com"],
      },
    ],
  },
}

权限检查流程:

用户请求 → 提取用户身份 (email/userId)
              ↓
       查找用户角色 (RBAC.users)
              ↓
       获取角色权限 (RBAC.roles)
              ↓
       检查资源访问权限
       (Agent/Channel/Tool)
              ↓
       允许/拒绝 + 审计日志

10.3.2 审计日志

源码位置: config/types.d.ts, infra/audit.ts

审计配置:

{
  // 审计日志
  audit: {
    enabled: true,
    
    // 日志级别
    level: "info",  // debug|info|warn|error
    
    // 记录内容
    log: {
      authentication: true,    // 登录/登出
      authorization: true,     // 权限检查
      agentAccess: true,       // Agent 访问
      toolUsage: true,         // 工具调用
      sessionChanges: true,    // 会话变更
      configChanges: true,     // 配置修改
      billing: true,           // 计费事件
    },
    
    // 存储配置
    storage: {
      type: "file",            // file|database|elk
      path: "~/.openclaw/audit/",
      rotation: {
        enabled: true,
        maxSize: "100MB",
        maxAge: "90d",
        compress: true,
      },
    },
    
    // 告警配置
    alerts: {
      enabled: true,
      rules: [
        {
          name: "多次登录失败",
          condition: "auth.failure.count > 5 in 5m",
          action: "notify:admin",
        },
        {
          name: "高风险工具调用",
          condition: "tool.exec.command in ['rm', 'sudo']",
          action: "notify:admin + require:approval",
        },
        {
          name: "异常 Agent 访问",
          condition: "agent.access.from.unknown.ip",
          action: "block + notify:admin",
        },
      ],
    },
  },
  
  // 日志格式
  logging: {
    format: "json",            // json|text
    includeFields: [
      "timestamp",
      "userId",
      "action",
      "resource",
      "result",
      "ipAddress",
      "userAgent",
    ],
  },
}

审计日志示例:

{
  "timestamp": "2026-03-03T12:30:45.123Z",
  "userId": "dev@company.com",
  "action": "tool.exec",
  "resource": "agent:coding",
  "details": {
    "command": "npm install",
    "args": ["-g", "openclaw"],
    "cwd": "/home/dev/project",
  },
  "result": "success",
  "duration": 1523,
  "ipAddress": "192.168.1.100",
  "userAgent": "OpenClaw/1.2.3",
  "sessionId": "agent:coding:feishu:default:direct:ou_xxx",
}

审计查询示例:

# 查询特定用户的操作
openclaw audit query --user "dev@company.com" --since "24h"

# 查询高风险操作
openclaw audit query --action "tool.exec" --grep "rm|sudo"

# 查询登录失败
openclaw audit query --action "auth.failure" --since "1h"

# 导出审计报告
openclaw audit export --format csv --output audit-report.csv

10.3.3 SSO 单点登录

源码位置: config/types.gateway.d.ts (TrustedProxy)

方案 1: Pomerium + OAuth

# Pomerium 配置 (config.yaml)
routes:
  - from: https://openclaw.company.com
    to: http://127.0.0.1:18789
    policy:
      - allow:
          or:
            - domain:
                is: company.com
            - email:
                is: admin@company.com

# Identity Provider (以 Google 为例)
idp:
  provider: google
  client_id: xxx
  client_secret: xxx
  redirect_url: https://openclaw.company.com/oauth2/callback

OpenClaw 配置:

{
  gateway: {
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        // Pomerium 传递的用户身份头
        userHeader: "x-pomerium-claim-email",
        
        // 验证请求来自 Pomerium
        requiredHeaders: [
          "x-pomerium-jwt-assertion",
          "x-pomerium-claim-email",
          "x-forwarded-proto",
        ],
        
        // 允许的用户白名单
        allowUsers: [
          "admin@company.com",
          "dev@company.com",
          "*@company.com",  // 或整个域名
        ],
      },
    },
    
    // TLS 配置
    tls: {
      enabled: true,
      certPath: "/etc/letsencrypt/live/openclaw.company.com/fullchain.pem",
      keyPath: "/etc/letsencrypt/live/openclaw.company.com/privkey.pem",
    },
  },
  
  // RBAC 与 SSO 集成
  rbac: {
    enabled: true,
    // 从 SSO 自动同步用户
    syncFromSSO: {
      enabled: true,
      provider: "pomerium",
      defaultRole: "viewer",
      roleMapping: {
        "admin@company.com": "admin",
        "dev@company.com": "operator",
        "*@company.com": "viewer",
      },
    },
  },
}

方案 2: Cloudflare Access + SSO

{
  gateway: {
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        // Cloudflare Access 头
        userHeader: "cf-access-authenticated-user-email",
        requiredHeaders: [
          "cf-access-jwt-assertion",
          "cf-access-authenticated-user-email",
        ],
        allowUsers: ["*@company.com"],
      },
    },
  },
}

方案 3: Authelia (自托管 SSO)

# Authelia 配置 (configuration.yml)
authentication_backend:
  file:
    path: /config/users_database.yml

access_control:
  rules:
    - domain: openclaw.company.com
      policy: two_factor
      subject:
        - group: admins
        - group: developers

session:
  name: authelia_session
  secret: unsecure_session_secret

identity_providers:
  oidc:
    clients:
      - client_id: openclaw
        client_secret: xxx
        redirect_uris:
          - https://openclaw.company.com/oauth2/callback
        scopes: ["openid", "profile", "email"]
{
  gateway: {
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        userHeader: "remote-user",
        requiredHeaders: ["authelia-user", "authelia-groups"],
        allowUsers: ["*@company.com"],
      },
    },
  },
}

企业版完整配置模板

{
  // ==================== 企业版完整配置 ====================
  
  // 1. SSO 单点登录
  gateway: {
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        userHeader: "x-pomerium-claim-email",
        requiredHeaders: ["x-pomerium-jwt-assertion"],
        allowUsers: ["*@company.com"],
      },
    },
    tls: {
      enabled: true,
      certPath: "/etc/letsencrypt/live/company.com/fullchain.pem",
      keyPath: "/etc/letsencrypt/live/company.com/privkey.pem",
    },
  },
  
  // 2. RBAC 权限管理
  rbac: {
    enabled: true,
    roles: {
      admin: {
        permissions: ["*"],
        agents: ["*"],
        channels: ["*"],
        tools: ["*"],
      },
      operator: {
        permissions: ["use:agents", "view:sessions"],
        agents: ["main", "coding"],
        channels: ["whatsapp", "feishu"],
        tools: ["read", "write", "exec"],
      },
      viewer: {
        permissions: ["view:sessions"],
        agents: ["main"],
        channels: ["whatsapp"],
        tools: ["read"],
      },
    },
    users: {
      "admin@company.com": { roles: ["admin"], department: "IT" },
      "dev@company.com": { roles: ["operator"], department: "研发" },
    },
  },
  
  // 3. 审计日志
  audit: {
    enabled: true,
    level: "info",
    log: {
      authentication: true,
      authorization: true,
      agentAccess: true,
      toolUsage: true,
      configChanges: true,
    },
    storage: {
      type: "file",
      path: "~/.openclaw/audit/",
      rotation: { maxSize: "100MB", maxAge: "90d", compress: true },
    },
    alerts: {
      enabled: true,
      rules: [
        { name: "多次登录失败", condition: "auth.failure.count > 5 in 5m" },
        { name: "高风险工具", condition: "tool.exec.command in ['rm', 'sudo']" },
      ],
    },
  },
  
  // 4. 工具审批
  approvals: {
    enabled: true,
    rules: [
      {
        tool: "exec",
        condition: { commands: ["rm", "sudo", "curl"] },
        requireApproval: true,
        approvers: ["admin@company.com"],
      },
    ],
  },
  
  // 5. 会话策略
  session: {
    dmScope: "per-account-channel-peer",
    maintenance: {
      prune: { enabled: true, maxAgeDays: 90 },
      cap: { enabled: true, maxTotalSessions: 5000 },
    },
  },
  
  // 6. 资源限制
  limits: {
    maxConcurrentSessions: 100,
    maxToolExecutionsPerHour: 1000,
    maxTokensPerDay: 1000000,
  },
}

附录 A: 配置速查表

A.1 最小可用配置

{
  agents: {
    list: [
      {
        id: "main",
        default: true,
        workspace: "~/.openclaw/workspace",
        model: "bailian/qwen3.5-plus",
      },
    ],
  },
  
  bindings: [
    { agentId: "main", match: { channel: "whatsapp" } },
  ],
  
  models: {
    providers: {
      bailian: {
        apiKey: "${DASHSCOPE_API_KEY}",
      },
    },
  },
  
  gateway: {
    auth: {
      token: "${OPENCLAW_GATEWAY_TOKEN}",
    },
  },
}

A.2 环境变量清单

# 必需
DASHSCOPE_API_KEY=sk-xxx
OPENCLAW_GATEWAY_TOKEN=xxx

# 通道 (按需)
WHATSAPP_DEFAULT_AUTH_TOKEN=xxx
TELEGRAM_BOT_TOKEN=xxx
FEISHU_LEAD_APP_ID=cli_xxx
FEISHU_LEAD_APP_SECRET=xxx

# 可选
OPENCLAW_LOG_LEVEL=info
HTTP_PROXY=http://127.0.0.1:7890

A.3 常用命令

# Gateway 管理
openclaw gateway start
openclaw gateway stop
openclaw gateway restart
openclaw gateway status

# 配置管理
openclaw config validate
openclaw config show --resolved
openclaw config get agents.list

# 通道管理
openclaw channels login --channel whatsapp
openclaw channels logout --channel whatsapp
openclaw channels status

# Agent 管理
openclaw agents list
openclaw agents add voc
openclaw agents remove voc

# 技能管理
openclaw skills list
openclaw skills install tavily
openclaw skills update

# 诊断工具
openclaw doctor
openclaw logs --follow

附录 B: 故障排查清单

B.1 Gateway 无法启动

# 1. 检查端口占用
lsof -i :18789

# 2. 检查配置文件
openclaw config validate

# 3. 检查环境变量
echo $DASHSCOPE_API_KEY
echo $OPENCLAW_GATEWAY_TOKEN

# 4. 查看详细日志
openclaw gateway --log-level debug

# 5. 重置配置
openclaw config reset

B.2 通道连接失败

# WhatsApp
openclaw channels login --channel whatsapp
# 检查 Baileys 认证:~/.openclaw/credentials/whatsapp/

# Telegram
openclaw channels login --channel telegram
# 检查 Bot Token: $TELEGRAM_BOT_TOKEN

# 飞书
openclaw channels login --channel feishu
# 检查 App ID/Secret: $FEISHU_XXX_APP_ID

B.3 Agent 路由错误

# 查看路由配置
openclaw config get bindings

# 测试路由
openclaw routing test --channel whatsapp --peer +8613800138001

# 查看 Agent 状态
openclaw agents status

# 检查会话
openclaw sessions list --agent main

B.4 工具调用失败

# 检查工具权限
openclaw config get agents.list[].tools

# 检查沙箱状态
openclaw sandbox status

# 查看工具日志
openclaw logs --grep "tool_call"

附录 C: 性能优化清单

C.1 LLM 优化

  • 使用性价比模型 (GLM-5/Qwen) 处理简单任务
  • 配置 fallbacks 防止单点故障
  • 调整 maxTokens 限制输出长度
  • 使用流式响应降低感知延迟

C.2 会话优化

  • 启用会话压缩 (threshold: 200)
  • 配置会话维护 (prune/cap/compact)
  • 调整 dmScope 减少会话数量
  • 定期清理过期会话

C.3 工具优化

  • 限制 exec 命令白名单
  • 启用工具沙箱
  • 配置工具超时时间
  • 缓存频繁读取的文件

C.4 Gateway 优化

  • 启用 TLS 减少握手延迟
  • 调整 bindHost 减少网络跳转
  • 配置日志级别减少 I/O
  • 启用诊断追踪性能瓶颈
#openclaw#AI#agent#智能体
留言板

暂无公开留言

未配置 Turnstile,当前为无验证码模式。