# OpenClaw 源码解读（3）： Workspaces 与多智能体路由

> 深入 OpenClaw Gateway 源码，解析这个唯一控制平面如何通过 WebSocket 网络、会话隔离、沙箱机制与 Pi RPC 运行时，实现对多设备、多会话的安全调度与流式传输。

- 原文链接: https://laojin.blog/blog/20260307_openclaw_source_code_3
- 作者: 老金
- 发布日期: 2026-03-07
- 标签: OpenClaw, 源码解读, AI Agent, 开源项目

---

在上一篇文章中，我们拆解了 OpenClaw 万物互联的中枢——Gateway 控制平面。了解了系统如何收发消息后，一个核心问题浮出水面：**当四面八方的消息涌入网关时，OpenClaw 是如何决定由哪个"大脑"来处理的？**

如果是个人私聊，我们需要一个全知全能的私人助理；如果是群组接入，我们可能只需要一个特定领域的客服或观察者。为了解决这个场景冲突，OpenClaw 引入了非常优雅的 **Workspaces（工作区）** 与 **多智能体路由（Multi-agent routing）** 机制。

![img1](https://pic-1258874139.cos.ap-hongkong.myqcloud.com/laojinblog/posts/20260307/01.png)

今天，老金就带大家深入 OpenClaw 的源码，扒一扒这个"多重宇宙"是如何运转的。

---

## 会话隔离模型

在很多初级 AI 应用中，所有的对话往往共享同一个全局上下文，这在多渠道接入时会导致灾难性的隐私泄露或幻觉。OpenClaw 在架构设计之初，就严格定义了会话隔离模型。

在源码的类型定义中，核心被划分为两类：**Main session（单人直聊）** 和 **Non-main sessions（群组/频道）**。

![img2](https://pic-1258874139.cos.ap-hongkong.myqcloud.com/laojinblog/posts/20260307/02.png)

```typescript
// src/core/session/types.ts 

export enum SessionType {
  MAIN = 'MAIN_DIRECT',       // 主人的超级会话
  NON_MAIN = 'NON_MAIN_GROUP' // 群组、公共频道或受限访客
}

export interface SessionContext {
  sessionId: string;
  type: SessionType;
  workspaceId: string; // 绑定的 Agent 工作区
  permissions: PermissionFlags;
}

```

* **Main session（主会话）：** 通常绑定管理员的直接通讯渠道（如你的专属 飞书 账号）。在这里，Agent 拥有最高权限，可以调用核心敏感工具（如操作宿主机本地命令、管理其他会话等）。
* **Non-main sessions（非主会话）：** 针对群聊、公开频道等。这类会话会被严格降级，放入沙箱环境。它们只能访问被明确授权的只读工具或受限回复能力，防止恶意群友通过 Prompt 注入（Prompt Injection）控制你的电脑。

---

## 路由分发

当一个外部请求（无论是 飞书 还是 企业微信）打到 Gateway 时，它是如何找到对应的 Agent 的呢？

OpenClaw 采用了一种多维度的路由解析策略。它会提取入站请求的 `Channel` (渠道)、`Account` (账户) 或 `Peer Node` (对等节点) 的标识，然后映射到预设的 Workspace 中。

我们可以看看核心的路由调度器是如何实现的：

```typescript
// src/core/router/AgentRouter.ts

export class AgentRouter {
  // 路由分发核心入口
  public async dispatchInboundMessage(message: InboundMessage): Promise<void> {
    // 1. 解析来源上下文
    const { channelId, senderId, isGroup } = message.metadata;

    // 2. 匹配对应的工作区 (Workspace)
    const workspaceId = await this.resolveWorkspace(channelId, senderId, isGroup);

    // 3. 实例化或唤醒对应的 Agent Runtime
    const agent = await AgentManager.getOrSpawnAgent(workspaceId);

    // 4. 将消息推入该 Agent 的处理队列
    await agent.process(message);
  }

  private async resolveWorkspace(channelId: string, senderId: string, isGroup: boolean): Promise<string> {
    // 默认回退到通用工作区
    let targetWorkspace = 'default_workspace';

    // 优先匹配群组专属 Agent
    if (isGroup) {
      const groupRule = await ConfigManager.getGroupRoutingRule(channelId);
      if (groupRule) return groupRule.workspaceId;
    }

    // 匹配特定私聊对象的专属 Agent
    const userRule = await ConfigManager.getUserRoutingRule(senderId);
    if (userRule) return userRule.workspaceId;

    return targetWorkspace;
  }
}

```

通过这种设计，你可以轻松实现：把报警频道交给"运维 Agent"，把某个群交给"摸鱼聊天 Agent"，而你自己的私聊则永远路由给"超级助理 Agent"。

![img3](https://pic-1258874139.cos.ap-hongkong.myqcloud.com/laojinblog/posts/20260307/03.png)

---

## 上下文注入机制

找到了对应的 Agent，下一步就是告诉大模型"你是谁、你能干什么"。

不同于将 Prompt 硬编码在数据库里，OpenClaw 采用了**基于文件系统的目录结构**来管理 Agent 的上下文。所有的配置都存在 `~/.openclaw/workspace` 目录下。

一个标准的工作区目录通常包含：

* `SOUL.md`：核心性格与底层指令（比如：你是一只叫 Molty 的龙虾，说话要带点幽默）。
* `AGENTS.md`：当前角色的具体任务定义。
* `TOOLS.md`：该工作区允许使用的工具列表（通过 Markdown 列表动态挂载）。

在发起 LLM 请求前，OpenClaw 会动态读取这些文件，组装成最终的 System Prompt：

```typescript
// src/core/agent/ContextBuilder.ts

import * as fs from 'fs';
import * as path from 'path';

export class ContextBuilder {
  public static buildSystemPrompt(workspacePath: string): string {
    const parts: string[] = [];

    // 1. 注入灵魂 (核心设定，优先级最高)
    const soulPath = path.join(workspacePath, 'SOUL.md');
    if (fs.existsSync(soulPath)) {
      parts.push('### CORE IDENTITY ###\n' + fs.readFileSync(soulPath, 'utf-8'));
    }

    // 2. 注入角色任务
    const agentPath = path.join(workspacePath, 'AGENTS.md');
    if (fs.existsSync(agentPath)) {
      parts.push('### CURRENT DIRECTIVES ###\n' + fs.readFileSync(agentPath, 'utf-8'));
    }

    // 3. 注入工具白名单与可用技能
    const toolsPath = path.join(workspacePath, 'TOOLS.md');
    if (fs.existsSync(toolsPath)) {
      parts.push('### AVAILABLE TOOLS ###\n' + fs.readFileSync(toolsPath, 'utf-8'));
    }

    // 最终拼接发送给 LLM
    return parts.join('\n\n');
  }
}

```

这种基于 Markdown 的文本拼接方式非常适合本地优先（Local-first）的理念。作为开发者，你甚至不需要写前端面板，直接用 VS Code 打开目录修改 Markdown 文件，保存的瞬间，下一个对话的 Agent 灵魂就已经变了。配合 Git 进行版本控制，体验非常丝滑。

---

## 总结

OpenClaw 通过 **区分主次会话** 保障了系统的底层安全，通过 **多维路由分发** 实现了对 20+ 渠道的有条不紊的管理，最后用极简的 **文件系统注入** 完成了 Agent 灵魂的组装。

这套"多重宇宙"机制，是 OpenClaw 能够从一个简单的聊天机器人，跃升为全平台 AI 管家的核心基石。

下一篇，我们将进入实战环节《OpenClaw 源码解读（4）：多渠道接入（Channels）源码实战》，看看这些千奇百怪的第三方平台协议，是如何被 OpenClaw 抹平差异的。

---
