agentleFS
pilluminapillumina/ascend-sleuth/skills/to-postmortem/SKILL.md

to-postmortem

Skill5 starsChanged 11 days agoMITView on GitHub

把一次或多次昇腾问题定位沉淀成知识。输入支持内联粘贴、单个/多个文件路径、或整个目录(批量导入历史案例)。提取症状/命令/root_cause/fix,检测框架给命名空间建议(批量模式一次确认),人确认,输出结构化 YAML 草稿 + postmortem.md,过语义校验和脱敏。无论知识产自哪里(本地 agent session / Kimi 网页对话 / 手工笔记 / wiki 导出),都从这里汇入——这是异构知识来源的统一入口。

  • Installs packages

The file

Files
SKILL.md

To Postmortem

知识注入入口与诊断工具解耦——无论问题在哪儿定位的,都能在这里沉淀。这是 ascend-sleuth 体系里最重要的动作:不沉淀,团队下次还得重新踩坑。

输入方式

接受四种输入:

1. 内联粘贴(单条,最常用):

/skill:to-postmortem "[把 Kimi/DeepSeek 对话、或手工排查笔记粘进来]"

2. 单个文件路径(大文档,免复制粘贴):

/skill:to-postmortem ~/cases/custA/notes.md

agent 读取文件,后续流程同内联。

3. 多个文件(一次沉淀几条相关 case,各自独立成文):

/skill:to-postmortem ~/cases/custA/notes.md ~/cases/custB/hang.md

4. 目录(批量导入历史案例,如从团队 wiki 导出的记录):

/skill:to-postmortem ~/cases/wiki-export/

扫描目录下 .md/.txt,每个文件各成一条。大文件逐个处理,不全量载入 context。目录模式就是批量导入历史案例的入口——不需要单独的批量导入 skill。

5. 批量诊断会话(面板「批量沉淀」生成,或用户说"把这些 session 都沉淀了"):

/skill:to-postmortem 批量沉淀这些 session:<session-id-a>、<session-id-b>

session id 解析到 traces/<id>.yaml(traces/ 锚主检出,用 python3 scripts/shared_dir.py traces 取绝对路径);每个 session 各成一条草稿,批量确认命名空间、每单各跑语义校验(同上面的批量模式)。来源 trace 的 sedimented.state 逐单回写 submitted。

谁该进这批,先问脚本,别凭记忆:python3 scripts/sediment_batch.py 只读清点——按「已收尾 / 有报告 / 有候选」列出还没沉淀的单,同一问题的多条 session 并成一组,并打印直接可用的批量命令;--json 给起草时读(含每组的报告文件名与候选正文,不必重读全部事件)。它不改 status、不改 feedback.outcome(那两条是诊断侧的事),也不判断该不该入库。

回写一次做完:草稿落 inbox 后逐单跑 python3 scripts/trace_transition.py <session> --field sedimented --state submitted --inbox-path <草稿路径> --json,把这几单的 sedimented 置 submitted。它只动 sedimented 与 updated_at,不追加收尾记录,也不重排其余字段;写不进去时会返回明确错误码。

二进制文档(.docx/.doc/.pptx/.xlsx/.rtf/.epub)预处理:客户报告、排查记录、汇报材料常是这些格式,先取到文本再走上面四种输入。约束是不变量,不是工具——只要满足三条:①文本取自原文件(不凭标题或上下文编造)②出处可核验 ③材料不外传(客户/内部文档不上传第三方服务)。工具怎么选、能不能装,都是这三条之下的实现细节。

省事的首选(装得上就用,装不上别卡死):

npx -y @firecrawl/anydoc <file> -o <file>.md     # Node ≥ 20,首次自动下载,保留表格/公式/脚注
# 无 Node 但有 Python ≥ 3.10:
pip install firecrawl-anydoc
python -c "import anydoc,sys; print(anydoc.to_markdown(sys.argv[1]))" <file>

