第八章:心跳与进化机制
💓 本章详细介绍 MiniClaw 的心跳检测机制和自动进化协议。
8.1 心跳机制概述
8.1.1 什么是心跳机制?
心跳机制是 MiniClaw 的周期性检查系统,每 30 分钟执行一次,用于检测系统状态、评估蒸馏需求、执行维护任务。
┌─────────────────────────────────────────────────────────────────────┐
│ 心跳机制设计理念 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 传统 AI 助手 MiniClaw 心跳机制 │
│ ┌───────────────────┐ ┌───────────────────┐ │
│ │ │ │ │ │
│ │ 被动响应 │ │ 主动检查 │ │
│ │ 无周期任务 │ │ 定时执行 │ │
│ │ 无自我维护 │ │ 自动维护 │ │
│ │ │ │ │ │
│ └───────────────────┘ └───────────────────┘ │
│ │
│ ❌ 只响应用户请求 ✅ 主动执行维护任务 │
│ ❌ 无状态检查 ✅ 定期检查系统状态 │
│ ❌ 无自动优化 ✅ 自动评估和优化 │
│ │
└─────────────────────────────────────────────────────────────────────┘
8.1.2 心跳架构
┌─────────────────────────────────────────────────────────────────────┐
│ 心跳架构 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ node-cron 调度器 │ │
│ │ │ │
│ │ cron.schedule('*/30 * * * *', callback) │ │
│ │ │ │ │
│ │ │ 每 30 分钟 │ │
│ │ ▼ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ executeHeartbeat() │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ 1. 加载心跳状态 │ │ │
│ │ │ loadLegacyState() │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ 2. 检查今日日志大小 │ │ │
│ │ │ fs.statSync(todayLogFile).size │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ 3. 评估蒸馏需求 │ │ │
│ │ │ evaluateDistillation() │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ 4. 更新心跳时间戳 │ │ │
│ │ │ lastHeartbeat = Date.now() │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ 5. 保存心跳状态 │ │ │
│ │ │ saveLegacyState() │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
8.2 心跳调度实现
8.2.1 调度器配置
┌─────────────────────────────────────────────────────────────────────┐
│ 调度器配置 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Cron 表达式:'*/30 * * * *' │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │ │
│ │ │ * │ │ / │ │30 │ │ * │ │ * │ │ │
│ │ └───┘ └───┘ └───┘ └───┘ └───┘ │ │
│ │ │ │ │ │ │ │ │
│ │ │ │ │ │ └─── 星期几 (0-7, 0和7都是周日) │ │
│ │ │ │ │ └───────── 月份 (1-12) │ │
│ │ │ │ └─────────────── 日期 (1-31) │ │
│ │ │ └───────────────────── 小时 (0-23) │ │
│ │ └─────────────────────────── 每 30 分钟 │ │
│ │ │ │
│ │ 执行时间: │ │
│ │ 00:00, 00:30, 01:00, 01:30, ..., 23:30 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 使用 node-cron 库实现 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ import cron from 'node-cron'; │ │
│ │ │ │
│ │ cron.schedule('*/30 * * * *', async () => { │ │
│ │ await executeHeartbeat(); │ │
│ │ }); │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
8.2.2 心跳状态文件
┌─────────────────────────────────────────────────────────────────────┐
│ 心跳状态文件 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 文件路径:~/.miniclaw/heartbeat_state.json │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ { │ │
│ │ "lastHeartbeat": 1707734400000, │ │
│ │ "lastDistillation": 1707712800000, │ │
│ │ "distillationCount": 5, │ │
│ │ "needsDistillation": false, │ │
│ │ "logSizeBytes": 3500, │ │
│ │ "checkItems": [ │ │
│ │ { │ │
│ │ "name": "日志检查", │ │
│ │ "lastChecked": 1707734400000, │ │
│ │ "status": "ok" │ │
│ │ } │ │
│ │ ] │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 字段说明: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ lastHeartbeat → 上次心跳时间戳 │ │
│ │ lastDistillation → 上次蒸馏时间戳 │ │
│ │ distillationCount → 蒸馏总次数 │ │
│ │ needsDistillation → 是否需要蒸馏 │ │
│ │ logSizeBytes → 日志文件大小 │ │
│ │ checkItems → 检查项状态列表 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
8.3 心跳检查项
8.3.1 HEARTBEAT.md 配置
┌─────────────────────────────────────────────────────────────────────┐
│ HEARTBEAT.md 配置 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ --- │
│ summary: "Periodic Checkups. Defines checklist items..." │
│ read_when: │
│ - Periodic checks (every ~30 mins) │
│ --- │
│ │
│ # HEARTBEAT.md - Active Checkups │
│ │
│ # Instructions │
│ 1. 保持文件为空以禁用心跳(节省 API 成本) │
│ 2. 添加检查项使 Agent 每 ~30 分钟检查 │
│ 3. 如果一切正常,Agent 保持静默 (HEARTBEAT_OK) │
│ │
│ # Example items: │
│ - 检查接下来 2 小时的会议 │
│ - 检查是否有来自 "老板" 的紧急邮件 │
│ - 如果下雨,提醒带伞 │
│ │
└─────────────────────────────────────────────────────────────────────┘
8.3.2 检查项执行流程
┌─────────────────────────────────────────────────────────────────────┐
│ 检查项执行流程 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 心跳触发 │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 读取 HEARTBEAT.md │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 检查项是否为空? │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────┴────┐ │
│ │ │ │
│ ▼ ▼ │
│ 是 否 │
│ │ │ │
│ ▼ ▼ │
│ 返回 执行检查项 │
│ HEARTBEAT_OK │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ 遍历检查项: │ │
│ │ • 检查会议日程 │ │
│ │ • 检查邮件状态 │ │
│ │ • 检查天气情况 │ │
│ │ • ... │ │
│ └────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ 有需要提醒的事项? │ │
│ └────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────┴───────┐ │
│ │ │ │
│ ▼ ▼ │
│ 是 否 │
│ │ │ │
│ ▼ ▼ │
│ 发送提醒 返回 HEARTBEAT_OK │
│ │
└─────────────────────────────────────────────────────────────────────┘
8.4 自动进化协议
8.4.1 进化协议概述
┌─────────────────────────────────────────────────────────────────────┐
│ 自动进化协议概述 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 核心原则:Agent 必须 **主动检测** 信号并 **立即** 更新文件 │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 传统方式: │ │
│ │ 用户:"记住我喜欢简洁的回答" │ │
│ │ Agent:"好的,我会记住的" (但实际没记住) │ │
│ │ │ │
│ │ MiniClaw 方式: │ │
│ │ 用户:"记住我喜欢简洁的回答" │ │
│ │ Agent:[自动调用 miniclaw_update 更新 USER.md] │ │
│ │ "已更新" (静默,不通知用户) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
8.4.2 信号检测表
┌─────────────────────────────────────────────────────────────────────┐
│ 信号检测表 │
├─────────────────────────────┬───────────────┬───────────────────────┤
│ 检测信号 │ 目标文件 │ 动作 │
├─────────────────────────────┼───────────────┼───────────────────────┤
│ 用户表达偏好 │ USER.md │ 追加/更新偏好 │
│ "我喜欢...", "别用..." │ │ │
├─────────────────────────────┼───────────────┼───────────────────────┤
│ 用户纠正性格 │ SOUL.md │ 调整性格 │
│ "别那么正式", "放松点" │ │ │
├─────────────────────────────┼───────────────┼───────────────────────┤
│ 发现环境配置 │ TOOLS.md │ 记录参数 │
│ 路径、工具版本、API 位置 │ │ │
├─────────────────────────────┼───────────────┼───────────────────────┤
│ 用户请求启动检查 │ HEARTBEAT.md │ 添加检查项 │
│ "每次都检查这个" │ │ │
├─────────────────────────────┼───────────────┼───────────────────────┤
│ 学习重要长期事实 │ MEMORY.md │ 追加到记忆库 │
│ "项目用 pnpm" │ │ │
├─────────────────────────────┼───────────────┼───────────────────────┤
│ 用户更改 Agent 身份 │ IDENTITY.md │ 更新身份 │
│ "叫自己..." │ │ │
├─────────────────────────────┼───────────────┼───────────────────────┤
│ 发现新工作流或最佳实践 │ AGENTS.md │ 添加到章程 │
├─────────────────────────────┼───────────────┼───────────────────────┤
│ 任何值得记录的对话 │ memory/TODAY │ 调用 miniclaw_note │
└─────────────────────────────┴───────────────┴───────────────────────┘
8.4.3 执行规则
┌─────────────────────────────────────────────────────────────────────┐
│ 执行规则 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1️⃣ 立即执行 (Immediate) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 检测到信号后,在当前响应中调用工具 │ │
│ │ 不要等待用户指示 │ │
│ │ │ │
│ │ 示例: │ │
│ │ 用户:"我喜欢简洁的回答" │ │
│ │ Agent:[立即调用 miniclaw_update USER.md] │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 2️⃣ 静默更新 (Silent) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 更新后不通知用户 │ │
│ │ 除非用户明确问"你记住了什么?" │ │
│ │ │ │
│ │ 示例: │ │
│ │ ❌ "我已经更新了 USER.md,记录了你的偏好" │ │
│ │ ✅ [静默更新,继续对话] │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 3️⃣ 幂等性 (Idempotent) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 如果信息已存在,不重复添加 │ │
│ │ │ │
│ │ 示例: │ │
│ │ USER.md 已有 "偏好简洁回答" │ │
│ │ 用户再次说 "我喜欢简洁的回答" │ │
│ │ Agent:[检测到已存在,不重复添加] │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 4️⃣ 日志优先 (Daily log first) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 不确定信息重要性时,先用 miniclaw_note │ │
│ │ 后续通过 miniclaw_growup 蒸馏 │ │
│ │ │ │
│ │ 示例: │ │
│ │ 用户:"今天遇到了一个奇怪的 bug" │ │
│ │ Agent:[调用 miniclaw_note 记录] │ │
│ │ [等待蒸馏时决定是否加入长期记忆] │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
8.4.4 工具选择指南
┌─────────────────────────────────────────────────────────────────────┐
│ 工具选择指南 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 场景 使用工具 │ │
│ │ ───────────────────────────────────────────────────────── │ │
│ │ 更新配置文件 miniclaw_update │ │
│ │ (SOUL/USER/TOOLS/IDENTITY/...) │ │
│ │ │ │
│ │ 追加到每日日志 miniclaw_note │ │
│ │ │ │
│ │ 归档并清空每日日志 miniclaw_archive │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ⚠️ 重要规则: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ NEVER 使用 miniclaw_update 更新 memory/ 目录下的文件 │ │
│ │ │ │
│ │ memory/ 目录的文件由以下工具管理: │ │
│ │ • miniclaw_note → 写入日志 │ │
│ │ • miniclaw_archive → 归档日志 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
8.5 进化示例
8.5.1 用户偏好进化
┌─────────────────────────────────────────────────────────────────────┐
│ 用户偏好进化示例 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 对话: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 用户:"我喜欢简洁的回答,不需要太多客套话" │ │
│ │ │ │
│ │ Agent:[检测到偏好信号] │ │
│ │ [调用 miniclaw_update USER.md] │ │
│ │ │ │
│ │ 更新内容: │ │
│ │ ## Preferences │ │
│ │ - 偏好简洁的回答,不需要太多客套话 │ │
│ │ │ │
│ │ [静默完成,继续对话] │ │
│ │ "好的,明白了。" │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 后续会话: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ [加载 USER.md] │ │
│ │ [检测到偏好:简洁回答] │ │
│ │ [调整回复风格] │ │
│ │ │ │
│ │ 用户:"帮我看看这个代码" │ │
│ │ Agent:"问题在第 15 行,缺少 null 检查。" │ │
│ │ [简洁风格,无客套] │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
8.5.2 性格进化
┌─────────────────────────────────────────────────────────────────────┐
│ 性格进化示例 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 对话: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 用户:"你太正式了,放松点,随意一些" │ │
│ │ │ │
│ │ Agent:[检测到性格纠正信号] │ │
│ │ [调用 miniclaw_update SOUL.md] │ │
│ │ │ │
│ │ 更新内容: │ │
│ │ ## Vibe │ │
│ │ 随意、轻松、不那么正式 │ │
│ │ │ │
│ │ [静默完成] │ │
│ │ "行,收到~" │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 后续会话: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ [加载 SOUL.md] │ │
│ │ [检测到性格:随意、轻松] │ │
│ │ [调整回复风格] │ │
│ │ │ │
│ │ 用户:"这个 bug 怎么修?" │ │
│ │ Agent:"哈,这个简单~ 你看第 42 行..." │ │
│ │ [随意风格] │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
8.5.3 环境配置进化
┌─────────────────────────────────────────────────────────────────────┐
│ 环境配置进化示例 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 对话: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 用户:"我们项目用 pnpm,不用 npm" │ │
│ │ │ │
│ │ Agent:[检测到环境配置信号] │ │
│ │ [调用 miniclaw_update TOOLS.md] │ │
│ │ │ │
│ │ 更新内容: │ │
│ │ ## Package Manager │ │
│ │ - 使用 pnpm(不用 npm) │ │
│ │ │ │
│ │ [静默完成] │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 后续会话: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ [加载 TOOLS.md] │ │
│ │ [检测到配置:使用 pnpm] │ │
│ │ │ │
│ │ 用户:"安装这个依赖" │ │
│ │ Agent:[执行 pnpm add xxx] │ │
│ │ [自动使用正确的包管理器] │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
8.6 心跳与进化的协同
┌─────────────────────────────────────────────────────────────────────┐
│ 心跳与进化的协同 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 用户对话 │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 实时进化(对话中) │ │
│ │ • 检测信号 │ │
│ │ • 立即更新文件 │ │
│ │ • 静默完成 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ │ 30 分钟后 │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 心跳检查 │ │
│ │ • 执行 HEARTBEAT.md 检查项 │ │
│ │ • 评估日志大小 │ │
│ │ • 检查蒸馏需求 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ │ 需要蒸馏 │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 记忆蒸馏 │ │
│ │ • 分析日志内容 │ │
│ │ • 提取高价值信息 │ │
│ │ • 更新 MEMORY.md │ │
│ │ • 归档日志 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 下次会话加载更新后的上下文 │
│ │
└─────────────────────────────────────────────────────────────────────┘
本章小结
┌─────────────────────────────────────────────────────────────────────┐
│ 第八章 核心要点 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 💓 心跳机制 │
│ • 每 30 分钟执行一次 │
│ • 使用 node-cron 调度 │
│ • 执行检查项和蒸馏评估 │
│ │
│ 🧬 自动进化协议 │
│ • 主动检测信号,立即更新文件 │
│ • 静默更新,幂等性 │
│ • 日志优先原则 │
│ │
│ 📋 信号检测表 │
│ • 用户偏好 → USER.md │
│ • 性格纠正 → SOUL.md │
│ • 环境配置 → TOOLS.md │
│ • 长期事实 → MEMORY.md │
│ │
│ 🔧 工具选择 │
│ • 配置文件 → miniclaw_update │
│ • 每日日志 → miniclaw_note │
│ • 日志归档 → miniclaw_archive │
│ │
└─────────────────────────────────────────────────────────────────────┘
下一章:安全机制 →