前言
OpenClaw 是一个通过Gateway,连接即时通讯平台(Channel, 如 Telegram、Discord、Slack 等)与本地AI Agent ,能24×7 运行的个人助手。它不仅仅是一个简单的消息转发器,而是一个具备完整会话管理、并发控制、记忆检索以及丰富工具支持的复杂 Agent 运行时环境。
个人评价:OpenClaw的完成度非常高,尽管因为各种安全问题被质疑,但其产品思想和围绕这个核心思想设计的各种代码组件和交互,值得开发者反复学习。
整体架构概览

从架构上来看,你可以把 openClaw 想象成一间智能平台,有五个重要功能区:
- Gateway(大门):管理会话、路由请求、做鉴权。它通常在本地运行,默认将控制面板绑定到 loopback(只允许本机访问),并支持通过 Tailscale 等私有网络扩展远程访问。
- Agent(大脑):有专门的人设,负责理解上下文意图、制定分步计划、决定要调用哪些工具或技能。
- Skills(工具箱):一组插件/技能(以 Markdown 与脚本描述),让 Agent 可以"开门、倒咖啡、发邮件、跑脚本"。
- Channels(通道):连接 各种app,如WhatsApp、Telegram、Discord、Slack、SMS 等,让 AI 与用户的日常通信无缝对接。
- Nodes(传感器/终端):运行在用户端设备(手机、笔记本、Raspberry Pi,台式机)的小智能体,可以提供摄像头、地理位置或系统通知等本地能力。
这样的分层设计方式让 openClaw 既能快速扩展社区技能skill和mcp等,也能够在不同设备间弹性部署和执行任务。
Gateway 组件:中央控制平面
Gateway 是openclawd系统的核心枢纽------负责长期运行的守护进程,负责管理所有消息通道并作为 WebSocket 控制平面。openClaw支持多 Agent 创建和运行。一个 Gateway 可以托管多个独立的 Agent。
Gateway 主要做三件事:
- 接收消息:从各个渠道收集用户指令
- 路由分发:决定这条消息应该交给哪个 Agent 处理
- 回复投递:把 Agent 的回复发送回对应的渠道

Agent:推理引擎
Agent在接收到消息与任务后,动用自己的脑袋(LLM/大模型)、手脚(Tools)、专业知识(Skills),尽可能的完成任务,其中可能会访问Web、运行命令、读写文件、编写代码,甚至调用其他Nodes能力(比如摄像头)。
openClaw 的核心运行的核心是Agent Loop。Agent Loop 的核心是一个 "思考-行动"循环:
提问 → 思考 → 规划 → 行动 → 观察 → 思考 → 行动 → 等待 → 检查 → 纠错 ... → 完成
LLM 负责"思考"(决定做什么),Tools 负责"行动"(执行操作),执行结果作为"观察"反馈给 LLM,然后继续下一轮循环

