gbrain Doctor 自动修复与评分体系改进:从误报噪声到可观测健康基线
【免费下载链接】gbrainGarry's Opinionated OpenClaw/Hermes Agent Brain项目地址: https://gitcode.com/gh_mirrors/gb/gbrain
gbrain doctor是 GBrain 大脑健康检查的核心命令,它聚合数十项检查(嵌入覆盖率、提取质量、同步新鲜度、多源漂移、frontmatter 完整性、矛盾探测等)并输出健康评分。本篇技术指南基于仓库中的docs/issues/doctor-auto-heal-and-scoring.md设计文档,系统讲解该健康检查体系存在的七类误报与能力缺口,并给出包括严重级别分级、时间感知矛盾判定、漂移基线、自动修复(auto-heal)、评分历史追踪与阈值加权在内的完整改进方案。读完本文,你将掌握 GBrain 健康检查体系的内部评分机制、各项检查的命令行入口与修复命令,以及如何通过配置和.gbrain状态文件把"一次性的健康快照"升级为"可持续观测、可自动修复的运维闭环"。
背景:健康评分体系的误报与缺位
GBrain 的gbrain doctor命令在 src/commands/doctor.ts 中实现,会执行数十项检查并汇总为健康评分。从该文件的实现看,评分机制基于"罚分制":每项检查的状态分为ok/warn/fail,其中fail扣 20 分、warn扣 5 分,最终health_score取max(0, 100 - 罚分)(见 src/commands/doctor.ts)。
同时,doctor 还会输出一个独立的brain_score——它衡量的是大脑数据构成质量,由五个分量加权合成:嵌入覆盖(35 分)、链接密度(25 分)、时间线密度(15 分)、孤立页(15 分)、死链(10 分),并在总分低于 70 时给出warn(见 src/commands/doctor.ts)。此外还区分brain_checks_score(大脑类目下检查失败数的扣分)与category_scores(按类目分别计算的分值),避免单一数字被某类噪声污染。
这套体系的问题在于:大量"检查确实发现了问题、但问题要么是噪声、要么无法人工修复"的情况会让 doctor 常年处于 WARN 状态,真正重要的异常反而被淹没。以下七个改进项按影响力排序,逐一展开。
一、Frontmatter 严重级别分级:让 96% 的噪声不再淹没真问题
问题定义
frontmatter 检查(frontmatter_integrity)报告的问题中,NESTED_QUOTES占了压倒性多数。文档给出的实测证据显示,一次检查共报告 7,131 个问题,分布如下:
frontmatter_integrity: 7131 issues across 3 sources default: 7012 (NESTED_QUOTES=6922, YAML_PARSE=90) media-corpus: 16 (MISSING_OPEN=15, YAML_PARSE=1) zion-brain: 103 (MISSING_OPEN=14, NESTED_QUOTES=89)其中真正需要处理的问题只有 280 个(约 4%),其余 96% 都是NESTED_QUOTES这类外观性 YAML 风格问题——例如title: "foo"这种引号在技术上并非必需。它们不影响同步、搜索、嵌入或任何功能,但当前实现把它们与真正的解析失败(YAML_PARSE)或缺少数值定界符(MISSING_OPEN)等同计权,导致 frontmatter 检查永远处于 WARN,真实问题反而被淹没。
从源码侧看,frontmatter 验证的完整错误码集合在 src/commands/frontmatter.ts 中定义为:MISSING_OPEN、MISSING_CLOSE、YAML_PARSE、SLUG_MISMATCH、NULL_BYTES、NESTED_QUOTES、EMPTY_FRONTMATTER。该文件提供的gbrain frontmatter validate子命令会按错误码分组统计每源数量,既可用于 CI,也可作为 doctor 的输入(见 src/commands/frontmatter.ts)。
改进方案
- 引入严重级别:
error(YAML_PARSE、MISSING_OPEN)vsinfo(NESTED_QUOTES); - doctor 的 WARN/FAIL 判定只依据 error 级问题;
- info 级问题仅在消息文本中报告,不影响检查状态;
- 增加可选
--pedantic参数,将 info 级问题纳入状态判定。
测试用例
| Frontmatter issues | 严重级别分解 | 期望状态 |
|---|---|---|
| 0 个问题 | 无 | OK |
| 仅 50 个 NESTED_QUOTES | 0 error, 50 info | OK(附带说明) |
| 3 个 YAML_PARSE | 3 error | WARN |
| 6900 NESTED_QUOTES + 3 YAML_PARSE | 3 error, 6900 info | WARN(提及 3 个 error) |
这套分级把"噪声占比"与"状态判定"解耦,配合--pedantic又能让严格模式下的 CI 依然能拦住 style 级问题。
二、时间感知的矛盾判定:把"演化"从"矛盾"中解放出来
问题定义
矛盾探测(contradiction probe)会把时间上的演化误判为矛盾。典型场景:
- 页面 A(4 月):“正在考虑方案 X”
- 页面 B(5 月):“已决定采用方案 Y”
这并非矛盾,而是同一主题随时间推进的演化。但探测逻辑缺乏时间意识。文档给出的实测数据显示,在 50 个查询、top-k=15 的一次探测中,共检出 120 条矛盾(112 条 high、8 条 medium),人工复核后发现约 60% 属于时间演化而非真实冲突。而页面本身带有effective_date或created时间戳,完全可以用来消歧。
源码侧的证据
时间感知矛盾判定并非空想——GBrain 的矛盾评估基础设施已经为此预留了接口。在 src/commands/eval-suspected-contradictions.ts 中,探测器的判定类型已经是六分类:no_contradiction、contradiction、temporal_supersession、temporal_regression、temporal_evolution、negation_artifact,并且探测时会把effective_date传给判定侧。在 src/core/eval-contradictions/auto-supersession.ts 中,实现会在双方都带日期且 claim 重叠时,比较effective_date大小并生成temporal_supersession决议(旧页面被新页面取代)。该文件还定义了 verdict 驱动的路由:temporal_supersession表示后发声明取代先发声明、temporal_regression表示回退、temporal_evolution表示演化(见 src/core/eval-contradictions/auto-supersession.ts)。
文档中还提到该能力"已在 PR #993 中设计",核心思路是:将effective_date/created传入 judge prompt,新增temporal_supersession判定,当双方都有日期且声明重叠时,倾向时间解释。
测试用例
| 页面 A 日期 | 页面 A 声明 | 页面 B 日期 | 页面 B 声明 | 期望判定 |
|---|---|---|---|---|
| 2026-04 | “Considering X” | 2026-05 | “Chose Y” | temporal_supersession |
| 2026-04 | “Revenue is $1M” | 2026-04 | “Revenue is $500K” | contradiction |
| null | “X is true” | null | “X is false” | contradiction |
| 2025-01 | “CEO of Company” | 2026-01 | “Former CEO” | temporal_supersession |
值得注意:只有当两个页面都有日期且日期不同时才偏向时间解释;无日期或同日期的冲突仍按 contradiction 处理——最后一行"CEO → Former CEO"的案例说明时间解释能正确处理职业状态的合理变化。
三、多源漂移基线:承认"已知不可修复"的 4,791 个页面
问题定义
约 4,791 个页面被标记为"多源漂移"(multi-source drift),根因是 v0.30.3 之前的一个putPage路由 bug:这些页面存在于default源,但本应归属于某个命名源。用于修复该问题的sources rehome命令尚未发布,因此每次 doctor 运行都会对约 4,800 个无人能修复的页面持续报 WARN。
改进方案
允许通过doctor.baselines配置声明已知不可修复的计数基线:
doctor: baselines: multi_source_drift: 4800当实际漂移数 ≤ 基线时判定为 OK;超过基线时才 WARN(表示出现了"新的漂移")。同时将基线持久化到.gbrain/doctor-baselines.json,使无配置文件场景也能生效:
{ "multi_source_drift": { "count": 4800, "acknowledged_at": "2026-05-15", "reason": "pre-v0.30.3 putPage misroutes" } }源码侧的证据
多源漂移检查在 src/commands/doctor/schema-pack-checks.ts 中实现,其中multiSourceDriftAdvice(count, sampleStr)负责生成修复建议文案;该文件注释明确说明:早期文本曾指向gbrain sources rehome,但该命令从未发布,因此建议文本已更正(见 src/commands/doctor/schema-pack-checks.ts)。此外,multiSourceDriftGitRootSkipNote用于标注因slug_root_mode='git-root'而跳过漂移遍历的页面(见 src/commands/doctor/schema-pack-checks.ts),这类页面被钉在 git 根目录模式下,本就不应参与漂移判定。multi_source_drift检查项也在 src/commands/doctor/report-remote.ts 中被消费,说明它同样出现在远程报告路径中。
测试用例
| 实际漂移 | 基线 | 期望结果 |
|---|---|---|
| 4791 | 4800 | OK |
| 4900 | 4800 | WARN(“比基线多出 100 个新漂移”) |
| 4791 | 0(无基线) | WARN(当前行为) |
基线机制的本质是把"已知历史存量"与"新出现的回归"分离:存量只记录、不报警,新增量才触发告警。
四、图片资产确认:为"故意外置"的图片提供出口
问题定义
当图片文件从磁盘缺失(存于外部存储、或被 git 清理)时,doctor-asset-paths检查会永久性 WARN,且没有任何方式声明"这些图片是有意外置的"。检查逻辑在 src/commands/doctor-asset-paths.ts 中实现。
改进方案
doctor --acknowledge image_assets:将当前缺失数量标记为已接受;- 接受记录存储在
.gbrain/doctor-baselines.json中; - 只对超出已接受数量的新增缺失图片报 WARN;
- 可选配置
image_assets.external_storage: true直接跳过磁盘检查:
doctor: image_assets: external_storage: true该方案与多源漂移基线共用同一持久化文件,形成了统一的"acknowledge 基线"心智模型:先确认存量,再关注增量。
五、Auto-Heal 自动修复模式:让可修复的 WARN 不再需要人工
问题定义
许多 doctor 警告都有已知的、可安全自动应用的修复方案,但当前每次都需要运维人员手动执行。
自动修复映射表
| 警告 | 自动修复 |
|---|---|
| Supervisor 未运行 | 启动 supervisor |
| 嵌入过期(stale embeddings) | 提交embed --stale任务 |
| 提取覆盖率 < 70% | 提交extract all --skip-existing任务 |
| 同步过期 | 提交 sync 任务 |
| 生效日期漂移 | 运行reindex-frontmatter |
这些修复命令在当前仓库中均可找到对应实现:gbrain embed --stale在 src/commands/embed.ts 中被推荐为外部调度器的常规组合(gbrain sync ... && gbrain embed --stale),doctor 的 embeddings 检查在 src/commands/doctor.ts 中会直接给出 "Run:gbrain embed --stale" 的建议;reindex-frontmatter是独立的 CLI 命令(注册于 src/cli.ts),doctor 的生效日期检查在 src/commands/doctor.ts 中会提示运行它来重算。也就是说,本文档设计的 auto-heal 实际上是把这些散落在各检查消息里的"人工建议"编排成"自动提交任务"。
改进方案
doctor --auto-heal模式:
- 先运行全部检查;
- 对可修复的 WARN:以**任务(job)**形式提交修复,而非内联执行——统一走任务队列,保证可观测、可重试;
- 报告哪些已被修复、哪些仍需人工处理;
- 幂等:先检查队列中是否已有相同任务,避免重复提交;
- 安全闸门:绝不自动修复 FAIL 级问题,只处理 WARN。
配置文件示例:
doctor: autoHeal: enabled: true minInterval: "6h" skip: - image_assets - multi_source_driftminInterval: "6h"用于限制自动修复频率,skip列表则把需要人工决策的检查排除在自动修复之外。
测试用例
| 检查状态 | Auto-heal 开启 | 任务已排队 | 期望行为 |
|---|---|---|---|
| WARN: 嵌入过期 | 是 | 否 | 提交 embed 任务 |
| WARN: 嵌入过期 | 是 | 是 | 跳过(幂等) |
| FAIL: max_crashes | 是 | 不适用 | 不自动修复 FAIL |
| WARN: 嵌入过期 | 否 | 不适用 | 仅报告 |
| WARN: image_assets | 是(但在 skip 列表) | 不适用 | 仅报告 |
"修复即任务"的设计是这一方案的关键:自动修复不绕过任务队列,因此修复过程可以被监控、限流和审计,而skip白名单与minInterval共同保证自动修复不会失控。
六、评分增量追踪:从"快照"到"趋势"
问题定义
当前每次doctor运行都只是一次独立快照,没有历史记录,无法判断健康分是在改善还是恶化。
改进方案
- 每次运行追加写入
.gbrain/doctor-history.jsonl:
{"ts":"2026-05-15T12:00:00Z","score":60,"brain_score":79,"checks":{"supervisor":"ok","embeddings":"ok",...}}doctor --trend:展示最近 N 次的分数与增量(delta);doctor --json:在输出中附带previous_score和delta字段。
这条改进与现有--json输出直接兼容。doctor 的 JSON 输出已有稳定的 schema(schema_version=2,见 src/commands/doctor.ts),其中包含health_score、brain_checks_score、category_scores等字段;本文档方案是在此基础上增加时间维度,让监控工具可以直接消费。
--json输出的两个分数口径需要区分:health_score是检查类目层面的扣分制总分,brain_score是 35/25/15/15/10 加权的大脑数据质量复合分(见 src/commands/doctor.ts),二者在历史记录中应分别存储,因为它们的含义不同、变化模式也不同。
七、阈值加权评分:让"最后一公里"被正确衡量
问题定义
当前评分下,嵌入覆盖率从 99% 提升到 100% 的权重,与从 50% 提升到 51% 完全相同。但事实上最后 1% 的难度远大于前 50 个 1%——超长页面、限流等因素使得高覆盖率的边际成本极高。
改进方案
基于阈值的分段评分:
- 100% = 满分
- ≥95% = 获得 90% 的分值
- ≥80% = 获得 70% 的分值
- <80% = 按比例线性计分
例如:嵌入覆盖分项满分 35 分(brain_score的组件之一),若覆盖率为 97%,则得 31.5 分而非按 97% 线性折算的 33.95 分——这样既奖励高覆盖,又不会让 99% 与 100% 的差距造成与 50% 与 51% 同样大的分值差异,分数变化更符合实际改进难度。
该改动仅影响评分算法层,不影响任何检查的 OK/WARN/FAIL 判定,因此风险面极小,可作为低优先级的"锦上添花"项。
优先级与实施路线
按设计文档给出的顺序,改进项的实施优先级如下:
- Frontmatter 严重级别分级——噪声消除收益最高(96% 的误报直接消失);
- 时间感知矛盾判定——误报消除收益最高,且已在 PR #993 中完成设计、当前仓库的六分类判定基础设施(src/core/eval-contradictions/auto-supersession.ts)已经就位;
- Auto-Heal 模式——长期价值最大,把 doctor 从"诊断工具"升级为"诊疗工具";
- 评分增量追踪——为监控与趋势分析提供数据基础;
- 多源漂移基线——生活质量改进,消除约 4,800 个无法修复的常驻 WARN;
- 图片资产确认——生活质量改进,与漂移基线共用同一持久化机制;
- 加权评分——锦上添花,风险最低。
总结:从诊断快照到健康闭环
gbrain doctor健康检查体系改进的核心方向是三个维度:
- 降噪:通过严重级别分级(frontmatter)与时间感知判定(矛盾探测),把"风格问题"和"时间演化"从真正的故障中剥离;
- 可管理:通过
.gbrain/doctor-baselines.json基线机制(多源漂移、图片资产)承认历史存量,让告警只对新增回归生效; - 自动化与可观测:通过 auto-heal 任务编排、
.gbrain/doctor-history.jsonl趋势追踪与阈值加权评分,让健康检查从"一次性的快照"进化为"可持续观测、可自动修复的运维闭环"。
这套改进体系完全围绕 GBrain 的既有架构展开:检查实现位于 src/commands/doctor.ts 及其剥离出的 src/commands/doctor/ 模块树,矛盾判定基础设施在 src/core/eval-contradictions/ 中已预留 verdict 扩展点,修复命令(embed --stale、extract all --skip-existing、reindex-frontmatter)全部存在且已被检查消息引用。任何下游 Agent 或运维人员,都可以依据本文档中每个改进项附带的测试用例表,验证实现是否满足预期行为。
【免费下载链接】gbrainGarry's Opinionated OpenClaw/Hermes Agent Brain项目地址: https://gitcode.com/gh_mirrors/gb/gbrain
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考