关于 schema-author
schema-author 是用于演进 gbrain schema pack 的技能,面向需要定义页面类型、前缀和链接类型的维护者。它涵盖候选类型评估、校验、变更和同步回填,并提供 dry-run 与审计记录。
主要功能
- 01评估 schema 覆盖率和未分类页面
- 02检测或建议候选类型
- 03添加页面类型和链接类型
- 04运行 lint 校验变更
- 05预览并同步回填页面类型
- 06记录 schema 变更审计
适用场景
- 01为研究者或论文页面新增类型
- 02整理目录下未分类的历史页面
- 03将新前缀映射同步到现有页面
- 04检查类型声明及前缀冲突
MCP 相关
MCP 客户端可通过 schema_apply_mutations 批量修改 schema pack;写入操作要求 OAuth admin scope。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ garrytan/ gbrain --skill schema-author安装后在 Claude Code 中输入/schema-author确认已加载。
详细介绍
schema-author — 演进你的 schema 包
非目标(请改用以下其他 skill)
此 skill 用于编写 schema 包(添加页面类型、链接动词、前缀、标志)。对于以下相邻任务,请转交其他 skill:
- 归档某个具体页面 →
skills/brain-taxonomist/SKILL.md。brain-taxonomist 在写入时进行路由("这条笔记应该放在哪里?")。schema-author 在编写规则时工作("存在哪些类型和前缀?")。 - 作为 EIIRP 迭代一部分的 schema 检查 →
skills/eiirp/SKILL.md已包含 schema 检查阶段。请勿重复。 - 仅查看某个类型的设置 → 直接使用
gbrain schema explain <type>。此 skill 用于修改包,而非读取包。 - 查询谁了解某个主题 → 直接使用
gbrain whoknows <topic>。schema-author 能让某类型可被专家路由,但不执行该查询。
约定
约定: 查找链(search → query → get_page → external)见 conventions/brain-first.md。
约定: 关于"何时添加类型、别名还是前缀"的启发式规则,见 conventions/schema-evolution.md。
何时调用
当用户(或同级 skill)提出以下任一请求时调用:
- "在我的 schema 中添加一个
researcher类型" - "我的
meetings/下有 4000 个未分类页面" - "我的 brain 不认识
journal-article是一种类型" - "将
paper设为可提取" - "根据我已摄入的内容提议类型"
- "同步新类型以回填现有页面"
如果是"这条笔记应该放在哪里"(请使用 brain-taxonomist)或"谁了解 X"(请使用 expert-routing / gbrain whoknows),则不要调用此 skill。
教程与愿景
- 为什么重要:
docs/what-schemas-unlock.md—— 7 个典型用例(让 4000 条不可见的会议记录可查询、创始人运营 brain、研究 brain、法律 brain、团队 brain、Agent 作为共同策展人),以及类型在查询时为何重要的结构性论证。在向用户推介 schema 编写之前请先阅读此文档,它解释了一堆笔记与具有结构的 brain 之间的区别。 - 5 分钟演示:
docs/schema-author-tutorial.md—— 复制内置包、添加 researcher 类型、同步,并通过gbrain whoknows验证 T1.5 连接。请使用占位页面,使其可在任意 brain 上运行而不影响真实内容。
工作流
阶段 1 — Brain(确认当前生效的包)
gbrain schema active --json
输出包含 pack_name、version、sha8、page_types_count、source_tier。如果 source_tier === "default",说明用户正在使用内置的 gbrain-base,任何修改都需要先进行分叉(见阶段 4)。
阶段 2 — 评估(当前包覆盖了哪些内容?)
gbrain schema stats --json
返回每个类型的页面数、未分类数量,以及 dead_prefixes(包中声明但没有匹配页面的前缀,很可能是错误声明)。如果覆盖率低于 90%,则说明存在值得分类的未分类内容。
gbrain schema review-orphans --json
未分类页面下钻。查找共享的路径前缀(例如"其中 12 个位于 research/papers/ 下")—— 这些是新类型的候选。
阶段 3 — 提议(包应添加哪些类型?)
gbrain schema detect --json
按 source_path 对页面进行聚类,并提议候选类型。仅使用启发式方法(不调用大模型)。
gbrain schema suggest --json
由大模型优化的候选类型,附带置信度分数。使用前 3 名的命中率作为提升候选类型的依据。
阶段 4 — 应用(修改 schema pack)
如果当前 schema pack 是内置的(gbrain-base 或 gbrain-recommended),
请先将其分叉:
gbrain schema fork gbrain-base mine
gbrain schema use mine
然后逐个添加类型:
gbrain schema add-type researcher \
--primitive entity \
--prefix people/researchers/ \
--extractable \
--expert
对于复杂的多项变更重构(例如添加类型,并添加指向该类型的链接动词),
通过 MCP 访问此接口的 Agent 可以使用批量操作 schema_apply_mutations:
{"op": "add_type", "name": "researcher", "primitive": "entity", "prefix": "people/researchers/", "extractable": true, "expert_routing": true}
{"op": "add_type", "name": "paper", "primitive": "annotation", "prefix": "research/papers/", "extractable": true}
{"op": "add_link_type", "name": "authored", "inference": {"page_type": "researcher", "target_type": "paper"}}
同步前先验证:
gbrain schema lint --with-db
--with-db 标志会启用 4 条感知数据库的规则
(extractable_empty_corpus、mutation_count_anomaly、
stored_type_is_alias、stored_type_undeclared),用于检测
误声明的类型,否则只能在运行时发现这些问题。
阶段 5 — 同步(用新类型回填现有页面)
先试运行:
gbrain schema sync --json
返回每个前缀的 would_apply 数量和示例 slug。如果数量看起来合理:
gbrain schema sync --apply
分批执行 UPDATE,每批 1000 行;不会阻塞并发写入者。
可安全重复运行(第二次执行 --apply 时不会发现需要回填的内容)。
阶段 6 — 验证
gbrain schema stats --json
此时覆盖率应 ≥95%。抽查新类型:
gbrain whoknows "machine learning"
如果 researcher 声明为 --expert,结果应包含类型为 researcher 的页面。(查询路径中感知 schema pack 的连接逻辑在 v0.40.6.0 中加入 — 在此版本之前的 brain 会静默忽略由自定义专家路由的类型。)
阶段 7 — 提交(保留变更)
如果 schema pack 纳入了源代码管理,只提交并推送 schema pack 文件:
cd ~/.gbrain/schema-packs/mine
gbrain git commit-push -m "schema: add researcher + paper types + authored link" -- pack.json
此操作会获取检出目录的写入者锁,并在推送被拒绝时通过合并来处理,不会变基,因此多个 Agent 共用检出目录时也很安全。退出码非零时:遇到 commit_lock_busy,重试一次;遇到 integrate_conflict,停止并询问用户应保留哪个版本的 pack.json;遇到 git_push_unavailable,表示无法访问远程服务(提交已保存;稍后使用 --push-only 重新运行),或者当 schema pack 仓库根本没有远程服务时,表示没有提交任何内容:仅在本地提交该 schema pack,运行 git add pack.json && git commit -m "<msg>" -- pack.json。绝不要退回使用 stash、pull --rebase 或普通推送(处理结果)。
如果 brain 守护进程正在运行(gbrain serve --http),其他进程会在 1 秒内获取变更(loadActivePack 中基于 stat-mtime 的 TTL 检查机制 — v0.40.6.0 修复了跨进程失效缺口)。
输出
- 修改后的 schema pack 文件,位于
~/.gbrain/schema-packs/<name>/pack.{json,yaml}。 - 每次变更都会在
~/.gbrain/audit/schema-mutations-YYYY-Www.jsonl中生成一条审计记录。 - 执行
sync --apply后,匹配行中的pages.type会得到回填。 - 查询路径(
whoknows、find_experts)现在会通过新的专家类型进行路由。
约定
- 输入: 指定类型 / 前缀 / 链接动词 / 标志变更的自然语言请求,或者
gbrain schema review-orphans的结果,其中显示了需要新类型的无类型页面。 - 输出: 位于
~/.gbrain/schema-packs/<name>/pack.{json,yaml}的修改后 schema pack 文件 + 位于~/.gbrain/audit/schema-mutations-YYYY-Www.jsonl的审计记录 +(如果执行了sync --apply)已回填至匹配行中的pages.type。 - 副作用: 使进程内 schema pack 缓存和该数据源的查询缓存失效。其他进程会在 1 秒内获取变更(基于 stat-mtime 的 TTL)。
- 幂等性: 每个基本操作都是幂等的。
add-alias/add-prefix遇到重复项时不执行任何操作;第二次运行sync --apply时不会发现需要更新的内容。 - 信任: CLI = 本地信任(不检查作用域)。MCP = OAuth
admin作用域(写入操作)。审计日志会为每次变更记录actor: mcp:<clientId8>。 - 原子性: 每次变更都由
withMutation的原子写入(.tmp + fsync + rename)和每个 schema pack 的O_CREAT|O_EXCL锁封装。写入过程中发生崩溃时,原始文件不会受到影响。
失败时的处理
遇到任何 gbrain 错误 code、退出代码、[AGENT] 块或 notice 块时,请遵循Agent 操作者协议。本技能特有的情况:
- 变更代码:
PACK_READONLY→ 先分叉(gbrain schema fork gbrain-base mine);STILL_REFERENCED→ 先移除指定的引用;LOCK_BUSY→ 等待约 30 秒后重试。 - 通过 MCP 操作时,变更会返回
insufficient_scope:写入 schema 需要adminscope,只有 brain 主机的操作者可以授予;请告知用户。 - 预写入 lint 门禁拒绝变更时:读取错误,修复指出的前缀或别名冲突,然后重新运行;切勿绕过 lint。
反模式
- 不要修改
gbrain-base或gbrain-recommended。 先分叉(gbrain schema fork gbrain-base mine)。这些是内置包;升级时会丢失编辑内容。变更原语会以PACK_READONLY拒绝操作。 - 不要仅因为曾导入某个目录进行分类,就为它添加类型。 包类型是永久性决策;一次性导入则不是。请参阅
skills/conventions/schema-evolution.md中的“少于 20 个页面,不要打包编纂”启发式规则。 - 不要给没有
path_prefixes的类型添加--expert。expert_routing_without_prefixlint 会对此发出警告——没有前缀的专家路由类型永远不会匹配 put_page 推断,因此whoknows不会显示这些类型,且不会有任何提示。 - 未经验证,不要提升
schema suggest候选项。 先运行lint --with-db,再运行add-type,以便在写入前发现前缀冲突。 - 不要混淆“归档单个页面”和“演进 schema”。 归档通过
brain-taxonomist路由;schema-author 用于编写类型分类体系本身。上文的“非目标”部分说明了两者的界限。 - 运行
sync --apply前不要跳过试运行。 始终先运行sync,查看would_apply计数和示例 slug。匹配 50,000 个页面的包前缀可以恢复,但速度很慢;先验证成本很低。 - 移除类型前,务必检查引用。 如果其他类型的
aliases/enrichable_types/link_types/frontmatter_links引用了该类型,remove-type会以STILL_REFERENCED拒绝操作。先解除这些引用;不要添加--force。
输出格式
调用时,此技能会生成结构化输出,既适用于人类阅读,也适用于 JSON 消费:
每次变更的结果(JSON):
{"schema_version": 1, "pack": "mine", "path": "~/.gbrain/schema-packs/mine/pack.json", "format": "json", "prev_sha8": "a1b2c3d4", "new_sha8": "e5f6g7h8"}
每批变更的结果(来自 schema_apply_mutations MCP 操作):
{"schema_version": 1, "pack": "mine", "batch_id": "batch-1716491400-abc123", "mutations_applied": 3, "results": [{...}, {...}, {...}]}
统计 JSON(按来源、汇总及失效前缀提示):
{"schema_version": 1, "pack_identity": "[email protected]+abc12345", "aggregate": {"total_pages": 4823, "typed_pages": 4710, "untyped_pages": 113, "coverage": 0.9766, "by_type": [{"type": "person", "count": 2104}, ...]}, "per_source": [...], "dead_prefixes": [{"type": "researcher", "prefix": "people/researchers/"}]}
Sync 试运行 JSON:
{"schema_version": 1, "apply": false, "pack_identity": "[email protected]+abc12345", "per_prefix": [{"type": "meeting", "prefix": "meetings/", "would_apply": 4000, "sample_slugs": ["meetings/2026-01-01-foo", ...], "dead_prefix": false, "applied": 0}], "total_would_apply": 4000, "total_applied": 0}
人类可读输出(Agent 的最终摘要):
- 每次变更一行:
Pack: <name> (<format>)和Sha8: <prev> → <new> - 统计:页面总数、已分类百分比、未分类数量、按类型细分、失效前缀列表
- Sync:试运行模式下,按前缀列出
would_apply/applied数量及示例 slug
失败时,错误信封遵循标准的 StructuredAgentError 格式:{error, code, message, details?}。变更原语的代码包括:PACK_NOT_FOUND、PACK_READONLY、PACK_CORRUPT、TYPE_EXISTS、TYPE_NOT_FOUND、INVALID_PRIMITIVE、INVALID_RESULT、IO_ERROR、STILL_REFERENCED、LOCK_BUSY。
失败模式
PACK_READONLY→ 你尝试修改gbrain-base或gbrain-recommended。请先分叉。INVALID_RESULT→ 此变更会产生悬空引用或前缀冲突。预写入 lint 门禁已捕获该问题。阅读错误消息;lint 规则名称会指出问题所在。STILL_REFERENCED→ 你尝试移除一个被其他类型的aliases/enrichable_types/link_types/frontmatter_links引用的类型。错误会列出所有引用。请先移除这些引用。LOCK_BUSY→ 另一个进程正在进行变更。等待 30 秒后重试;如果确认持有锁的进程已卡死,也可以传入--force。permission_denied(仅限 MCP)→ 你的 OAuth 客户端没有adminscope。请使用gbrain auth register-client --scopes admin重新注册。