用过 ChatGPT 的人都有过这种体验:每次打开新对话,又得从头介绍一遍”我是谁、我在做什么、我上次跟你说过什么”。对话结束,一切归零。
这不是 AI 不够聪明,而是 LLM 天生无状态——session 结束就失忆。
OpenClaw 解决的就是这个问题。它不是又一个聊天界面,而是一套让 LLM 变成持久化 Agent 的框架:有记忆、有闹钟、有手脚,关掉窗口它还在。
和OpenClaw折腾了有段时间了,打算记录一下我的个人使用心得。本文作为第一篇,重点聊两件事:怎么让它记住东西,以及怎么让它自己动起来。
1. 架构速览 🏗️
先看全貌。OpenClaw 的核心组件:
1 | Gateway(常驻进程) |
几个关键设计决策:
- 文件系统即状态。记忆就是 markdown 文件,不需要向量数据库,
cat就能看,git就能版本管理。 - Gateway 常驻。不是”用的时候启动”,而是一直在跑。这样 cron 任务和心跳才有意义。
- Skill 热插拔。新能力以 SKILL.md 的形式挂载,不改代码,重启即生效。
2. 持久化记忆:三层架构 🧠
这是我觉得 OpenClaw 最优雅的设计。记忆分三层,各司其职:
第一层:SOUL.md — 我是谁
1 | # SOUL.md |
这个文件定义 Agent 的”人格”。每次 session 启动时自动加载,所以它永远知道自己是谁。不需要你每次提醒”你是一个轻松风格的助手”。
第二层:MEMORY.md — 长期记忆
1 | # 长期记忆 |
这是你与小龙虾的每一次互动后沉淀下来的精华。不是对话记录的堆砌,而是从日常交互中提炼出来的重要信息。为了确保MEMORY.md能及时更新,我设置了一个每日反思任务,让我的龙虾在每天晚上回顾过去24小时的对话,将关键内容存入MEMORY.md。
1 | 【每日自我反思】 |
第三层:memory/YYYY-MM-DD.md — 每日日志
1 | # 2026-03-21 (周六) |
这是小龙虾的日记,记录与你交流的内容的要点总结,按天存储。只有今天和昨天的会被加载到 session context 里,不会把所有历史都塞进去。
Compaction:对话压缩机制
Session 的上下文窗口是有限的。聊久了怎么办?
OpenClaw 用了 compaction 机制。当对话超过一定长度时,系统会把前面的对话压缩成一段摘要,释放 token 空间。但压缩前会触发一个 pre-compaction flush——给 Agent 一个机会把重要信息写到文件里。
1 | 对话进行中... |
但实测下来,自动compaction可能会导致最近一两回合对话的信息丢失(可能因为这部分对话正好卡在了pre-compaction flush和compaction之间)。如果这部分对话正好包含关键信息的话,龙虾“失忆”的现象就会特别明显。
所以我在 AGENTS.md 里加了一条规则:做完就记 memory,不等 pre-compaction flush。因为 compaction 随时可能发生,重要的东西要立刻落盘。
3. 自主调度:Cron + Heartbeat ⏰
有了记忆,Agent 不会失忆了。但它还是被动的——你不说话它就歇着。
Cron:定时任务
OpenClaw 内置了 cron 系统。每个 cron 任务在独立的 session 里运行,互不干扰。
1 | # 创建一个每天 22:00 执行的反思任务 |
例如,我现在跑着这些 cron:
| 时间 | 任务 | 做什么 |
|---|---|---|
| 19:00 | learn | 从知识库学习新文章 |
| 22:00 | self-reflect | 每日反思 |
| 23:00 | ai-daily-news | 自动生成 AI 日报 |
| 23:20 | investment-analysis | 对给定标的进行分析并给出投资建议 |
Heartbeat:心跳巡查
Cron 是精确定时,Heartbeat 是模糊轮询。Gateway 每隔一段时间 ping 一下 Agent,Agent 决定要不要做点什么。
适合心跳的场景:批量检查(邮件+日历+通知一起看)、不需要精确时间的巡查、比较轻量级的任务。
适合 cron 的场景:精确时间、需要隔离的 session、需要指定不同 model 的任务。
我目前还没有找到需要Heartbeat的场景,因此我的HEARTBEAT.md 里就一行:
1 | 无需执行任何操作。 |
4. Skill:可复用的能力封装 🔧
当你发现多个 Agent 在 cron prompt 里写着差不多的逻辑时,就该封装成 Skill 了。
封装前:每个 cron 写一大段 prompt
1 | investment-learn 的 prompt(25 行): |
封装后:一个 Skill + 参数化调用
SKILL.md(定义一次):
1 |
|
cron prompt(精简到 3 行):
1 | 按 agent-learn skill 学习新内容。参数: |
Skill 的三级加载机制也值得一提:
- Metadata(name + description)— 始终在 context 里,~100 词
- SKILL.md body — 匹配到才加载,<5k 词
- references/ 和 scripts/ — 按需读取,不限大小
这保证了:装 20 个 Skill 不会撑爆 context,只有用到的才会加载。
养虾一段时间,最直观的感受是:它开始像一个”人”了。不是说它有多聪明,而是更像一个身边的伙伴——知道昨天发生了什么,记得我给过的反馈,懂得我的喜好,具有主观能动性(会自我反思和主动干活)。
当然坑也踩了不少,也没少花时间在给龙虾“治病”上。但这正是学习的过程与折腾的乐趣所在。