anydoc 或任何库都装不上(离线、无 Node/Python、版本冲突)→ 先自己找路,不要直接判失败。 已知可行的零依赖路线(这些格式本质都是 zip + XML):

  • .docx:python -m zipfile -e <file> out/(Windows 无 Python 时用 [System.IO.Compression.ZipFile]::ExtractToDirectory)后读 out/word/document.xml,按 <w:p> 段落取 <w:t> 文本拼回;out/word/media/ 是内嵌图片。
  • .pptx:ppt/slides/slide*.xml(备注在 ppt/notesSlides/);.xlsx:xl/sharedStrings.xml + xl/worksheets/sheet*.xml;.odt/.ods/.odp:content.xml。
  • 这条路拿到的文本通常够沉淀(case 要的是症状/命令/根因,不是版式);丢掉的表格结构/排版如实记进 postmortem,别假装完整。
  • 探索出的新路线跑通了,值得固化 → 收尾的伴随演进评估会看到"重复手动动作"信号并决定是否写成步骤(见 /skill:evolve-check),不要在这里自己加卡。
  • 真的都抽不出来 → 明确告诉用户"这份文件抽不出来,请转成 md 或贴文本",不静默跳过附件——附件里的报错原文正是 case 的 symptoms 证据。
  • 目录模式的扫描范围随之扩展到上述扩展名,逐份取到文本后再成条。
  • 截图:纯文本通道(anydoc 或 XML 提取)都只出文字,文档里的定位截图会被丢掉(anydoc 无占位、无告警)。.docx/.pptx/.xlsx/.odt 都是 zip,用 python -m zipfile -e <file> out/ 取 word/media/(pptx 为 ppt/media/,xlsx 为 xl/media/),再用自己的图片识别能力直接读图(模型支持图片输入时)。
  • 读不了图就如实记缺口:在 postmortem 里列「未提取的证据」清单(文件名 + 所在段落上下文 + 未识别原因),草稿标 needs-human-review。不要拿截图的标题或上下文推测报错原文——symptoms 只写文本里确有的内容。
  • 不外传:不要用 --ocr hosted(把整份文档上传第三方服务);客户材料一律本地处理。

