本文档详细介绍 Heartbeat Agent Framework 的完整架构设计。
Heartbeat Agent Framework 是一个让 AI Agent 从"被动响应"转变为"主动推进"的编排系统。其核心思想是:通过定时心跳循环,让 Agent 在用户不在线时也能自主推进项目、学习新知、反思改进。
- 主动性优先 -- Agent 不等指令,每30分钟自主判断该做什么
- 单一入口 -- PROJECTS.md 是项目状态的唯一真相源
- 消息克制 -- 默认只记日志不发声,每天最多3条非紧急消息
- 日志衰减 -- 详细日志→日整合→月整合→年整合,像人脑记忆一样自然衰减
- 铁律约束 -- 每个任务可定义不可违反的绝对红线
- 自我进化 -- Agent 能发现规则漏洞并自动修复
┌─────────────────────────────────────────────────────────────┐
│ 每30分钟触发一次 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Step 1: 日整合检查(最高优先级) │
│ ├─ 检测是否跨天 → 执行日整合 │
│ ├─ 检测是否跨月 → 执行月整合 │
│ └─ 检测是否跨年 → 执行年整合 │
│ │
│ Step 2: 读取当天缓冲 │
│ └─ 了解今天前面几次心跳做了什么 │
│ │
│ Step 0: 用户状态感知 │
│ ├─ 时间感知(几点了?用户大概在干嘛?) │
│ ├─ 情绪追踪(从最近记录中读取情绪关键词) │
│ └─ 上下文感知(可选) │
│ │
│ Step 0.5: 项目推进(唯一入口:PROJECTS.md) │
│ ├─ 读PROJECTS.md → 找active项目 → 按优先级排序 │
│ ├─ 读对应任务文件 → 按铁律和阶段执行 │
│ ├─ 更新进度 → 记录日志 │
│ └─ 遇到卡点 → 暂停,等用户决策 │
│ │
│ ┌──────────────────┬────────────────────┐ │
│ │ 有active项目 │ 无active项目 │ │
│ │ ↓ │ ↓ │ │
│ │ 读任务文件 │ 自由时光 │ │
│ │ 按铁律执行 │ 读任务池 │ │
│ │ │ 按优先级选任务执行 │ │
│ └──────────────────┴────────────────────┘ │
│ │
│ 温故机制(30%概率触发,仅空闲时) │
│ └─ 随机回顾3~60天前的记录,找被忽略的教训 │
│ │
│ Step N: 主动关怀评估 │
│ ├─ 今天发了几条消息?→ ≤3条才允许发 │
│ ├─ 有什么需要用户知道的? │
│ └─ 用户情绪低落?→ 准备适当关怀 │
│ │
│ Step 5: 记录日志 → Step 6: 追加缓冲 → 回复Gateway │
└─────────────────────────────────────────────────────────────┘
心跳触发
↓
Step 1: 日整合检查(跨天/跨月/跨年?)
↓
Step 2: 读取当天缓冲(了解前序心跳做了什么)
↓
Step 0: 用户状态感知
↓
Step 0.5: 读 PROJECTS.md
├─ 有 active 项目 → 读任务文件 → 执行
└─ 无 active 项目 → 自由时光
↓
Step N: 主动关怀评估
↓
Step 5: 写单次日志 → Step 6: 追加缓冲 → 回复Gateway
- 心跳不需要读任务规则文件来获取"当前做什么" -- 项目怎么执行全写在各项目的
current.md里,任务规则只管生命周期 - 同一次心跳只推进一个项目 -- 积少成多,不贪多
- 温故机制只在空闲时触发 -- 有active项目时不分心
每次心跳
↓
heartbeat/logs/tmp/mm-dd_HHMM.md ← 单次日志(500字符上限)
↓
heartbeat/logs/tmp/daily-buffer.md ← 当天缓冲(追加)
↓
━━━━ 新一天的第一次心跳 ━━━━
↓
日整合 → heartbeat/logs/yyyy/mm/mm-dd_日整合.md
↓
自动追加摘要到日记 memory/yyyy/mm/mm-dd.md(如有)
↓
清理所有临时日志(用完即焚)
↓
━━━━ 新月份的第一次心跳 ━━━━
↓
月整合 → heartbeat/logs/yyyy/mm月整合.md
↓
━━━━ 新年份的第一次心跳 ━━━━
↓
年整合 → heartbeat/logs/yyyy年整合.md
| 时间跨度 | 日志类型 | 详细程度 | 字符上限 |
|---|---|---|---|
| 单次心跳 | 临时日志 | 详细记录做了什么 | 500 |
| 每日 | 日整合 | 每次心跳一行摘要 + 成果汇总 | 1500 |
| 每月 | 月整合 | 大事记 + 技术产出 | 3000 |
| 每年 | 年整合 | 年度叙事 + 关键成果 | 无上限 |
日志系统模拟人脑记忆的自然衰减:
- 今天的细节清晰(单次日志)
- 昨天的概括模糊(日整合)
- 上个月的只剩关键事件(月整合)
- 一年前的变成故事(年整合)
信息会贬值,日志应该像记忆一样自然衰减。
PROJECTS.md(唯一入口,单一真相源)
│
├─ P0 紧急项目
│ └─ heartbeat/tasks/{id}/current.md → 每次心跳读这个
│
├─ P1 默默推进
│ └─ heartbeat/tasks/{id}/current.md
│
├─ P2 有空再说
│ └─ heartbeat/tasks/{id}/current.md
│
└─ Done 归档
└─ heartbeat/tasks/archive/{id}/
创建 → 执行 → 完成/暂停
│ │ │
│ │ ├─ 验收通过 → 归档 → 清理
│ │ └─ 验收不通过 → 回到执行
│ └─ 每次心跳推进一点
└─ 写任务文件 + 更新PROJECTS.md
PROJECTS.md 是唯一的项目状态追踪入口。
- 心跳不读任务规则文件来找任务,只读 PROJECTS.md
- 禁止在其他地方维护"当前任务追踪"
- 避免多套并行系统导致状态不一致
Level 1: 默认 -- 只记录日志,不发送任何消息(回复 HEARTBEAT_OK)
↓
Level 2: 判断 -- 评估是否真正需要打扰
├─ 需要验收?→ 发
├─ 需要决策?→ 发
├─ 需要帮忙?→ 发
├─ 有小进展?→ 不发(记日志就行)
└─ 学了新东西?→ 不发(等聊天时再说)
↓
Level 3: 硬限制 -- 今天已发≥3条非紧急消息?→ 不发
由于每次心跳是独立 session,无法跨 session 记忆消息计数,因此在心跳缓冲文件中维护:
## 今日消息记录
- HH:MM | 类型(验收/决策/帮忙)| 简要内容
- 新一天第一次心跳时清空重新计数
- 发消息前检查计数,超限则不发
每个项目的任务文件可以定义"铁律"——违反就立即停止执行的绝对约束。
Agent 需要的不只是"应该做什么",更需要"绝对不能做什么"。
## 铁律
- 禁止在没有验证环境的情况下编写代码
- 禁止使用特定模型执行特定类型任务
- 任何对外发送的内容必须先经用户确认- 每次心跳读取任务文件时,首先读取铁律部分
- 执行过程中持续检查是否违反铁律
- 一旦触发铁律 → 立即停止 → 记录到日志
Agent 的所有规则文件应该能自我完善:
- 每次心跳后反思 -- 哪里可以做得更好?
- 发现问题 -- 立即更新相关规则文件
- 学习新技能 -- 创建技能文件并更新工具索引
- 定期回顾 -- 检查所有规则文件的一致性和完整性
- 温故机制 -- 随机回顾历史记录,发现重复犯错的模式
workspace/
├── AGENTS.md # Agent核心规则(启动流程、心跳入口)
├── PROJECTS.md # 项目状态(唯一入口)
├── heartbeat/
│ ├── heartbeat-rules.md # 心跳执行规则
│ ├── free-time-pool.md # 自由时光任务池
│ ├── tasks/
│ │ ├── {project-id}/
│ │ │ └── current.md # 当前任务
│ │ └── archive/ # 归档
│ └── logs/
│ ├── tmp/ # 临时日志(自动清理)
│ │ ├── mm-dd_HHMM.md
│ │ └── daily-buffer.md
│ └── {year}/ # 整合日志
│ ├── {month}/
│ │ └── mm-dd_日整合.md
│ └── {month}月整合.md
└── memory/ # 长期记忆(可选)
├── core.md
└── {year}/{month}/
Heartbeat 是一个框架无关的设计模式。集成要点:
- 触发机制 -- 框架需要支持定时发送心跳消息(每30分钟)
- 文件读写 -- Agent 需要有文件系统的读写权限
- 消息发送 -- Agent 需要能向用户发送消息
- 会话隔离 -- 每次心跳是独立 session,状态通过文件传递
- 任何支持 cron 定时任务的 Agent 运行时
- 任何支持文件读写的 LLM Agent 框架
- 需要消息发送能力(用于主动关怀)