1. 项目概述
作为一名长期使用OpenClaw的开发者,我发现了一个亟待解决的痛点:这个强大的AI工具每次对话都像一张白纸,完全不会"记住"之前的经验。想象一下,你花了半小时解决了一个复杂的技术问题,下次遇到类似情况时,OpenClaw却又要从头开始摸索——这种重复劳动实在太低效了。
相比之下,像Hermes Agent这样的工具已经能够从经验中自动创建技能(skills)。这让我开始思考:能否让OpenClaw也具备类似的自我改进能力?经过一段时间的探索和实践,我开发出了一套简单但有效的解决方案。这不是什么高深莫测的黑科技,而是一个实实在在的工程实现,完全基于OpenClaw现有的架构进行扩展。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 需求分析与设计思路
2.1 核心痛点解析
OpenClaw的"健忘症"主要体现在四个方面:
- 复杂任务重复劳动:比如创建飞书多维表格、批量写入数据、设置视图这一套操作,每次都要重新走一遍流程
- 错误经验无法沉淀:某些API需要先创建字段才能写入数据,这种"先决条件"每次都要重新摸索
- 用户纠正未被利用:当用户指出"不是这样,应该是..."时,这些宝贵反馈没有被系统吸收
- 高频操作未优化:同一个操作反复出现3次以上,却没有被固化为标准流程
2.2 技术方案选型
在解决思路上,我评估了两种主要方案:
方案一:定时轮询(Cron)
- 优点:实现简单,资源消耗低
- 缺点:实时性差,无法感知正在发生的事件
- 适用场景:对实时性要求不高的批量处理
方案二:持续运行的Daemon
- 优点:实时响应,即时处理
- 缺点:进程管理复杂,资源占用高
- 适用场景:需要即时反馈的关键业务
经过权衡,我选择了混合方案:使用Daemon作为后台服务,但采用30秒轮询机制。这样既保证了较好的实时性(最大30秒延迟),又避免了持续监控的资源消耗。这种设计在工程实践中很常见,比如很多日志监控系统就采用类似的策略。
提示:在选择轮询间隔时,需要平衡实时性和系统负载。经过测试,30秒对于大多数使用场景已经足够,同时不会给系统带来明显负担。
3. 系统架构设计
3.1 整体架构
系统由三个核心组件构成:
- OpenClaw主Session:用户交互入口,负责记录会话日志
- Learning-Daemon:Node.js后台进程,负责经验提取和技能生成
- Skills存储目录:存放自动生成的技能文件
code复制┌─────────────────────────────────────────────────────┐
│ OpenClaw 主 Session │
│ (用户交互入口) │
└─────────────────────┬───────────────────────────────┘
│ 工具调用写入 session JSONL
▼
┌─────────────────────────────────────────────────────┐
│ learning-daemon (Node.js 后台进程) │
│ • 每 30 秒轮询最新 session JSONL │
│ • 检测触发条件 │
│ • 生成标准 SKILL.md │
└─────────────────────┬───────────────────────────────┘
│ 写入
▼
┌─────────────────────────────────────────────────────┐
│ ~/.openclaw/workspace/skills/auto-generated/ │
│ (自动生成的 skills 存放目录) │
└─────────────────────────────────────────────────────┘
3.2 关键设计决策
3.2.1 基于文件系统的状态管理
OpenClaw本身是Stateless的,但它会将每次会话记录到JSONL文件中。这个设计非常巧妙:
- JSONL文件是append-only的,即使session还在进行中也可以读取
- 文件系统作为持久化存储,比内存更可靠
- 不需要修改OpenClaw核心架构,扩展性强
3.2.2 智能触发机制
不是所有会话都值得记住,我定义了四类触发条件:
| 触发类型 | 检测标准 | 处理方式 |
|---|---|---|
| 复杂任务 | ≥5次工具调用 | 提取完整工作流 |
| 错误恢复 | 检测到error后成功 | 记录错误处理经验 |
| 用户纠正 | 包含"不是"、"不对"等关键词 | 提取正确做法 |
| 重复操作 | ≥3次相同工具调用 | 生成快捷技能 |
3.2.3 被动学习与主动获取结合
- 被动学习:Daemon从实际操作中提取经验,沉淀为技能
- 主动获取:通过ClawHub/agentskills.io获取外部技能
- 两者结合形成完整的能力成长闭环
4. 核心实现细节
4.1 Daemon主循环实现
Daemon的核心是一个简单的轮询循环:
javascript复制async function main() {
// 初始化:记录所有现有文件位置
const files = fs.readdirSync(SESSIONS_DIR)
.filter(f => f.endsWith('.jsonl'));
for (const file of files) {
filePositions.set(file, fs.statSync(file).size);
}
while (true) {
const activeSession = getActiveSession();
if (activeSession) {
await analyzeSession(activeSession);
}
await new Promise(r => setTimeout(r, POLL_INTERVAL));
}
}
这个实现有几个关键点:
- 启动时记录已有文件的位置,避免重复处理历史数据
- 使用异步循环,避免阻塞
- 每次轮询间隔30秒(POLL_INTERVAL)
- 只处理活跃session,减少不必要的计算
4.2 复杂任务检测算法
检测复杂任务的逻辑如下:
javascript复制function detectComplexTask(messages) {
let toolCalls = 0;
for (const msg of messages.slice(-RECENT_WINDOW)) {
if (msg.role === 'assistant' && Array.isArray(msg.content)) {
for (const block of msg.content) {
if (block.type === 'toolCall') toolCalls++;
}
}
}
return toolCalls >= TOOL_CALL_THRESHOLD;
}
算法说明:
- 只检查最近的RECENT_WINDOW条消息(默认50)
- 只统计assistant发起的toolCall
- 当toolCall次数超过TOOL_CALL_THRESHOLD(默认5)时触发
4.3 技能文件生成
生成的SKILL.md遵循标准格式:
markdown复制---
name: "auto-[任务类型]-[日期]"
description: "自动生成的skill"
version: 1.0.0
category: auto-generated
trigger: "触发条件"
---
# 自动生成Skill
## 何时使用
## 解决什么问题
## 关键工具链
## 注意事项
文件结构设计考虑:
- 元数据区块包含必要信息,便于分类管理
- 使用Markdown格式,易读易维护
- 包含使用场景、问题描述、工具链和注意事项等完整信息
5. 部署与运维
5.1 后台运行配置
由于Daemon需要长期运行,必须正确处理进程管理:
bash复制nohup /opt/homebrew/bin/node ~/.openclaw/scripts/learning-daemon.js > /tmp/openclaw-learning-daemon.log 2>&1 &
关键参数说明:
nohup:防止进程在终端关闭时被杀死> /tmp/openclaw-learning-daemon.log:重定向输出到日志文件2>&1:将标准错误也重定向到日志&:后台运行
5.2 权限管理
OpenClaw默认对危险操作有审批机制,需要适当调整:
- 修改
exec-approvals.json配置文件 - 只放行必要的命令路径
- 遵循最小权限原则
5.3 监控与维护
建议的监控措施:
- 定期检查日志文件大小
- 设置日志轮转,避免单个文件过大
- 监控Daemon进程状态
bash复制# 检查进程状态
ps aux | grep learning-daemon
# 查看最新日志
tail /tmp/openclaw-learning-daemon.log
6. 效果评估与对比
6.1 能力对比
| 能力 | Hermes Agent | OpenClaw实现 |
|---|---|---|
| 自我改进 | 内置 | Daemon实现 |
| 技能市场 | agentskills.io | ClawHub互通 |
| 持久记忆 | 内存 + skill | 文件系统 |
| 触发延迟 | 实时 | 30秒轮询 |
6.2 性能考量
虽然OpenClaw的实现有30秒延迟,但具有以下优势:
- 架构稳定性:不修改核心代码,风险可控
- 扩展性强:可以随时调整轮询间隔
- 资源友好:不会持续占用大量CPU
在实际使用中,30秒延迟对大多数场景影响不大,因为:
- 复杂任务通常需要更长时间完成
- 错误恢复和经验沉淀不需要实时处理
- 高频操作的识别也不需要即时响应
7. 实践经验与优化建议
7.1 踩坑记录
问题一:exec审批弹窗
- 现象:Daemon执行命令时被拦截
- 解决:在
exec-approvals.json中配置白名单 - 建议:只放行必要路径,定期审查
问题二:进程意外终止
- 现象:终端关闭后Daemon退出
- 解决:使用nohup和&组合
- 建议:添加进程监控和自动重启
问题三:日志文件膨胀
- 现象:日志文件快速增长
- 解决:配置logrotate轮转
- 建议:设置合理的日志级别
7.2 优化方向
-
动态轮询间隔:
- 空闲时延长间隔(如60秒)
- 检测到活跃session时缩短间隔(如10秒)
-
技能去重:
- 计算技能相似度
- 合并重复或相似的技能
-
优先级队列:
- 为不同类型的技能设置优先级
- 重要技能优先处理
-
技能验证机制:
- 自动测试生成的技能
- 收集使用反馈持续优化
8. 设计哲学与思考
这个项目的核心价值不在于技术复杂度,而在于工程思维的应用。它体现了几个重要的设计原则:
- 增量改进:在现有架构上扩展,而非推倒重来
- 务实主义:接受30秒延迟的trade-off,换取稳定性
- 可观测性:完善的日志和监控机制
- 渐进式优化:先实现核心功能,再逐步完善
AI的"自我改进"不一定要依赖复杂的算法,有时简单的工程方案就能解决实际问题。关键在于:
- 明确目标:要解决什么具体问题
- 理解约束:现有架构的限制是什么
- 找到平衡:在理想方案和可行方案之间折衷
这套机制虽然简单,但已经显著提升了我的工作效率。现在OpenClaw能够记住常见问题的解决方案,重复性工作减少了至少30%。更重要的是,这个方案证明了:通过合理的工程设计和适度的妥协,我们可以在不改变核心架构的情况下,为AI工具添加有价值的新能力。
