news 2026/9/21 20:58:57

gbrain 版本升级回归指南:v0.18 脑库原地迁移到最新 schema 的 Claw-test 全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
gbrain 版本升级回归指南:v0.18 脑库原地迁移到最新 schema 的 Claw-test 全流程
  • 人工智能
  • RAG
  • Agent 记忆
  • MCP 服务
  • 知识管理

【免费下载链接】gbrain

Garry's Opinionated OpenClaw/Hermes Agent Brain

项目地址:https://gitcode.com/gh_mirrors/gb/gbrain
点击查看免费下载

将 v0.18 遗留脑库原地升级到最新 schema,是 gbrain 历史摩擦最集中的回归点:嵌入式 schema 的每次演进都可能让老库卡在旧schema_version上无法前进。本指南以仓库自带的 Claw-test 升级场景 upgrade-from-v0.18 为主线,逐步讲解"先摸底、再迁移、复检、查数据"的完整升级验证路径,并结合源码说明迁移链、种子重放与摩擦上报协议背后的实现原理。读完你将掌握一套可复现的升级回归门禁方法,并能在升级遇阻时用gbrain friction log把问题精确"钉"下来供项目方调优。

场景解剖:一个专门测"升级卡死"的 Claw-test

在 scenario.json 中,升级场景被声明为:

{ "kind": "upgrade", "from_version": "0.18.0", "description": "Pre-v0.18 brain shape replayed via PGLite SQL dump; migration chain walks forward to LATEST", "expected_phases": ["doctor.db_checks"], "seed": "seed", "brain": "brain", "oracle": { "query": "alice", "min_results": 1 } }

几个关键设计意图:

  • kind: "upgrade"与同目录的 fresh-install 场景 形成对照:fresh-install 测"从零建库",upgrade 测"旧库前进",两者走的是完全不同的代码路径;
  • from_version: "0.18.0"明确被测起点:harness 会把一个 v0.18 形状的 PGLite SQL dump 重放到全新数据库中,模拟"你继承了一个别人留下的旧脑库";
  • expected_phases: ["doctor.db_checks"]是断言基线:流程跑完后,harness 必须从 stderr 捕获到doctor.db_checks进度事件,否则判为失败(对应 claw-test.ts 中的verifyExpectedPhases逻辑);
  • oracle: { query: "alice", min_results: 1 }是"真相检验":迁移完成后查询alice必须命中至少 1 条结果,证明升级没有丢数据。

场景自带的脑库只有一个页面 brain/people/alice-example.md,其 frontmatter 注明该页面与 fresh-install 场景内容相同,本场景测的是升级流程而非摄取,从而保证两类场景的差异只在于"库是怎么来的"。

升级四步走:从摸底到验证

任务书 BRIEF.md 给出了四条明确指令,这也是任何真实 gbrain 用户升级旧脑库时应遵循的操作顺序。

第一步:升级前体检——gbrain doctor --json

对继承来的旧脑库,先运行:

gbrain doctor --json

目的有二:一是记录升级前的基线状态;二是把"旧库本身已有的健康问题"与"迁移引入的问题"区分开。注意观察输出中的 warnings 与 fix-hints——若升级后出现同样的问题,说明并非迁移所致;若出现新问题,则要怀疑迁移链本身。

从源码看,doctor是 gbrain 的全科体检入口,doctor.ts 将检查按类别拆分为 core-health、calibration、queue-jobs、graph-embedding、routing-federation、search-eval、extraction-sync、consolidation-cycle、pglite-worker 等模块,最终汇总为一个三元状态:

status: 'healthy' | 'warnings' | 'unhealthy';

(见 doctor.ts)。升级场景的验收标准正是基于这个三元模型:结果必须是healthywarnings绝不能是unhealthy。这与 harness 的断言逻辑一致——claw-test.ts 对非healthy/warnings的状态直接判失败。

第二步:原地升级——gbrain init --pglite

带上既有数据库路径执行:

gbrain init --pglite --path <existing-brain-path>

--pglite明确选择本地 PGLite 引擎(对应 init.ts 中的isPGLite分支),--path指定数据库文件位置。迁移链会检测库中的旧schema_version,然后沿迁移列表一步步前进到最新版本,全程无需手工导出再导入。

从源码看,src/core/migrate.ts 是整个升级的引擎:

  • 每个迁移是MIGRATIONS数组中的一步,最新版本号直接由数组推导:LATEST_VERSION = MIGRATIONS.length > 0 ? …(migrate.ts);
  • 执行时先对比当前schema_versionLATEST_VERSION,打印形如Schema version ${current} → ${LATEST_VERSION} (${pending.length} migration(s) pending)的进度(migrate.ts);
  • 每个迁移在事务内运行,成功才提交并回写schema_version,失败则回滚、版本停留在原值(migrate.ts)——这是"失败不产生半迁移状态"的保障。

另外 init.ts 中有几个对升级场景至关重要的行为:--migrate-only走纯 schema 升级路径、完全不触碰既有配置(init.ts);--force重新初始化时若未显式指定引擎会保留已配置的引擎(init.ts),避免把 postgres 配置静默改写成 pglite 而孤立掉原有数据。

