OpenClaw 底层架构与原理分析

目录

OpenClaw 是什么?

OpenClaw 是一个可以在本地运行或远程部署的个人助手,可以自主通过终端命令或者工具访问各种系统资源。用户以对话的方式和它进行交互,甚至能将即时通信软件作为渠道,通过手机使用。

从核心来看,OpenClaw 是一个 TypeScript 写的 CLI 应用程序。

  • 在本机(或服务器)上运行,并暴露一个 Gateway Server(网关服务器)负责:连接各种 IM 渠道、管理会话、调用大模型、把回复发回对应渠道。
  • 调用各类 LLM API(Anthropic、OpenAI、本地模型等),在本地执行工具(tools),按你的需求在电脑上做事情

目前有这么大热度的主要原因,是切中了「个人 AI 助手 + 多渠道 + 自托管」 这个需求。

OpenClaw 架构

从在聊天软件里给 OpenClaw 发消息,一直到收到回复,OpenClaw 中间发生了什么?

  1. 渠道适配器(Channel Adapter)

渠道适配器接收你的消息并进行处理(标准化、提取附件)。不同的消息应用和输入流有各自专用的适配器。

  1. 网关服务器(Gateway Server)

网关服务器是任务/会话协调器,它接收你的消息并将其传递给正确的会话。

对于一个会话中的任务请求,OpenClaw 使用基于 lane 的命令队列。每个会话有自己专用的命令队列,默认并行处理,只有低风险的可并行化任务可以并行运行(例如 cron 定时任务)。

  1. 智能体运行器 (Agent Runner)
    1. 首先会进行模型解析,判断用哪个模型,选择可用的 API Key。
    2. 动态拼装 system prompt,包含可用工具、skills、记忆,然后追加 session 历史(从 .jsonl 文件读取)。
    3. 检查上下文窗口是否还有足够空间。如果上下文快满了,对上下文做摘要。
  2. 大模型 API 调用
  3. 智能体循环
    1. 如果 LLM 返回的是工具调用(tool call)响应,OpenClaw 就会在本地执行工具,并把结果追加回对话。
    2. 这个过程会重复,直到:LLM 输出最终文本(final text),或达到最大轮数(默认约 20)
  4. 回复路径 (Response Path)
    1. 回复通过渠道适配器回到用户。
    2. session 会持久化到一个基础的 JSONL(JSON Lines) 文件:每行是一个 JSON 对象,记录用户消息、工具调用、工具结果、模型回复等。这就是 OpenClaw 的基于 session 的记忆。

Gateway

简单来说,Gateway 是一个常驻后台的消息路由服务。

如果同时有 100 个用户@机器人,Gateway 怎么处理并发?

Gateway 用异步非阻塞 IO 处理请求。每个消息生成唯一 request_id,防止混淆。Agent 执行队列化,避免资源竞争。

OpenClaw 的记忆机制

OpenClaw 有两套机制:

  • 上面提到的 JSONL 格式的会话转录
  • 记忆文件:Markdown 格式,存放在 memory/YYYY-MM-DD.mdMEMORY.md
    • memory/YYYY-MM-DD.md:每日日志(仅追加日常笔记和运行上下文),在会话开始时读取今天和昨天的内容。
    • MEMORY.md 精心整理的长期记忆(决策、偏好和持久性事实)。

检索时,它用的是 向量检索 + 关键词匹配的混合方案

当开启一段新对话时,会有一个 hook(钩子) 抓取上一段对话,并写一份 Markdown 摘要。

如果记忆太多了,应该如何优化?

如果记忆存储太多,发给 LLM 的 Prompt 太大,会导致上下文溢出以及额外的token 消耗,OpenClaw 采取了两种措施来进行记忆的优化。

  1. 会话压缩,将较早的对话总结为一条紧凑的摘要条目,并保持近期消息不变。
  2. 设置最大阈值,过大的话将其摘要压缩;

此外,用户可以想办法去自主优化记忆,比如:将 Memory.md 重新整理到topic目录下,每一个主题对应一个 md 文件。这样就可以根据场景按需加载。Memory.md只存储索引和关键规则。每日使用 cron 定时复盘。

OpenClaw 的会话压缩机制

每个模型都有一个上下文窗口(可见的最大 token 数)。长时间运行的对话会累积消息和工具结果;一旦窗口空间紧张,OpenClaw 会压缩较早的历史记录以保持在限制范围内。

压缩会将较早的对话总结为一条紧凑的摘要条目,并保持近期消息不变

摘要存储在会话历史中,因此后续请求使用的是:压缩摘要、压缩点之后的近期消息

压缩会持久化到会话的 JSONL 历史记录中。

也可以使用 /compact 强制执行一次压缩。

OpenClaw 中的 Skills

Skill 是一个文件夹,里面包括 SKILL.md声明技能名字、调用时机、具体的工作流程,references/存放参考文档,scripts/存放可执行脚本。

Agent Skills 的关键是渐进式披露,分三层加载:

  1. 技能发现:先读取所有技能的元数据(name 和 description),判断需要哪一个任务。(实现:两次调用 / 检索)
  2. 加载核心指令:LLM 加载 SKILL.md 的正文内容,获取详细指导。
  3. 加载资源文件:只在需要时读取额外文件(如脚本、参考文档)。

形象化来理解,skill 相当于肌肉记忆,把原来需要思考的时间和 token 都省略了。

在 OpenClaw 中,Skills 从三个位置加载:

  • 内置 Skills:随安装包一起发布(npm 包或 OpenClaw.app)
  • 全局 Skills:~/.openclaw/skills
  • 工作区 Skills:<workspace>/skills