流程

  1. 提取:从输入中抽出——
    • 症状、执行的命令和输出、排除的假设、root cause、fix
    • 级联噪声:文档中标注了“次级现象”“不需要单独分析”“误导”的症状——提取为 case 的忽略项(diagnosis 里加一条“忽略 X 级联报错,都是根因后的 noise”)。昇腾调试里极常见——一个根因级联出几十条 secondary error
    • code-patch 的 file:line:如果 fix 涉及代码改动,提取精确的 file:line(如 conn.py:31-41)。code-patch 的 file:line = env-var fix 的 export X=Y——是 fix 的可执行部分
  2. 命名空间建议:agent 检测或推断框架,给选项,人输入数字确认(约 5 秒):
    [1] training/mindspeed-llm/   (检测到 mindspeed-llm)
    [2] training/verl/            (检测到 verl)
    [3] common/                   (跨框架,或不确定)
    • 完全没涉及框架(纯硬件/CANN/驱动报错)→ 选项变为 [1] common/,人按回车
    • 检测到多个框架 → 按置信度排序,第一项标 (most likely)
    • 这个确认本身就是质量检查:人在 mindspeed-llm 和 common 间选,本质在自问“这问题是框架特有的还是通用的”
    • 批量模式(多个文件/目录输入时):命名空间确认改为一次批量——agent 按检测到的框架分组报告(如“12 个 mindspeed-llm、5 个 verl、3 个 common”),人一次确认或调整。语义校验仍逐个跑,失败的标 needs-structurer-review。批量模式不逐个 30 秒确认,改成抽审。
  3. 输出结构化 YAML 草稿 + postmortem.md:
    • postmortem 策略:源是混乱对话/手工笔记 → 写完整 postmortem.md(提炼+结构化);源已经是结构化文档(调查报告/issue/wiki)→ postmortem.md 只写指针(# 原文见:<source-url/path>),不重写。YAML case 草稿两种情况都照常产出。
    • 标 investigation_quality: high | medium | low——人的调查质量判断(五天详查 vs 随手记录),不是来源验证
    • 标 verification: {source: <档>, detail: <引用>}——这一档决定草稿能不能升格:自诊断的问题(带 source_session)默认要等来源 trace 闭环才会被 groom 升格(命中单看 feedback.outcome: resolved,无命中单看 status: resolved);没闭环就该如实标 investigation,并知道它会被闸门拦下(除非补强外部证据并走 owner 双签)。别为了让草稿过关而抬高档位——档位是外部证据强度,不是主观评价——来源验证状态(与 investigation_quality 区分:quality=内容判断质量,verification=外部证据强度)。档位按「来源形态」分,不按 issue 分——issue 只是外部来源之一,官方案例文档与本地闭环同样是来源:
      • upstream-fix-merged:来源是上游 issue 且关联 fix PR 已合入(references 含 pull/<n> 或确认 merged)——内容被外部验证(根因+修复代码合入),最强档;
      • upstream-official-doc:来源是上游官方发布的案例/指南文档(如框架仓库 best_practices/ 下的定位实践、官方 troubleshooting 指南),含完整定位链与验证结论——内容被上游发布验证,但无指向本问题的 fix PR;
      • upstream-maintainer-confirmed:上游 issue 维护者确认 resolution 但无 fix PR 引用;
      • investigation:本地深度排查/源码分析定位(source_ref 佐证),无上游确认;
      • engineer-report:工程师现场回报验证过(最强现场证据,rare)。 detail 记 issue/PR 号、文档路径或来源路径。无明确外部验证 → 不填 verification(如实:仅调查级)
    • 产出报告里写一行闸门预判(别让草稿静默积压):来源 session 未闭环且 verification: investigation → 明说「本单过不了 groom 的升格闸门;出路三条:等现场闭环 / 补强外部证据 / owner 双签」;已闭环 → 写「可过闸」;强证据档但未闭环 → 写「可过闸,但需 owner 双签」。groom 的闸门口径见 /skill:knowledge-groom(自诊断来源默认须闭环)。
    • 来源是上游 issue / PR 时,标 upstream: [{repo, issue|pr, url}](case 内字段,非注释)——它是外部对照自动查证(python3 scripts/verify_upstream_outcomes.py)的唯一分母:有锚点的 case 才靠上游状态自动确认「内容对不对」,没有锚点的客户侧现网问题只能等现场回报。issue 与 pr 二选一,url 写原址让人点开;只写这条 case 的来源那个,正文里顺带提到的同族 issue 不算锚点(写多个会让查证对上错的那一个)。它判断不了「现场是否解决」,那只有现场能给。
    • 标 novelty: new_pattern | variant | covered(pre-triage,对比现有 case 判定):用命中 (namespace × category) 的读侧视图 knowledge/_index/<ns>__<category>.list(一行一条 case;category 未定回退 <ns>.list;已知 namespace 时不读全库总表)按 symptoms/tags 定位候选,再全量读候选 case 本体比对 root_cause/fix——无重叠 → new_pattern;同主题不同形态 → variant(注明 variant_of:<case-id>);已有 case 覆盖 → covered(注明 covered_by:<case-id>)。给出证据(如"同算子×同网络,增量=升级修复"),groom 复核该标签而非重判
    • 标 category: interrupt | precision | performance 三选一,无 other(按症状判断——interrupt 是 hang/crash/OOM/启动失败、precision 是 NaN/数值发散/输出错误/乱码、performance 是吞吐/延迟)。分不进去 → 由人确认归入最接近的分类,不设 other
    • 标 tags(sub-type,如 oom、kv-cache、precision.convergence)
    • 根因定位到源码时(如 vllm-ascend 某文件某行),标 source_ref: {repo, ref, file, line}——repo 写 org/repo 且要能在 source-catalog.d/ 解析到;ref 用触发版本对应的 commit/tag,line 可选。源码不落库,只记代码指针(诊断按需取该版本片段)
    • 来源是诊断 session 时,标 source_session: <session_id>(case 内字段,非注释)——它是反馈结算判定「自证」的唯一依据:来源 session 自己回报的 resolve 记 self_resolved、不计入 resolved(同一份证据不数两次)。不写这个字段,结算只能退回「计入 resolved」,等于让产地自证冒充独立命中。 3.5. triage 路由同步(知识增长自动补全路由):产出 case 草稿后,检查该 case 的 symptoms 关键词能否被路由正则(triage-tree.yaml,生成物)路由到正确性质。路由分两层、加词只碰性质层:侧(训练 / 推理)由工程师的事实确定,不写进症状词;性质层是 triage-tree.d/<性质>.yaml(一性质一文件:10-interrupt.yaml / 20-precision.yaml / 30-performance.yaml),词表训推共用——所以一个新词只写一次,两侧同时生效,也不必再判断"这是训练侧还是推理侧的说法"。有合入后重建 job 的部署只改性质文件、不提交聚合:聚合 triage-tree.yaml 由主干 job 重建。没有这个 job 的部署二选一:保留旧纪律(改完跑 python3 scripts/rebuild_generated.py --check,聚合随 PR 提交),或合入后由人在 main 上跑 python3 scripts/rebuild_generated.py --sync。门是覆盖检查:源里每条症状组都得在聚合里;新文件还要在 00-protocol.md 的 sources: 里登记,否则不会被拼进聚合;同性质两人并发由 union 自动两边都留;route_check.py --wide-words 会列出"同一形态被两个性质同时认领"的词,加词前扫一眼:
    • 能 → 无需动作(路由已覆盖);
    • 不能(新形态 OOD,正则没识别)→ 在产出报告里给出路由症状建议(新正则追加到对应性质文件里该性质的 symptoms,如 "过度思考" → 20-precision.yaml),随 case PR 一并提交(structure 部分,人审确认)——triage 随知识入库增长,不靠手工补;拿不准放哪个性质 → 建议标 needs-review,groom 定夺;拿不准是不是某一侧的专属措辞(vllm serve 这类只在推理侧成立的写法)→ 同样标 needs-review:写进共用词表不会报错,但会让另一侧的同性质 case 掉到别的性质或没命中。
  4. 语义校验(关键,区别于格式校验):
    • 先跑结构校验的确定性工具:python3 scripts/verify_case_draft.py <草稿路径>——它管机械可判的那一半(YAML 可解析、必需字段非空、category/severity/fix_type 取值合法、ref_knowledge 不悬挂且指向 active 词条、quickly_check.expected 的 regex 可编译且无空分支、diagnosis 无空步)。草稿在 inbox 期间没有任何门(CI 的 build_index 只在 case 进 knowledge/ 后才解析它),所以这一步是它唯一的确定性检查点;也支持 --all 校全库。
    • regex 在输入附的真实日志片段上能否匹配
    • expected 值类型/数量级合理性
    • command_template 里的路径在已知部署模板里是否存在
    • 校验失败 → 标 needs-structurer-review(与 needs-human-review 区分:前者是格式/语义可疑,后者是语义不明)
  5. 脱敏:扫描 Bearer ...、sk-...、password=、内网 IP 段 → 替换 [REDACTED]。在人确认前,不是事后补救。这是 KB 进私有的第二道防线,第一道是 repo 可见性(见 README)
  6. 人扫一眼确认 root cause 和 fix → done(30 秒内)

产出落点

草稿落在哪个 inbox:先 python3 scripts/shared_dir.py inbox 取绝对路径(锚在主检出、跨 worktree 共写;写相对 postmortems/inbox/ 的草稿,转正时在 worktree 里读不到、清 worktree 就丢)。下面是相对仓库根的写法:

  • postmortems/inbox/<case-id>.md(postmortem 或指针)
  • postmortems/inbox/<case-id>.case.yaml(YAML 草稿)
  • 草稿 case YAML 顶层加 created_at: <ISO-8601 带时区>。它只给沉淀队列算年龄、提醒超过 2 周;升格写进 knowledge/ 时删掉,它不是 case schema 字段。
  • inbox 是待审队列(见 postmortems/inbox/README.md):每周 /skill:knowledge-groom 批处理三分类(new_pattern / variant_of / covered_by)后人审。审完:postmortem 转正 ../YYYY-QN/(covered 也转正——Tier 3 语料,不是丢弃)、new 的草稿升格 knowledge/<ns>/

同一个问题只沉淀一次——本 skill 只有新增路径、没有更新模式,重复调用不会改已有条目:

  • 闭环结果不走这里。它通过来源 trace 的 feedback 事件流转(pending → 现场确认 resolved),结算读 trace、不读 inbox 草稿,所以闭环不需要第二次沉淀、也不需要第二个 PR。
  • 再调一次只会新增草稿,且分诊时被 novelty 判成 covered_by(因为知识库已有这条)→ 被当已覆盖处理,属空转。
  • 若后来拿到更强的证据(实测对照、上游 fix PR 等),要改的是已升格 case 的 verification 档位,直接编辑该文件走知识修改流程——不经过本 skill。
  • 已经重复沉淀了:删掉 inbox 里那份重复草稿即可,别让它进 groom。

生成后明确告诉用户存哪了——报出具体路径(如 postmortems/inbox/custA-ep-hang.md)和 YAML 草稿位置,说明"周审后转正",别让工程师去找自己的产出。

写草稿时的行文:postmortem 与 case 词条都是给人读、给人审的文本,按 docs/spec/writing-norms.md 写(可选论证层,不影响本 skill 执行);本面的定制条款见该文件 §3 的「case / reference 词条」与「postmortem」两行——症状句要能直接当 grep 判据,root_cause / fix 只写结论与依据,时间线只放可观察事实。

结算与提 PR 的粒度(别每次闭环都开 PR):诊断现场回报 fix 结果后,trace 里记 feedback 事件即可(feedback.outcome: pending → 现场确认后置 resolved)。现场回报的结算与入库按周批走一次——知识整理收尾的结算步骤跑 settle_trace_feedback.py,把计数写进条目使用记录,一个知识变更 PR 覆盖当期全部变更。本地连着定位多个问题时,不要每闭环一个就提一个 PR:计数只影响候选排序(排序对时效不敏感),而结算游标是 gitignored 的共享运行时件、不进 git。理由是三条写入点的git 归属刻意不同:现场记录含客户信息故不进 git,条目使用记录是学习环的持久知识故必须入库,指标时序是周节奏的人复核汇总故不等每次反馈。

回写来源 trace 的沉淀状态(诊断闭环):若本次沉淀来源是一个诊断 trace(输入提到 traces/<session_id>.yaml,或用户从诊断面板"沉淀此案例"触发),产出草稿落 inbox 后回写该 trace 的 sedimented.state: submitted(动作发生时写,零推断)——诊断面板据此显示"已提交沉淀待审",不再重复提示沉淀。转正(knowledge/archived)由用户在面板/对话确认时更新,本 skill 不写。

收尾 evolve-check(伴随演进评估,默认执行)

先落执行记录(evolve-check 读它作现场): python3 scripts/log_skill_exec.py --skill to-postmortem --products "<case-id>(submitted),..." --reason "<一句话根因/来源>" --source <来源 skill> --tokens <估算>

草稿产出、出最终报告前,执行一次伴随演进评估(read skills/evolve-check/SKILL.md 遵循):对照它的触发条件表看本轮现场——同族沉淀满三条(记信号,不在这里归纳)、replay/Tier 3 暴露覆盖缺口、提取/校验环节有重复手动动作与流程摩擦。内容动作直接执行、不产卡: 补 case 走本流程。归纳 reference 不在这一步做——草稿还在 inbox、没升格, to-reference 的 sources[].cases 会引用一个不存在的 id(groom 拒掉那条草稿后更糟); 同族信号只写进报告,等升格后由 knowledge-groom 的 R8 提炼(那时 case id 已在 knowledge/)。 只有信号连带要求改行为面(triage 分支、skill 步骤、闸门绑定、索引形态)时,才把观察交给 python3 scripts/evolve_intake.py record …(按部署声明落卡或落台账,别直接调 ev_proposal.py --new; 产卡后接 golden/S2 验证 → 进攒批); 无信号则报告加一行"evolve-check:无演进信号"。这是流程默认收尾,不需要用户另说 "改进系统"——演进由数据触发,像人学习。产出与流程报告一并给出。

为什么是这个体系的核心

团队不能统一 agent 时,知识注入入口必须与诊断工具解耦。/to-postmortem 是这个解耦的实现——任何工具的对话都能沉淀。别期望团队成员额外写文档,agent 提取、人审批,成本从 20 分钟降到 30 秒。

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.