这是上一篇拆解 Matt Pocock skills 的文章的续篇。上一篇拆解了 Pocock 的设计思想——这篇把这些思想应用到一个真实的场景:昇腾训练和推理支持团队的日常问题定位。这不是一个已实现的系统,而是一个从具体约束出发、经过两轮自我审视后收紧过的体系设计草案。


1. 场景与约束

角色是昇腾支持工程师,接口 MindSpeed-LLM、MindSpeed-MM、veRL、vllm-ascend、SGLang 等框架在 A2 / A3 / A5 不同架构上的客户问题。问题覆盖三类:

  • 功能中断:框架报错、进程崩溃、通信 hang
  • 精度异常:loss 异常、FP8 衰减、allreduce 精度退化
  • 性能退化:吞吐下降、step time 波动、EP 通信占比过高

有四个约束决定了这个体系不能照搬 Pocock:

  1. 团队不能统一使用同一个 AI coding agent——公司网络限制和工具偏好导致诊断对话分散在多个 AI Chatbot(Claude Code、Kimi、DeepSeek 网页版)甚至纯手工排查中。
  2. 已有大量历史案例,但格式混乱——截图、IM 聊天记录、个人笔记都有。
  3. 新 case 每周新增 5-10 个,且 A2 / A3 / A5 的差异持续扩大。
  4. 个人维护能力有限,任何需要一个人持续手工维护的方案都会在三周内腐化。

约束 1 和约束 4 是两把最硬的尺子:前者决定了"诊断能力"无法均匀分布到每个团队成员的工具上,后者决定了任何引入重型基础设施(向量库、复杂流水线)的方案都会失败。下面所有设计决策都反复用这两把尺子量过。


2. 体系概览:三层架构

+-----------------------------------------------------------+
| Skill 层:agent 可加载的 markdown 指令(低频变更)            |
| /diagnose            核心诊断循环(含 Tier-2-miss 自起草)     |
| /emergency-triage    生产中断时的紧急排查                      |
| /resume-diagnosis    读取状态文件,续接被打断的诊断             |
| /to-postmortem       从任意来源(含外部对话)沉淀知识           |
| /knowledge-groom     周期性维护:升格/校验/退休/置信度/速查表    |
+-----------------------------------------------------------+
| Knowledge 层:agent 与人共用的数据                            |
| Tier 1  triage-tree.yaml   症状→namespace 路由(≤30 分支)    |
| Tier 2  knowledge/<ns>/    结构化 case(两阶段加载)           |
| Tier 3  postmortems/       原始记录(v1 关键词检索)           |
|         CHEATSHEET.md      groom 自动生成的人读速查表          |
+-----------------------------------------------------------+
| Script 层:已有工具链 + 薄胶水                                |
| ascend-profile-analyze / mem-analyze / bench-run /          |
| collect-profiling / machine-ops                             |
| log-format-contracts/   框架日志字段的稳定性契约(新增,薄)     |
+-----------------------------------------------------------+

先说清三层的边界,因为"skill"这个词很容易被用成全栈概念:

  • Skill 层就是 agent 能加载的 markdown 文件——YAML 头(name/description/可选 disable-model-invocation)+ 自然语言 body + 用相对路径引用的参考文件。skill 的 body 是写给模型看的指令,不是给程序解析的。
  • Knowledge 层是数据:agent 和人都读、都写。
  • Script 层是真正动手执行命令的工具链。它不是 skill 的一部分,而是 skill 在某个步骤里调用的外部能力。

这个体系里真正复杂的是知识架构(Knowledge 层),但真正容易设计错的是 skill 与 harness 的接缝(§4、§6、§15)和 agent 执行的可靠性(§3 原则 7、§9.2、§11)。

一条 case 的完整生命周期(注意路径 A/B 能力不对称,详见 §7):

定位问题(两条路径,能力不对称)
    |
    +-- 路径 A:在 Claude Code / Codex 中协作诊断
    |       agent 可执行命令、读日志、跑 Script
    |       -> 跑 /diagnose(自动诊断 + 知识匹配 + 过程 trace)
    |       -> Tier-2 命中:给 fix;Tier-2 未命中但最终解决:
    |          agent 当场起草候选 case,附在 postmortem 里(自起草,§4.1)
    |       -> session 结束(经 harness hook)生成 postmortem 草稿
    |
    +-- 路径 B:用 Kimi / DeepSeek 网页版 或 纯手工
    |       无法执行命令——/diagnose 不可用
    |       -> 人对照 CHEATSHEET.md 手动排查
    |       -> 把对话/笔记粘贴给 /to-postmortem 沉淀
    |
    +-- 共同出口:postmortem.md -> postmortems/YYYY-QN/

/knowledge-groom(每周运行)
    -> 扫未处理 postmortem(含 agent 自起草的候选 case)
    -> 人审批 -> 结构化 + 语义校验 -> 追加 knowledge/<ns>/
    -> 校验 references / 值重复 / 计算 confidence_score / 软退休
    -> 重新生成 CHEATSHEET.md

3. 设计原则

七条原则。前六条从 Pocock 适配,第六条是这个场景逼出来的,第七条是第二轮审视补的——也是最容易被忽略、最致命的一条。

原则 1:一个 skill 只做一件事,做完就停。
初稿把整条诊断链塞进一个 skill,违反了这条。修订版拆成五条(§4)。一条 skill 的 body 不应长到模型会在 session 后段忘掉前面的分支。

原则 2:人判断不能被自动化取代,但可以被结构化。
skill 不替人做诊断决策——它给出结构化验证清单,人执行后把结果贴回来,agent 分析后给出下一步。

原则 3:上下文窗口是有限资源,要显式管理——且真正的消耗是日志,不是知识库。
诊断 session 的 context 八成是 profiler 数据和 log 输出,知识库只占小头。所以预算目标不是"压到 15% 窗口",而是"给日志留出足够空间"。详见 §6。

原则 4:知识不绑定在 skill body 里。
skill body 只写诊断方法论。具体的 case rules 存在 knowledge/ 下,按需加载。
一个诚实的例外:Tier 1 的 triage-tree.yaml 表面上是知识(YAML 格式),实质是 skill 的控制流外置——它决定加载哪些 namespace,是诊断程序的"分派表"。维护它等于维护 skill 的一部分,所以它低频变更、由体系维护人主导。

