news 2026/9/23 8:06:50

GBrain Compiled Truth + Timeline 模式:可搜索大脑页面的双区架构与实现原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GBrain Compiled Truth + Timeline 模式:可搜索大脑页面的双区架构与实现原理

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.tssrc/core/timeline-write-through.tssrc/core/timeline-extract.tssrc/core/search/hybrid.ts)剖析双区拆分、哨兵识别、时间线提取与搜索加权的底层实现。读完你将掌握如何为人物、项目、概念页维护"30 秒即可读完、每条论断都有出处、检索时最新综合结论优先浮现"的持久知识结构,并理解为什么REWRITEAPPEND是不可混淆的两个动作。

一、为什么需要"双区":从追加日志到可综合的真相

没有双区结构时,大脑页面会退化为纯追加日志:想了解一个人,你必须通读 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 携带typetitletags,供类型推断与检索使用(src/core/markdown.tsserializeMarkdown会统一补全这三项)。
  • <!-- timeline -->是 GBrain 自己写页面时使用的标准哨兵,位于 compiled truth 与 timeline 之间。上方的一切都是编译真理,下方的一切都是时间线。
  • 每个时间线条目由日期 | 摘要加缩进续行(细节)构成,并强制携带[Source: ...]来源引用——这是 docs/guides/source-attribution.md 中质量规范对每条事实的要求。

2.2 时间线条目的规范书写格式

从源码 src/core/timeline-extract.ts 看,GBrain 的时间线提取器识别三种格式:

  1. Format 1 — 子弹格式- **YYYY-MM-DD** | Source — Summary。这是规范(canonical)形态,也是timeline-write-through写入磁盘文件的形态。
  2. Format 2 — 标题格式### YYYY-MM-DD — Title,其后的内容作为 detail 提取。
  3. 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 核心规则表

ZoneActionExplanation
Compiled truthREWRITECurrent synthesis. Changes when evidence changes.
TimelineAPPENDEvidence 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 的findTimelineSplitIndexfacts-fence.ts中的镜像实现):

  1. <!-- timeline -->——首选,无歧义,GBrain 写页面时自己输出的就是它(serializeMarkdown在 markdown.ts 中固定拼接<!-- timeline -->);
  2. --- timeline ---——装饰性分隔符;
  3. ---仅当下一非空行是## Timeline## History时生效(兼容老版本 gbrain 写入的文件)。

其余任何位置的裸---都是 Markdown 水平线(horizontal rule),不是分隔符。splitBody(markdown.ts)的注释记录了一个重要教训:把裸---当分隔符曾在 wiki 语料上造成 83% 的内容截断,因此源码刻意只对"下一行是 Timeline/History 标题"的裸---放行。此外,findTimelineSplitIndex还会跳过 YAML frontmatter,避免 frontmatter 的---定界符误触发规则 3。

4.5 哨兵不限制时间线提取:引用也会铸成行

这是最容易忽视的隐藏行为:每个受信任的写入路径(put_page/captureauto_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 拆分:splitBodyfindTimelineSplitIndex

页面读入时,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):

  1. 通过resolvePageWriteTarget解析磁盘写入目标;磁盘不可达或配置关闭(sync.write_throughoff)时回退到纯 DB 插入(handled: false),行为与旧版完全一致;
  2. renderTimelineEntry(L148-L176)把条目渲染为规范子弹- **YYYY-MM-DD** | source — summary,并用 FS 提取器反推出将存入 DB 的元组——存入的元组与重新提取的元组按构造收敛,杜绝每次 sync 重复插入;
  3. 拿页面锁后,对磁盘文件执行"读-改-写":spliceTimelineIntoFileText(L216-L280)按日期序把子弹插入时间线区(保持列表升降序方向),插入后必须能 round-trip 提取回原元组,否则不落盘;
  4. 原子写:唯一临时文件 + rename,失败清理临时文件;随后更新pages.timeline列并插入timeline_entries行(去重索引ON CONFLICT DO NOTHING);
  5. 在启用持久化加固(durability-hardened)的仓库上,best-effort 提交到 git。

