GBrain Compiled Truth + Timeline 模式:可搜索大脑页面的双区架构与实现原理
【免费下载链接】gbrainGarry's Opinionated OpenClaw/Hermes Agent Brain项目地址: https://gitcode.com/gh_mirrors/gb/gbrain
导读
GBrain 的每张大脑页面(brain page)都遵循"编译真理(Compiled Truth)+ 时间线(Timeline)"双区结构:哨兵线之上是随时被重写的当前综合结论,哨兵线之下是只增不改的原始证据轨迹。本文基于 docs/guides/compiled-truth.md 展开,结合仓库源码(src/core/markdown.ts、src/core/timeline-write-through.ts、src/core/timeline-extract.ts、src/core/search/hybrid.ts)剖析双区拆分、哨兵识别、时间线提取与搜索加权的底层实现。读完你将掌握如何为人物、项目、概念页维护"30 秒即可读完、每条论断都有出处、检索时最新综合结论优先浮现"的持久知识结构,并理解为什么REWRITE与APPEND是不可混淆的两个动作。
一、为什么需要"双区":从追加日志到可综合的真相
没有双区结构时,大脑页面会退化为纯追加日志:想了解一个人,你必须通读 200 条时间线条目,而答案埋在 #147 号条目里。这正是 "What the User Gets" 一节描述的问题。
引入双区后:
- Compiled Truth(编译真理):给出"当前状态"的结论性综合——30 秒可读完的评估段落。它随证据变化而重写,始终是最新理解。
- Timeline(时间线):追加式证据轨迹——每条带日期、来源的事件记录,永不修改。它是 compiled truth 中每条论断的证明。
六个月、上百条时间线条目会被压缩成一段始终"当前"的评估。docs/GBRAIN_SKILLPACK.md将此描述为 memex 愿景的落地:代理自动检测实体、丰富页面、建立交叉引用,并自动维护 compiled truth。
二、页面结构:哨兵线之上的综合与之下的证据
2.1 标准页面模板
原文档给出的完整示例结构如下(这是新建页面时应遵循的模板):
--- type: person title: Sarah Chen tags: [engineering, acme-corp] --- ## Executive Summary One paragraph. How you know them, why they matter. ## State VP Engineering at Acme Corp. Managing 45-person team. Reports to CEO. ## What They Believe Strong opinions on test coverage. "Ship it when the tests pass, not before." ## What They're Building Leading the API migration from REST to GraphQL. Target: Q3 completion. ## Assessment Sharp technical leader. Under-appreciated internally. Watch for signs of burnout. ## Trajectory Ascending. Likely CTO track if the migration succeeds. ## Relationship Met through alice-example. Had coffee 3x. Last: discussed API architecture thesis. ## Contact sarah@acmecorp.com | @sarahchen | linkedin.com/in/sarahchen <!-- timeline --> ## Timeline - **2026-04-07** | Met at team sync. Discussed API migration timeline. Seemed energized about GraphQL pivot. [Source: Meeting notes, 2026-04-07 2:00 PM PT] - **2026-04-03** | Mentioned in email re Q2 planning. Taking lead on ops. [Source: Gmail, sarah@acmecorp.com, 2026-04-03 10:30 AM PT] - **2026-03-15** | First meeting. Intro from alice-example. Strong technical background. [Source: User, direct conversation, 2026-03-15 3:00 PM PT]要点拆解:
- YAML frontmatter 携带
type、title、tags,供类型推断与检索使用(src/core/markdown.ts的serializeMarkdown会统一补全这三项)。 <!-- timeline -->是 GBrain 自己写页面时使用的标准哨兵,位于 compiled truth 与 timeline 之间。上方的一切都是编译真理,下方的一切都是时间线。- 每个时间线条目由日期 | 摘要加缩进续行(细节)构成,并强制携带
[Source: ...]来源引用——这是 docs/guides/source-attribution.md 中质量规范对每条事实的要求。
2.2 时间线条目的规范书写格式
从源码 src/core/timeline-extract.ts 看,GBrain 的时间线提取器识别三种格式:
- Format 1 — 子弹格式:
- **YYYY-MM-DD** | Source — Summary。这是规范(canonical)形态,也是timeline-write-through写入磁盘文件的形态。 - Format 2 — 标题格式:
### YYYY-MM-DD — Title,其后的内容作为 detail 提取。 - Format 3 — 内联引用格式:
[Source: <source>, YYYY-MM-DD]。这是 GBrain 质量规范要求每条大脑写入都携带的引用形式,因此带日期的证据在大脑页面中无处不在。提取器会为页面内每条此类引用登记一条时间线行——其日期取自引用、摘要取自引用所在的行(剥离代码 span)。只有孤悬在自己的空段落中的引用(上下都是空行)不会生成任何行。
三、更新页面:两个动作,两种命运
原文档给出的更新流程伪代码是理解本模式的心法,逐行翻译如下:
update_brain_page(slug, new_info, source): page = gbrain get {slug} // TIMELINE: always APPEND (never edit existing entries) gbrain timeline-add {slug} { date: today, summary: new_info.summary, detail: new_info.detail, source: format_source(source) // [Source: who, channel, date time tz] } // COMPILED TRUTH: REWRITE (not append) // Read the existing compiled truth // Integrate new information // Write the updated synthesis updated_truth = rewrite_compiled_truth(page.compiled_truth, new_info) gbrain put {slug} { compiled_truth: updated_truth, // timeline is NOT passed — it's managed by add_timeline_entry }对应到实际 CLI:
gbrain timeline-add <slug> <date> <text>追加时间线条目(见 src/cli.ts 的用法行)。源码层面它路由到addTimelineEntry(PostgreSQL 引擎实现在 src/core/postgres-engine.ts),落库到timeline_entries表。gbrain put {slug} {compiled_truth}仅写入综合区。切勿把 timeline 传回 put——时间线由add_timeline_entry独占管理,混传会导致pages.timeline列被静默破坏(见下文 6.4 的include_content说明)。
3.1 核心规则表
| Zone | Action | Explanation |
|---|---|---|
| Compiled truth | REWRITE | Current synthesis. Changes when evidence changes. |
| Timeline | APPEND | Evidence trail. Never edited, only added to. |
每一条 compiled truth 论断都必须能追溯到时间线条目。如果 Assessment 写着"内部未得到充分赏识(under-appreciated internally)",时间线里就该有支撑该判断的证据条目。
四、Tricky Spots:六个必须避开的坑
原文档列出了六个最容易出错的地方,下面逐条结合源码深挖其成因。
4.1 REWRITE 意味着重写,不是追加
不要给 compiled truth 追加新段落。正确做法是重写整个相关小节,把新信息整合进去。不再准确的旧评估应当被更新,而不是与新结论并列存在。如果写成"追加模式",页面最终会积累互相矛盾的评估,综合区就失去了"30 秒读懂"的价值。
4.2 时间线条目不可变
绝不编辑已有条目。如果信息有误,就新增一条修正条目:
- 2026-04-10 | Correction: Sarah is VP Eng, not CTO. Previous entry was wrong.这条规则的底层由两层机制保证:
- 去重索引:
timeline_entries表的唯一键是(page_id, date, md5(summary), source)(ON CONFLICT ... DO NOTHING),意味着同一事件重复追加会被静默吞掉,而修改已有行会破坏与磁盘 markdown 的一致性。 - 写穿(write-through)的一致性:见 6.3 节,磁盘文件是合并点,任何旁路编辑都会在下次 sync 时被重新提取并与表对账。
4.3 搜索权重偏向 compiled truth
gbrain query返回时,compiled truth 分块的相关性高于时间线分块。源码证据在 src/core/search/hybrid.ts:
- 混合检索管道为 keyword + vector → RRF 融合 → 归一化 → boost → cosine 重排 → 去重;
const COMPILED_TRUTH_BOOST = 2.0(hybrid.ts)——RRF 归一化后,chunk_source === 'compiled_truth'的分块获得2.0x 加权;compiledTruthBoost(hybrid.ts)进一步限定:该分块不能是unverified的自动提取存根,也不能是空文本的合成标题行——避免 boost 把空分块抬到榜首。
这意味着:最新的综合结论会最先出现在搜索结果中,而不是一条随机的历史时间线条目。
4.4 哨兵的选择:裸---不是哨兵
GBrain 在第一个被识别的哨兵处拆分 compiled_truth 与 timeline,识别优先级如下(src/core/markdown.ts 的findTimelineSplitIndex与facts-fence.ts中的镜像实现):
<!-- timeline -->——首选,无歧义,GBrain 写页面时自己输出的就是它(serializeMarkdown在 markdown.ts 中固定拼接<!-- timeline -->);--- timeline ---——装饰性分隔符;- 裸
---仅当下一非空行是## Timeline或## History时生效(兼容老版本 gbrain 写入的文件)。
其余任何位置的裸---都是 Markdown 水平线(horizontal rule),不是分隔符。splitBody(markdown.ts)的注释记录了一个重要教训:把裸---当分隔符曾在 wiki 语料上造成 83% 的内容截断,因此源码刻意只对"下一行是 Timeline/History 标题"的裸---放行。此外,findTimelineSplitIndex还会跳过 YAML frontmatter,避免 frontmatter 的---定界符误触发规则 3。
4.5 哨兵不限制时间线提取:引用也会铸成行
这是最容易忽视的隐藏行为:每个受信任的写入路径(put_page/capture,auto_timeline默认开启)以及extract timeline都会扫描整页寻找带日期标记——包括- **YYYY-MM-DD** | ...子弹和行内[Source: ..., YYYY-MM-DD]引用。因此:
- 质量规范强制的每条引用(citation)若位于 compiled truth 中,就会按引用的日期铸造一条永久时间线行,摘要取引用所在段落(剥离代码 span);
- 上面示例页面把引用都放在哨兵线之下,所以没有暴露这个隐患;
- 唯一不铸造任何行的放置方式:引用孤悬在自有段落中(上下均为空行);
gbrain config set auto_timeline off可关闭写入路径上的提取(配置项注册见 src/core/config.ts);- 没有 timeline-remove 命令,只有精确重复(exact-duplicate)去重——再次印证"时间线只增不改"。
4.6 不要跳过 Assessment 小节
Assessment 是整页的价值所在。"Strong technical leader" 是任何 API 都无法提供的判断——它是对这个人你自己的读解。这才是大脑页面优于 LinkedIn 的原因。这个观点与 docs/guides/entity-detection.md 中"代理维护 compiled truth"的定位一脉相承:机器负责记录证据与维护综合,人(或代理的推理层)负责价值判断。
五、源码级实现:双区如何被拆分、写入与检索
5.1 拆分:splitBody与findTimelineSplitIndex
页面读入时,src/core/markdown.ts 的splitBody将正文按哨兵一分为二:
- 找到哨兵:
lines.slice(0, splitIndex)为 compiled_truth,lines.slice(splitIndex + 1)为 timeline; - 找不到哨兵但存在裸
## Timeline/## History小节且该小节形态为"带日期的子弹列表"(DATED_BULLET_RE匹配- 2024-05-01 ...之类)时,启用 #2225 回退:只把该小节划入 timeline,后续无关的 H2 小节保留在 compiled truth 中——防止普通 wiki 页面带散文的## History小节被整个吞进时间线; - 两者皆无:整页视为 compiled truth。
5.2 写入:timeline-write-through的原子追加
src/core/timeline-write-through.ts(#1856)保证了手动时间线写入的端到端一致性。核心流程(writeTimelineEntryThrough,L292-L436):
- 通过
resolvePageWriteTarget解析磁盘写入目标;磁盘不可达或配置关闭(sync.write_throughoff)时回退到纯 DB 插入(handled: false),行为与旧版完全一致; renderTimelineEntry(L148-L176)把条目渲染为规范子弹- **YYYY-MM-DD** | source — summary,并用 FS 提取器反推出将存入 DB 的元组——存入的元组与重新提取的元组按构造收敛,杜绝每次 sync 重复插入;- 拿页面锁后,对磁盘文件执行"读-改-写":
spliceTimelineIntoFileText(L216-L280)按日期序把子弹插入时间线区(保持列表升降序方向),插入后必须能 round-trip 提取回原元组,否则不落盘; - 原子写:唯一临时文件 + rename,失败清理临时文件;随后更新
pages.timeline列并插入timeline_entries行(去重索引ON CONFLICT DO NOTHING); - 在启用持久化加固(durability-hardened)的仓库上,best-effort 提交到 git。
注意第 3 步的哲学:磁盘文件是文件型编辑(facts 栅栏、手写编辑)的合并点,绝不从 DB 行整体重建文件——否则旁路编辑会被静默回滚。手动条目缺省来源标记为'manual'(L127),因为裸摘要(无分隔符)会被提取器碎片化,必须有诚实的 provenance。
5.3 读取:get_page的include_content无损往返
MCPget_page操作(src/core/ops/pages.ts)默认返回compiled_truth与timeline两个字段;当需要编辑后无损回写时,传入include_content: true会得到规范序列化content字段 = frontmatter + body +<!-- timeline -->哨兵 + timeline。代码注释(L180-L188)明确指出:手工拼接compiled_truth + timeline(丢哨兵)会在下次写入时静默破坏pages.timeline——这正是 4.5 节隐患的读取侧镜像。
六、如何验证你的页面符合模式
- 更新一个人物页:加入新的会面信息。检查:compiled truth 被REWRITE(而非追加),时间线顶部出现新条目。
- 搜索该人物:
gbrain query "Sarah Chen"。compiled truth(当前综合)应排在最前,而不是一条随机时间线条目——这是 2.0x boost 的直接验证。 - 检查可追溯性:compiled truth 中的每条论断都应有对应的时间线条目。通读两区并核对。
- 检查不可变性:更新后,旧时间线条目应原样未动——日期、来源、内容与原始条目完全一致(去重索引 + 写穿一致性保证这一点)。
七、延伸阅读
- GBrain Skillpack 参考架构:compiled truth 在整体知识骨干中的定位,以及 50+ 内置技能的关系
- Source Attribution:每条事实的引用格式与来源层级
- Entity Detection:实体检测如何驱动页面的自动丰富与综合维护
- 关键实现文件:src/core/markdown.ts、src/core/timeline-write-through.ts、src/core/timeline-extract.ts、src/core/search/hybrid.ts
【免费下载链接】gbrainGarry's Opinionated OpenClaw/Hermes Agent Brain项目地址: https://gitcode.com/gh_mirrors/gb/gbrain
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考