news 2026/9/21 7:38:15

gbrain v0.18.0 多源大脑(Multi-source Brains)迁移与配置实战:一个数据库承载多个知识仓库

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
gbrain v0.18.0 多源大脑(Multi-source Brains)迁移与配置实战:一个数据库承载多个知识仓库
  • 人工智能
  • RAG
  • Agent 记忆
  • MCP 服务
  • 知识管理

【免费下载链接】gbrain

Garry's Opinionated OpenClaw/Hermes Agent Brain

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

本指南以 skills/migrations/v0.18.0.md 迁移文档为核心骨架,结合仓库源码(src/core/source-resolver.ts、src/commands/sources.ts、src/commands/migrations/v0_18_0.ts)与配套实战指南 docs/guides/multi-source-brains.md,系统讲解 gbrain 的sources一等公民原语:从自动迁移、CLI 命令面、六级解析优先级、联邦(federation)语义,到面向 Agent 的引用契约。读完你将在单个 gbrain 后端上同时运行"统一知识大脑"与"用途隔离大脑",并让cd ~/yc-media && gbrain query "X"这类按目录自动定位 source 的体验直接可用。

一、v0.18.0 迁移文档讲了什么:sources 成为一等公民

v0.18.0(该迁移说明正文沿用旧版编号,内部 schema 迁移为 v16/v17)将source提升为数据库中的一等公民原语:一个 gbrain 后端可以同时持有多个知识仓库(如wikigstackyc-mediagarrys-list),彼此拥有干净的边界。核心变化有三条:

  1. 行级作用域:每一行pagesfilesingest_log都归属于一个sources(id)行。
  2. Slug 按 source 唯一:slug 不再全局唯一,而是(source_id, slug)复合唯一——两个 source 可以各自拥有topics/ai,且它们是不同的页面。
  3. 联邦开关federated=true(升级后默认 source 的取值)加入跨源召回池,参与无前缀的默认搜索;federated=false是隔离态,仅在被--source <id>显式点名时才会被搜到。

这同时支撑"统一知识大脑"(wiki + gstack 都联邦)与"用途分离大脑"(yc-media + garrys-list 都隔离)两种形态并存于同一数据库。

配套的完整用户指南位于 docs/guides/multi-source-brains.md,本文以迁移说明为主线,同时并入该指南的可操作细节。

二、机械迁移:自动执行、幂等、无需人工操作

迁移说明明确:gbrain upgrade会链式调用gbrain apply-migrations --yes,随后自动运行两条内部迁移:

  • migration v16—— 创建sources表,以{"federated": true}配置种子化default行,并把升级前的sync.repo_pathsync.last_commit继承到default行中。该迁移是纯新增(additive-only),不破坏任何既有引擎代码。
  • migration v17—— 给pages增加source_id TEXT NOT NULL DEFAULT 'default' REFERENCES sources(id),将全局UNIQUE(slug)约束替换为复合UNIQUE(source_id, slug),同时引擎的 upsert 路径同步改为ON CONFLICT (source_id, slug),保证约束替换与写入路径原子落地。

两条迁移均幂等,可安全重跑。

源码侧,src/commands/migrations/v0_18_0.ts 中的编排器将这次升级拆成三个阶段:

  • Phase A(schema):调用runMigrateOnlyCore()执行迁移链;
  • Phase B(storage backfill):检查file_migration_ledger是否存在,存在则调用runStorageBackfill按台账重写存储对象(PGLite 因无 files 表直接跳过);该阶段在 Step 7 存储回填落地前预期可能为skipped
  • Phase C(verify):断言sources('default')行存在;若已安装pages_source_slug_key复合约束,还会校验不存在source_id IS NULL的脏行。

最终状态由 schema 与 verify 阶段共同决定:complete/partial/failed,并写入已完成的迁移记录。

迁移文档同时预告了后续小版本的内容:v0.17.1 将基于调用方身份原语做 ACL 强制(现在已随 JSONB 槽位下发access_policy,强制留待身份机制设计完成);v0.18.0 会同时落地会话注入(.jsonl转录、容量上限提升、session PageType)与按 source 的 retention/TTL。

三、sourcesCLI 子命令全解

迁移文档给出了完整的命令面(src/commands/sources.ts 的实现与之对应):

