这是上一篇拆解 Matt Pocock skills 的文章的续篇。上一篇拆解了 Pocock 的设计思想——这篇把这些思想应用到一个真实的场景:昇腾训练和推理支持团队的日常问题定位。这不是一个已实现的系统,而是一个从具体约束出发、经过两轮自我审视后收紧过的体系设计草案。
1. 场景与约束
角色是昇腾支持工程师,接口 MindSpeed-LLM、MindSpeed-MM、veRL、vllm-ascend、SGLang 等框架在 A2 / A3 / A5 不同架构上的客户问题。问题覆盖三类:
- 功能中断:框架报错、进程崩溃、通信 hang
- 精度异常:loss 异常、FP8 衰减、allreduce 精度退化
- 性能退化:吞吐下降、step time 波动、EP 通信占比过高
有四个约束决定了这个体系不能照搬 Pocock:
- 团队不能统一使用同一个 AI coding agent——公司网络限制和工具偏好导致诊断对话分散在多个 AI Chatbot(Claude Code、Kimi、DeepSeek 网页版)甚至纯手工排查中。
- 已有大量历史案例,但格式混乱——截图、IM 聊天记录、个人笔记都有。
- 新 case 每周新增 5-10 个,且 A2 / A3 / A5 的差异持续扩大。
- 个人维护能力有限,任何需要一个人持续手工维护的方案都会在三周内腐化。
约束 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)
| |
把重分支逻辑外置到 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/ 的权威记录:
| |
references 可选——只有 root cause 被确认为多框架共用的底层问题时才填。这是整个体系最优雅的演化机制:知识图谱 bottom-up 生长,等重复 root cause 自然浮现才提升,而不是事前猜。
5.4 Tier 1: triage-tree.yaml(分类路由 + 退化)
每条分支指向多个 namespace,按顺序搜索。<detected_framework> 是 §4.1 自动检测的结果。
| |
两个第二轮补的机制:
- triage 决策必须记进 trace(命中哪个分支、路由到哪些 namespace)。§14 的"路由准确率"指标依赖它——这是把"路由错"(分到错的 namespace)和"KB 空"(分对了但没匹配 case)分开测的前提,两者修复动作相反。
- 优雅退化:当 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)。
| |
关键设计决策:
- 两阶段加载:阶段一 agent 只读
id/title/symptoms/quickly_check/confidence(约 70 token/条),跑quickly_check过滤出 ≤5 候选;阶段二才全量加载候选 body。阶段二按confidence_score降序验证——命中最可靠的优先。 - 分布式参数化:
command升级为command_template(含{{log_path}}模板变量,agent 按检测到的部署填充)+rank_selector(coordinator/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_cause 或 symptoms 的记录不进检索候选。
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 1 | triage-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 3 | postmortem 关键词片段 | rg top-3 | ~5K |
| 平台 | platforms/ | 按检测平台 | ~0.5K |
| 知识库合计(正常/退化) | ~15-16K / ~20K | ||
| 日志/profiler 输出 | 命令执行结果 | —— | 50-100K+ |
两个结论:
- 知识库不是瓶颈。两阶段加载 + 索引便宜,让优雅退化(加载所有 namespace 索引)的最坏情况也只到 ~20K,仍可控。退化的可行性正是两阶段设计的回报。
- 真正吃 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:
- 升格:扫未处理 postmortem(含 agent 自起草的候选 case),结构化 + 语义校验 → YAML → 追加 namespace;语义校验失败标
needs-structurer-review,语义不明标needs-human-review。 - 引用完整性校验:扫所有
references,检查指向真实存在的文件和锚点。悬挂引用进 PR 报告。 - 值重复检测:检测框架 case 的
expected/fix_on_mismatch是否硬编码了common/权威记录拥有的值。是 → 标 must-fix,要求改成引用。这堵住 references 是软链接、值却各自为政的一致性漏洞。 - 置信度重算:从
hits/misdiagnoses/last_hit重算每条 case 的confidence_score。 - 软退休:
last_hit超 12 周且compat区间过期的 case → 移入_archive/(§5.7)。检查_archive/中 case 是否因新compat区间该复活。 - namespace 拆分建议:某 namespace 超 30 条 → 报告内容分布 + 拆分建议。
- 同 namespace 合并建议。
- CHEATSHEET 重生成(§13)。
8.2 演化信号
| 信号 | 触发动作 |
|---|---|
| 单 namespace 超 30 条 | groom 给拆分建议——这时才建子目录 |
| 两个框架 namespace 各有条 case 指向同 root cause | 在 common/ 下建权威记录,框架层加 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,对应不同平台:
| |
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 后更新它:
| |
恢复时人跑 /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 速查表:
| |
三作用:路径 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,每两周手工追加:
| |
季度回顾时,用真实数据校准 §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.5 | ROI 未验证(§16),先度量自起草采纳率再开 |
| 值重复检测(§8.1) | v2 | 等 common/ 真有权威记录再说 |
| review 批量协议(§8.5) | v2 | 等 PR 量上来再说 |
| 联邦 common/(§8.6) | v2+ | 先写规则,等真出现 drift |
v1 砍到 6 个机制,设计回到"接近 Pocock 重量级、但带执行可靠性"——这才是约束 4 下能活下来的形态。
步骤
- 建 namespace 骨架——创建
knowledge/目录结构(含_archive/、_drafts/、platforms/)和三份platforms/*.md。只建空目录。 - 手工播种第一批 case——领域 owner 挑过去半年最高频 10 条 root cause,直接写 Tier 2 YAML(含
command_template/rank_selector/compat/confidence初始值)。目标:第一周命中率 20%。 - 搭 triage-tree.yaml 框架——提取最高频 5-8 个症状组,配
search_namespaces。同时实现优雅退化路径(§5.4),保证冷启动时 triage 猜错也能命中已播种 case。 - 搭五条 skill + references/——写
/diagnose(含 trace 写入和 Tier-2-miss 自起草)、/emergency-triage、/resume-diagnosis、/to-postmortem(含语义校验)、/knowledge-groom。先拿 3-5 个真实 case 验证/to-postmortem的语义校验假阴性率。 - 跑第一轮
/knowledge-groom——度量自动结构化成功率 + 语义校验拦截率,生成第一版 CHEATSHEET.md,做第一次 references 完整性 + 值重复校验。 - 建
docs/metrics.md——第二轮 groom 后开始记录,含三个过程类指标(路由准确率、执行-误诊归因比、置信度分布)。 - 配路径 A 的 session-end hook——让 Claude Code / Codex 在 session 结束自动生成 postmortem(含 agent 自起草候选 case)。
- Tier 3 关键词检索验证——等 Tier 2 到 50 条以上,验证
rg兜底命中率;不够再评估向量(§5.6)。
附录:与 Pocock 体系的设计映射
| Pocock 概念 | Ascend Skills 对应 | 异同 |
|---|---|---|
/grill-with-docs | /diagnose | 都是人加 agent 协作 |
CONTEXT.md | knowledge/(namespace)+ platforms/*.md | Pocock 静态术语单文件;这里是 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 不假设长状态机执行;诊断场景必须有 |