第三步:升级后复检——gbrain doctor --json

迁移完成后再跑一次体检,验收标准同上:status必须为"healthy""warnings"永远不应出现"unhealthy"。两次体检的对比是"迁移干净"的直接证据:第一次发现的问题应当被迁移解决,或至少不恶化。

第四步:数据可用性验证——gbrain query "alice"

gbrain query "alice"

这一步验证的不只是"表还在",而是检索仍能命中旧数据:升级前已入库的内容(例如people/alice-example.md这条 person 页面)在迁移后必须可被查询到。这正是 scenario.json 中oracle: { query: "alice", min_results: 1 }的由来——若查询结果为空,说明迁移链虽跑通但数据或索引出了问题,同样算回归。

摩擦上报协议:把升级痛点"钉"下来

任务书特别强调:迁移步骤是全项目历史痛苦最高的回归点。因此,升级验证过程中任何"令人困惑、缺失、意外或错误"的情况都应通过摩擦日志上报:

gbrain friction log --severity {confused|error|blocker|nit} --phase <which-step> --message "<what-happened>" [--hint "<what-could-be-better>"]

若某一步顺利通过,同样可以上报 delight——项目方正在把升级流程调优到"零摩擦"。

从 src/commands/friction.ts 的实现看,该命令带有完整的类型约束与五个子命令:

  • 类型校验--kind只能是friction | delight | phase-marker | interrupted--severity只能是confused | error | blocker | nit(friction.ts),非法值直接报错并以退出码 2 结束;
  • 必填参数--phase--message缺一不可(friction.ts),--hint可选但强烈建议填写"怎样做会更好";
  • 五个子命令log追加一条记录、render将一次运行渲染为 Markdown 或 JSON(--json控制格式,Markdown 默认开启--redact脱敏)、list按运行列出计数、summary并排展示 friction 与 delight 汇总、diff对比两次运行(或两个 agent)之间"各自独有"与"共有但变化"的条目;
  • 来源标记:harness 场景中写入时source: 'claw',便于区分"真人上报"与"自动化 harness 上报"。

值得留意的是,上报入口本身是降级可用的:即使升级失败、数据库处于半迁移状态,摩擦记录仍能正常写入,不会因为"库坏了"而丢失"库坏了"这个证据。

常见升级摩擦模式与排查要点

任务书点名的四个高频摩擦模式,对应四条排查线索:

  1. 迁移链在某个具体 schema 版本失败——务必同时记录失败时的schema_version与报错信息。由于每个迁移在独立事务中执行(见上文 migrate.ts),失败迁移不会污染其他步骤,修正后重试是安全的;
  2. Doctor 标出问题但 fix-hint 不可执行——上报时在--hint里写清你期望的可执行建议,这类反馈直接驱动 doctor 修复提示的优化;
  3. gbrain init --pglite没认出既有脑库——检查--path是否指向真实存在的 PGLite 文件,以及数据库目录是否被--force等参数误伤;
  4. 需要手工 SQL 才能解卡——任何必须手写 SQL 的情况都是迁移链设计缺陷的信号,应作为blocker级摩擦上报。

种子机制:升级场景如何"造出"一个真实旧库

升级场景无法像 fresh-install 那样凭空建库——它必须有一个真实的 v0.18 形状数据库来触发迁移链。这正是 seed/README.md 讲述的内容。

当前仓库中该目录仅是脚手架占位(dump.sql尚不存在,场景在测试门禁上按 fresh-install 行为处理),v1.1 将放入真实 dump。制作真实种子的标准流程:

  1. 检出 v0.18 版本源码:git checkout v0.18.0
  2. gbrain init --pglite --path /tmp/v0.18-seed.pglite对小规模 fixture 脑库初始化;
  3. gbrain import <fixture-brain>灌入数据;
  4. 将 PGLite 以 SQL 形式导出:通过executeRaw('SELECT * FROM pg_dump(...)')扩展、直接拷贝文件,或pglite-tools dump /tmp/v0.18-seed.pglite > dump.sql
  5. dump.sql放入 seed 目录;
  6. 同步更新expected.json中的页面计数,使其与实际 dump 页数一致。

dump.sql存在时,harness 的执行路径(对应 claw-test.ts 的 upgrade 预相位)为:先用动态导入的seedPgliteFromFile()把 dump 重放到<tempdir>/.gbrain/brain.pglite,随后执行gbrain init --pglite让迁移链从旧schema_version走到 LATEST,最后断言gbrain doctor --json返回status: 'ok'