gbrain sources add <id> --path <p> [--name <n>] [--federated|--no-federated] gbrain sources list [--json] gbrain sources remove <id> [--yes] [--dry-run] [--keep-storage] gbrain sources rename <id> <new-display-name> gbrain sources default <id> gbrain sources attach <id> # 在 CWD 写入 .gbrain-source gbrain sources detach # 移除 .gbrain-source gbrain sources federate <id> gbrain sources unfederate <id>

Source ID 规则

迁移文档规定 id 必须匹配a-z0-9?——以小写字母或数字开头结尾、中间可含连字符、最长 32 字符。源码 src/commands/sources.ts 与 src/core/source-id.ts 共享同一正则SOURCE_ID_RE,校验失败会抛出可读错误(如Invalid source id "Wiki". Must be 1-32 lowercase alnum chars...)。

id 在创建后不可变rename只改显示名),它被用作[source:slug]引用中的稳定引用键。list --json会输出每个 source 的页面数与联邦状态(对应SourceListEntryid / name / local_path / federated / page_count / last_sync_at字段)。

补充:配套指南还列出了sources add的另两种形态——--url <git-url>一键克隆注册远程仓库,以及archive / restore / archived / purge软删除 TTL 体系(详见后文"进阶"小节)。

四、按目录默认:.gbrain-source点文件与六级解析优先级

迁移文档的核心体验承诺是"像 kubectl / terraform / git 一样按上下文定位":在~/.gstack/内执行gbrain sources attach gstack会写入一个只含单词gstack.gbrain-source点文件;之后在该目录或其任何子目录运行 gbrain 命令都会自动选中gstack作为默认 source。gbrain sources detach则移除该点文件。

任何命令解析目标 source 时的完整优先级为:

  1. 显式--source <id>标志;
  2. GBRAIN_SOURCE环境变量;
  3. CWD 或任一祖先目录中的.gbrain-source点文件(向上逐级查找);
  4. 注册 source 中local_path包含 CWD 者(最长前缀胜出——嵌套的~/gstack~/gstack/plans在更深层时解析到plans);
  5. 通过gbrain sources default <id>设置的脑级默认;
  6. 字面default(向后兼容兜底)。

这套逻辑在源码 src/core/source-resolver.ts 的resolveSourceId中原样落地,注释明确写着"为 CLI 命令解析 source id"(该文件头注释标注为 v0.18.0)。几个值得注意的实现细节:

  • 点文件信任校验readDotfileWalk使用lstatSync(而非statSync)检查点文件,防止符号链接被静默跟随;isTrustedDotfile拒绝符号链接、他属主与世界可写文件,避免多用户主机上共享目录被植入伪造点文件(见 src/core/source-resolver.ts)。
  • 点文件容错:非法内容(如下划线旧 id、手改带空白)静默落入下一级,而不是抛错——因为点文件常被运维手改,宽容语义能保住解析链其余部分。
  • 显式层严格--sourceGBRAIN_SOURCE两个显式层则相反,非法值会直接抛出SourceTargetError
  • 并发 realpath:第 4 级对所有注册local_path与 CWD 做并行 realpath 解析(Promise.all),避免单个慢路径(网络挂载、macOS 按访问安全扫描)串行拖垮整个解析层,成本上界是"最慢的单个 source"而非其总和(见 src/core/source-resolver.ts)。
  • 归档优先性:第 4 级中活跃 source 优先于已归档 source 参与前缀匹配,归档树的更深注册不会遮蔽活跃父级。
  • resolveSourceWithTier(src/core/source-resolver.ts)返回{ source_id, tier, detail },供gbrain sources current在任何破坏性操作前展示"解析到了哪个 source、为什么"。

此外源码还实现了resolveSourceIdEngineFree(无引擎的瘦客户端走显式/环境变量/点文件三层)与resolveSourceForRepoPath(针对sync --repo <dir>以仓库目录为锚点解析,而非调用方 cwd)。

五、联邦语义:跨源召回是显式选择

每个 source 行的 JSONB config 中存储federated布尔值,语义如下表:

含义
true参与无前缀gbrain search "X"的结果(默认 source 升级后即为此值)
false(新 source 默认)仅当通过--source <id>或带限定的引用时才会被检索

交互式gbrain sources add会提示选择联邦状态;非交互模式用--federated/--no-federated。之后可用gbrain sources federate <id>/unfederate <id>随时翻转。