如果 Skills 名称冲突,优先级为:工作区 Skills > 全局 Skills > 内置 Skills

插件可以通过在 openclaw.plugin.json 中列出 skills 目录(相对于插件根目录的路径)来发布自己的 Skills。插件 Skills 在插件启用时加载,并参与正常的 Skills 优先级规则。

在 OpenClaw 中,SKILL.md 多了一个 metadata字段(单行 JSON),用于在加载时过滤 Skills。

比如 os 字段设置可用的平台列表,该 Skills 仅在这些操作系统上有资格使用。requires.env字段,设置需要的环境变量,必须存在才可以使用这个 skill。

多智能体

目标:将多个隔离的智能体(独立的工作区 + agentDir + 会话),加上多个渠道账户(例如两个 WhatsApp)在一个运行的 Gateway 网关中。入站消息通过绑定路由到智能体。

一个智能体是一个完全独立作用域的大脑,拥有自己的:

  • 工作区(文件、AGENTS.md/SOUL.md/USER.md、本地记忆、skills)。
  • 状态目录(agentDir)用于认证配置文件、模型注册表和每个智能体配置。
  • 会话存储(聊天历史 + 路由状态)位于 ~/.openclaw/agents/<agentId>/sessions 下。

Gateway 网关可以托管一个智能体(默认)或多个智能体并行。

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

多智能体协同

子智能体是从现有智能体运行中,生成的后台智能体运行。

启动行为:/subagents spawn 以用户命令方式启动后台子智能体,它们在自己的会话中运行,任务完成后会向请求者聊天频道回发一条最终完成消息。

子智能体不能生成子智能体。

多智能体路由

通过 ~/.openclaw/openclaw.json 配置文件设置,通过 bindings字段设置确定性路由。

通过 bindingsmatch 字段 (channel, accountId, peer)三元组设置渠道、账号和私信/群组/频道 id。

json 复制代码
{
  agents: {
    list: [
      {
        id: "home",
        default: true,
        name: "Home",
        workspace: "~/.openclaw/workspace-home",
        agentDir: "~/.openclaw/agents/home/agent",
      },
      {
        id: "work",
        name: "Work",
        workspace: "~/.openclaw/workspace-work",
        agentDir: "~/.openclaw/agents/work/agent",
      },
    ],
  },
  // 确定性路由:第一个匹配获胜(最具体的优先)。
  bindings: [
    { agentId: "home", match: { channel: "whatsapp", accountId: "personal" } },
    { agentId: "work", match: { channel: "whatsapp", accountId: "biz" } },
    // 可选的每对等方覆盖(示例:将特定群组发送到 work 智能体)。
    {
      agentId: "work",
      match: {
        channel: "whatsapp",
        accountId: "personal",
        peer: { kind: "group", id: "1203630...@g.us" },
      },
    },
  ],
  // 默认关闭:智能体到智能体的消息必须明确启用 + 加入允许列表。
  tools: {
    agentToAgent: {
      enabled: false,
      allow: ["home", "work"],
    },
  },
  channels: {
    whatsapp: {
      accounts: {
        personal: {
          // 可选覆盖。默认:~/.openclaw/credentials/whatsapp/personal
          // authDir: "~/.openclaw/credentials/whatsapp/personal",
        },
        biz: {
          // 可选覆盖。默认:~/.openclaw/credentials/whatsapp/biz
          // authDir: "~/.openclaw/credentials/whatsapp/biz",
        },
      },
    },
  },
}

安全性

类似 Claude Code,OpenClaw 有一个命令 allowlist 机制:

~/.openclaw/openclaw.json 里找到 tools 配置,加上 exec 的 allowlist:

json 复制代码
{
  "tools": {
    "exec": {
      "policy": "allowlist",
      "allowlist": [
        "ls", "cat", "echo", "pwd", "find", "grep",
        "git", "npm", "node", "python3", "pip3",
        "curl", "wget", "open", "brew"
      ]
    }
  }
}

allowlist 模式下,AI 只能运行你列表里的命令,其他一律拒绝。

如果觉得 allowlist 太严,至少设一个 denylist,把最危险的命令拦掉:

json 复制代码
{
  "tools": {
    "exec": {
      "denyCommands": ["rm", "rmdir", "dd", "mkfs", "sudo", "su", "chmod", "chown"]
    }
  }
}

参考资料:https://docs.openclaw.ai/zh-CN

相关推荐
irpywp2 小时前
GitHub项目Velxio:浏览器里的全架构硅谷
架构·github
Mahut2 小时前
我们是怎么用 TanStack 全家桶的
前端·javascript·架构
源远流长jerry2 小时前
NFV(网络功能虚拟化):重塑未来网络架构的革命性技术
linux·服务器·网络·架构
yubin12774086292 小时前
openclaw多agent测试
多agent·openclaw
龙侠九重天3 小时前
使用 OpenClaw 自动化日常任务的 10 种实用方法
人工智能·ai编程·openclaw
梦里花开知多少3 小时前
深入理解Android binder线程模型
android·架构
放下华子我只抽RuiKe53 小时前
深度学习-04-NLP项目实战
人工智能·深度学习·学习·自然语言处理·openclaw·development
好家伙VCC4 小时前
**发散创新:用 Rust实现数据编织(DataWrangling)的高效流式处理架构**在现
java·开发语言·python·架构·rust
qq_335809524 小时前
小龙虾(openclaw)本地安装教程
openclaw