原则 5:知识沉淀是 side effect——诊断中解决的新问题,agent 当场起草候选 case,人只做验证。
诊断完不让人写文档。更激进的一步:当 Tier-2 未命中、靠深度排查最终解决时,/diagnose 直接起草一条候选 case(quickly_check + diagnosis + 置信度 low),随 postmortem 一起交给 groom。人的角色从"结构化混乱对话"上移到"验证 agent 起草的草案"——人在更高价值的环节。这是把被动 KB 升级成自起草 + 人验证的半自动 KB,但不放弃原则 2(人不做结构化,但仍是最终判断者)。

原则 6:诊断能力绑定执行力,沉淀能力对所有工具开放。
这是约束 1 逼出来的:能跑 bash 的 agent(路径 A)才能诊断;任何工具(含路径 B 的网页版对话)都能通过 /to-postmortem 沉淀知识。不要假装"诊断也与工具解耦"——它没有。这条原则让 §7 的 A/B 分工成为一等公民,也让 CHEATSHEET.md 从"离线备用"升级为"路径 B 的主诊断入口"。

原则 7:执行过程必须可观测——否则误诊无法归因。
这是第二轮最深的发现。整条诊断链是一台有 7+ 分支的状态机,但 LLM 是随机的过程执行器。如果没有过程日志(加载了哪些 namespace、按什么顺序跑了哪些 check、是否标了 low_confidence),一次误诊就无法区分"case 错"还是"agent 执行错"——而两者的修复路径完全不同。混在一起会让 groom 去改一个本来正确的 case,这是会主动污染知识库的错误反馈回路。所以 /diagnose 每步都写 trace(§11),误诊先读 trace 归因(§9.2 第四层)。


4. Skill 层:五条 skill,各司其职

4.1 /diagnose —— 核心诊断循环

合并了初稿的 /diagnose-training-issue/diagnose-inference-issue。训练/推理的区别是 namespace 的事,不是 skill 的事。

流程(核心循环详见 references/diagnosis-procedure.md):
1. 收集症状
   - 错误信息、环境变量、框架版本、硬件平台
   - 自动检测框架:pip list | grep -i 'mindspeed|vllm|sglang|verl'
   - 主动裁剪日志:只贴相关 rank、只贴报错栈最后 N 行(§6)

2. 分类 -> 加载 triage-tree.yaml(Tier 1)
   - 记录 triage 决策到 trace(命中哪个分支、路由到哪些 namespace)—— §14 路由准确率依赖它
   - 框架检测到 -> 先搜 training|inference/<framework>/,再搜 common/
   - 框架未检测到 -> 只搜 common/
   - triage 置信度低(多个分支弱匹配)-> 优雅退化:加载所有 namespace 索引(§5.4)
   - 无法分类 -> 直接 Tier 3 关键词检索

3. 诊断(两阶段加载 Tier 2,见 §6)
   - 阶段一:加载命中 namespace 的索引(id/title/symptoms/quickly_check/confidence)
   - 跑 quickly_check(primary + fallback)过滤出候选 case
   - 阶段二:全量加载候选 case,按 confidence_score 降序验证
   - 命中 -> 输出 root cause + fix(附 rollback)
   - 未命中 -> 进入深度排查
   - 每步动作写 trace(§11)

4. 深度排查(Tier 2 未命中)
   - 调用 Script 层(§15):ascend-profile-analyze / mem-analyze 等
   - Tier 3 关键词检索提供启发式提示
   - 人工/agent 联合分析

5. 产出
   - resolution: resolved / escalated / unknown
   - Tier-2 命中:常规 postmortem 草稿
   - Tier-2 未命中但最终解决:postmortem 含一段 agent 起草的候选 case(原则 5),
     标 confidence_score 初始值,交 groom 验证
   - 完整 trace 随 state 文件留存(§11)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
---
name: diagnose
description: >
  昇腾训练/推理问题的核心诊断循环。收集症状、按 triage-tree 路由、
  两阶段加载并验证 Tier 2 case、命中给 fix 或转深度排查。
  Tier-2 未命中但最终解决时起草候选 case。全程写 trace。
  仅在能执行命令的 agent(Claude Code / Codex)中可用。
disable-model-invocation: true   # 诊断决策需要人触发
---

# Diagnose

## 何时用
出现训练或推理问题,且你在能执行 bash 的 agent 中。
路径 B(网页版/手工)请改用 CHEATSHEET.md。

## 流程
核心循环见 references/diagnosis-procedure.md。
平台分派见 references/platform-dispatch.md。Script 调用见 §15。
每步必写 trace 到 diagnosis_state.yaml(§11)——这是原则 7 的硬要求。

## 不要做
- 不要替人决定 root cause——给结构化清单,人执行后贴回结果。
- 不要连续尝试第三个 case——两次未解决即转人工(§9.2)。
- 不要把全量 profiler 灌进 context——裁剪到相关 rank + 栈尾(§6)。
- 生产中断请改用 /emergency-triage;被打断后续接用 /resume-diagnosis。