注意第 3 步的哲学:磁盘文件是文件型编辑(facts 栅栏、手写编辑)的合并点,绝不从 DB 行整体重建文件——否则旁路编辑会被静默回滚。手动条目缺省来源标记为'manual'(L127),因为裸摘要(无分隔符)会被提取器碎片化,必须有诚实的 provenance。

5.3 读取:get_pageinclude_content无损往返

MCPget_page操作(src/core/ops/pages.ts)默认返回compiled_truthtimeline两个字段;当需要编辑后无损回写时,传入include_content: true会得到规范序列化content字段 = frontmatter + body +<!-- timeline -->哨兵 + timeline。代码注释(L180-L188)明确指出:手工拼接compiled_truth + timeline(丢哨兵)会在下次写入时静默破坏pages.timeline——这正是 4.5 节隐患的读取侧镜像。

六、如何验证你的页面符合模式

  1. 更新一个人物页:加入新的会面信息。检查:compiled truth 被REWRITE(而非追加),时间线顶部出现新条目。
  2. 搜索该人物gbrain query "Sarah Chen"。compiled truth(当前综合)应排在最前,而不是一条随机时间线条目——这是 2.0x boost 的直接验证。
  3. 检查可追溯性:compiled truth 中的每条论断都应有对应的时间线条目。通读两区并核对。
  4. 检查不可变性:更新后,旧时间线条目应原样未动——日期、来源、内容与原始条目完全一致(去重索引 + 写穿一致性保证这一点)。

七、延伸阅读

  • 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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 8:05:58

MATLAB实现0-9数字语音识别系统:从原理到工程实践

1. 项目概述&#xff1a;基于MATLAB的0-9数字语音识别系统这个MATLAB语音识别项目实现了一个能识别数字0-9的完整解决方案&#xff0c;特别适合需要快速入门语音处理的开发者。系统包含GUI界面、完整注释和项目报告三大部分&#xff0c;我实际测试下来识别准确率能达到85%以上&…

作者头像 李华
网站建设 2026/9/23 8:05:38

正向代理与反向代理:一文讲透区别,以及为什么代理IP是正向代理

在日常开发中&#xff0c;“代理”这个词出现的频率相当高。Nginx 配负载均衡时叫反向代理&#xff0c;写爬虫配 IP 时叫正向代理。但真要让人用一两句话说清楚两者的区别&#xff0c;不少人还是会含糊。本文从代理的本质出发&#xff0c;把正向代理和反向代理的工作机制、适用…

作者头像 李华
网站建设 2026/9/23 8:04:22

Jetson AGX Orin六路同步采集:从硬件支持到工程落地的全栈解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/23 8:03:16

复杂UI组件重构:逻辑表达式与原子化构建实战

复杂 UI 组件重构&#xff0c;一直是个让人又爱又恨的话题。爱的是重构完之后代码清爽、扩展自如的那股爽劲&#xff0c;恨的是重构过程中牵一发而动全身&#xff0c;稍不留神就把原本还能跑的业务逻辑改得面目全非。我最近正好完成了一个规则配置类复杂组件的重构&#xff0c;…

作者头像 李华
网站建设 2026/9/23 8:02:39

业务战略可视化工具:动态评估与决策优化

1. 项目概述"VTC战略与落地②&#xff1a;战略规划层的革命——一张图看清所有业务的生死位置"这个标题揭示了企业战略管理领域的一个关键痛点&#xff1a;如何直观、清晰地评估各项业务在整体战略布局中的位置和价值。作为从业15年的战略咨询顾问&#xff0c;我深知…

作者头像 李华
网站建设 2026/9/23 8:02:25

真实金融系统设计避坑指南:账户、对账、幂等与分布式事务

我第一次接手这个项目时&#xff0c;团队给到的资料其实只有一个仓库名&#xff1a;financial-services。坦白讲&#xff0c;看到这个命名我一度以为它只是某个聚合支付组内部的中间件&#xff0c;真正把代码和业务文档翻完之后才发现&#xff0c;里面装的是一个完整的数字金融…

作者头像 李华