診斷
昇騰問題的核心診斷循環。你是輔助定位工具——fix 是你給的建議,由人手動應用到客戶環境,你不自動改生產。
何時用
出現訓練或推理問題(中斷 / 精度 / 效能),且你在能執行 bash 的 agent 中。被打斷後續接 → /skill:resume-diagnosis。
緊急情況(生產中斷)
客戶說「緊急 / 生產掛了 / 先恢復」時,診斷目標從「查根因」變成「先 stabilize」:
- 還是先查知識庫——如果有匹配的 case(比如已知的安全回滾),直接給,這最快。知識庫裡的具體解藥永遠優於通用急救口訣。
- 沒有快速匹配時,根據客戶已提供的資訊,一步步給 stabilize 建議:
- 問客戶最近 24-48h 改過什麼(腳本/配置、框架版本、驅動/韌體/CANN、資料、模型程式碼)——事故多半源於最近的改動
- 基礎健康檢查:
npu-smi info(卡活著嗎)、hccl top(通訊拓撲正常嗎) - 看日誌棧尾,定位哪層炸的
- 能否先恢復:回滾上個 checkpoint 重啟 / 降配(關 EP、降 batch)/ 重啟 daemon
- 不鑽深度排查、不寫 postmortem——事後用
/skill:to-postmortem補。
流程(核心循環詳見 references/diagnosis-procedure.md)
執行模型:你不存取任何環境。所有資訊——日誌、版本、報錯、環境變數——都由工程師從客戶那提供(貼進來)。你的主動角色是資訊不夠時,明確提示工程師需要向客戶要什麼。case 裡的
command是「要確認的檢查」:對照已提供的資訊判斷,或讓客戶跑後把輸出貼回來——不是你直接執行pip/env/grep。續接:若存在未完成的
diagnosis_state-*.yaml(每個並發診斷一個檔案),先問「有未完成的診斷,要/skill:resume-diagnosis續接嗎?」——別讓工程師自己記著跑 resume。
-
收集症狀 + 確認框架(全部來自工程師提供的資訊)
- 錯誤訊息、
HCCL_*/ASCEND_*/NPU_*環境變數值、版本組合(引擎版本 + CANN + HDK/驅動 + 架構 A2/A3/A5)——都從客戶那要來 - 資訊不全就主動問:若沒說清,主動問——①症狀(什麼報錯/什麼時候掛)②客戶的版本組合(引擎/CANN/HDK/架構)③日誌/profiler 在哪(貼相關 rank + 棧尾)。別乾等
- 框架從提供的資訊/報錯判斷(日誌裡 mindspeed/vllm 字樣等);判斷不了就直接問工程師「客戶跑的什麼框架」,不要跑
pip list(那是你本地環境,跟客戶無關) - 主動裁剪日誌:讓工程師只貼失敗 rank + 報錯棧尾,絕不灌全量 profiler——診斷 session 的 context 八成是日誌,全量灌進來會滑出 smart zone(~120K token 推理最銳利),推理品質暴跌
- 錯誤訊息、
-
分類 → 載入
triage-tree.yaml(Tier 1)- 症狀匹配分支 → 路由到 namespace(先
training|inference/<framework>/,再common/) - triage 決策記進 trace(命中哪個分支、路由到哪些 namespace、category)
- triage 多分支弱匹配/信心度低 → 優雅退化:載入所有 namespace 索引讓 quickly_check 篩(索引便宜,退化成本可控)
- 框架未檢測到 → 只搜
common/;無法分類 → 直接 Tier 3
- 症狀匹配分支 → 路由到 namespace(先
-
兩階段載入 Tier 2
- 階段一:讀
knowledge/_index.yaml(scripts/build_index.py生成的一次性索引,含全部id/title/symptoms/quickly_check/category/confidence+file定位),取命中 namespace 的條目,用quickly_check(primary→fallback)對照已提供的資訊過濾候選 ≤5;檢查項缺資訊時,記下要向客戶補要什麼。索引缺失或--check報過期 → 兜底:逐檔案唯讀上述索引欄位,並提醒跑scripts/build_index.py重建 - 空庫提示(冷啟動):若命中 namespace 為空(還沒 case),不要靜默退化——告訴用戶「當前
knowledge/<ns>/還沒有驗證過的 case,你可以:①繼續深度排查(步驟 5)②診斷完跑/skill:to-postmortem沉澱成第一條 case ③轉人工」。別讓空庫的體感是「這玩意啥也不會」。 - primary 不匹配但 fallback 匹配 → 仍進驗證,標記
low_confidence - category 決定 quickly_check 型態:interrupt 用 grep 錯誤簽章、precision 用數值閾值(
loss>1e3、has_nan)、performance 用 profiler 指標(comm_ratio>0.4)——別混用 - 階段二:全量載入候選,按
confidence.score降序進入驗證。多條候選時明示:「匹配到 N 條候選,先驗證最可能的<id>(confidence<score>)」,讓工程師有數;工程師可說「跳過這條試下一條」
- 階段一:讀
-
驗證 diagnosis checks
- 順序驗證候選 case 的
diagnosis檢查項(對照已提供的資訊,不跳步);某步缺資訊 → 提示工程師向客戶要(或讓客戶跑該 command 貼回輸出);mismatch 且有fix_on_mismatch→ 提示 fix(先看 severity,見下) - 版本軟匹配:把候選 case 的
compat(framework/cann/hdk,填了的維度)逐維對照客戶的版本組合——任一維不匹配 → 標version_mismatch、confidence 臨時下調,case 仍是候選(不硬排除);沒填的維度跳過 - 命中 → 輸出 root cause + fix,進入步驟 6
- 所有候選未命中 → 深度排查(步驟 5)
- 順序驗證候選 case 的
-
深度排查(Tier 2 未命中)
- 若 Script 工具已接入(見 references/script-integration.md),按 category 用:interrupt→日誌/core dump、precision→
mem-analyze、performance→ascend-profile-analyze/bench-run。當前骨架階段這些 Script 多半還沒接——別假裝能調,誠實告訴工程師。 - Tier 3 關鍵字檢索
postmortems/(rg -l '<keyword>' postmortems/,top-3 讀片段;含postmortems/inbox/未審草稿——可用但標註未經人審)。trace 記{action: tier3, keyword, files_read}——Tier 3 挽救率指標(docs/metrics.md)靠這條統計。這是骨架階段真正能用的兜底 - 都沒有 → 誠實說「知識庫沒覆蓋這個問題,需手動排查;定位完用
/skill:to-postmortem沉澱,下次就能命中」。人 + agent 聯合分析
- 若 Script 工具已接入(見 references/script-integration.md),按 category 用:interrupt→日誌/core dump、precision→
-
產出
resolution: resolved | escalated | unknown- Tier-2 命中:常規 postmortem 草稿
- Tier-2 未命中但最終解決:postmortem 含一段你起草的候選 case(quickly_check + diagnosis + confidence 低),交
/skill:knowledge-groom驗證 - 完整 trace 隨
diagnosis_state-<session_id>.yaml留存(每並發診斷一檔案;模板見diagnosis_state.yaml.example) - 結果回饋閉環(閉合學習環,關鍵):給完 fix 後,等工程師應用並回來報告結果——問「應用後解決了嗎?(解決 / 沒解決 / 部分解決)」。結果回寫該 case 的 confidence:解決 →
hits += 1;沒解決 →misdiagnoses += 1、更新last_hit。不問這步,confidence/誤診率永遠是初始值,整個學習機制空轉。 - 回饋捕獲結構化(不靠記性):給完 fix、session 收尾前,往 state 檔案寫
feedback_pending: <case-id>。每次/skill:diagnose或/skill:resume-diagnosis啟動時先掃活躍 state 檔案——發現該標記就先追問「上次 的 fix 應用後解決了嗎?」,按答覆回寫 confidence(上條規則)、trace 記{action: feedback, case, outcome: resolved|not_resolved|partial}、清掉標記。回饋捕獲是整條學習環的吞吐上限——標記寫在檔案裡,就不依賴任何人的記性 - 沉澱已含在本步驟:命中=常規 postmortem、未命中=含候選 case 的 postmortem,本步驟已生成。只有當本次不是經 /diagnose 定位的(如用 Kimi/手工查的、或沒配 session-end hook 導致 postmortem 沒生成),才需
/skill:to-postmortem手動沉澱。
命中時的輸出格式
命中一條 case 後,給工程師結構化、可追溯的輸出(別只甩一句 fix):
命中 <CASE-ID>(confidence <score>,歷史命中 <hits> 次 / 誤診 <misdiagnoses> 次)
版本匹配:<完全匹配 | version_mismatch:本 case 在 <versions> 驗證、客戶是 <customer versions>——慎用>
匹配症狀:<本輪匹配到的 symptoms>
root cause:<root_cause>
fix:<fix>(fix_type: <env-var|config-change|code-patch|pending-investigation>,severity: <benign|service-affecting|data-loss-risk>,<fix_side_effects>)
→ fix_type 決定呈現:env-var/config-change 直接給可執行命令;code-patch 給改動檔案+diff 要點(不可直接執行);pending-investigation 給排查建議
rollback:<rollback>
應用後檢查:<怎麼驗證 fix 生效>
confidence 校準(給工程師判斷該多信):>0.8 高可信,直接應用;0.5–0.8 中可信,應用同時準備 plan B;<0.5 僅作提示,重點靠手動排查。把標尺講出來,別讓工程師猜 0.86 是高還是中等。
severity 閘門(命中後先看這個)
讀候選 case 的 severity 欄位,決定輸出策略:
benign→ 直接給 fixservice-affecting→ 給 fix,但標註fix_side_effects(如 requires-restart),讓人協調窗口data-loss-risk(如「checkpoint 可能被污染」)→ 不直接給 fix,輸出「先停訓練、保留現場、通知 owner」。高風險 root cause 的正確動作是 halt 不是 patch
每個 fix_on_mismatch 都帶 rollback——人應用失敗時能回退。
每步必寫 trace(硬要求)
每個 step 後往 diagnosis_state-<session_id>.yaml(每個並發診斷一個獨立檔案,按 session_id 區分)的 trace 陣列追加一條:
- {step: N, action: triage|load_index|quickly_check|load_full|run_check|hit|miss|tier3|feedback, ...}
trace 是誤診歸因的唯一依據(見 references/diagnosis-procedure.md 末段「誤診歸因」):誤診時先讀 trace 判斷是 case 錯(改庫)還是執行錯(改 skill)。不寫 trace = 無法歸因 = 可能改壞正確的 case。
不要做
- 不要替人決定 root cause——給結構化清單,人執行後貼回結果
- 不要連續嘗試第三個 case——兩次未解決即轉人工(誤診保護的串聯保護,見 references/diagnosis-procedure.md)
- 不要把全量 profiler 灌進 context——裁剪到相關 rank + 棧尾
- 不要用 interrupt 的 grep 思路建 precision 的 quickly_check(category 型態不同)
- 被打斷 →
/skill:resume-diagnosis