把重分支逻辑外置到 references/*.md、而不是全塞进 body,是控制 drift 的关键。真实的复杂 skill(如 HyperFrames)就是这么做的。

disable-model-invocation: true 是 Claude Code 专属开关——标记后该 skill 只能 /diagnose 显式调用。在 Kimi/DeepSeek 这类没有 invocation 机制的工家里,“user-only"靠工作流规范保证。这条原则只在路径 A 可强制,承认这一点比假装它跨工具成立更诚实。

4.2 /emergency-triage —— 生产中断时的紧急排查

/diagnose 里拆出来。紧急模式的流程和正常诊断完全不同(跳过分类、不改配置、不记 postmortem),混在一个 skill 里只会让 body 更长、更容易 drift。

触发:人显式说"生产中断/紧急/先恢复服务",或直接 /emergency-triage

流程:
1. 跳过症状分类和 Tier 2 匹配(不改任何配置)
2. 加载 CHEATSHEET.md 的"紧急恢复"部分(人工维护,见 §13)
3. 输出人类可读排查清单,每项标注 risk(safe / caution)
4. 不记录 postmortem——等事后手动跑 /to-postmortem

终点:服务恢复。事后知识沉淀是异步的,不阻塞恢复。

4.3 /resume-diagnosis —— 续接被打断的诊断

流程:
1. 读 diagnosis_state.yaml(§11,含 trace)
2. 复述上次停在哪一步、排除了哪些 case、当前 active case
3. 等待人执行上次要求的命令并贴回输出,继续诊断

4.4 /to-postmortem —— 从任意来源沉淀知识

解决的核心问题:团队成员不一定用同一个 agent 做诊断,因此知识注入入口必须与诊断工具解耦。这是路径 A/B 唯一对等的环节

用法:
  /to-postmortem "[粘贴 Kimi/DeepSeek 的完整对话]
                  [或粘贴纯手工排查笔记]"

流程:
1. 从输入中提取症状、命令和输出、排除的假设、root cause、fix
2. agent 检测或推断框架,给命名空间建议,人确认(约 5 秒)
3. 输出结构化 YAML 草稿 + postmortem.md
4. 语义校验(关键,见下):
   - regex 在输入附的真实日志片段上能否匹配
   - expected 值类型/数量级合理性
   - command_template 里的路径在已知部署模板里是否存在
   校验失败 -> 标 needs-structurer-review(与 needs-human-review 区分)
5. 脱敏扫描(§13)-> 人扫一眼确认 -> done

needs-structurer-review vs needs-human-review 是两个不同的闸门。后者是"语义不明,人要补充”;前者是"格式/语义可疑(regex 不匹配样例、期望值离谱、路径不存在),人要核对"。区分它们是因为:一个格式良好但语义错误的 case(比如 expected: ">= 4194304" 其实该是 8388608)比没有 case 更糟——它造成确定性误诊。结构化是全系统错误率最高的环节,却曾得到最少的校验,这一步补上。

命名空间确认不是额外管理负担——它是一种轻量质量检查。当人在 training/mindspeed-llm/common/ 之间选择时,本质上在自问"这个问题是框架特有的还是通用的",这个自问本身就能暴露误判。

4.5 /knowledge-groom —— 周期性维护

体系的演化引擎。完整职责见 §8,这里只列它干什么:

触发:手动运行,建议每周一次

流程:
1. 扫 postmortems/ 新增且通过审批的 .md(含 agent 自起草的候选 case)
2. 逐个尝试结构化 + 语义校验 -> YAML -> 追加 namespace
3. 校验所有 references 可达;检测框架 case 是否硬编码了 common/ 权威值(§8.1)
4. 重算每条 case 的 confidence_score(hits/misdiagnoses,§5.5)
5. 软退休检测:过期 case 移入 _archive/(§5.7)
6. namespace 拆分建议(>30 条时)
7. 重新生成 CHEATSHEET.md(§13)
8. 产出 PR:变更列表 + 高风险变更标记 + 各类建议

5. Knowledge 层:三层与命名空间

5.1 命名空间设计原则

命名空间的分割维度只有一个约束:在 case 创建时就能确定的东西可以做分割,需要诊断完成后才能确定的东西留给 groom 去整理

  • 框架名——session 开始 30 秒内就能确定。创建 case 时即可分到对应 namespace。
  • root cause 层(CANN / HCCL / NPU driver?)——这是诊断的目标,不是输入。所以不做 cann/hccl/ 预分割。等同一个 root cause 在多个框架 namespace 重复出现时,groom 提取到 common/

这条原则是整个知识架构的地基——它防止了经典的"过度分区"失败:用一个诊断结束时才知道的维度去预分割,结果一半 case 被放错桶。它也是一条可移植的元原则:只在写入时可知的维度上做分割

5.2 目录结构

初始 namespace 平铺。等单个 namespace 超 30 条 case 时,groom 给拆分建议,这时才建子目录。

knowledge/
+-- training/
|   +-- mindspeed-llm/
|   +-- mindspeed-mm/
|   +-- verl/
+-- inference/
|   +-- vllm-ascend/
|   +-- sglang/
+-- common/                  # 框架检测失败 -> 兜底;groom 发现多框架共用 -> 提升
+-- _archive/                # 软退休的过期 case(不进检索索引)
+-- _drafts/                 # agent 自起草、待 groom 验证的候选 case(可选,也可并入 postmortem)
+-- platforms/
    +-- a2-910a.md
    +-- a3-910b.md
    +-- a5-910c.md

5.3 common/ 与框架层的引用关系

框架层 case 保留框架特有的诊断步骤,但在 root cause 层面引用 common/ 的权威记录:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# training/mindspeed-llm/ep_hang.yaml
cases:
  - id: MSLLM-EP-HANG-001
    references: common/hccl/buffer_config.yaml#ASCEND-HCCL-BUFFER-001
    diagnosis:
      - step: 1
        command_template: "grep 'all_to_all' {{log_path}}"
        rank_selector: coordinator
        expected: "regex:timeout"
    root_cause: "same as referenced case"
    fix: "See referenced case."

references 可选——只有 root cause 被确认为多框架共用的底层问题时才填。这是整个体系最优雅的演化机制:知识图谱 bottom-up 生长,等重复 root cause 自然浮现才提升,而不是事前猜。

5.4 Tier 1: triage-tree.yaml(分类路由 + 退化)

每条分支指向多个 namespace,按顺序搜索。<detected_framework> 是 §4.1 自动检测的结果。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
branches:
  - id: training_hang
    symptoms:
      - "timeout" | "hang" | "stuck at step"
      - "NCCL.*timeout" | "HCCL.*timeout"
    search_namespaces:        # 最多加载 3 个
      - training/<detected_framework>/
      - common/
    fallback: Tier 3
  - id: uncategorized
    symptoms: []
    search_namespaces: [common/]
    fallback: Tier 3

两个第二轮补的机制

  1. triage 决策必须记进 trace(命中哪个分支、路由到哪些 namespace)。§14 的"路由准确率"指标依赖它——这是把"路由错"(分到错的 namespace)和"KB 空"(分对了但没匹配 case)分开测的前提,两者修复动作相反。
  2. 优雅退化:当 triage 多分支弱匹配、置信度低时,不只 fallback 到 common/,而是加载所有 namespace 的索引让 quickly_check 自己筛。这能救冷启动——triage-tree 在第一周是猜的,退化机制保证已播种的 case 不会因路由错而不可达(§12)。索引很便宜(§6),退化成本可接受。

分支数不超过 30。框架检测失败时只用 common/。三个 namespace 还不够说明症状太模糊——直接走 Tier 3。如前所述(原则 4 例外),triage-tree 是 skill 控制流的 YAML 外置,由体系维护人维护。

5.5 Tier 2: 结构化 case entry(两阶段加载 + 学出置信度 + 分布式参数化)

schema 在第二轮做了三处升级:命令参数化(command_template + rank_selector)、置信度学出来(confidence 由 groom 计算)、版本兼容非单调(compat)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
cases:
  - id: MSLLM-EP-HANG-001
    title: "HCCL buffer undersize for large-scale EP dispatch"
    platforms: ["A5-910C", "A3-910B"]
    compat:                              # 非单调版本区间
      - framework: mindspeed-llm
        ranges: [">=2.4.0,<2.7.0", ">=2.8.0"]   # 2.7 因重构失效,2.8 恢复

    confidence:                          # groom 计算,非人设定
      hits: 18
      misdiagnoses: 1
      score: 0.86                        # hits/(hits+misdiagnoses),按时间衰减
      last_hit: "2026-W28"

    symptoms:
      - "all_to_all_single hangs at step usually after 1000+"
      - "world_size >= 64"

    references: common/hccl/buffer_config.yaml#ASCEND-HCCL-BUFFER-001

    quickly_check:                       # 阶段一加载——过滤
      primary:
        command_template: "grep -c 'all_to_all' {{log_path}}"
        rank_selector: coordinator       # 只查协调者 rank
        expected: "regex:^[1-9]"
      fallback:
        command_template: "grep -ci 'timeout|hang|stuck' {{log_path}}"
        rank_selector: all_failed        # 查所有失败 rank
        expected: "regex:^[1-9]"

    diagnosis:                           # 阶段二加载——仅候选 case
      - step: 1
        command_template: "env | grep HCCL_BUFFSIZE"
        rank_selector: coordinator
        expected: ">= 4194304"
        fix_on_mismatch: "export HCCL_BUFFSIZE=4194304"
        rollback: "unset HCCL_BUFFSIZE"

    next_on_fail: "MSLLM-EP-HANG-003"

    root_cause: "HCCL internal buffer insufficient for EP all-to-all"
    fix: "export HCCL_BUFFSIZE=4194304 before training launch"

关键设计决策:

  • 两阶段加载:阶段一 agent 只读 id/title/symptoms/quickly_check/confidence(约 70 token/条),跑 quickly_check 过滤出 ≤5 候选;阶段二才全量加载候选 body。阶段二按 confidence_score 降序验证——命中最可靠的优先。
  • 分布式参数化command 升级为 command_template(含 {{log_path}} 模板变量,agent 按检测到的部署填充)+ rank_selectorcoordinator / all_failed / rank_0 / by_topology)。这把"查哪个 rank"从 agent 临场决定变成 case 作者显式声明——分布式领域(world_size >= 64)不能只查 rank 0。
  • 学出的置信度confidence.score 由 groom 从 hits/misdiagnoses 计算(按 last_hit 时间衰减),不由人设定。候选排序、§8.2 的优先级、§9.2 的"低置信一次失败即转人工"都基于它。旧的 priority 字段废弃——它是人拍脑袋的,score 是数据派生的。
  • 非单调版本兼容compat.ranges 是区间列表,能表达"2.4-2.6 有效、2.7 失效、2.8 恢复"。groom 在框架发新版时检查每条 case 的区间是否需更新。
  • next_on_fail 可选。references 可选。

ID 命名规范<NAMESPACE_PREFIX>-<AREA>-<NNN>。框架 namespace 用缩写(MSLLM/VASC/SGL/VERL),common/ASCEND 前缀。

common/ 子路径的时机common/ 初始平铺。只有 groom 发现某 root cause 在多个框架 namespace 重复出现时,才建子目录(如 common/hccl/)。

5.6 Tier 3: postmortems/(v1 关键词检索)

原始诊断记录,不做结构化。仅用于 T1/T2 未命中时的兜底。

v1 用关键词检索,不上向量库。原因很硬:大多数 coding harness 没有原生向量存储,搭一套 embedding + 索引 + 查询 + 增量更新是和 Script 层量级相当的基础设施,违背约束 4。关键词检索是 harness 原生的(rg 谁都有),零额外维护。

具体做法:agent 用症状关键词 rg -l '<keyword>' postmortems/,取 top-3 文件读片段。粗糙但够用——Tier 3 本来就是兜底。

向量检索列为 v2+ 候选,三个条件同时满足才考虑:(a) Tier 2 超 150 条;(b) 未命中率持续 > 40% 两周;(c) 有人愿意 owning 索引基础设施。在此之前,任何"加个向量检索"的提议都按违反约束 4 拒绝。

文件由 session-end summary 或 /to-postmortem 生成,按季度目录归档。缺少 root_causesymptoms 的记录不进检索候选。

5.7 退休机制:知识只长不缩是 bug

compat 区间之外的版本、last_hit 过久的 case 必须能退出活跃集,否则会持续占索引、制造误诊。

软退休规则:区分两种"未命中"——

  • cold(从未被 quickly_check 选中为候选):不退休。一条正确但罕见的 case 占索引成本极低(~70 token,见 §6),保留它比误删更划算。误删一条罕见但正确的 case 是静默知识损失,且无法被发现。
  • tried-and-failed(被选中为候选但近 12 周都未解决):若同时 confidence.score 低 → 移入 knowledge/_archive/
  • 版本过期compat 区间已被框架主线超过 → 移入 _archive/(与是否命中无关)。

退休是"软"的——不是删除,是退出活跃集。trace(§11)能区分 cold 和 tried-and-failed:候选加载记录在 trace 里,没有加载记录的就是 cold。

compat 的非单调设计让退休也能"复活":一条 case 在 2.7 退休,2.8 恢复兼容时 groom 检测到新区间、从 _archive/ 移回。

Tier 2 总量上限触发合并(§8.3)是另一处收缩,但合并策略必须显式写进 PR。


6. 检索策略与上下文预算

第一轮重算过一次 token 表。第二轮加一行(退化场景):

内容加载策略估算 token
Tier 1triage-tree ≤30 分支始终全量~3.5K
Tier 2 阶段一命中 namespace 索引按分支加载 ≤3 namespace~5K
Tier 2 阶段一(退化)所有 namespace 索引triage 低置信时(§5.4)~10K
Tier 2 阶段二候选 case body仅候选 ≤5 条~1.5K
Tier 3postmortem 关键词片段rg top-3~5K
平台platforms/.md按检测平台~0.5K
知识库合计(正常/退化)~15-16K / ~20K
日志/profiler 输出命令执行结果——50-100K+

两个结论:

  1. 知识库不是瓶颈。两阶段加载 + 索引便宜,让优雅退化(加载所有 namespace 索引)的最坏情况也只到 ~20K,仍可控。退化的可行性正是两阶段设计的回报。
  2. 真正吃 context 的是日志。一次 EP hang 的 profiler 输出轻松 50K+。所以 /diagnose 必须主动裁剪日志(只贴相关 rank、只贴报错栈最后 N 行),否则模型把全量灌进窗口。过程 trace 写到 diagnosis_state.yaml 文件,不进 context——它不消耗推理窗口,只消耗磁盘。

Pocock 的 “smart zone”(约 120K 推理最锐利)在这里的直接含义:KB ~16K + 裁剪后日志 ~40-60K ≈ 60-80K,留在 smart zone 内。日志不裁剪就滑出 smart zone。


7. 知识注入与协作(诚实的 A/B 框架)

核心目标精确表述:知识沉淀对所有工具开放,诊断能力只对能执行命令的 agent 开放。这两件事不一样。

路径 A:agent 协作诊断路径 B:外部定位
使用场景工程师用 Claude Code / Codex工程师用 Kimi / DeepSeek 网页版或手工
能否诊断——跑 /diagnose不能——无法执行命令
诊断入口/diagnose 自动诊断 + 知识匹配人对照 CHEATSHEET.md 手动排查
能否沉淀——session-end hook 自动生成 postmortem;Tier-2-miss 时 agent 自起草候选 case——/to-postmortem "[粘贴对话]"
人需要做什么扫一眼确认 root cause 和 fix(30s)同左
后续/knowledge-groom 定期升格到 Tier 2同左

这张表让 CHEATSHEET.md(§13)的战略地位变了:它不是"agent 挂了时的离线备用",而是路径 B 的主诊断入口。约束 1 决定了一部分团队成员注定在路径 B——给他们一个能用的、人读的、和 YAML 同源的速查表,比指望他们都切到 Claude Code 现实得多。

“session 结束时 agent 自动跑 summary"在路径 A 里需要一个 harness 钩子(Claude Code 的 session-end hook),不是 skill 本身能保证的。这条要写进部署清单。

团队分工

角色职责
一线工程师路径 A 跑 /diagnose、路径 B 查 CHEATSHEET;诊断完跑 /to-postmortem;扫一眼确认
领域 owner审批 /knowledge-groom 的升格 PR(高风险变更强制深审,§8.5);手补无法结构化的 case
体系维护人维护 triage-tree、审议 namespace 合并/拆分、裁决 confidence 争议、裁决退休、裁决跨团队 common/ 冲突(§8.6)

8. 演化与维护

体系需要自我约束——不加控制的增长会摧毁检索效率。这一节合并了所有演化机制。

8.1 /knowledge-groom 的完整职责

每周跑一次(连续四周无新 postmortem 则自动切双周)。一次 groom 产出是一个 PR:

  1. 升格:扫未处理 postmortem(含 agent 自起草的候选 case),结构化 + 语义校验 → YAML → 追加 namespace;语义校验失败标 needs-structurer-review,语义不明标 needs-human-review
  2. 引用完整性校验:扫所有 references,检查指向真实存在的文件和锚点。悬挂引用进 PR 报告。
  3. 值重复检测:检测框架 case 的 expected/fix_on_mismatch 是否硬编码了 common/ 权威记录拥有的值。是 → 标 must-fix,要求改成引用。这堵住 references 是软链接、值却各自为政的一致性漏洞。
  4. 置信度重算:从 hits/misdiagnoses/last_hit 重算每条 case 的 confidence_score
  5. 软退休last_hit 超 12 周且 compat 区间过期的 case → 移入 _archive/(§5.7)。检查 _archive/ 中 case 是否因新 compat 区间该复活。
  6. namespace 拆分建议:某 namespace 超 30 条 → 报告内容分布 + 拆分建议。
  7. 同 namespace 合并建议
  8. CHEATSHEET 重生成(§13)。

8.2 演化信号

信号触发动作
单 namespace 超 30 条groom 给拆分建议——这时才建子目录
两个框架 namespace 各有条 case 指向同 root causecommon/ 下建权威记录,框架层加 references
Tier 2 整体未命中率 > 60% 持续两周先看路由准确率(§14):路由准确率低→改 triage-tree;路由准但未命中→加 case
某 case confidence.score 高且命中频繁自动进入候选优先验证队列
某 case confidence.score 低且仍被加载标记待复审;命中一次失败即转人工(§9.2)
某 case 标 needs-structurer-review 超 14 天提醒领域 owner
某 case tried-and-failed 12 周且 confidence.score 低,或 compat 版本过期软退休到 _archive/(cold case 不退,§5.7)
发现悬挂 references 或值重复进 PR 报告,标 must-fix

8.3 不增长的约束(v1 假设,非教条)

这些都是 v1 起点假设,应在每季度 metrics 回顾(§14)里按真实检索 precision/recall 调整:

  • Tier 2 单 namespace 上限 30(超限触发拆分建议)
  • Tier 2 总量上限 200(超限强制合并——合并策略必须显式写进 PR:合并哪两条、以哪条为主、被合并方 ID 重定向到主条)
  • Tier 1 上限 30 分支
  • Tier 3 最小质量阈值(缺 root_cause/symptoms 不进检索)

正确做法是季度回顾测 namespace 在 20 vs 40 条时的检索拐点,用数据校准。

8.4 PR 积压处理

演化被人注意力瓶颈锁死——和约束 4 最直接的冲突。每条升格都要人审,每周 5-10 新 case,单个 owner 必然积压。

  • groom 每次报告 backlog 大小。
  • backlog > 20 条触发临时 groom 会话,体系维护人介入分摊审批。
  • backlog 连续三轮增长,作为 §14 红色信号上达,触发职责重新划分。

8.5 Review 批量协议:对抗疲劳

owner 批 PR 是二元闸门,但一个 session 里审 30 条 PR,第 30 条得到的 scrutiny 远少于第 1 条。misdiagnosis 信号是事后捕获错误,不是 review 时防错。

  • groom PR 在 session 内随机排序审,避免靠前的总被细看、靠后的总被略过。
  • 自动标高风险变更为强制深审,不进 30 秒快通道:新建 common/ 权威记录、改 expected 值、改 fix_on_mismatch、改 compat 区间、confidence.score 被手动覆盖。
  • 高风险变更要求两个 owner 签字(领域 owner + 体系维护人)。

8.6 联邦 common/:当组织是碎裂的

设计假设"团队"是一个整体。但约束 1 和训练/推理两个子团队的现实暗示组织可能碎裂。如果两个子团队各自跑 groom,各自在 common/ 下为同一个 HCCL root cause 建权威记录——common/ 会 drift。

  • 协议先于实现:定义 common/ 权威记录的唯一性约束——同一 root cause 只允许一条权威记录,跨团队冲突由体系维护人裁决。
  • groom 检测跨团队 common/ 重复(root_cause 文本相似度 + 关键字段比对),报告冲突,不自动合并。
  • 先写规则,等真出现 drift 再实现自动化——不要为一个还没发生的组织问题提前建系统。

9. 诊断匹配的边界情况

9.1 quickly_check 的衰减:regex 只是权宜之计

quickly_check 是 Tier 2 匹配的性能关键。系统性盲区:日志格式随框架升级改变,grep 匹配不到,即使 root cause 正确,case 也被跳过。这是必然事件。

分层回退(primary + fallback + low_confidence)能缓解,但fallback 也是 regex,只是衰减得慢一点。真正的解法在 Script 层:

版本化的日志格式契约。让各框架承诺一组稳定的错误标识(error_code 字段,或保证向后兼容的子串如 [HCCL_E_TIMEOUT])。quickly_check 优先匹配稳定标识,而不是自由文本。这要求框架团队配合(在 log-format-contracts/ 下维护契约),把"日志漂移导致 case 失效"从必然事件降成可控事件。

契约建立前,双 regex 是权宜之计,靠 §8.2 的未命中率信号及时修补。

9.2 误诊保护:匹配到 ≠ 解决了

两个 case 可能有几乎相同的症状却完全不同的 root cause。四层保护:

层一:fix 标注回滚。每个 fix_on_mismatch 携带 rollback

层二:串联保护。agent 连续两次匹配到不同 case 且第一次 fix 没解决 → 强制转人工,不再尝试第三个 case。写入 /diagnose body 和 references/diagnosis-procedure.md

层三:误诊率追踪。case 命中但 fix 未解决时,标 misdiagnoses += 1 并更新 last_hit。误诊率比未命中率更关键——高未命中率说明库不够大,高误诊率说明库有错误信息。

层四:执行-误诊归因(process fidelity,原则 7)。每次误诊,先读 diagnosis_state.yaml 的 trace 判断是 case 错还是执行错

  • trace 显示 quickly_check 顺序跑对、check 命令执行结果也对、但 root cause 判断错 → case 错,改库。
  • trace 显示 agent 跳过了 fallback、加载了错误 namespace、或没标 low_confidence → 执行错,改 skill body 或 references/。

两者修复路径完全不同。混在一起会让 groom 去改一个本来正确的 case——这是会主动污染知识库的错误反馈回路。trace 是堵这个洞的唯一手段。

9.3 多跳诊断:next_on_fail

可选字段 next_on_fail 指向下一个应尝试的 case id。

自动生成需 session 级 case 共现遥测,v1 没有——所以 v1 完全靠人手工填,自动生成标为 v2+。注意:trace(§11)已经记录了 session 内命中的 case 序列,这套数据正是 next_on_fail 自动生成所需的输入——所以 v2 不需要新建遥测层,只需要分析 trace。

9.4 平台差异:字段级而非 case 级

一个 case 可有多组 diagnosis,对应不同平台:

1
2
3
4
5
diagnosis:
  - platforms: ["A5-910C", "A3-910B"]
    steps: [ ... ]
  - platforms: ["A2-910A"]
    steps: [ ... ]

platforms/*.md 存平台级背景知识。agent 加载 Tier 2 时同时加载匹配平台差异文件。


10. 紧急模式:生产挂了的时候没人想走流程

独立成 /emergency-triage(§4.2)。紧急排查后的 postmortem 由人事后补齐——知识不会丢,但不会在紧急时刻阻塞人。

CHEATSHEET.md 的"紧急恢复"部分人工维护。紧急场景通常不是"某个 YAML case 能匹配”,而是"先查最近变更、再查基础链路、再查日志最后一段报错"。


11. Session 中断与恢复(兼过程日志)

诊断不是连续时段。被同事打断去开会,回来记不住之前查什么,agent 上下文可能已被 compact。diagnosis_state.yaml 同时承担两个角色:恢复现场 + 过程日志(原则 7)/diagnose 每个 step 后更新它:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
session_id: "2026-07-09-ep-hang-a5"
status: in_progress
current_step: 3
excluded_cases: [ASCEND-EP-HANG-001, ASCEND-EP-HANG-002]
active_case: ASCEND-EP-HANG-003
last_action: "等待用户执行 check_ep_topology.py 并贴回输出"
trace:                                # 过程日志——误诊归因(§9.2 第四层)+ 路由准确率(§14)依赖它
  - {step: 1, action: triage, branch: training_hang, routed: [training/mindspeed-llm/, common/]}
  - {step: 2, action: load_index, namespaces: [training/mindspeed-llm/, common/], n_cases: 34}
  - {step: 3, action: quickly_check, case: MSLLM-EP-HANG-001, primary: pass}
  - {step: 3, action: quickly_check, case: MSLLM-EP-HANG-007, primary: fail, fallback: pass, marked: low_confidence}
  - {step: 3, action: load_full, candidates: [MSLLM-EP-HANG-001, MSLLM-EP-HANG-007], order: by_confidence_score}

恢复时人跑 /resume-diagnosis,agent 先读状态文件而不是从头收集症状。

注意 harness 限制:harness session 不会自动续——必须人重新 invoke skill。/resume-diagnosis body 第一条就是"读 diagnosis_state.yaml"。

状态文件生命周期:case 标 resolved/escalated 时,状态文件移入 history/。active 目录只留进行中 session。并发诊断检测靠 session_id 不匹配——但这是脆弱机制(两人用同样命名习惯会漏检),只作为"可能已被接手"的提示,不作为硬阻塞。trace 历史不删——它是 §14 路由准确率和执行保真度指标的数据源。


12. 冷启动:第一周怎么活

设计假设 Tier 1/T2 有内容。但团队刚采纳时,triage-tree 只有两个分支,knowledge/ 各 namespace 是空的。工程师跑 /diagnose,agent 发现 Tier 2 空,跳 Tier 3——Tier 3 也空。

方案一:手工播种第一批 case。上线前,领域 owner 手工挑过去半年最高频的 10 条 root cause,直接写 Tier 2 YAML。不等 postmortem 积累——跳过 groom。这 10 条应覆盖约 50% 日常 issue。第一周命中率 20% 就够让人感到"这东西有用"。

方案二:空库提示,不要静默退化/diagnose 首次运行发现 Tier 2 空,主动提示"我还没数据,但有深度排查/CHEATSHEET/转人工三个选项"。

方案三(第二轮补):triage-tree 冷启动闭环。§12 还有个隐藏问题:triage-tree 第一周也是猜的(约束 2 说历史案例格式混乱,你其实不知道哪些症状组最高频)。猜错的 triage-tree 会把已播种的 case 路由到错的 namespace,让它们不可达。§5.4 的优雅退化(triage 低置信时加载所有 namespace 索引)正好堵这个洞——triage 猜错时,退化机制让 quickly_check 自己在所有 namespace 里筛,已播种的 case 仍可达。冷启动的 triage 不完美也没关系,退化兜底。


13. 人机界面:CHEATSHEET 与脱敏

13.1 自动生成 CHEATSHEET.md

不是每个工程师每次都愿意用 agent。CHEATSHEET 是路径 B 的主诊断入口(§7),不是可选项。/knowledge-groom 每次运行时产出 Markdown 速查表:

1
2
3
4
5
6
7
## training/mindspeed-llm

### EP Hang

| 检查命令 | 期望值 | 修复方式 | 平台 |
|----------|--------|---------|------|
| `env \| grep HCCL_BUFFSIZE` | >= 4194304 | `export HCCL_BUFFSIZE=4194304` | A5, A3 |

三作用:路径 B 诊断入口、dogfooding 知识质量(生成的表看不下去说明 YAML 有问题)、新成员 onboarding。紧急恢复部分人工维护,挂在速查表顶部。

13.2 数据脱敏

客户日志可能含 token、API key、内网 IP。/to-postmortem 和 session-end summary 生成时增加 redact()——扫描 Bearer ...sk-...password=、内网 IP 段,替换为 [REDACTED]。脱敏在人确认前,不是事后补救。


14. 量化指标与回顾

第一轮有命中率/误诊率。第二轮加三个过程类指标——它们是原则 7 的度量:

指标含义作用
命中率Tier 2 直接匹配解决的比例库够不够大
误诊率命中了但 fix 没解决库有没有错误信息
路由准确率最终 root cause 所在 namespace 是否在被加载集合里区分"路由错"和"KB 空"(§8.2)
执行-误诊归因比误诊中 case 错 vs 执行错的比例区分"改库"和"改 skill"(§9.2 第四层)
置信度分布低置信 case 占比、低置信高命中 case 数发现需复审的 case;监控探索偏差(§16)
自起草采纳率groom 验证通过的草案 / agent 起草总数原则 5 范式升级的安全阀;低于阈值则降级自起草(§16)
trace 完整性有 trace 记录的 step / 实际执行 step原则 7 的自举监控;trace 缺失即执行保真度异常
平均诊断时间、知识增长率、退休率——健康度

记录方式:docs/metrics.md,每两周手工追加:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
## 2026-W28
- 处理 issue: 12(路径 A 7 / B 5)
- Tier 2 命中: 7 (58%)
- 误诊: 1(归因:case错 1 / 执行错 0)
- 路由准确率: 10/12 (83%)
- 低置信 case 占比: 3/47
- 自起草采纳率: 1/1 (100%)
- trace 完整性: 11/12 (92%)
- 新增 postmortem: 4(含 agent 自起草 1)/ 升格: 2
- 软退休: 1
- groom backlog: 6(绿)
- 平均诊断时间: ~45min

季度回顾时,用真实数据校准 §8.3 的阈值,回答:“这三层架构真的在变好用,还是我们在自欺欺人?”


15. Script 层集成点

Script 层是诊断真正动手的层,是 /diagnose 步骤 4 和 §9.1 日志契约的落点:

Script何时调输入agent 消费的输出
ascend-profile-analyze/diagnose Tier 2 未命中,有 profiler 数据profiling 目录report.md(op 级耗时/通信占比)
mem-analyze精度问题,Tier 2 未命中tensor dump + 参考基线数值偏差表
bench-run性能问题,需基线对比模型/配置吞吐/step time 对比
collect-profiling/diagnose 发现缺 profiler 数据训练启动配置profiling 目录
machine-ops环境健康自检(/diagnose 步骤 1)npu-smi / hccl 拓扑状态
log-format-contracts/*契约文件,非脚本——quickly_check 优先匹配的稳定错误标识(§9.1)

约定:agent 调 Script 后只读生成的报告文件,不把 stdout 全量灌进 context(§6 裁剪原则同样适用)。Script 输出格式写进 references/script-integration.md,由体系维护人和 Script 作者共同维护。


16. 待解决的问题

问题为什么暂时不做
case authorship 追踪git blame 已解决
groom 运行频率前三个月每周;连续四周无新 postmortem 切双周
next_on_fail 自动生成v1 靠人填;v2 分析 trace 自动建议(§9.3)
诊断图谱可视化Tier 2 < 50 条时手动追踪就够。建了没人用会更尴尬
领域 owner 正式定义团队自行协商;默认框架 namespace 由牵头人审,common/ 任何 owner 批即过
向量检索(Tier 3 升级)v2+,三个触发条件同时满足才考虑(§5.6)
联邦 common/ 自动化§8.6 先写规则;等真出现 drift 再实现

已知固有局限(靠 metrics 监控,不靠加机制解决)

下面三条是范式的固有张力,不是设计洞——继续加机制只会加剧复杂度(见 §17 的 v1 范围切分),所以接受它们并用 §14 的指标监控:

  • 自起草 draft 质量:原则 5 的 ROI 取决于 agent 起草质量。用 自起草采纳率 监控;持续低于阈值则把自起草降级为"只起草 quickly_check,不起草完整 diagnosis"。
  • trace 自举悖论:用 trace 观测执行保真度,但写 trace 本身也依赖执行保真度。缓解:trace 是简单 append(drift 风险低),且 trace 缺失本身是异常信号,用 trace 完整性 监控。
  • 置信度 rich-get-richer:高置信 case 越试越准、低置信 case 长期冷。quickly_check 无差别放候选(置信只排序)是部分缓解;§5.7 的 cold-case 不退堵住最坏症状。彻底解法(exploration floor)会增加误诊风险,留给 §14 数据驱动决策。

17. 接下来的步骤

v1 范围切分

两轮下来设计积累了不少机制。每一个单独成立,但 v1 不能全上——否则违背约束 4(个人维护能力有限),也背离 Pocock 的极简精神。v1 只上"没有它就会出错或建不准"的机制,其余写进路线图:

机制建议理由
trace + 执行保真度归因(§9.2 第四层、§11)v1原则 7;没有它误诊会污染库
学出置信度(§5.5)v1候选排序依赖;实现简单
语义校验 needs-structurer-review(§4.4)v1结构化是错误率最高环节,必须守
command_template + rank_selector(§5.5)v1分布式领域必需,否则 case 建不准
优雅退化(§5.4)v1冷启动闭环,代码量小
compat 非单调区间(§5.5)v1.5单调区间先够用;等真出现 2.7 失效、2.8 恢复再上
自起草候选 case(原则 5)v1.5ROI 未验证(§16),先度量自起草采纳率再开
值重复检测(§8.1)v2等 common/ 真有权威记录再说
review 批量协议(§8.5)v2等 PR 量上来再说
联邦 common/(§8.6)v2+先写规则,等真出现 drift

v1 砍到 6 个机制,设计回到"接近 Pocock 重量级、但带执行可靠性"——这才是约束 4 下能活下来的形态。

步骤

  1. 建 namespace 骨架——创建 knowledge/ 目录结构(含 _archive/_drafts/platforms/)和三份 platforms/*.md。只建空目录。
  2. 手工播种第一批 case——领域 owner 挑过去半年最高频 10 条 root cause,直接写 Tier 2 YAML(含 command_template/rank_selector/compat/confidence 初始值)。目标:第一周命中率 20%。
  3. 搭 triage-tree.yaml 框架——提取最高频 5-8 个症状组,配 search_namespaces同时实现优雅退化路径(§5.4),保证冷启动时 triage 猜错也能命中已播种 case。
  4. 搭五条 skill + references/——写 /diagnose(含 trace 写入和 Tier-2-miss 自起草)、/emergency-triage/resume-diagnosis/to-postmortem(含语义校验)、/knowledge-groom。先拿 3-5 个真实 case 验证 /to-postmortem 的语义校验假阴性率。
  5. 跑第一轮 /knowledge-groom——度量自动结构化成功率 + 语义校验拦截率,生成第一版 CHEATSHEET.md,做第一次 references 完整性 + 值重复校验。
  6. docs/metrics.md——第二轮 groom 后开始记录,含三个过程类指标(路由准确率、执行-误诊归因比、置信度分布)。
  7. 配路径 A 的 session-end hook——让 Claude Code / Codex 在 session 结束自动生成 postmortem(含 agent 自起草候选 case)。
  8. Tier 3 关键词检索验证——等 Tier 2 到 50 条以上,验证 rg 兜底命中率;不够再评估向量(§5.6)。

附录:与 Pocock 体系的设计映射

Pocock 概念Ascend Skills 对应异同
/grill-with-docs/diagnose都是人加 agent 协作
CONTEXT.mdknowledge/(namespace)+ platforms/*.mdPocock 静态术语单文件;这里是 namespace + references 网络
/domain-modeling/knowledge-groom定期维护知识结构
postmortem(Pocock 没有)postmortems/ + agent 自起草候选 case昇腾场景核心机制;自起草是 Pocock 没有的范式升级
disable-model-invocation/diagnose 等设 user-only仅 Claude Code 可强制;跨工具靠规范(§4.1)
ask-matt 路由器/diagnose + triage-tree统一入口;triage-tree 是 skill 控制流的 YAML 外置
每个implement只做一个 ticket每条 skill 只做一件事初稿违反(god-object),修订版拆成五条(§4)
smart zone(120K)§6 token 预算不是"压到 15% 窗口",是"给日志留空间"
(无对应)过程 trace + 执行保真度(原则 7)Pocock 的 skills 不假设长状态机执行;诊断场景必须有