mcpField
S
schema-author

schema-author

github.com/garrytan生产力31.3k173 次安装今天更新
代码仓库

关于 schema-author

schema-author 是用于演进 gbrain schema pack 的技能,面向需要定义页面类型、前缀和链接类型的维护者。它涵盖候选类型评估、校验、变更和同步回填,并提供 dry-run 与审计记录。

主要功能

  1. 01评估 schema 覆盖率和未分类页面
  2. 02检测或建议候选类型
  3. 03添加页面类型和链接类型
  4. 04运行 lint 校验变更
  5. 05预览并同步回填页面类型
  6. 06记录 schema 变更审计

适用场景

  1. 01为研究者或论文页面新增类型
  2. 02整理目录下未分类的历史页面
  3. 03将新前缀映射同步到现有页面
  4. 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 需要 admin scope,只有 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_prefix lint 会对此发出警告——没有前缀的专家路由类型永远不会匹配 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 客户端没有 admin scope。请使用 gbrain auth register-client --scopes admin 重新注册。

评论

支持 Markdown