← 返回首页

写在前面

上一篇文章发出后,有读者问我:"OpenClaw 听起来很强大,但它的内部是怎么工作的?Gateway、Agent、Channel 之间是什么关系?"

确实,光知道"能做什么"不够,知道"怎么做到"才更有价值。

这篇文章,我就带大家深入 OpenClaw 的内部世界,从架构设计到代码实现,全面拆解这个 AI 助手框架。


一句话解释架构

OpenClaw = Gateway(网关)+ Agent(大脑)+ Channel(渠道)+ Skills(技能)+ Memory(记忆)

五大模块协同工作,构成了一个完整的 AI Agent 系统。


整体架构图

┌─────────────────────────────────────────────────────────────────┐
│                        Channels                             │
│   ┌────────┐  ┌────────┐  ┌────────┐  ┌────────┐           │
│   │  Feishu│  │Telegram│  │Discord │  │ WhatsApp│  ...    │
│   └────────┘  └────────┘  └────────┘  └────────┘           │
└──────────────────────────────┬──────────────────────────────┘
                               │
                               ▼
┌─────────────────────────────────────────────────────────────────┐
│                        Gateway                             │
│   ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐   │
│   │   Router   │  │  Session   │  │   Auth Manager  │   │
│   │   消息路由  │  │   会话管理   │  │    权限控制     │   │
│   └─────────────┘  └─────────────┘  └─────────────────┘   │
│   ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐   │
│   │   Channel  │  │   Skills   │  │    Memory      │   │
│   │   通道管理  │  │   技能系统  │  │     记忆系统    │   │
│   └─────────────┘  └─────────────┘  └─────────────────┘   │
└──────────────────────────────┬──────────────────────────────┘
                               │
                               ▼
┌─────────────────────────────────────────────────────────────────┐
│                         Agent                              │
│   ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐   │
│   │  Provider   │  │   Tools    │  │   Prompts      │   │
│   │   模型调用   │  │   工具调用   │  │     提示词      │   │
│   └─────────────┘  └─────────────┘  └─────────────────┘   │
└───────────────────────────────────────────────────────────────┘

5 大核心模块

1. 网关 - 控制平面 🚀

网关是整个系统的大脑和心脏,负责协调所有组件。

核心职责

功能 说明
消息路由 接收 Channel 消息,转发给 Agent
会话管理 管理每个用户的对话状态
权限控制 验证用户身份和权限
技能调度 决定何时调用哪个 Skill

核心代码

// Gateway 核心逻辑
class 网关 {
  private router: Router;
  private sessionManager: SessionManager;
  private skillManager: SkillManager;
  private memoryManager: MemoryManager;
  private agent: Agent;

  async handleMessage(channel: string, user: string, message: string) {
    // 1. 权限验证
    if (!await this.authManager.verify(user)) {
      throw new AuthError('未授权用户');
    }

    // 2. 获取/创建会话
    const session = await this.sessionManager.getOrCreate({ channel, user });

    // 3. 构建 Prompt(含记忆)
    const prompt = await this.buildPrompt(session, message);

    // 4. 调用 Agent
    const response = await this.agent.complete(prompt);

    // 5. 通过原渠道回复
    await this.channel.send(user, response);
  }

  private async buildPrompt(session: Session, message: string): Promise<Prompt> {
    // 短期记忆:当前会话
    const shortMemory = session.messages;

    // 长期记忆:向量检索
    const longMemory = await this.memory.search(message, { limit: 5 });

    return {
      system: SYSTEM_PROMPT,
      context: longMemory,
      conversation: shortMemory,
      user: message
    };
  }
}

2. Agent - AI 大脑 🧠

Agent 负责与 AI 模型交互,是真正的"智能"所在。

核心功能

功能 说明
模型调用 支持 Anthropic/OpenAI/Google 等多种模型
Tool 选择 决定调用哪个工具完成请求
Prompt 管理 构建和优化提示词

Provider 抽象