源码中localFederatedSourceIds(src/core/source-resolver.ts)把这个承诺转成检索作用域:给定已解析 source 与命中的 tier,返回[已解析source, ...其他联邦source]的展开集合;但当调用方显式点名(flag/env/dotfile tier)或已解析 source 本身被显式隔离(federated=false)时不做展开——隔离源无论在哪个方向都不会被混入跨源读取。相关行为有test/local-federated-search-scope.test.tstest/recall-federated-search-scope.test.ts覆盖。

六、Agent 引用契约:[source-id:slug]

多源搜索结果天然需要可定位的引用。迁移文档规定:

当 Agent 拿到多源搜索结果时,必须[source-id:slug]形式引用页面。

示例:

你提到的蒸馏协议——参见 [wiki:topics/ai] 与 [gstack:plans/multi-repo] 的出处。

引用键是sources.id(不可变),绝不使用sources.name(可变的显示名)。因此即使用户执行gbrain sources rename,既有引用依然有效。

七、三大典型场景:统一、分离与混合

迁移文档将完整场景指引指向 docs/guides/multi-source-brains.md,其中给出三个规范场景的可复制命令:

场景 1:统一知识召回(wiki + gstack)

# 注册 gstack 并联邦,使其加入跨源搜索 gbrain sources add gstack --path ~/.gstack --federated # 钉住目录,让 gbrain sync 知道在走哪个 source cd ~/.gstack && gbrain sources attach gstack # 首次同步 gbrain sync --source gstack # 此后 `gbrain search "retry budgets"` 会同时命中 wiki 与 gstack, # 每个结果都带 source_id 供 Agent 正确引用

结果:wiki 页面与 gstack 计划分属不同source_id、不同 slug 命名空间,但共享搜索面。

场景 2:用途分离大脑(yc-media + garrys-list)

# 两个 source 都隔离(federated=false) gbrain sources add yc-media --path ~/yc-media --no-federated gbrain sources add garrys-list --path ~/writing --no-federated # 分别钉住各自目录 (cd ~/yc-media && gbrain sources attach yc-media) (cd ~/writing && gbrain sources attach garrys-list) # 各自独立同步 gbrain sync --source yc-media gbrain sync --source garrys-list

效果:在两个目录之外搜索只返回default主脑;在~/yc-media内搜索只返回 yc-media;在~/writing内只返回 garrys-list。联邦是显式选择,不会泄漏。需要临时跨源检索时:

gbrain search "tech layoffs" --source yc-media,garrys-list

场景 3:混合(wiki 联邦 + 会话隔离)

# 联邦 source gbrain sources add gstack --path ~/.gstack --federated # 会话转录走隔离 source,避免主导每次搜索结果 gbrain sources add sessions --path ~/.claude/sessions --no-federated

八、写入保护:无前缀写入默认防错

解析器从不在歧义时静默选源——它会以清晰可修的错误终止。迁移配套指南进一步给出无前缀写入的防护:

  • 在"存在至少一个非 default source,且default之外页面多于default内页面"的脑上,无前缀gbrain sync拒绝执行(需--source <id>重定向);gbrain import警告;MCP stdio 在写入实际落到 default 层时打印一次进程内提示。
  • gbrain sync --dry-run只预览不改写,并输出同样的路由指引。
  • GBRAIN_ALLOW_DEFAULT_WRITE=1是脚本化流水线确需写入default时的逃生舱。

源码中的assessDefaultWriteGuard(src/core/source-resolver.ts)正是这一策略的实现:当nonDefaultSources >= 1 && nonDefaultPages > defaultPages时判定需要守卫;deleted_at IS NULL过滤掉软删除页,避免"墓地分布"扭曲判定;查询失败则 fail-open(守卫绝不能成为合法写入失败的原因)。assessDefaultWriteGuardOnce用 WeakMap 按引擎记忆进程内评估结果,避免大量无前缀写入反复全表聚合。

九、v0.18.0 尚未包含的内容

迁移文档明确列出了本次发布范围之外、将随本发布周期后续 Step 落地的能力:

  • ingest_log.source_id—— 随 Step 5 同步重写落地;
  • links.resolution_type与限定[[source:slug]]wikilink 解析 —— 随 Step 4 链接抽取重写落地;
  • files.page_slug → page_id外键重写 +file_migration_ledger+ 存储对象前缀化 —— 随 Step 7 存储回填落地;
  • 源感知的搜索去重 —— 随 Step 3 落地;
  • gbrain sources import-from-github <url>—— 推迟到管道稳定后的补丁版本。