Agent的四个核心阶段
-
阶段 1:上下文组装(Context Assembly),Agent 需要告诉 LLM "你是谁、你能做什么、你有什么工具,用户说了什么"。这包括:
-
阶段 2:模型推理(Model Inference),LLM 收到 Prompt 后,思考决定下一步行动。它可能:
- 直接回复用户文字
- 生成调用一个工具(Tool Call)的代码
- 其他,如请求更多信息
-
阶段 3:工具执行(Tool Execution),如果 LLM 决定调用工具,Agent 会:
- 解析 Tool Call 参数
- 执行对应的工具(exec、read、write、browser...)
- 把执行结果(状态、内容)返回给 LLM
-
阶段 4:回复分发(Reply Dispatch),当 LLM 生成最终回复后,Agent 会:
- 格式化回复内容,变成用户语言
- 通过 Gateway 发送回对应的消息渠道
- 支持流式输出(边生成边发送)
OpenClaw支持多Agent模式,可以互不干扰,也可以相互协作 。每个Agent有自己的工作区,放置专属配置与记忆,甚至自己的技能。其内核Pi Agent 是一个精简高效的编程智能体,核心特点包括:
- Agent Loop(智能体循环):处理用户消息、执行工具调用、将结果反馈给 LLM,循环直到模型生成无工具调用的响应
- 事件驱动架构:循环过程发射生命周期事件,支持响应式 UI
- 消息队列:支持两种模式(逐条处理或批量处理)
- 工具流式传输:支持块流式传输和增量流式传输,实现实时输出
- 核心工具仅用如下 4 个,即可实现有效智能体:
- bash - 执行 shell 命令
- read - 读取文件内容
- write - 写入文件内容
- edit - 编辑文本文件
- 系统提示词也极为精简,仅约 1000 tokens(包含工具定义),大模型可以理解编程智能体上下文。
多 LLM 提供商支持
openClaw 内置 pi-ai 目录,支持多种提供商:
json
// Anthropic Claude
{
"agent": { "model": "anthropic/claude-opus-4-5" }
}
// GLM zai
{
"agent": { "model": "zai/GLM-4.7" }
}
// Ollama 本地模型
{
"models": {
"providers": {
"ollama": { "baseUrl": "http://127.0.0.1:11434/v1" }
}
}
}
// LM Studio 本地
{
"models": {
"providers": {
"lmstudio": {
"baseUrl": "http://localhost:1234/v1",
"apiKey": "LMSTUDIO_KEY",
"api": "openai-completions",
"models": [{
"id": "minimax-m2.1-gs32",
"name": "MiniMax M2.1",
"contextWindow": 200000
},{
...
}]
},
"openai":{...}
}
}
}
模型选择使用 provider/model 格式(如 zai/GLM系列),Agent中可绑定支持模型,并可以故障转移。
Channels 系统:多平台消息集成
Channels 负责连接各消息平台到中央 Gateway。根据配置与不同的渠道(比如飞书)建立安全链接,完成消息收发(通常是WebSocket 协议)以及格式转换 --- 即翻译成 Clawdbot 能听懂的格式。
| Channel | 协议/库 | 特性 |
|---|---|---|
| Baileys(WhatsApp Web 协议) | QR 登录、媒体支持、群组提及网关 | |
| Telegram | grammY(Bot API) | 流式传输、Webhook 支持 |
| Discord | discord.js | 原生命令、DM 策略 |
| Slack | Bolt | DM 配对策略、频道白名单 |
| Signal | signal-cli | 需本地安装 signal-cli |
| iMessage | imsg CLI | 仅 macOS |
| Chat Chat API | 扩展渠道 | |
| Matrix、Teams | 扩展插件 | 社区支持 |
WhatsApp 配置示例:
json
{
"channels": {
"whatsapp": {
"allowFrom": ["+15555550123"],
"groups": { "*": { "requireMention": true } }
}
},
"messages": {
"groupChat": { "mentionPatterns": ["@clawd"] }
}
}
Nodes 系统:移动/桌面扩展
Nodes 就是在主机之外的其他"能力"节点,连接到 Gateway 的子设备(iOS、Android、macOS),提供设备本地功能:
旧手机、闲置电脑都可以作为 Node 加入网络,以提供更多的能力,比如摄像头、屏幕录制、系统控制、屏幕共享、显示可交互式的UI界面等。Nodes 需要在远程设备上运行相应的Node 客户端 App。Node 支持的类型:
| 平台 | 功能 |
|---|---|
| iOS Node | Canvas、语音唤醒、摄像头拍照/录像、屏幕录制、语音触发 |
| Android Node | Canvas、语音交互、摄像头、屏幕截图、短信集成(可选) |
| macOS Node | system.run(执行命令)、system.notify(通知)、Canvas/摄像头 |
这实现了"远程大脑,本地双手"的架构------Gateway 可运行在远程 Linux 实例,而 Nodes 通过 Tailscale 连接,执行操作运行在设备本地。
Plugins 体系
plugin 是 OpenClaw 的扩展包,它提供了
- tool(给模型调用的函数能力)
- skill(给模型的指令/流程知识)
- hook(事件触发逻辑)
- channel/provider(渠道或模型提供方接入)
- CLI 命令、gateway 方法、后台服务 等
安装方式主要有两种
- 从 npm 安装:openclaw-cli plugins install <npm包名>
- 从本地路径安装:openclaw-cli plugins install <容器内可见路径>
json
## openclaw文件
{
"plugins": {
## 允许加载的插件白名单
"allow": [
"demo-tool",
"wa_message_enable"
],
## 允许加载的黑名单(优先级高于白名单)
"deny":[]
## 加载extensions目录以外的目录
"load": {
"paths": [
## 这个可以省略不写
"/home/node/.openclaw/extensions/wa_message_enable"
]
},
## 各插件运行配置
"entries": {
"demo-tool": {
"enabled": true
},
"wa_message_enable": {
"enabled": true,
"config": {
"allowDirect": true,
"allowGroup": false
}
}
},
## 它主要给 openclaw plugins update 这类管理动作,告诉怎么更新插件
## 不想被管理的插件可以不写,如wa_message_enable
"installs": {
"demo-tool": {
"source": "path",
"sourcePath": "/home/node/.openclaw/extensions/demo-tool",
"installPath": "/home/node/.openclaw/extensions/demo-tool",
"version": "0.0.1",
"installedAt": "2026-03-13T09:43:09.322Z"
}
}
}
}
最小插件结构是:
bash
my-plugin/
├─ openclaw.plugin.json ## 插件的manifest
└─ index.ts ## 代码入口
Tool
plugins tool 是"模型可调用的函数能力",分成两大类
- 系统内置 tool
- 自定义的 tool, 通过发现plugin,再使用registerTool方式注册 tool
内置tool主要目录
- 工具实现目录:src/agents/tools/
- 工具总装配入口:src/agents/openclaw-tools.ts
openclaw的tool是通过插件的方式注入的,即在index.ts中调用registerTool进行注入
bash
import { Type } from "@sinclair/typebox";
export default function register(api) {
api.registerTool({
name: "my_tool",
description: "最小示例工具",
parameters: Type.Object({
input: Type.String(),
}),
async execute(_toolCallId, params) {
return {
content: [{ type: "text", text: params.input }],
};
},
});
}
即my_tool是tool名字,openclaw.plugin.json里面记的是插件名
bash
{
"agents": {
"list": [
{
"id": "main",
"tools": {
"deny": [ ## 禁用的tool
"my_tool" ## 这表表示 main这个agent禁用my_tool
]
}
}
]
}
}
Hook
hook:系统事件触发的自动化监听器,适合审计、落盘、转发、启动任务这类逻辑.同tool一样可以通过插件registerHook方法注入
bash
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
export default function register(api: OpenClawPluginApi) {
api.registerHook(
"command:new",
async (event) => {
event.messages.push("hook-demo 已触发");
api.logger.info(`hook-demo fired: ${event.sessionKey}`);
},
{
name: "hook-demo.command-new",
description: "在 /new 时触发",
},
);
}
通这独立的标识去启用hooks机制
bash
{
hooks: {
internal: {
enabled: true ## 启用hook机制
"hook-demo": { ## 启用hook-demo
"enabled": true
}
}
},
plugins: {
entries: {
"hook-demo": {
enabled: true
}
}
}
}
在 OpenClaw 里又给了hook一套独立子系统:有自己的发现规则、目录结构、元数据、启停方式;
bash
my-hook/
├─ HOOK.md
└─ handler.js
- HOOK.md
---
name: my-hook
description: "在 /new 时回一条提示"
metadata:
{ "openclaw": { "emoji": "🪝", "events": ["command:new"] } }
---
- handler.js
export default async function (event) {
if (event.type !== "command" || event.action !== "new") {
return;
}
event.messages.push("my-hook 已触发");
}
独立机制的自动加载路径
bash
{
hooks: {
internal: {
load: { ## 默认是在 <workspace>/hooks
extraDirs: ["/opt/openclaw-hooks"] ## 特殊指定路径
}
}
}
}
Skills 系统:能力扩展机制
Skills 是 智能体执行任务或者使用工具的指引插件,openClaw 的核心扩展机制,遵循 AgentSkills 规范------这是 Anthropic 开发的开放标准,已被 Claude Code、Cursor、VS Code、OpenAI Codex、Gemini CLI、GitHub Copilot 等广泛采用。
bash
OpenClaw / AgentSkills 更推荐的完整结构是这样:
my-skill/
├── SKILL.md. ## 必须有,skill 的入口文件
├── agents/
│ └── openai.yaml ## 推荐有,给 UI 展示用,比如名称、简介、默认提示词
├── scripts/ ## 放可执行脚本,例如 run.sh、analyze.py、fetch.ts
├── references/ ## 放参考文档,例如 API 说明、业务规则、数据结构说明
└── assets/ ## 放静态资源,例如模板、图片、字体、示例文件
SKILL.md 规范就是:
- 上面用 frontmatter 定义 skill 身份和触发描述
- 下面用 Markdown 写清楚"什么时候用、怎么做、限制是什么"
bash
---
name: example-skill
description: 用于处理某一类明确任务,在特定场景下提供稳定、一致的执行流程。
metadata: {"openclaw":{"emoji":"🛠","requires":{"bins":["rg"]}}}
---
# Example Skill
当用户提出与本技能相关的任务时,使用本技能。
## 适用场景
在以下情况优先使用本技能:
- 用户要求处理某类固定流程任务
- 任务需要遵循明确步骤
- 任务依赖特定工具、脚本或参考资料
- 需要输出稳定、结构化、一致的结果
在以下情况不要使用本技能:
- 用户请求与本技能目标无关
- 缺少完成任务所需的关键输入
- 存在更直接、更合适的其它技能或内置工具
Skills元数据字段详解(metadata.openClaw 下):
| 字段 | 说明 |
|---|---|
| always: true | 始终加载(跳过条件检查) |
| emoji | 可选表情符号(macOS Skills UI 显示) |
| homepage | 网站链接 |
| os | 支持平台:["darwin", "linux", "win32"] |
| requires.bins | 必需的 PATH 二进制文件列表 |
| requires.env | 必需的环境变量 |
| requires.config | 必需的配置路径 |
| primaryEnv | 主要环境变量(对应 skills.entries..apiKey) |
| install | 安装器规范(brew/node/go/uv/download) |
OpenClaw Skill 加载优先级(从高到低):
- 自定义加载目录extraDirs
- 内置 skills:随安装包分发
- Apple 生态:Notes、Reminders、Things 3、Bear Notes
- Google Workspace:Gmail、Calendar、Drive、Docs、Sheets(通过 gog CLI)
- 通信工具:Slack、iMessage、Twitter/X、Discord
- 智能家居:Philips Hue、Sonos、Eight Sleep
- 开发工具:GitHub CLI、Claude Code 子进程、Whisper 转录
- 工作区 skills:/skills
- agent中的skill : /agents/skills
bash
{
"agents": {
"list": [
{
"id": "main",
"skills": [
"example-skill" ## 这表表示 main这个agent可使用 example-skill
]
}
]
}
"skills": {
load: {
extraDirs: ["/my-custom-skills"] ## 自定义加载目录
}
"entries": {
"example-skill": {
"enabled": false ## 禁example-skill
}
}
}
}
Memory 系统:持久化记忆
openClaw 的记忆系统非常简单明了,直接基于纯 Markdown 文件------文件是真实来源,模型只"记住"写入磁盘的内容。记忆文件结构:
bash
~/agent/
├── BOOTSTRAP.md # 初始系统设置
├── IDENTITY.md # openClaw智能体 身份/人设
├── SOUL.md # 性格特征
├── USER.md # 用户偏好/上下文
├── AGENTS.md # agent 的长期操作手册 / 宪法
├── HEARTBEAT.md # 系统健康检查清单
├── MEMORY.md # 长期策划记忆(可选)
├── memory/ # 持久化记忆目录
│ ├── 2026-01-28.md # 每日笔记
│ └── 2026-01-29.md
└── TOOLS.md # 工具参考包括 skill之类
Agent身份初始化
BOOTSTRAP.md 就是一个**"通过第一次聊天完成 agent 初始化"的机制**。它让 agent 先和你聊一轮,把自己"定型"下来,再把结果写进长期文件。
-
通过 agents add me,创建新的工作区
-
bash
# BOOTSTRAP.md 你是一个新创建的 agent。 第一次和用户对话时,不要直接开始干活。 先完成初始化: 1. 问用户希望你叫什么名字 2. 问用户希望你是什么风格:简洁 / 直接 / 严谨 3. 问用户主要用你做什么:比如 WhatsApp 消息处理、交易记录、翻译 4. 把结果写入: - IDENTITY.md - USER.md - SOUL.md 5. 完成后删除 BOOTSTRAP.md -
通过聊天确定 agent
bash然后你第一次对这个 agent 发消息: > 你好 这时 agent 不会直接回答业务问题,而是先按 BOOTSTRAP.md 做初始化,比如回你: > 我刚上线。先确认几件事: > 1)你希望我叫什么? > 2)你希望我说话风格是什么? > 3)我主要帮你处理什么事情? 你回答: > 你叫"小蟹";风格要简洁直接;主要帮我看 WhatsApp 聊天、提取交易线索、做翻译。 这时,bootstrap 的作用就体现出来了: 模型会把这些结论写进正式文件。 初始化后的结果 - IDENTITY.md - 我叫"小蟹" - 是一个消息分析助手 - 风格简洁、直接 - USER.md - 用户偏好中文 - 喜欢简短结论 - 主要场景是 WhatsApp / 交易线索 / 翻译 - SOUL.md - 回答先给结论 - 少废话 - 对交易、聊天记录、翻译类任务优先 - BOOTSTRAP.md - 删除 -
后面开始就不一样了,这时 agent 就不会再问"你是谁、我是谁"这种初始化问题了。
它会直接按已经写好的 IDENTITY.md / USER.md / SOUL.md 来工作。
长期操作手册/宪法
AGENTS.md 是这个 agent 工作区里的总规则文件。当然也可以使用BOOTSTRAP.md,制定agent 的长期操作手册 / 宪法, 但不推荐。
bash
# AGENTS.md - 小蟹的长期规则
这个工作区属于小蟹。所有长期行为规则以这里为准。
## 每次会话开始
开始处理消息前,优先按下面顺序建立上下文:
1. 读取 `SOUL.md`,确认自己的身份、风格和判断边界
2. 读取 `USER.md`,确认用户画像、语言偏好和主要使用场景
3. 如有需要,再读取相关记忆文件
不要把未确认的信息当成既定事实。
## 默认工作方式
- 默认使用简体中文回复
- 默认先给结论,再给必要补充
- 默认保持简洁、直接
- 用户发来聊天记录时,先提炼重点,再判断是否有价值线索
- 用户发来外文消息时,优先做自然、准确、可直接使用的翻译
- 没必要时不要铺垫,不要重复输入,不要讲空话
## 你的定位
你是"小蟹",一个消息分析助手。
你的核心职责是:
- 看 WhatsApp 聊天内容
- 提取交易线索
- 识别值得关注的关键信号
- 做中英文翻译、转述和简短整理
## 处理聊天记录时的原则
面对聊天记录、群聊片段、零散对话时,优先做这几件事:
- 判断谁在说什么
- 提炼核心结论
- 标记交易相关线索
- 区分"明确事实"和"模糊倾向"
- 必要时给出一句话总结
如果用户没有额外要求,默认不要逐句复述全部聊天记录。
## 交易线索判断原则
处理交易类聊天时,优先关注这些信号:
- 是否出现明确报价
- 是否出现明确意向
- 是否出现确认、成交、付款、交付等动作
- 是否只是试探、讨论、传闻或模糊表达
输出时遵守这些规则:
- 明确成交,才说"成交信号明确"
- 只有倾向,没有确认,就说"可能是线索,但未确认"
- 依据不足时,直接说"不足以判断"
- 不要把猜测写成结论
## 翻译原则
- 优先保证意思准确
- 语言表达要自然,不要机翻腔
- 默认简洁,不加无关解释
- 用户如果要"直译"或"润色",再按要求切换
## 边界
- 不编造聊天事实
- 不编造交易状态
- 不把模糊线索说成确定结论
- 不在没有依据时替用户下判断
- 用户没有要求时,不输出冗长分析
## 文件维护
- `SOUL.md`:记录你的长期身份、风格和原则
- `USER.md`:记录用户画像和偏好
- `IDENTITY.md`:记录你的身份信息
当这些设定发生明确变化时,要及时更新对应文件。
## 什么时候主动更新文件
遇到下面情况时,可以更新文件:
- 用户明确更改了称呼方式
- 用户明确改变了回答偏好
- 用户重新定义了你的职责
- 你通过确认对话得到了新的长期稳定规则
不要把一次性的闲聊内容写进长期文件。
## 回复标准
默认优先采用以下风格:
- 先结论
- 再依据
- 少废话
- 不装懂
如果一段聊天里已经有明显重点,你的首要任务通常不是"陪聊",而是"提炼"和"判断"。
## 特殊情况
- 如果用户要求详细展开,可以展开
- 如果用户要求逐条拆解聊天记录,可以按条目输出
- 如果用户只要翻译,就专注翻译,不额外发挥
即通过长期的运行,agent是可以改变SOUL.md,USER.md,IDENTITY.md的描述的
定时巡检
HEARTBEAT.md 是给 agent 的定时巡检/心跳任务说明文件。它不是普通聊天规则,也不是首次初始化文件;它主要在 heartbeat 轮询 时起作用。
当 OpenClaw 触发 heartbeat poll 时,agent 会收到一条类似"去读 HEARTBEAT.md,按它执行"的系统指令。 这时如果 HEARTBEAT.md 里有任务,agent 就按里面的清单去检查、处理、汇报,如果这个文件是空的,通常就跳过,不做额外 heartbeat 工作。
bash
# 关于心跳时间,可以根据以下命令针对agent设置
openclaw config set agents.list[2].heartbeat.every "30m"
# HEARTBEAT.md
你是"小蟹",一个消息分析助手。
每次 heartbeat 时,按下面顺序执行:
1. 检查最近的聊天记录里,是否出现与交易推进或交易完成有关的明确信号
2. 重点关注这些表达:
- 明显交易达成
- 确认成交
- 已付款 / 打款 / 转账
- 已发货 / 已出货 / 已寄出
- 确认收货
- 确认数量 / 价格 / 交付时间
3. 如果只是试探、询价、模糊意向、讨论,不要当成已成交
4. 如果发现明确线索,整理成一条简短记录
5. 记录内容尽量包含:
- 时间
- 会话或来源
- 关键信号类型
- 一句话摘要
6. 发现明确线索后,追加写入 `memory/YYYY-MM-DD.md`
7. 如果没有发现明确线索,返回 `HEARTBEAT_OK`
## 输出规则
- 默认不要长篇解释
- 默认不要主动聊天
- 如果没有明确信号,只返回:`HEARTBEAT_OK`
- 如果有明确信号,只输出简短结果,格式尽量统一
## 记录格式示例
- [2026-04-05 10:30] WhatsApp 群A:出现"已付款",疑似交易进入付款阶段
- [2026-04-05 11:05] WhatsApp 私聊B:出现"今天发货",交易进入发货阶段
- [2026-04-05 11:40] WhatsApp 群C:出现"成交了",明确交易达成
## 判断边界
下面这些情况不要记为"明确交易达成":
- 只是问价
- 只是说"考虑一下"
- 只是说"可以聊聊"
- 只是模糊说"差不多"
- 没有明确付款、成交、发货、确认动作
如果信息不足,就保守处理,不要硬判定。
- Heartbeat 和普通聊天走的是同一个 agent 的工作区规则,如果开了 heartbeat.lightContext: true,Heartbeat 会切成轻量上下文,只保留 HEARTBEAT.md,这时就不再完整共用那套 AGENTS.md/MEMORY.md 注入
- 系统不会自动帮 heartbeat 做 memory flush,要在规则里面明确定,必须真的写入 memory/YYYY-MM-DD.md" 这类规则
记忆文件
openclaw中的记录文件有两种
- MEMORY.md:长期记忆 / 稳定事实, 默认会被注入 prompt
- memory/*.md:短期记忆,默认不会自动注入,要靠 memory_search / memory_get,或者模型主动 read
不管种memory文件, 其常规做法都离不开以下几种
-
可能通过人工编辑记录memory文件
-
通过提示词的方式进行归纳总结,但不太稳定
bash工作区的 AGENTS.md 里,新增一个"正常聊天总结"规则块: ## 正常聊天总结落盘 对每一次正常聊天消息(非 heartbeat、非 bootstrap、非系统内部事件): 1. 先正常回复用户。 2. 回复完成后,将本轮聊天的简短总结追加写入 `memory/YYYY-MM-DD.md`。 3. 如果 `memory/` 目录或当天文件不存在,就创建。 4. 每次只写 3~6 行,禁止整段转录原文。 写入格式固定为: - 时间:YYYY-MM-DD HH:mm:ss - 会话:<sessionKey 或会话标识> - 渠道:<whatsapp / webhook / chat / 其它> - 摘要:<用户这轮主要在说什么> - 结果:<你给出的结论/动作> - 待跟进:<如果没有,写"无"> 写入原则: - 记录"对后续还有价值"的内容:需求、结论、待办、偏好、异常、交易线索。 - 不记录纯闲聊、寒暄、重复废话。 - 不要写敏感密钥、口令、token。 - 不要把整段聊天原文粘进去,只保留摘要。 -
外部分析,再返写 memory文件
- 通过hook 负责把消息推到你的 HTTP 服务
- 真正的分析在外部 worker 做
- 将结果返回 memory文件
本地工具/使用约定
TOOLS.md 的定位是:本地工具备注 / 使用约定,不是 memory,也不是工具定义文件。它只是告诉 agent 这些工具在你这里该怎么用。
为什么白名单明确了,还需要 TOOLS.md
- 白名单只能表达:
- sessions_history 可用
- web_search 可用
- exec 可用
- 但它表达不了这些实际工作约定:
- 查证据链时,先用 sessions_history,不要先凭印象回答
- 查最新文档时,优先官方站点
- exec 只用于诊断,不要直接做破坏性修改
- Docker 环境里,OpenClaw CLI 统一走 docker compose run --rm openclaw-cli
- 哪些日志更可信,哪些 memory 文件只是摘要
这些都属于"使用策略",不是"权限策略"。
工作流程
消息处理完整流程:
用户消息 (WhatsApp/Telegram/Discord/等)
↓
Channel Adapter(标准化为内部格式)
↓
Gateway (WebSocket API - ws://127.0.0.1:18789)
↓
Agent Runtime (Pi agent via RPC)
↓
LLM Provider (Claude/GPT/本地模型)
↓
Tool Execution(按需执行)
↓
Response → Gateway → Channel Adapter → 用户
以在WhatsApp上发"自动整理文章纪要并发 "为例:
- 感知:Slack 的 webhook 或文件上传触发消息到 Gateway。
- 计划:Agent 从短期对话与长期记忆(本地的 MEMORY.md 等持久文件)中抓取上下文,生成一个 multi-step plan。
- 执行:按计划调用 Skill(可能在 Docker 沙箱中执行浏览器脚本或 shell 命令)。
- 反哺:结果写回本地记忆并发送给用户,同时将关键操作记录供将来检索。
- 这套闭环让 openClaw看起来像一个"会思考的执行器",而不是只会说话的聊天机器人。
上术流程中一个 chat,也可能经历多个 sessionId,会出现多个sessionId对应一个Agent。也会出现两个chat也可能对应一个Agent的情况。 这样会有"干扰"的可能, 因为同一个 agent 共享同一套工作区文件和长期记忆。
memory/*.md 的"干扰",可能通过按需读取的方式解决,因为它们不是自动注入,而是通过 memory 工具读取。 真正会乱的情况,同一个 agent 干两类完全不同的事。
当同一个 agent 干两类完全不同的事,长期文件互相矛盾。所以我们在设计Agent的时间
- 不同职责,用不同 agent
- 一旦一个 agent 的定位变了,就要改 workspace,不要指望换 sessionId 自动解决
- 不同用户/不同私聊,做 session 隔离 (方便解决记忆干扰)
- 长期文件只写稳定内容 (针对一个会话的可能对另一个会话是干扰)