// LLM Provider 抽象
abstract class LLMProvider {
  abstract readonly name: string;
  abstract complete(prompt: Prompt): Promise<LLMResponse>;
  abstract *completeStream(prompt: Prompt): AsyncGenerator<Chunk>;
  abstract completeWithFunctions(prompt: Prompt, tools: Tool[]): Promise<FunctionCall>;
}

// Anthropic 实现
class AnthropicProvider extends LLMProvider {
  readonly name = 'anthropic';

  async complete(prompt: Prompt): Promise<LLMResponse> {
    const response = await this.client.messages.create({
      model: 'claude-sonnet-4-20250514',
      max_tokens: 4096,
      system: prompt.system,
      messages: [
        ...prompt.context.map(c => ({ role: 'assistant', content: c.content })),
        { role: 'user', content: prompt.user }
      ]
    });

    return {
      content: response.content[0].text,
      usage: {
        input: response.usage.input_tokens,
        output: response.usage.output_tokens
      }
    };
  }
}

模型配置

# openclaw.yaml
models:
  primary:
    provider: anthropic
    model: claude-sonnet-4-20250514
    api_key: ${ANTHROPIC_API_KEY}
  
  fallback:
    provider: openai
    model: gpt-4o
    api_key: ${OPENAI_API_KEY}

3. Channel - 消息通道 📱

Channel 是 OpenClaw 与外部世界连接的桥梁

支持的渠道

类别 渠道
即时通讯 微信、Telegram、Discord、Slack、Signal、iMessage
企业协作 飞书、钉钉、Microsoft Teams
其他 Matrix、BlueBubbles

Channel 抽象

// Channel 抽象基类
abstract class Channel {
  abstract readonly name: string;
  abstract readonly capabilities: ChannelCapability[];

  // 接收消息
  abstract onMessage(handler: MessageHandler): void;

  // 发送消息
  abstract send(to: string, content: MessageContent): Promise<void>;

  // 消息格式转换
  abstract parse(raw: any): Message;
  abstract format(message: Message): any;
}

飞书 Channel 示例

// 飞书消息处理
class FeishuChannel extends Channel {
  readonly name = 'feishu';
  readonly capabilities = ['text', 'image', 'card', 'interactive'];

  private app: FeishuApp;

  constructor(config: FeishuConfig) {
    super();
    this.app = new FeishuApp(config.appId, config.appSecret);
  }

  // 接收消息
  onMessage(handler: MessageHandler): void {
    this.app.on('message', async (event) => {
      const message = this.parse(event);
      const response = await handler(message);
      await this.send(event.sender.user_id, response);
    });
  }

  // 发送卡片消息
  async send(to: string, content: MessageContent): Promise<void> {
    const card = {
      header: {
        title: { tag: 'plain_text', content: '🤖 AI 助手' },
        template: 'blue'
      },
      elements: [
        { tag: 'markdown', content: content.text }
      ]
    };
    await this.app.sendCard(to, card);
  }
}

配置示例

channels:
  feishu:
    enabled: true
    app_id: ${FEISHU_APP_ID}
    app_secret: ${FEISHU_APP_SECRET}

  telegram:
    enabled: true
    bot_token: ${TELEGRAM_BOT_TOKEN}

4. Skills - 技能系统 🛠️

Skills 是 OpenClaw 的扩展机制,让你能无限扩展 AI 的能力。

Skill 结构

interface Skill {
  readonly name: string;
  readonly description: string;
  readonly version: string;

  // 初始化
  init(context: SkillContext): Promise<void>;

  // 注册工具
  registerTools(): Tool[];

  // 处理消息(可选)
  handle?(message: Message): Promise<HandleResult>;
}

天气 Skill 示例

class WeatherSkill implements Skill {
  readonly name = 'weather';
  readonly description = '查询天气信息';
  readonly version = '1.0.0';

  private apiKey: string;

  constructor(config: WeatherConfig) {
    this.apiKey = config.apiKey;
  }

  async init(): Promise<void> {
    console.log('🌤️ Weather skill initialized');
  }