既有调用方继续以defaultsource 工作,Agent 无需任何行为变更;新能力全部通过新增的sourcesCLI 面以 opt-in 方式使用。

十、宿主仓库动作与升级既有脑

迁移文档明确:宿主仓库无需任何动作。若宿主 Agent 通过标准gbrain sync流程管理大脑,它继续作用于 default source,行为无变化。要开始使用多源:

# 注册新 source gbrain sources add gstack --path ~/.gstack --no-federated # 钉住目录,免去每次 --source 标志 cd ~/.gstack gbrain sources attach gstack # 摄取 gbrain sync --source gstack

配套指南补充了两个易踩的坑(git 要求):

  • --pathsource 必须是 git 仓库(或仓库内子目录),且路径下要有已提交的跟踪文件——git init后即使--allow-empty提交也不够,注册校验读的是git ls-tree HEAD作用域内的真实跟踪内容。未满足时sources add会直接拒绝并给出可操作错误。
  • --force跳过该校验,适用于"注册时自动化管道还没 git init"的场景;gbrain 不会替你自动git init
  • 若同步锚点(last_commit)因 force-push / 历史重写 / 从零 init 而失效,gbrain sync会自动检测并恢复(完整重导入或对孤儿书签做树到树 diff),无需手工重置。

升级既有脑只需两步:gbrain sources add gstack --path ~/.gstack --federatedcd ~/.gstack && gbrain sources attach gstack && gbrain sync——现有defaultsource 完全不受影响。

十一、进阶:归档、耐久性与更广阔的坐标系

配套指南 docs/guides/multi-source-brains.md 还在 sources 之上提供了更多可组合能力:

  • 按 source 保留/软删除gbrain sources archive <id>(软删除并隐藏于搜索,TTL 宽限期内保留数据)、archived(列出过期项)、purge(永久删除过期归档;仍被 OAuth 客户端引用的 source 会以Blocked:报告,需先gbrain auth revoke-client <id>)。
  • 一键远端引导gbrain sources add wiki --url <git-url> --pat-file <pat>克隆 + 注册 + 自动加固(auto-harden)一次完成:本地 auto-push 钩子、scripts/brain-commit-push.sh、AGENTS.md/RESOLVER.md 中的耐久性规则、30 分钟拉取 cron 与仓库级凭证;harden/unharden/pull可随时审计与拆除。安全边界:推送自动化只装在本机、token 按仓库接线、绝不落入仓库/远端 URL/日志/JSON 报告。
  • 坐标系区分:source 是"数据库内"轴;若需连接整个独立数据库(团队发布、带独立访问策略的脑),那是gbrain mounts addbrain轴,两轴拓扑见 docs/architecture/brains-and-sources.md。

总结:v0.18.0 的 multi-source brains 是一套"一个数据库、多个知识仓库、干净隔离、显式联邦"的完整原语。迁移全自动且幂等,CLI 面覆盖注册到耐久性全生命周期,六级解析优先级复刻了 kubectl/git 的上下文习惯,而[source-id:slug]引用契约保证了 Agent 在多源召回下仍能稳定、可重命名地引用来源。把本文中的命令与源码路径(src/core/source-resolver.ts、src/commands/sources.ts、src/commands/migrations/v0_18_0.ts)对照阅读,即可在既有单源脑上无痛切换到多源拓扑。

  • 人工智能
  • RAG
  • Agent 记忆
  • MCP 服务
  • 知识管理

【免费下载链接】gbrain

Garry's Opinionated OpenClaw/Hermes Agent Brain

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

相关推荐

上一篇:MTKClient项目:MT6765设备DAA签名验证失败问题分析与解决
下一篇:解决Owncast直播平台Logo缓存难题:从根源到优化的完整指南

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

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

汽车软件工程师ASPICE实战指南:核心流程、产物清单与避坑技巧

/* 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 7:09:36

GD32H759 RT-Thread以太网驱动移植实战:从RMII到Ping通

/* 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 6:59:02

固态变压器SST:从工频变压器到碳化硅模块的电力电子革命

/* 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 5:30:43

2026研发效能管理平台选型指南:7款主流工具深度对比

/* 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 5:30:40

睡眠耳机怎么选?蓝牙主动降噪与久戴不痛的核心参数解析

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

作者头像 李华