OpenClaw通用架构分析
把你的AI放在自己的服务器上,而不是别人的网页里
——OpenClaw 架构与实践
第一章:为什么不是打开一个网页就够了?
“一切从实践中来,一切到实践中去。”
——认识论
实践场景
你在网上看到了一个叫 OpenClaw 的东西——“一个开源的 AI Agent 框架”。
你想试试。按照正常人的思路,你去找它的网站……没找到。你再找 App Store 下载……也没有。最后你在 GitHub 上找到它,看到一行安装命令。装完之后,你在终端里敲了一个命令,一个服务启动了,监听在 18789 端口上。然后你打开浏览器,连到http://localhost:18789——出现了一个聊天界面。
你终于能跟它说话了。
但你脑子里冒出一个问题:为什么不能直接给我一个网页地址?为什么要我装在自己机器上?
引出矛盾
今天你用的大多数 AI 产品——ChatGPT、Claude、Gemini——都是 SaaS:打开网页、注册账号、开始聊天。它们替你管好了服务器、升级版本、备份数据。你拿来就用,什么都不用操心。
但 OpenClaw 走的是另一条路——你自己是管理员。
这堵墙在实践中的体现很明显:
- 你要自己装 Node.js,自己配置,自己启动服务
- 升级要看 Release Notes,手动拉新版本
- 出了问题只能自己排查
- 但它不会限制你一个月能聊多少条,因为模型是你自己配的
- 你的对话不上传给别人,因为全在你的机器上
这就是核心矛盾:SaaS 产品替你管理一切,但你也失去了对一切的控制权。开源自托管让你拥有完全的控制权,但管理成本落到了你头上。
理论/经验:自托管智能体网关
OpenClaw 的架构选择,是围绕"自托管"这个前提长出来的:
你的机器上跑着一个 Gateway 服务(端口 18789) ↓ 你是管理员——配置、数据、能力都在你手里 ↓ 你配一个或多个 Agent(每个有独立的工作区、人格、模型) ↓ Agent 通过渠道对外服务(Web 页面 / Telegram 机器人 / Discord 等)为什么自托管?因为 OpenClaw 的设计者认定了三件事:
- 你的数据不该在别人的服务器上— 对话历史、配置、记忆,全在你的磁盘里
- 你的 Agent 不该被别人限速限流— 你自己付模型 API 费用,没有"每月固定条数"这种限制
- 你的 Agent 必须可定制— SaaS 产品给你一个固定界面,OpenClaw 让你改到源代码级别
付出的代价就是:你要当管理员。
| 对比维度 | SaaS AI 产品 | OpenClaw(自托管) |
|---|---|---|
| 谁管服务器 | 提供商 | 你 |
| 谁管升级 | 提供商 | 你 |
| 数据在哪里 | 提供商服务器 | 你的机器 |
| 扩展能力 | 产品给你什么用什么 | 你自己加技能、加渠道 |
| 费用 | 按月订阅 | 自己付模型 API 费用 |
| 知识门槛 | 零 | 懂命令行和配置 |
回到实践
所以当你第一次看到openclaw gateway这个命令、看到 18789 这个端口时,你不是在装一个工具——你是在在自己的机器上架设一台 AI 服务器。门槛比打开网页高,但换来的东西也比打开网页多。
你在哪里读到 OpenClaw 不重要。重要的是你读完了知道:它不是被托管在别处的产品,是可以被你自己运营和管理的基础设施。
第二章:一条消息是怎么变成一段回复的?
“感觉到了的东西,我们不能立刻理解它,只有理解了的东西才更深刻地感觉它。”
——《实践论》
实践场景
你连上了 18789 端口,在聊天框里打了一行字,按了回车。过了一会儿,屏幕上一段回复出现了。看起来就像 ChatGPT 一样——输入、等待、输出。
但 OpenClaw 不是直接访问 OpenAI 或 DeepSeek 的 API 然后把结果还给你。它多做了很多事——尽管看上去一样简单。
引出矛盾
你"感觉"到它回复了你——就像感觉到手机响了接起来有声音。但真遇到问题了,客服问你"Gateway 的日志看了吗?Session 是哪个?技能加载了吗?"——你才意识到你完全不知道这个过程怎么拆。
你知道"出去"的是什么——你输入的文字。你知道"回来"的是什么——Agent 的回复。但你不知道中间发生了什么。一张黑布隔在输入和输出之间。你摸得到两边,但看不见里面。
这就是核心矛盾:Agent 和人之间隔着一层看似简单的 UI,但复杂的传动机构被完全隐藏了。一旦需要诊断问题,你就变成了拆盲盒。
理论/经验:消息在 OpenClaw 中的完整路径
一条消息从你发出到看到回复,穿越了五层:
你 → 渠道(WebChat / Telegram / CLI / …) ↓ Gateway(端口 18789 —— 统一入口) ↓ 1. 验证身份(你是谁?) ↓ 2. 判断来源(从哪个渠道来的?) ↓ 3. 路由(这条消息该走哪个 Agent?) ↓ Session 管理 ↓ 4. 恢复或创建会话(之前聊过没?) ↓ Agent 循环(核心) ↓ 5. 组装上下文:人格文件 + 记忆 + 技能 + 工具列表 + 历史对话 ↓ 6. 调用大模型 ↓ ┌── 如果是文字回复 ──→ 直接输出 ──┐ │ │ └── 如果是工具调用 ──→ 执行工具 → 结果喂回模型 → 继续循环 ──┘ ↓ Session 持久化(写回对话历史) ↓ Gateway 推送到渠道 ↓ 你 ← 看到回复这五层各自解决一个独立的问题:
| 层 | 解决的问题 |
|---|---|
| 渠道 | 把各种消息源的差异归一成统一格式——你在 WebChat 打进去的字,跟从 Telegram 发来的消息,到了 Gateway 这里就是同一种东西 |
| Gateway | 统一验证和路由——不管从哪来、不管有几个 Agent,都走这一个入口 |
| Session | 会话隔离和复用——群聊和 DM 互不干扰,同一个人连续聊天自动接上上下文 |
| Agent Loop | 想和干的分离——大模型负责想,工具负责干,Loop 负责协调 |
| 技能 + 工具 | 能力可插拔——想加新能力就写一个 markdown 文件,不用改代码 |
回到实践
下次你再对着 OpenClaw 发一条消息,你可以自己在脑子里走一遍这条路径:
“这条消息进 18789 了 → Gateway 验了我的身份 → 找到我的 session → Agent 加载了我的配置和技能 → 调了一次大模型 → 没有工具调用 → 直接输出 → 写回 session → 我收到了。”
这条路径走一次只要一两秒。但理解它之后,你再也不会觉得"输入→输出"是一个简单操作了——你看到的是一套精密的分层传动机构在一两秒内跑完了全线。
第三章:一个 AI 怎么拥有"人格"?
“内因是变化的根据,外因是变化的条件。”
——《矛盾论》
实践场景
你打开 OpenClaw 开始跟它聊天。它自称一个名字,有特定的语气,对有些问题果断、对有些问题谦让。它似乎知道自己是谁、在跟谁说话、应该怎么回应。
但你很清楚:大模型本身没有"人格"——你给它什么系统提示,它就是什么样子。换一组提示词,它就变成另一个人。
那么,OpenClaw 的这种"稳定人格"是怎么保持的?
引出矛盾
每次 Agent Loop 启动,你都给了大模型一个上下文——里面带着服务端的配置、用户的信息、对话的历史。但这个上下文是怎么长成的?谁决定了大模型的"人设"?
如果说大模型是一个演员,那么系统提示词就是剧本。但问题在于:演员每场演出只拿到当场的剧本,不拿到全部剧本。换一个 session,剧本就从头来。你怎么保证每次拿到的剧本都是同一个"人"?
这就是矛盾:大模型是白纸一张,但 Agent 需要一个稳定、可预期的人格。这个人格不能靠程序员写死在代码里,因为用户需要自己能改。
理论/经验:工作区文件驱动人格系统
OpenClaw 的解法是工作区文件 + 角色路由。
工作区里有一组 markdown 文件,定义了 Agent 的"人":
workspace/ ├── AGENTS.md ← 运行规则(知道怎么做事) ├── SOUL.md ← 人格设定(知道怎么做人) ├── MEMORY.md ← 长期记忆(记得发生过什么) ├── USER.md ← 用户资料(知道自己跟谁说话) ├── TOOLS.md ← 工具偏好(知道用什么顺手) └── IDENTITY.md ← 自我介绍(知道自己叫什么)每次新的会话启动时,这些文件被全量读入系统提示。所以 Agent 每次重启都知道自己是谁、在跟谁说话、应该怎么回应。
人格文件最值得关注的特性:
- 它们是文本文件,不是数据库— 你打开编辑器就能改,不用 SQL、不用 API。改完保存,下次对话就生效。
- 它们是用户可控的— 开发者设计框架,但人格的定义权在你手里
- 它们可以组合出多角色— 同一份 SOUL.md 里可以写角色路由表,根据不同的关键词匹配不同人格
SOUL.md 里的角色路由示例
| 触发关键词 | 角色 | 说明 |
|---|---|---|
| 分析、怎么看、矛盾 | 分析专家 | 辩证分析,给你结构性答案 |
| 技能、SKILL、触发词 | 技能开发者 | 按规范格式写技能文档 |
| 其他 | 默认助手 | 灵活应对 |
回到实践
OpenClaw 聊起来像一个人,不是大模型恰好生成了符合你期望的语气——而是因为每次对话开始前,一组精心编写的 markdown 文件被放进了它的"认知基础"里。改一行 SOUL.md,人格就变了。不是你写代码重新编译它,是你拿着文本编辑器改了段话。
这就是"内因是变化的根据"——Agent 的人格不是代码决定的,是你在那一堆 markdown 文件里写下的定义决定的。
第四章:一个不会动手的大模型怎么成了干活的好手?
“不同质的矛盾,只有用不同质的方法才能解决。”
——《矛盾论》
实践场景
你对 OpenClaw 说:“帮我把这个目录里的文件统计一下,按类型分类,输出一份报告。”
OpenClaw 说:“好的”,过了几秒,一份完整的文件统计报告出现在屏幕上,分类清晰、数据准确。
但你仔细想一下:OpenClaw 背后是一个大模型——大模型会写文字、会推理,但它不会读文件。它没有眼睛、没有手、不能操作文件系统。它怎么统计的?
引出矛盾
大模型的能力边界是生成文本。它不知道当前目录有什么文件,因为它没有"看"的能力。它不能执行 Shell 命令,因为 LLM API 让你传 message 和工具定义,不让你传 Shell 指令。
但用户需要的 Agent,恰恰是要能执行的——读文件、跑脚本、查数据库、调 API。如果 Agent 不能做这些事,它就是一个高级聊天机器人,不是智能体。
这就是核心矛盾:大模型只会"想"(生成文字),但用户需要的是"干"(执行操作)。
理论/经验:Agent Loop 工具调用机制
OpenClaw 用一个叫做Agent Loop的循环机制来解决这个矛盾。
工作方式很简单:
用户:统计文件 ↓ Agent 循环开始: 第 1 轮:调 LLM LLM 推理 → "我需要列出文件,应该用 terminal 工具跑 ls" LLM 输出工具调用 ↓ 拦截工具调用 → 执行 hermes_terminal("ls -R") → 拿到文件列表 ↓ 第 2 轮:把文件列表喂回 LLM LLM 推理 → "有 32 个 .md 文件, 15 个 .py 文件……" LLM 输出分类结果 ↓ 输出给用户三步走:
| 步骤 | 谁做的 | 做了什么 |
|---|---|---|
| 想 | 大模型(LLM) | 分析用户需求,决定该调什么工具、传什么参数 |
| 干 | Agent Loop | 拦截 LLM 发出的工具调用请求,调用真实函数执行 |
| 再看 | 大模型 | 拿到工具执行结果,继续推理下一步或输出最终回复 |
每一步之间,Agent Loop 就是那个转接器——它把 LLM 的"想法"翻译成"动作",再把"动作的结果"翻译回 LLM 能理解的格式。
OpenClaw 可以接入的工具有几类:
| 工具来源 | 举例 | 怎么接的 |
|---|---|---|
| 内置工具 | read/exec/write/edit | 框架自带的,开箱即用 |
| MCP 桥工具 | 任何第三方 Agent 暴露的能力 | 通过 MCP 标准协议接入 |
| 自定义工具 | 你写的 API 调用脚本 | 通过工具定义注册进去 |
回到实践
你让 OpenClaw 统计文件、写文章、分析架构——每一个看起来像"跟 AI 聊天"的操作,背后都是 Agent Loop 在"想→干→再想→再干"地转圈。大模型一动嘴,Agent Loop 就跑断腿。但你作为用户,只看到它回答了你。
这就是 Agent 跟聊天机器人的区别:聊天机器人只知道怎么回答你。Agent 知道怎么帮你把事情办了——因为它有手。
第五章:一个 Gateway 怎么伺候好多个"人"和多个"地方"?
“具体问题具体分析。”
——《实践论》
实践场景
你的 OpenClaw 跑起来了,正在 WebChat 上跟你聊天。但你出门在外,只有手机——你想通过 Telegram 继续聊。另外,你还有一个朋友想用 Discord 跟你的 Agent 说话——但你觉得应该给他安排一个不一样的 Agent,性格偏正式一些,不像跟你聊天这么随意。
一个 Gateway,多个人,多个地方,每个人还要不同的 Agent——这怎么实现的?
引出矛盾
三个不同的问题压在一起:
- 多个渠道— Telegram 有自己的 Bot API,Discord 有自己的 Gateway,Web 有自己的 WebSocket——每套协议都不同
- 多个 Agent— 一个给你当哥们,一个给同事当助手,你不能让同一个 Agent 用同一套语气对所有人
- 多条消息— 如果同时来三条消息,全交给同一个 Agent 会串,全串行处理会慢
不把这些理清楚,你的 OpenClaw 就只能在单机单用户单渠道下运行——谈不上"基础设施"。
这就是核心矛盾:统一运行服务和差异化服务能力之间的矛盾。
理论/经验:多 Agent 路由 + 渠道绑定系统
OpenClaw 把"谁在说话"和"谁在回答"用一套 binding 系统解耦了。
Binding 决定路由(每条消息该走哪个 Agent):
消息来源:Telegram / Discord / WebChat / CLI ↓ Binding 规则:一条接一条匹配 1. 先查 peer(是否是特定用户发的?) 2. 再查 guild(是否是特定群组的?) 3. 再查 channel(是否来自整个渠道?) 4. 最后查 default(没匹配上就用默认 Agent) ↓ 路由到匹配的 Agent匹配规则是"最具体优先"——你对指定用户发来的消息单独安排了某个 Agent,那就它;没有任何特殊规则,就走默认 Agent。
每个 Agent 完全隔离:
Agent A(跟你聊天——随意、哥们) ├── 自己的工作区(SOUL.md: "你是个哥们") ├── 自己的人格文件 ├── 自己的 session 历史 └── 自己的技能列表 Agent B(跟同事对接——正式、专业) ├── 自己的工作区(SOUL.md: "你是个专业助理") ├── 自己的人格文件 ├── 自己的 session 历史 └── 自己的技能列表两个 Agent 共享一个 Gateway 进程、共享一个 18789 端口——但在逻辑上完全独立。Agent A 不知道 Agent B 跟谁聊了什么,反之亦然。
多渠道通过适配器接入:
每个渠道配一个适配器文件,把平台协议翻译成统一格式:
| 平台 | 接入方式 | OpenClaw 适配器做了什么 |
|---|---|---|
| WebChat | 浏览器直接连 WS | 渲染聊天界面,历史记录 |
| Telegram | Bot API token | 轮询更新,发送消息 |
| Discord | Gateway 连接 + Bot token | 监听事件,发送消息 |
| CLI | 终端 WS 连接 | 无界面交互 |
| 更多 | 各平台协议 | 归一化成统一消息格式 |
回到实践
所以当你在 WebChat 上跟 OpenClaw 聊天,你的朋友通过 Telegram 跟另一个 Agent 聊天——看起来是四个独立聊天窗口,实际上都是同一个 Gateway(同一个 18789 端口)在背后统一路由。
谁在哪个渠道、发给哪个 Agent、用什么人格说话——这一切在 Binding 规则表里定义好之后,服务器就不需要你手操了。消息进来自动匹配,正确的人用正确的语气回答正确的来源。
这就是"具体问题具体分析"在架构上的体现——每个场景不同(渠道不同、用户不同、用途不同),解决方案也不同(不同的 Agent、不同的人格、不同的适配器),但所有的"具体"都归一在同一个 Gateway 之下。
小结
“一切从实践中来,一切到实践中去。”
OpenClaw 每一层的架构设计,都是从一个很具体的实践困境出发的:
| 实践困境 | 架构解法 |
|---|---|
| 不想把数据和对话交到别人服务器上 | 自托管 Gateway |
| 想知道消息在服务端经历了什么 | 五层链路(渠道→Gateway→Session→Agent Loop→技能/工具) |
| 需要 Agent 拥有稳定可预期的人格 | 工作区文件驱动人格系统 |
| 大模型只会想不会干 | Agent Loop 工具调用机制 |
| 一个服务要对多个平台、多人、多角色提供服务 | 多 Agent 路由 + 渠道绑定系统 |
它不是从一本系统设计教科书里抄出来的。每一层都是被一个问题"逼出来"的——你先遇到了"用户发了一条消息,我怎么知道该给哪个 Agent?"这道题,然后才有了 Binding 系统。你先遇到了"每次对话都要重新介绍自己"这个烦人的事,然后才有了 session 持久化。
OpenClaw 的架构是长出来的,不是想出来的。
好的架构的特点就在这:你不觉得它复杂,但它确实复杂。只是把复杂藏到了你不需要看见的地方。