重放实现的细节值得展开。在 src/core/claw-test/seed-pglite.ts 中:

  • seedPglite()打开一个全新的 PGLite 文件,用splitStatements()把 dump 切分成独立语句后逐条exec——逐条执行是为了让 SQL 错误能精确定位到出错的语句(错误信息会带上前 120 字符的语句预览,便于排查种子漂移);
  • splitStatements()是刻意"朴素"的分号切分器:只识别单引号字符串与--行注释,不依赖完整 SQL 解析器,对规范pg_dump输出足够(seed-pglite.ts);
  • 同文件还提供readPgliteSchemaVersion()——一个非变更式的版本探针:直接打开 PGLite 读config表中key = 'version'的行,不经过迁移链。注释特别解释了为什么必须这么做:CLI 每次连接都会走connectEngine → initSchema自动应用待迁移项,若用常规 CLI 读版本,验证器自身就执行了被测的升级,得到的"通过"毫无意义(seed-pglite.ts)。

注意一个刻意设计:dump 缺失是响亮失败(LOUD failure)而非跳过。源码注释写得很清楚——跳过会在当前版本上新建数据库,制造一个"从未真正执行过迁移"的假绿色升级结果(claw-test.ts)。这保证了测试门禁不会自欺欺人。

回归门禁的价值:一个 bug 家族的教训

seed README 揭示了这套场景要防的到底是什么:"upgrade-wedge" bug 家族(#239/#243/#266/#357/#366/#374/#375/#378/#395/#396)——每当 gbrain 在嵌入式 schema blob 中新增"带索引的列"、却没有相应重触发 bootstrap 时,就会复现同一类升级楔死问题。这一长串编号说明:这类问题在过去反复出现、反复修复,因此才需要一条专门的自动化回归防线。

upgrade-from-v0.18 场景正是这条防线:它把"旧库能否一路迁移到 LATEST"变成每次测试必须通过的硬性断言,从源头拦截"发布即升级失败"。

相关资源导航

  • 场景任务书:本次升级验证的完整操作指令
  • 场景元数据:kind、oracle、expected_phases 等断言配置
  • 种子制作与测试说明:v0.18 dump 的生成、重放与 upgrade-wedge bug 家族背景
  • 示例脑库页面:查询验证用的标准数据
  • 对照场景:与升级场景配对的新装基线
  • 迁移链核心实现:schema_version检测、LATEST_VERSION 推导与事务化迁移
  • init 命令实现:--pglite/--path/--migrate-only/--force等升级相关参数
  • doctor 实现:healthy | warnings | unhealthy三元健康状态
  • claw-test harness:upgrade 场景的 seed 重放与相位断言
  • 种子重放实现:seedPglitereadPgliteSchemaVersion与语句切分器
  • 摩擦上报 CLI:log/render/list/summary/diff 五个子命令
  • 人工智能
  • RAG
  • Agent 记忆
  • MCP 服务
  • 知识管理

【免费下载链接】gbrain

Garry's Opinionated OpenClaw/Hermes Agent Brain

项目地址:https://gitcode.com/gh_mirrors/gb/gbrain
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

Spring Boot集成ONLYOFFICE实现企业级文档协作

1. 项目概述最近在开发一个需要在线文档协作功能的企业级应用&#xff0c;经过多方对比最终选择了ONLYOFFICE作为文档编辑解决方案。ONLYOFFICE不仅提供了完整的文档处理能力&#xff0c;还能完美集成到Spring Boot项目中。下面我将详细介绍整个集成过程&#xff0c;包括环境准…

作者头像 李华
网站建设 2026/9/21 20:56:19

从 PyTorch 迁移到 Apache MXNet:Gluon API 逐项对照实战指南

深度学习机器学习人工智能 【免费下载链接】mxnet Lightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more 项目地址&#xff1a; https://gitcode.c…

作者头像 李华
网站建设 2026/9/21 20:54:52

装饰器模式深度解析:用组合替代继承,实现功能动态扩展

装饰器模式这东西&#xff0c;我最早接触的时候也觉得就那样&#xff0c;无非是包装一下对象嘛。直到后来在项目里被继承结构逼到墙角&#xff0c;才真正体会到这个模式的精妙之处。如果你也在为“怎么优雅地给类加功能”发愁&#xff0c;或者准备面试被问到设计模式&#xff0…

作者头像 李华
网站建设 2026/9/21 20:49:50

Claude Code 跑 Opus4.5,Token 请求走 TaoToken 行不行?

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

作者头像 李华
网站建设 2026/9/21 20:37:00

C++模板编程:从基础实现到现代技巧

1. 为什么我们需要模板编程&#xff1f;记得刚入行那会儿&#xff0c;每次写个简单的max函数都要重载好几遍&#xff0c;int版本、float版本、double版本...代码重复得让人抓狂。直到有一天mentor甩给我一段模板代码&#xff0c;我才恍然大悟——原来C早就为我们准备好了更优雅…

作者头像 李华
网站建设 2026/9/21 20:34:26

JWT 与 Ed25519:从三段式结构到 Node.js 密钥实践

目录背景与目标一、JWT 是什么&#xff1a;三段式结构三种常见签名算法怎么选二、Ed25519 密钥是什么三、公钥和私钥的对应关系&#xff08;重点&#xff09;四、本地用 Node.js 生成密钥对4.1 推荐&#xff1a;crypto.generateKeyPairSync4.2 备选&#xff1a;Web Crypto API五…

作者头像 李华