  registerTools(): Tool[] {
    return [
      {
        name: 'get_weather',
        description: '获取指定城市的天气信息',
        parameters: {
          type: 'object',
          properties: {
            city: {
              type: 'string',
              description: '城市名称,如北京、上海'
            }
          },
          required: ['city']
        }
      }
    ];
  }

  // 工具实现
  async getWeather(city: string): Promise<WeatherResult> {
    const response = await fetch(
      `https://api.weather.com/v3/forecast?city=${city}&key=${this.apiKey}`
    );
    return response.json();
  }
}

Skill 加载

class SkillManager {
  private skills = new Map<string, Skill>();

  async loadSkills(skillDirs: string[]): Promise<void> {
    for (const dir of skillDirs) {
      // 动态加载
      const skill = await this.importSkill(dir);

      // 初始化
      await skill.init(this.createContext());

      // 注册工具到 Agent
      const tools = skill.registerTools();
      this.agent.registerTools(tools);

      this.skills.set(skill.name, skill);
    }
  }
}

官方 Skills

Skill 功能
weather 天气查询
xiaohongshu-generator 小红书推文生成
qqbot-cron 定时提醒
calendar 日历管理

5. Memory - 记忆系统 💾

Memory 让 OpenClaw 能"记住"之前说过的话

三层记忆架构

┌─────────────────────────────────────┐
│           短期记忆                    │
│     (当前会话上下文,内存中)          │
│     session.messages                │
└─────────────────┬───────────────────┘
                  │
                  ▼
┌─────────────────────────────────────┐
│           长期记忆                    │
│    (向量数据库,持久化存储)          │
│    LanceDB / SQLite                 │
└─────────────────┬───────────────────┘
                  │
                  ▼
┌─────────────────────────────────────┐
│           文件记忆                    │
│    (从文件系统读取上下文)            │
│    workspace/*.md                    │
└─────────────────────────────────────┘

Memory Manager

class MemoryManager {
  // 短期记忆
  private shortTerm = new ShortTermMemory();

  // 长期记忆(向量)
  private longTerm = new LanceDBMemory();

  // 文件记忆
  private fileMemory = new FileMemory();

  // 搜索记忆
  async search(query: string, options: SearchOptions): Promise<MemoryResult[]> {
    // 1. 向量检索
    const vectorResults = await this.longTerm.search(query, {
      limit: options.limit || 5
    });

    // 2. 文件检索
    const fileResults = await this.fileMemory.search(query);

    // 3. 合并结果
    return this.mergeResults(vectorResults, fileResults);
  }

  // 保存会话到长期记忆
  async saveSession(session: Session): Promise<void> {
    const embeddings = await this.embed(session.messages);
    await this.longTerm.save({
      id: session.id,
      embeddings,
      metadata: {
        channel: session.channel,
        user: session.user,
        timestamp: Date.now()
      }
    });
  }
}

配置示例

memory:
  short_term:
    max_messages: 100
    ttl: 3600000  # 1小时

  long_term:
    enabled: true
    provider: lancedb
    path: ./data/memory

  file_memory:
    enabled: true
    paths:
      - ./workspace
      - ./memory

消息流转完整流程

用户发送消息
    │
    ▼
┌─────────────────┐
│   Channel      │ 接收消息,解析格式
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│    Gateway     │ 权限验证
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Session Manager │ 获取/创建会话
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Memory Manager  │ 检索相关记忆
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│     Agent       │ 调用 LLM + Tools
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Memory Manager  │ 保存到长期记忆
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│    Gateway     │ 路由到原 Channel
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│   Channel      │ 发送回复
└─────────────────┘
         │
         ▼
    用户收到回复

总结

OpenClaw 的架构设计体现了几个核心思想:

  1. 分层解耦 - Gateway、Agent、Channel、Skills、Memory 各自独立
  2. 可扩展 - Skill 和 Channel 都是插件化设计
  3. 本地优先 - 数据本地存储,尊重隐私
  4. 多渠道统一 - 统一的消息抽象,屏蔽各渠道差异

这种架构使得 OpenClaw 不仅仅是一个聊天工具,而是一个可定制的 AI Agent 平台


下篇预告:《Channel 通道系统实现原理》,敬请期待。