- 人工智能
- RAG
- Agent 记忆
- MCP 服务
- 知识管理
【免费下载链接】gbrain
Garry's Opinionated OpenClaw/Hermes Agent Brain
导读:gbrain(Garry's Opinionated OpenClaw/Hermes Agent Brain)把个人/团队知识库变成了会自我维护的系统——而让"自我维护"真正运转起来的,是一整套 20+ 项常驻定时任务编排。本篇以 docs/guides/cron-schedule.md 为核心骨架,完整还原参考调度表、cron 落地命令、强制安静时段门控与跨时区处理,并深入到
gbrain dream夜间循环的三级裁剪级联(triage cascade)、oneshot 合成模式与排水池并发模型,结合 triage-rescue.ts、synthesize.ts 等源码验证每一项配置旋钮的真实默认值与行为。读完你将能照抄出一套可上生产、可验证、不打扰用户的定时大脑维护方案。
为什么要有一张调度表:大脑的"复利"从定时开始
原文档开篇就点明了这组任务的意义:一个生产级大脑运行着 20+ 项周期任务,让知识库保持鲜活、持续累积(compounding)。如果不做这件事,大脑只会在你手动摄入数据时才更新——页面过期、实体信息单薄、引用断裂、Agent 基于旧上下文作答。
而配好之后,效果是闭环的:
- 邮件、社交媒体、日历、会议自动流入大脑;
- 单薄页面在夜间被自动充实;
- 断裂的引用被自动修复;
- 你醒来时,大脑比入睡时更聪明。
这正是 docs/guides/cron-schedule.md 想要传递的核心思想:调度不是运维杂活,而是大脑的"存活机制"。文章末尾的 Tricky Spots 第一条把它讲得很重:"dream cycle 不是可选的——没有它,信号从每一次对话中泄漏出去;有了它,什么都不丢。这是一个会遗忘的 Agent 和一个会记住的 Agent 之间的区别。"
参考调度总表
以下是原文档给出的生产环境参考调度表(每个任务的 Brain Interaction 描述了它如何作用于大脑,Recipe 列指向仓库中的配套食谱):
| 频率 | 任务 | 与大脑的交互 | 食谱 |
|---|---|---|---|
| 每 30 分钟 | 邮件监控 | 搜索发件人、更新人物页 | email-to-brain |
| 每 30 分钟 | X/Twitter 采集 | 创建/更新媒体页、实体抽取 | x-to-brain |
| 工作日 3 次/天 | 会议同步 | 完整摄入 + 参会人传播 | meeting-sync |
| 每周 | 日历同步 | 每日文件 + 参会人丰富 | calendar-to-brain |
| 每日上午 | 晨间简报 | 检索日历参会人、交易状态、活跃线程 | briefing skill |
| 每周 | 大脑维护 | gbrain doctor、embed stale、孤儿页检测 | maintain skill |
| 夜间 | Dream Cycle | 实体清扫、丰富薄弱点、修复引用 | 见下文 |
值得注意的原文档观点:"20+ 个任务听起来很多,但别过度 cron"(详见 Tricky Spots 第 3 条)。起步只需三件事:邮件(30 分钟)、dream cycle(夜间)、大脑健康检查(每周),然后随集成食谱逐个增加。
优先使用 gbrain 原生的调度面
系统 cron 是最低公分母,但 gbrain 自带多个调度面,原文档明确要求"能匹配就先用手边的":
gbrain dream—— 官方夜间维护循环(lint、backlinks、extract、sync、embed、synthesize)。直接调度它,而不是下面手工搓 dream cycle 脚本。gbrain jobs/ minions—— 带重试、退避和审计轨迹的任务队列,可提交 shell 任务或 LLM 子代理。详见 minion-orchestrator skill:它区分确定性 shell 任务(gbrain jobs submit shell ...)与 LLM 子代理任务(gbrain agent run ...),并给出"超过 ~2 分钟的操作必须走持久执行阶梯(durable-execution ladder)+ deadman 检查"的路线约定。gbrain autopilot—— 常驻后台守护进程,按自身节奏运行循环(sync、extract、embed、backlinks、durible job 处理都在其中,见 maintain skill 的 Autopilot check 小节)。cron-schedulerskill(skills/cron-scheduler/SKILL.md)—— 教 Agent 管理其宿主的调度器,契约包含:调度错峰(每 5 分钟槽位最多 1 个任务、无冲突)、时区感知的安静时段门控(带 user-awake 覆盖)、薄任务提示("读 skills/X/SKILL.md 并运行",禁止内联 3000 字长提示)、幂等性、结果落盘为报告(reports/{job-name}/{YYYY-MM-DD-HHMM}.md)。- Bootstrap 会话触发的调度——
gbrain bootstrap安装由 HEARTBEAT.md 驱动的、随会话活动触发的调度,见 bootstrap.md。
对于"仅调度sync+embed --stale"这一具体场景,主文档是 live-sync.md。
cron-schedulerskill 还给出一个重要的多源大脑经验:当gbrain sources list显示 2+ 个活跃源时,用一条合并 cron 行替代 N 条按源条目——
*/5 * * * * gbrain sync --all --parallel 4 --workers 4 --skip-failed并发预算大约是parallel × workers × 2 ≈ 32个连接(每个按文件 worker 各自开一个 2 连接池),要保持在 Postgresmax_connections之下。gbrain doctor在检测到 2+ 个活跃源时会以sync_consolidation检查的形式直接给出这条推荐行。反模式则包括:所有任务挤在同一分钟(:00)、在 cron 里内联超长提示词、未先在 3–5 个条目上测试就跑全量、任务重跑产生不同输出(非幂等)、安静时段发通知、以及给每个源单独写gbrain sync --source <id>条目。
实现:在系统 cron 中落地
原文档给出了一套可直接照抄的 crontab 实现(注意cd到各采集器目录、重定向日志、用&&串联、用--json便于脚本解析):
# Email collector — 每 30 分钟 */30 * * * * cd /path/to/email-collector && node email-collector.mjs collect && node email-collector.mjs digest # X/Twitter collector — 每 30 分钟 */30 * * * * cd /path/to/x-collector && node x-collector.mjs collect >> /tmp/x-collector.log 2>&1 # Meeting sync — 工作日 10 点、16 点、21 点 0 10,16,21 * * 1-5 cd /path/to/meeting-sync && node meeting-sync.mjs >> /tmp/meeting-sync.log 2>&1 # Calendar sync — 周日 10 点 0 10 * * 0 cd /path/to/calendar-sync && node calendar-sync.mjs --start $(date -v-7d +%Y-%m-%d) --end $(date +%Y-%m-%d) # Brain health — 每周一早上 6 点 0 6 * * 1 gbrain doctor --json >> /tmp/gbrain-health.log 2>&1 && gbrain embed --stale # Autopilot health gate — 每天 7 点。退出码就是信号: # 0 = 新鲜(或未安装),1 = 需要关注(心跳过期、从未运行或已暂停),2 = 守护进程自行退出轮换。 # 状态只读文件系统,因此即使数据库宕机也能工作。 0 7 * * * gbrain autopilot --status >> /tmp/gbrain-autopilot-health.log 2>&1 || your-notify "gbrain autopilot needs attention" # Dream cycle — 夜间 2 点 0 2 * * * /path/to/dream-cycle.sh逐行要点:
- 邮件采集拆两步:
collect负责抓取,digest负责生成摘要,两者都必须执行,摘要依赖采集结果; gbrain doctor --json && gbrain embed --stale用&&保证只有健康检查通过才触发嵌入回填(embed 只对缺失嵌入的 chunk 生效,是 >100 文件大同步或--no-embed运行的安全网);gbrain autopilot --status的退出码是被设计成可用于门控的:0/1/2 三态在 live-sync.md 与 maintain skill 中均有明确约定,且--status只读文件系统、不连数据库——这正是它能在数据库故障期间依旧工作的原因;--json会给出state、heartbeat_age_seconds、paused_reason、disabled_reason等完整报告。
关于gbrain sync+gbrain embed --stale这条链路的底层细节,live-sync.md 补充了很有价值的前提:gbrain 面向 SupabaseTransaction pooler(端口 6543)调优,但engine.transaction()(迁移、DDL、同步导入)会路由到派生的direct连接(db.<ref>.supabase.co:5432)。该 direct 主机是 IPv6-only 的,IPv4-only 主机不可达时会自动回退到 pooler 并打印一条 stderr 警告——但 pooler 约 2 分钟的语句超时可能截断超长迁移或批量导入。修复方式:设置GBRAIN_DIRECT_DATABASE_URL为 Session pooler 字符串,或启用 Supabase 的 IPv4 附加服务;GBRAIN_DISABLE_DIRECT_POOL=1可整体跳过 direct pool。验证方法:跑一次gbrain sync,比对gbrain stats的页面数与仓库中可同步文件数。
同步本身是提交驱动、幂等且可恢复的:它导入的是committed变更,未提交的编辑与未跟踪文件会计入 drift 并打印N uncommitted file(s) not synced,而非静默忽略;并发运行安全(同一提交两次同步因内容哈希一致而 no-op);被杀掉的同步会从数据库检查点恢复,bookmark 只在真正完成时前进。若你的工作流确实要写不提交的文件,可用gbrain sync --working-tree(单次)或gbrain config set sync.include_working_tree true(常驻配置,dream cycle 等所有调用方都遵守)——但先过一遍git status,因为 untracked 意味着git status列出的所有未忽略的临时文件和密钥都会被纳入。
安静时段门控(强制)
原文档把这一节标为MANDATORY:每个会发送通知的 cron 任务都必须先检查安静时段。门控是一个由你创建的小脚本(gbrain 不附带它),在每一个发通知的 cron 脚本顶部调用;被扣下的输出进一个 holding 目录,由晨间简报清空。不要从这里复制片段——完整门控脚本与模式以 Quiet Hours 为唯一权威主页。
quiet-hours.md 给出的核心逻辑:
QUIET_START = 23 // 当地 11 PM QUIET_END = 8 // 当地 8 AM is_quiet(local_hour): return local_hour >= QUIET_START OR local_hour < QUIET_END发送任何通知前必须:① 确定用户当前时区(来自配置或 heartbeat 状态);② 将当前 UTC 时间转成当地时间;③ 若在安静时段:扣下消息、不发送。扣下时写入 holding 目录:
if is_quiet(): mkdir -p /tmp/cron-held/ write("/tmp/cron-held/{job-name}.md", output) exit // 不发送 else: send(output)晨间简报负责拾取:
morning_briefing(): held_files = list("/tmp/cron-held/*.md") if held_files: briefing += "## Overnight Updates\n\n" for file in held_files: briefing += read(file) delete(file)可用的 shell 实现(quiet-hours-gate.sh):
#!/bin/bash # quiet-hours-gate.sh — run before any notification TIMEZONE="${USER_TIMEZONE:-US/Pacific}" LOCAL_HOUR=$(TZ="$TIMEZONE" date +%H) if [ "$LOCAL_HOUR" -ge 23 ] || [ "$LOCAL_HOUR" -lt 8 ]; then echo "QUIET_HOURS=true" exit 1 # 不发送 fi echo "QUIET_HOURS=false" exit 0 # 可以发送在 cron 脚本中使用:
# 先检查安静时段 if ! bash scripts/quiet-hours-gate.sh; then mkdir -p /tmp/cron-held echo "$OUTPUT" > /tmp/cron-held/$(basename "$0" .sh).md exit 0 fi # 非安静时段——正常发送 send_notification "$OUTPUT"关于/tmp/cron-held/的一个现实提醒(quiet-hours 文档 Tricky Spots 第 3 条):/tmp在重启后不保留(macOS 还会定期清理)。如果一条扣下的消息绝不允许跨重启丢失,改用持久目录(如~/.local/state/cron-held/)。
另外,gbrain 本身已原生理解安静时段的两处地方,应优先使用:
- 自升级:
auto模式只在安静时段应用升级,通过gbrain config set self_upgrade.quiet_hours '{"start":23,"end":8,"tz":"US/Pacific"}'配置,见 upgrades-auto-update.md; - 其余自定义 cron、采集器、通知路径,用上文 shell 模式兜底。
cron-schedulerskill 还补充了 user-awake 覆盖规则:默认安静时段为本地 11 PM–8 AM;若用户正处于活跃状态(user-awake 标志),安静时段被挂起;安静时段输出进 held 队列,晨间联系时释放积压。
旅行感知的时区处理
原文档给出了 Agent 侧推断逻辑:读取日历中的航班、酒店、出差中(out-of-office)块来推断用户当前所在地与时区,所有呈现给用户的时间都用当地时区。
// 示例:用户飞往东京 // 太平洋时间下午 2 点 = 东京凌晨 3 点 = 安静时段 // 扣下通知,并入晨间简报 get_user_timezone(): calendar = gbrain search "flight" --type calendar --recent 7d if recent_flight: return infer_timezone(flight.destination) return config.default_timezone // fallback: US/Pacific旅行时:在家乡的清醒时段会触发、但在目的地撞上睡眠时段的 cron 任务,会被扣下并并入下一个晨间简报——零配置变更。quiet-hours.md提供了与之配套的操作状态结构(userAwake、currentLocation、可选的homeLocation,garryAwake别名仅为兼容保留,生产者应写userAwake),并给出了何时应更新时区的信号:日历显示用户飞往某地、用户提到身处不同城市、或用户活跃时段偏移(凌晨 3 点 PT 还在回复 = 大概率在旅行)。
需要诚实地指出局限(quiet-hours Tricky Spots 第 4 条):基于日历的时区探测依赖用户日历中存在带位置数据的航班/酒店事件;如果用户出行不建日历条目,系统检测不到迁移。此时回退到活跃时段分析,仍不确定就问用户。
Dream Cycle:最重要的 cron 任务
原文档用一句话定义它的地位:"最重要的 cron 任务——在你睡觉时运行。"
gbrain 已内置:直接调度gbrain dream
gbrain dream把维护循环的后半段(lint、backlinks、extract、sync、embed、synthesize)合并为一条命令。每晚调度它,下面伪代码中的 Phase 4(以及 Phase 2 的大部分卫生检查)就被覆盖了。文中给出的伪代码是面向还要在其上叠加 LLM 驱动实体清扫与记忆整合的 Agent 的"宿主侧变体"。
关于日期的归属有一个容易踩的细节:夜间摘要落在你实际生活过的日历日上。循环按显式--date>cycle.timezone配置 > 宿主 IANA 时区 > UTC 的顺序分桶——因此一个在本地午夜之后运行的调度,会落在你生活过的那一天,而不是 UTC 日期。当宿主时钟区与你不同(比如云端机器在 UTC)时,固定一次即可:
gbrain config set cycle.timezone America/Los_Angeles合成成本控制:triage 级联
synthesize 阶段是一个两阶段级联:一个廉价的打分 triage(utility 层模型,每条新 transcript 一次调用)为昂贵的逐 transcript 合成子代理把关。原文档给出的旋钮(在 config.ts 的配置键清单中均有对应注册,例如dream.triage.threshold、dream.triage.rescue_floor、dream.triage.rescue_min_segments、dream.triage.rescue_content_types、dream.triage.max_chars、dream.triage.max_tokens、dream.triage.max_ms、dream.triage.concurrency、dream.synthesize.mode、dream.synthesize.link_manifest、dream.synthesize.quote_verify、dream.synthesize.inline_concurrency、dream.synthesize.max_turns、dream.synthesize.max_submissions_per_source_per_day):
dream.triage.threshold(默认 0.5)——得分门槛,是 transcript 通过闸门的两种方式中的第一种(下文 verified-segment rescue 是第二种)。得分会缓存,因此重新调参即可瞬间重新闸控,零新增 LLM 调用。太多常规内容被合成就调高;真实信号被跳过就调低。models.dream.triage——triage 模型(默认 utility 层 / Haiku 档)。dream.triage.max_chars(默认 24000,下限 1000)——发送给评审的每条 transcript 采样窗口(头/中/尾)。它不属于缓存有效性的一部分——修改后需gbrain dream retriage --force在新采样下重新评审。dream.triage.max_tokens(默认 2048,下限 256)——评审输出预算。dream.triage.concurrency(默认 4,钳制 1–16)——并发评审调用数。- Verified-segment rescue(埋没信号恢复,$0):得分落在
[dream.triage.rescue_floor, threshold)区间内的 transcript,只要满足两个条件仍可通过:评审自己引用的片段中至少dream.triage.rescue_min_segments(默认 2;设为 0 即禁用)个在 transcript 中验证为子串,且其内容类型在dream.triage.rescue_content_types(默认mixed,reflection,idea,strategy,people——绝不 rescue routine/technical)中。零额外 LLM 调用、可作用于缓存裁决;dream retriage读取同一道闸门,因此 reconcile 扫描永远不会取消被 rescue 准入的任务。遥测字段:details.triage.rescue_checked/rescue_fired。 dream.synthesize.quote_verify(默认开启)——对新建 dream 页的机械式写后引用验证/修复(被改写的"引号"会修复为逐字 transcript 片段或去掉引号;绝不发明内容)。关闭开关是事故逃生舱;遥测落在details.synthesis.quote_verify。dream.synthesize.max_turns(默认 16)——agentic 子代理与 oneshot 回退的合成回合预算(默认 oneshot 路径——见下节——是单次补全,从不消耗回合)。triage 映射把手预抽取的片段交给子代理,因此中档默认模型(models.dream.synthesize,reasoning档)+ 16 回合预算就是预期的配对——用 frontier 模型覆盖既不必要又拖慢队列。完整性来自 triage 覆盖(每个文件都被评分,减去max_ms预算下推迟的文件)加上片段引导的提示词,而不是模型大小。若写入页数偏低,可调到 30 并检查details.synthesis.avg_turns是否存在上限压力。dream.triage.max_ms(默认 5 分钟)——每周期评审新文件的墙钟预算;大的冷语料库跨几个周期完成 triage(缓存文件免费)。被推迟的文件标记为"not yet triaged",绝不静默拒绝。dream.synthesize.max_submissions_per_source_per_day(默认 0 = 关)——按源每日合成任务数的可选上限;忙碌部署用 200/天是合理值。
维护配方——修改阈值后、经历TRIAGE_VERSION提升后(当前版本按峰值而非平均打分;提升后首个周期会在max_ms预算内重新评审语料库并把其余推迟到后续周期),或要排空排队的合成积压时:
gbrain dream retriage --dry-run # 会改什么(零 LLM 调用) gbrain dream retriage --reconcile-queue # 重新评分 + 取消未通过闸门的排队任务 gbrain dream retriage --audit-rejects 20 # 用合成模型对 20 个被拒任务做二次意见源码层面的印证:synthesize.ts 头部注释完整描述了该管道——discoverTranscripts → runTriagePass(有界池,受 dream.triage.max_ms 限制)→ judgeSignificance(utility 模型,在 max_chars 内的头/中/尾采样)→ 得分 ≥ threshold 通过 / 得分在 [rescue_floor, threshold) 且内容类型在白名单且 ≥ rescue_min_segments 个片段验证为子串则 rescue 通过(F2 救援,$0,仅闸控时刻)→(读取时——重调阈值或 rescue 旋钮 = 零重新评审)。而 triage-rescue.ts 用常量给出了 rescue 的精确默认值:DEFAULT_RESCUE_FLOOR = 0.30、DEFAULT_RESCUE_MIN_SEGMENTS = 2、DEFAULT_RESCUE_CONTENT_TYPES = ['mixed','reflection','idea','strategy','people'],以及一个关键细节MIN_RESCUE_SEGMENT_NORM_CHARS = 40——"实质性"片段至少 40 个归一化字符,过短的验证引用(一个名字、一句问候)不算埋没信号的证据;applyTriageRescue对任何畸形形状(null 分数、缺失片段、非字符串引用)都失败关闭(fail-closed),绝不抛异常;passesTriageGate先做廉价的阈值判定,否则进入 rescue 区间。文档所述"双方式过闸"与"retriage 读取同一道闸门"正是由passesTriageGate这一单一入口保证的(文件注释里明确写着 one-gate rule:任何消费者都从同一入口读取,不能各自手搓score >= threshold检查)。
合成速度:oneshot 模式 + 排水池
triage 级联之上是执行旋钮:
dream.synthesize.mode(默认oneshot)——每个合成子代理如何运行。oneshot对一条已携带预检索LINK CANDIDATES清单和写入白名单的提示词做一次无工具补全,然后以编程方式校验并写入页面(slug 语法、白名单、transcript 哈希后缀、精确匹配 wikilink——任何写入前全部检查;嵌入移出模型路径,在阶段末尾由一次只覆盖本阶段写入页面的有界 pass 回填——绝不整库扫描)。响应未通过任何检查时会在同一任务内自动回退到经典 agentic 循环——无工作丢失、无需重新提交。oneshot 尝试与其回退调用都是实际付费的 provider 工作,都计入合成 token/花费遥测。典型效果:每条 transcript 的 10+ 次 provider 往返(上限默认 16 回合,调高max_turns后更多)→ 1 次。回退旋钮:gbrain config set dream.synthesize.mode agentic。dream.synthesize.link_manifest(默认开)——零嵌入的预检索清单(由 triage 裁决中缓存的实体 + 片段笔记构建)。对两种模式都有益:agentic 子代理不再把回合烧在低产搜索上;oneshot 子代理提前拿到链接目标。dream.synthesize.inline_concurrency(默认 1,钳制 1–8)——Postgres 上按运行排队的子任务队列的并发排水循环(PGLite 总是串行排水)。provider 上限仍由速率租约控制(每条路径上的每次 provider 往返都持有一个租约槽),因此这个旋钮只消除排队等待,绝不过度驱动 API。
如何读阶段报告(details.synthesis):
mode、oneshot_jobs/fallback_jobs/agentic_jobs+fallback_reasons直方图——fallback 率上升意味着模型在违反输出契约,先看首要原因再考虑回退 agentic;length包含输出用量到达请求上限的畸形响应(即使 provider 的 stop reason 不明确);queue_wait_ms_p50/p95与child_runtime_ms_p50/p95——缓慢但健康的排水可见,不会与卡死混淆;dead_jobs/degraded——任何子任务未完成的运行都不会盖章冷却(cooldown),因此下一次夜间运行会精确重试失败的 transcript;所有子任务都死亡的运行会大声宣告阶段失败。当每一次尝试的页面写入都失败时,合成子任务也会进入死信——completed从不意味着"零页面写入"。
还有三个字段回答"花了多少钱、落没落地":
spend——阶段实际花费,cost_basis: 'in+out+cache_read'。子任务从minion_jobs的 token 数按配置的合成模型计价求和;triage 来自 pass 自身的用量。total_usd只在两者都有定价时才非 null——未定价的模型读出来是 unknown 而非假0。details.triage以相同口径携带评审自己的tokens_in/tokens_out/cost_usd。children_zero_pages——完成但没写任何页面的子任务数。这个数字攀升意味着模型在产出"合法但空洞"的输出——而一片全绿的阶段状态会掩盖它。quote_verify——写后引用 pass 触碰了什么:检查/修复/剥离的片段数、作为已存在而跳过的页面数、不平衡段落数,以及仅告警的未接地数字/日期断言计数。
每次调用的花费还会以阶段标签进入chat_usage_log账本:编排器自己的调用在phase:synthesize下,每个排干的子任务在自己的job:<name>下——两者永不重复计数。
它做什么:四阶段伪代码
原文档给出了完整的 dream cycle 伪代码骨架,值得完整保留(它把"会记住的 Agent"翻译成了可执行步骤):
dream_cycle(): // Phase 1: 实体清扫 conversations = get_todays_conversations() for message in conversations: entities = detect_entities(message) for entity in entities: page = gbrain search "{entity.name}" if not page: create_page(entity) // 新实体,创建 + 丰富 elif page.is_thin(): enrich_page(entity) // 单薄页面,补全 else: update_timeline(entity) // 已有页面,追加今天的提及 // Phase 2: 修复断裂引用 pages = gbrain list --type person --limit 100 for page in pages: for entry in page.timeline: if not entry.has_source_attribution(): fix_citation(entry) // 缺失时补 [Source: ...] if entry.has_tweet_url() and not entry.url_is_valid(): fix_url(entry) // 断裂的推文链接 // Phase 3: 整合记忆 patterns = detect_patterns_across_conversations() for pattern in patterns: promote_to_memory(pattern) // 临时 → 持久知识 // Phase 4: 同步 gbrain sync --no-pull --no-embed gbrain embed --stale对照 maintain skill,gbrain dream官方管线的实际阶段顺序是lint -> backlinks -> sync -> synthesize -> extract -> patterns -> embed -> orphans(可选阶段如 atoms/concepts/drift 插在中间)。skill 补充了两个新阶段的实现细节:
- Patterns 阶段:在
extract之后运行(保证图状态新鲜)。读取dream.patterns.lookback_days(默认 30)内的近期 reflections,做一次 Sonnet pass 找出反复出现的主题,当 ≥dream.patterns.min_evidence(默认 3)篇 reflection 支撑一个主题时写入wiki/personal/patterns/<theme>。完成一次运行会记录它消费的最新 reflection(dream.patterns.last_evidence_ts);窗口内没有更新的 reflection 时,重复运行以no_new_evidence跳过而不支付另一次模型 pass——gbrain dream --phase patterns --once可强制一次。 - 冷却:
dream.synthesize.cooldown_hours(默认 12)意味着 autopilot 下每天至多约 2 次 synthesize 运行。完成时间戳dream.synthesize.last_completion_ts只在成功运行时写入(跳过/失败不写)。显式--input/--date/--from/--to调用绕过冷却。 --dry-run语义:运行打分 triage pass(评审并缓存新文件裁决)但跳过合成子代理。不是零 LLM 调用——要零调用预览请用gbrain dream retriage --dry-run。- 信任边界:合成子代理运行在显式写路径白名单(来自
_brain-filing-rules.json的dream_synthesize_paths.globs)之下;即使提示注入成功也写不出白名单。PROTECTED_JOB_NAMES使 MCP 根本无法提交子代理任务。 - 幂等与隐私:transcript 以
(file_path, content_hash)为键,同内容重跑是 no-op;dream.synthesize.exclude_patterns(默认["medical", "therapy"])在任何 LLM 调用前过滤 transcript,条目自动包裹为词边界正则(medical匹配 "medical advice" 但不匹配 "comedical")。
搭建 Dream Cycle
按宿主分类的三种搭建方式(原文档原文保留):
OpenClaw:以 DREAMS.md 作为默认 skill 随附。light / deep / REM 三个阶段在安静时段自动运行。
Hermes Agent:
/cron add "0 2 * * *" "Dream cycle: search today's sessions for entities I mentioned. For each person, company, or idea: check if a brain page exists (gbrain search), create or update it if thin. Fix any broken citations. Then consolidate: read MEMORY.md, promote important signals, remove stale entries." --name "nightly-dream-cycle"Claude Code / 自定义 Agent:创建一个脚本:
#!/bin/bash # dream-cycle.sh # 检查安静时段(应当在安静时段运行——这正是我们运行的时机) echo "Dream cycle starting at $(date)" # Phase 1: 实体清扫(派生子代理) # 读取今天的对话日志,抽取实体,更新大脑 # Phase 2: 官方维护循环(lint, backlinks, extract, sync, embed, synthesize) gbrain dream # Phase 3: 呈现循环标记的任何问题 gbrain doctor --json | jq '.checks[] | select(.status=="warn")' echo "Dream cycle complete at $(date)"晨间简报与每周维护如何纳入调度
参考调度表里的 Daily AM briefing 与 Weekly brain maintenance 分别由两个 skill 承担,它们的输入正好是前面各环节的产出:
- briefing skill 在动笔前有完整的 pre-briefing 上下文拉取:
gbrain salience --days 7(情感/活动显著性扫描)、gbrain anomalies(对 30 天基线的统计异常)、gbrain recall --query ... --json(个人事实与偏好)、gbrain recall --since-last-run --supersessions --pending --rollup --json(热记忆脉冲:隔夜解决的矛盾、top 提及、上次简报以来的新事实、待整合数),以及有 Google 源时的gbrain waiting --json(开环:谁在等你)。输出格式中每个事实都带[Source: slug, updated DATE]内联引用;简报默认只读。--since-last-run会推进~/.gbrain/recall-cursors/<source>.json游标;作为 cron 运行时务必显式传--source <slug>或设GBRAIN_SOURCE——cron 不会以仓库根目录为 cwd 启动。 - maintain skill 提供
gbrain doctor --remediation-plan --json+gbrain doctor --remediate --yes --target-score 90 --max-usd 5的自治路径(按依赖排序的修复计划,--max-usd是硬成本上限,防止合成循环在无人看管时烧掉 Anthropic 额度),以及逐维度的手动走查:stale 页、孤儿页、死链、缺失交叉引用、gbrain extract links --dir ~/brain、gbrain extract timeline --dir ~/brain、back-link 铁律、filing 违规、引用审计、标签一致性、gbrain features --json、嵌入新鲜度(大刷新用nohup gbrain embed refresh > /tmp/gbrain-embed.log 2>&1 &)、RLS/模式/文件存储健康与开放线程。健康检查输出有标准化的## Brain Health Report — YYYY-MM-DD表格结构,为大脑健康留下随时间可审计的轨迹。
容易踩的坑(Tricky Spots)
原文档总结了五点,每一条都值得在生产前逐条对照:
- Dream cycle 不是可选的。没有它,信号从每一次对话中泄漏;有了它,什么都不丢——这是"会忘记的 Agent"与"会记住的 Agent"的分水岭。
- 安静时段门控要挂在每个通知任务上。只要有一个任务跳过门控,用户就会在凌晨 3 点被 ping——一次凌晨 3 点的打扰足以让用户禁用整个系统。
- 别过度 cron。20+ 个任务听起来很多,但起步只需:邮件(30 分钟)、dream cycle(夜间)、大脑健康(每周)。随着集成食谱逐步增加。
- 时区变化是自动的。不要因为用户出行就让他重配 cron——读日历、推断时区、调整投递。
- 被扣下的消息必须被拾取。如果安静时段扣下了通知,晨间简报必须包含它——否则信息就丢了。
如何验证(How to Verify)
原文档给出的五步验收清单,是这套调度方案"可落地"的最后一块拼图:
- 安静时段:把安静时段设为当前小时。跑一个发通知的 cron。验证输出去了
/tmp/cron-held/,而不是发到消息渠道。 - Dream cycle:手动运行 dream cycle。检查单薄实体页被丰富、断裂引用被修复。
- 邮件采集 cron:等 30 分钟。检查
data/digests/里出现新的 digest。 - 晨间简报:检查被扣消息出现在简报中。
- 健康检查:运行
gbrain doctor --json。所有检查应通过。
结合 live-sync.md 还可以再加两项调度链路的专项验证:编辑一个 brain 文件、commit、push,等下一个同步周期后用gbrain search "<文本>"确认新内容出现(返回旧内容即同步失败);以及gbrain stats中页面数应等于仓库中可同步 markdown 文件数、已嵌入 chunk 数应接近总 chunk 数(大缺口说明gbrain embed --stale没跟在 sync 后面)。
本指南是 GBrain Skillpack 的一部分。延伸阅读:Quiet Hours、Live Sync、Operational Disciplines、cron-scheduler skill、minion-orchestrator skill。
- 人工智能
- RAG
- Agent 记忆
- MCP 服务
- 知识管理
【免费下载链接】gbrain
Garry's Opinionated OpenClaw/Hermes Agent Brain
相关推荐
GoFr 内置 Cron 任务调度实战:基于 using-cron-jobs 示例解析定时任务注册、调度与可观测性
GoFr 内置 Cron 任务调度实战:基于 using cron jobs 示例解析定时任务注册、调度与可观测性 导读 本篇文章以仓库中的 examples/
后端微服务云原生可观测性Spring AI MCP Server SSE 端点无响应排查指南:/sse 访问异常的快速修复路径
Spring AI MCP Server SSE 端点无响应排查指南:/sse 访问异常的快速修复路径 本文整理 Spring AI MCP Server 以
人工智能大模型AI AgentRAG后端工具调用MCP 服务MCP ClientsEnable Screenshot vs 同类工具:为什么它是最佳选择?
Enable Screenshot vs 同类工具:为什么它是最佳选择? 在数字生活中,我们经常遇到无法截图的场景——银行APP的支付界面、视频平台的版权内容、
移动开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考