上一篇聊了「OpenClaw 是什么」。这一篇更偏工程视角:OpenClaw 到底怎么实现一个可长期运行的 Agent 系统?消息是怎么进来的?怎么路由到 Agent?工具调用与定时任务如何编排?
如果你做过 Agent 落地,会很熟悉这些关键词:channel、tool、session、cron、memory、安全边界、幂等、观测……OpenClaw 的价值在于把这些抽象成一套可部署的 runtime。
1. 一张“脑内架构图”:OpenClaw 由哪些块组成?
你可以把 OpenClaw 想成三层:
1) 接入层(Channels):连接外部世界(Telegram/钉钉/QQ/…),负责收消息、发消息。 2) 编排层(Gateway + Routing + Sessions):决定“这条消息交给哪个 Agent/哪个会话”,并维护状态与生命周期。 3) 执行层(Agents + Tools/Skills + Jobs):Agent 负责决策,Tools 负责执行,Jobs(cron 等)负责触发。
对应到工程实体,大致是:
- Gateway(守护进程):常驻运行,连接多个 channel provider,维护连接与重连。
- Channel Plugin:每个渠道一个适配器,实现 inbound/outbound。
- Agent:可配置多个(不同模型/不同工作空间/不同权限),按路由绑定到渠道。
- Session:把对话与任务上下文组织起来(类似“对话线程 + 状态机”)。
- Skills:可复用的工具说明与脚本集合,给 Agent 一个“可靠使用工具”的方法。
- Cron/Jobs:把定时触发变成一等公民,支持隔离执行、送达与去重。
- Memory:长期/短期记忆(文件化/向量化),为跨会话连续性服务。
2. 核心流程 1:一条消息从“外部”到“Agent”的路径
把它拆成 8 步,你会发现它是一条典型的事件驱动流水线:
1) Channel 收到事件 - 可能是文本、图片、语音、文件、按钮回调等。
2) 插件标准化(Normalize) - 把不同平台的 message schema 归一:from/to/messageId/timestamp/chatType/attachments…
3) 封装输入(Envelope) - 给 Agent 一个稳定的“输入格式”,避免每个渠道都写一套提示词。
4) 路由(Routing/Binding) - 根据规则把消息交给指定 agent(例如 QQ 走 hang-ai,Telegram 走 main)。
5) 会话选择(Session Key) - 同一用户/群聊映射到固定 session,确保上下文连续。
6) Agent 推理(Decide) - Agent 选择:直接回复,还是调用工具(搜索/执行/写文件/定时任务)。
7) 工具执行(Tools/Skills) - 工具是“副作用层”:读写文件、访问网络、调用 API、跑命令。
8) 回传与发送(Outbound Deliver) - 将 Agent 结果交给 channel 插件发送,处理分段、markdown、富媒体等。
这条链路里,最容易做坏的其实是第 2~5 步:输入不干净、路由不清晰、session 混乱,都会让 Agent “聪明但不稳定”。OpenClaw 的设计重点正是在这里。
3. 核心流程 2:工具调用如何“可靠地执行”?
一个可落地的 Agent 系统,工具调用必须具备三种属性:
3.1 可控(Controllable)
- 工具入口有限且明确(不是什么都能 exec)。
- 敏感能力要有策略(allowlist/denylist/人工确认)。
3.2 可观测(Observable)
- 能看到:调用了什么工具、参数是什么、耗时多久、失败原因。
- 能复盘:某次输出是怎么来的。
3.3 可恢复(Recoverable)
- 失败要能重试/降级(例如 web fetch 失败就换来源)。
- 长链路要能分段(先产出,再补充)。
OpenClaw 的 skill 机制,本质是在做“把提示词工程变成可维护的工程资产”。你不希望每次靠大模型临场发挥写一堆 shell;你希望它遵循一个稳定的脚本与约定。
4. 核心流程 3:Cron/Jobs(定时任务)为什么是 Agent 生产化的关键?
很多 Agent 项目死在“能对话,但不能跑”。原因是: - 任务不能准点触发 - 不能隔离执行(被主会话上下文污染) - 失败后没有送达保障 - 会重复发送(没有幂等)
OpenClaw 的 cron 设计可以抽象成:
- 触发器(schedule):cron / every / at
- 执行体(payload):systemEvent 或 agentTurn(隔离会话跑)
- 投递(delivery):把结果发到指定 channel/target
- 幂等/去重:通常用 state 文件(last_date/last_hash)或业务键
一个很实用的经验:凡是“每天推送/定时汇总/提醒”的任务,都要把幂等写成硬性要求。这比“写得更聪明”重要得多。
5. 语音/图片等多媒体:为什么“把内容注入正文”很关键?
以语音为例,很多系统会把语音转写结果作为“附件描述”塞进消息里,但 Agent 可能把它当噪声过滤掉,最后表现为“不回复”。
更可靠的做法是: - 语音 → 转写 - 把转写文本当作用户输入正文(例如前缀“(语音转写)xxx”) - 同时保留附件元信息(可选):文件路径、时长、来源
这其实是一条通用原则:
Agent 真正在乎的是“它以为用户说了什么”。 所以多模态处理的结果要进入“正文层”,而不是“旁注层”。
6. 可复用的方法论:如何用 OpenClaw(或任何 Agent Runtime)做出稳定的系统?
下面这套方法论与 OpenClaw 强相关,但本质上是通用的 Agent 工程原则。
方法论 1:把 Agent 系统拆成“决策层 vs 执行层”
- 决策层:LLM/Agent(可变、概率性)
- 执行层:脚本/工具/skill(确定性、可测试)
越早把副作用收敛到执行层,你的系统越稳。
方法论 1.5:模块化优先——Plugin 与 Skill 是“可加载的工程单元”
很多 Agent 项目后期会失控,本质原因是:所有能力都堆在一个巨大的代码/提示词里,无法升级、无法替换、也无法复用。
OpenClaw 的架构里有两个非常值得复用的抽象:
- Plugin(插件):面向“渠道/外部系统”的适配层。它把不稳定、强耦合的外部差异隔离掉(消息格式、鉴权、富媒体、限流、重连…)。
- Skill(技能):面向“工具使用”的可维护模块。它把“如何调用某个工具”沉淀成文档/脚本/约定,让 Agent 可靠执行。
你在研发其他项目时可以照搬这套思想:
1) 把所有 I/O 做成插件接口(inbound/outbound 都走统一协议) 2) 把执行能力做成可装卸的模块(每个模块有清晰的输入输出契约) 3) 把运行时策略配置化(允许按项目/按环境切换能力组合)
这样系统才具备“长期演进能力”: - 想换搜索引擎/供应商?替换 skill 即可。 - 想多接一个渠道?加一个 plugin,不影响核心。 - 想做权限收敛?在 runtime/策略层统一控制。
方法论 2:事件驱动 + 明确的状态机
你会发现 OpenClaw 的心智模型很像: - event in → route → session → agent → tools → deliver
这其实就是一个状态机。把“会话键/幂等键/任务键”定义清楚,系统就会稳定。
方法论 2.5:把“配置”当成系统契约(Contract),而不是参数堆
OpenClaw 里很多稳定性来自于“约束前置”: - 绑定规则(哪个 channel → 哪个 agent) - 工具权限(哪些 tool 可用/哪些 elevated 禁止) - 推送策略(cron 的去重文件、重试退避)
工程上你可以把它抽象成:
- 配置即策略:把可变决策(谁能做什么、什么时候做)从代码里拿出来。
- 配置可审计:出现事故时能追溯“当时允许了什么”。
- 配置可迁移:换环境/换机器/换团队时,复制配置即可复现能力。
方法论 3:任何自动推送都必须幂等
推荐最低配:
- last_date(今天发过就退出)
- last_hash(内容一致就退出)
把它当成产品级需求,而不是“优化项”。
方法论 4:先做可观测,再做智能
一个很反直觉的点: - 你以为“让模型更聪明”能解决问题 - 实际上,80% 的线上问题来自:超时、失败重试、权限、消息格式、平台限制
所以先把日志、运行记录、失败原因打通,后面再谈“更聪明”。
方法论 5:安全边界要前置
建议至少做到: - 渠道 allowlist / groupPolicy - 敏感工具禁用或需要确认 - 不信任外部内容(把网页/邮件当不可信输入)
Agent 的安全不是模型能解决的,是架构要解决的。
7. 总结
OpenClaw 的架构并不神秘:它把 Agent 的生产化问题拆解为一组工程模块(channel、session、tool、cron、memory、安全策略),并把“核心流程”做成可运行、可观测、可扩展的系统。
如果你要复用它的方法论,记住一句话就够:
让 LLM 做决策,让系统做约束,让工具做执行。
这就是把 Agent 从 demo 推向长期运行系统的关键。