| name | tech-docs-guard |
| description | 评估 CANN 算子仓的「进阶教程 / 开发指南」类文档质量——通读文档 + 对照算子代码**静态**查证(默认不跑),按五轴(找得到/信得过/学得会/可操作/读得懂)找出 漏讲/讲不清/过时/对不上代码/概念讲错,产出带证据与改进建议的体检报告(MD + HTML)。涉及「评进阶教程 / 开发指南文档质量 / 文档对不对得上代码 / 教程审稿 / tutorial 体检 / 文档信不信得过」等意图时使用。只评不改不跑,只对着文档与代码出诊断。 |
| keywords | ["文档质量","文档体检","算子文档","文档对照代码","教程审稿","tutorial 体检","doc review","CANN 文档"] |
tech-docs-guard
模拟一个挑剔但讲证据的审稿人:通读进阶教程,对照代码查证它「看得懂 / 跑得通 / 信得过」,把「漏讲 / 讲不清 / 过时 / 对不上代码 / 讲错」逐条带证据写成体检报告。
一句话:进阶教程的目的是「教得会」。本 skill 默认不跑——靠读懂教程 + 拿代码当裁判做静态评估,而不是真机执行。
⚠ 本 skill 的三条灵魂(不可违背)
- 不打玄学分。主观判断(讲不清 / 教不会 / 讲错)flag 之前先 steelman——先替这段文字辩护到最强(「有没有一种读法这里其实没问题?」),辩不过去才算缺陷;报的话必须给判例(读者会卡在哪 + 原文 + 改进建议),并标「教学判断(非代码事实)」。
- grep 不到 ≠ 编造。对照代码只能证明「字符串出现过/没出现」,不能证明它是当前有效入口。结论三态:
确认对不上(有强证据反证)/ 疑似过时(静态没找到,但可能生成/外部/分支)/ 未找到静态证据(存疑,不指控)。只有强证据才写「确认」。
- 按「实际开发者影响」判,不按「机械字面对照」判。报一条(尤其升 blocker)前自问:正常开发者照这文档做,真会被卡住吗?还是他会理解意图、自然适配? 文档里大量是示意/演示(教某个写法、给个例子),不是要逐字粘贴。只有文档明确要求「把这段粘贴/替换进某文件」的【规定式】内容、照做真出错,才升 blocker;【示意式】内容(如「这样加一行 PRINTF 打印」)里变量名/签名与某真实文件对不上 → 读者会自然适配 → 至多 misleading、通常不报。 别把「逐字符照抄能否编译」当唯一标准——那会制造一堆实际影响不大的误报。
这个 skill 只评、不改、不跑、不探索:真跑教程/算子、改写文档、准备环境都是别的工具的事;本 skill 只对着文档和代码出诊断。
When to invoke
- 「评一下 ops-X 的算子开发指南 / 进阶教程写得行不行」
- 「这教程跟代码对得上吗 / 信不信得过」
- 「按教程能不能学会 / 哪里讲不清 / 哪里漏了」
- 任何「审进阶教程文档质量」的请求
Inputs(零硬编码,每次会话发现或询问)
-
目标仓 + 代码根:从 CWD 发现候选仓(有 docs/ 的子目录),或用户给绝对路径。对照代码需要仓的源码根。
-
待评文档:不写死路径——每仓目录/命名不一样、还会变,故每次自行扫描发现:
cd skills/agent-tools/tech-docs-guard
python3 -m scripts.find_tutorials <repo_root> --under docs --json
-
不假定 SOC / 版本:教程若声明前提(CANN 版本/SOC),以教程为准来核「版本适配」。
评估框架(五轴最小核)
| 层 | 轴 | 看什么 |
|---|
| 前置 | 找得到 | 该教程是否存在、入口能否导航到(断链/标题误导/目录不可达) |
| 主评 | 信得过 | 命令/flag/路径/配置默认值/函数签名/讲错 → 对照代码,走分级证据 + 三态 |
| 辅评 | 学得会 | 可迁移性 / 心智模型 / 讲「为什么」 / audience-fit(按教程类型,不必太严格) |
| 限定 | 可操作 | 只报静态阻断项(默认不跑,不下「能跑通」结论) |
| 表达 | 读得懂 | 只报影响理解的术语/结构/模糊决策点 |
缺陷 = 形态 × 来源:形态 缺 / 糊 / 错 / 冗;「错」的来源 对不上代码 / 过时 / 概念讲错 / 自相矛盾。
指标第一分类(决定怎么判):
| 可量化(确定性) | 不可量化(教学判断) |
|---|
| 怎么判 | 规则 / grep / parse / AST | LLM 阅读 + 先 steelman |
| 能下的结论 | 确认对不上 / 一致(强证据) | 最多「疑似 / 教学判断」,绝不写确认 |
| 报告 | 事实问题,先列,可计数 | 教学判断,后列,带标签,只定性 |
| 自校验 | 必带 代码位置 / 匹配串 | 必带 判例 + steelman 通过 |
Workflow
P0 — 发现并确认「目标仓 + 代码根 + 待评教程」(中文交互)
- 发现候选仓(CWD 下含
docs/ 的子目录)+ 仓源码根。
- 范围默认只取根
docs/ 技术文档(中央文档:开发指南 / 安装 / context / invocation 等),不逐个算子目录扫——算子文档量太大(全仓上千篇)、问题过多难处理,且中央文档对开发者更关键。需要扫某算子目录时由用户显式指定再扩。
- 发现用
python3 -m scripts.find_tutorials <repo_root> --under docs --json:它枚举 <repo>/docs/ 下全部技术 .md(含 context/install/invocation,非只教程),且严格限定在 docs/ 子树。
- (不要用无
--under 的裸 find_tutorials——那是「全仓找进阶教程」启发式,既越出 docs/ 又漏掉 docs/ 里的非教程文档。)
AskUserQuestion 确认评哪些(可多份);要扩到某算子目录就 --under <algo_dir>。
- 没扫到任何进阶教程 → 如实记「该仓无进阶教程」(覆盖度缺口,属「找得到」轴缺陷),出报告。
P1 — 判教程类型 + 受众(决定「讲为什么」严格度 + API 签名比对深度)
读教程标题/开头,判:
- 类型:教学型(标题/目标即教原理,如《算子开发指南》)→「讲为什么」必要但 graded、不必太严格;流程型(纯操作)→「讲为什么」加分;API 用法型(教你怎么调接口)→ API 签名比对升【必要】,其余流程型则 grep 只作线索标「(推断)」。
- audience-fit:目标读者 / 前置能力 / 是否衔接 quickstart 写明了吗?未写明 → 降低「学得会」结论置信度,不直接判教学失败。
- 落
doc_meta(教程路径 + 类型 + 受众 + 代码根)。
P2 — 可量化检查(对照代码,走「事实闸」+ 三态)
先读分类清单当 checklist:references/problem-taxonomy.md(8 类:C1–C6 可量化 / J1–J2 教学 + 三轴 impact/type/conf)。逐条按它排查。
P2.0 脚本铺底(T0,~0 token,机械类先免费查) — 跑两个确定性脚本,产出直接落 findings。--under 跟 P0 范围一致(默认 docs,扩到算子目录就传该目录):
python3 -m scripts.linkcheck <code_root> --under docs --json <out> —— 死链/死锚(C1),限定在所评范围内;
python3 -m scripts.support_table_check <code_root> [--under <algo_dir>] --json <out> —— 算子文档「产品支持表」跨文档自相矛盾(C5,铁证)。它针对算子文档:不传 --under 时自动跳过中央 docs/(中央文档无产品支持表);评 docs/ 中央文档时此脚本本就 0 条,主要在评算子目录时才有用。
能干净脚本化的只有「死链」「跨文档矛盾」两类。dtype/支持表「vs 代码」因「老芯片 binary 可能别处承接 / 需逐参数对齐」要判断,不脚本化(实测脚本一上 800+ 误报),留给下面的 LLM。脚本只是免费多查、不替代逐篇 LLM。
然后从教程抽出具体物(命令/脚本/flag/配置键/路径/默认值/函数名/内链),先 token 分诊 再核:
- 仓内对象(脚本名/仓内 flag/配置键/仓内静态路径)→ 去代码根 grep/parse,按证据等级(强=定义入口/可执行脚本定义;中=引用;弱=注释/测试/文档)定三态。
- 外部命令(cmake/bash/pip/git)→ 按环境依赖看,grep 不到 ≠ 缺陷。
- 占位符(
<repo>/$ASCEND_HOME/{soc})→ 不按字面 grep,改查「文档有没有解释取值来源」。
- 生成/安装产物路径 → 不直接判「对不上」。
- 配置默认值:只对可静态追踪的字面默认值下硬结论;来自 env/条件分支/CMake option 的标「无法静态确证」。
- API 签名(仅 API 用法型教程必做):核 函数名/参数/返回 vs 代码;须 AST/ctags,grep 只作线索标「(推断)」。
每条 → 记 原文 + 证据等级 + 代码位置 + 三态 + category(8 类之一,C1–C6/J1–J2) + root_cause? + impact。这些是高置信事实问题(报告先列、可计数)。
impact(开发者影响,按「后果+方向」定,不按类目机械映射):blocker=照做会失败(编不过/步骤扑空/选到用不了的芯片/类型;如支持表假√、dtype 表多列代码不支持的)· misleading=困惑但能恢复(死链/同篇矛盾/示例输出贴错)· minor=几乎无后果(锚文本错字/排版/欠声明=漏列代码其实支持的)。报告按 impact 排序、阻断在前。
⚠ 默认舍弃 minor:finder 不查不报瑕疵(锚文本错字/排版/欠声明/术语不统一/外部 URL 等),只产 blocker/misleading;render 默认也丢 minor。需要瑕疵时由用户显式开 --with-minor。这样省精力、问题量可控。
⚠ 内嵌代码片段(C3)按「示意 vs 规定」判,别机械升 blocker(灵魂③):只有文档明确要求「把这段粘贴/替换进某文件」的【规定式】片段、照做真编不过才升 blocker;【示意式】片段(教某个写法/给个例子,如「这样加一行 PRINTF 打印 tiling 值」,周围代码只是上下文)里变量名/签名与某真实文件对不上 → 读者会自然适配、教学点本身是对的 → 至多 misleading、通常不报。升 blocker 前先 steelman:「正常开发者真会照贴被卡住,还是会理解意图?」
P2.1 每条 finding 的展示字段(对齐报告引擎 templates/report-engine.html,面向文档维护者、不写黑话) — finding 除上面的 category/impact/cls/axis/quote/code_location/verdict/root_cause,再产出下面字段(render_html 直接用;缺了才从 improvement 降级派生,质量打折):
- 三轴:
impact(阻断/误导/瑕疵)· type 缺陷类型(走决策树:文档里没有=missing 缺失;有但与代码/数学/自身冲突=untrust 不可信;在且对但表达费解/不一致=readable 易读性。假√=untrust、漏行=missing、两种写法都对只是不统一=readable)· conf(bool:坐实=true 确认 / 线索级=false 疑似)· check(code 须查代码 / doc 查文档 / rule 查规则)。
- 四件套:
prob [1] 问题一句话 ≤40字「<要素><错在哪>」· conseq [2] 对开发者的后果(阻断类 conseqBad=true)· fig [3] 图示(可省)· fix [4] 修复方向一句话。
fig 三形态(与 type 配):untrust→{kind:'conflict', a:{tag,val 文档错}, b:{tag,val 实际对}} · missing→{kind:'gap', have:{tag,items[]}, doc:{tag,items[](缺项加"缺:"前缀)}} · readable→{kind:'incons', items:[{loc,val}], note};拿不准就省略。figNote 可选注解,可用 <b>对</b>/<span class="bad">错</span> 标色。
improvement 仍保留(完整解释,供 MD 报告与卡片折叠区;fix 是它的一句话浓缩)。
P3 — 不可量化判断(学得会 / 读得懂,走「steelman + 判例闸」)
对教学类指标(讲为什么[按 P1 类型] / 可迁移性 / 心智模型 / 概念讲错 / 认知过载 / 概念是否解释充分 / 模糊决策点):
- 每条 flag 前先 steelman:打它最强反论——「上文/附录是否已给了依据?有没有一种读法读者不会卡?」过不了才报。
- 报的话给判例:
读者任务 + 卡点原文 + 缺失信息 + 改进建议,标「教学判断(非代码事实)」。
- 「概念讲错」(把原理讲反等)必须有外部反证(仓内实现 / 官方 CANN 文档 / 同仓权威教程 / API 语义 / 可静态推出的代码行为);只有 LLM 推理 → 降级「疑似概念风险 / 需人工确认」,不写「确认讲错」。
这些是教学判断(报告后列、只定性、不可计数)。
P4 — 结论报告(定性档 + 干净交接 + 自校验)
产出 CWD/tech-docs-report/tech-docs-guard/<repo>/REPORT.md + REPORT.html(默认双格式):
cd skills/agent-tools/tech-docs-guard
python3 -m scripts.render_report --repo <repo> [--format both|html|md]
报告默认出 HTML:render_html 吐自包含引擎 templates/report-engine.html(华为风 · CSS+JS,勿改)+ 注入从 findings 映射的 DATA 数组——顶部双汇总条、阻断横幅、按文件速览、筛选、分组卡片(红绿对照图)、修改清单全由引擎 JS 现算。卡片按 P2.1 四件套(问题/后果/图示/修复)+ 三轴徽章(严重度·确定度·类型)呈现;保留 REPORT.md 备 diff/PR 引用。
必备模块:
- 覆盖标注(TE-1):
doc_meta.axes_evaluated 记本轮真评过的轴;未评过的轴在总评标「本轮未评」而非「合格」,不把覆盖缺口伪装成通过。某轴 finder 失败/未产出务必如实(别让空轴假装合格)。
- 总评:五轴各给定性档(合格 / 有缺陷 / 不合格 / 本轮未评)+ 缺陷计数(仅可量化条计数)+ 开发者影响分布(🔴阻断 / 🟠误导 / ⚪瑕疵,阻断优先修、瑕疵可缓);一句话结论;教程类型/受众。
- 事实问题(可量化) —— 先列:每条
原文 / 轴 / 形态·来源 / 证据等级 / 代码位置 / 三态 / 改进建议。
- 教学判断(不可量化) —— 后列,带「教学判断」标签:每条
原文 / 判例(读者会卡在…) / 改进建议;概念讲错附外部反证或「疑似」。
- 每条统一「干净交接」格式:
原文 + 类别(可量化/不可量化) + 证据或判例 + 三态结论 + 开放问题(没能确证的) + 下一责任人(文档作者)。
自校验闸(render 强制):可量化条必带 代码位置/匹配串;不可量化条必带 判例 + steelman 痕迹。缺则该条不准进报告(标记待补),防止玄学批评和无证据指控混进去。
跨轴去重(TE-2):多个 finder 在同一教程行命中同一处(如信得过 + 读得懂各报一遍)时,render 按 (类别, 教程行号) 折叠,保留证据最强一条、其余记 also_hit,五轴计数不虚高。findings.json 保留全部(非破坏式),只在报告层去重。
批量 / 全仓模式(按算子分组,实测省 ~50% token)
评多篇算子文档时,别一篇一个 finder——按算子分组,一个 finder 评一个算子的全部文档:分类清单 + 该算子代码只载一次,几篇文档共摊那 74K 固定开销(实测每篇 82K→2639K,约省一半;还能跨本算子文档抓出复制粘贴/支持表矛盾,更准)。
- 发现 + 分组:找含
op_host 的算子目录,把其下所有 .md 归到该算子;中央文档(docs/zh/...,无算子可分组)逐篇评。
- 逐算子 finder:一次 Read 该算子全部文档 + grep 其代码一次,对照
references/problem-taxonomy.md 挑问题。
- 每条 finding 带
doc(指明哪一篇)+ category + impact + 三态。
- 先跑 P2.0 脚本(linkcheck / support_table_check)一次铺满全仓,再让分组 finder 补残差。
省 token 的大头是分组共摊固定开销,不是脚本;脚本只免费多查死链/跨文档矛盾。全仓一轮实测外推 ~81M→~40M。
铁律与禁忌
- ✓ 默认不跑(静态):结论只能写「未发现/存在静态阻断项」,禁止写「能跑通」。
- ✗ 不打玄学分:不可量化每条先 steelman 再 flag + 给判例;过不了 steelman 不报。
- ✗ grep 不到 ≠ 编造:三态结论,只有强证据反证才写「确认对不上」;「概念讲错」无外部反证 → 降级「疑似」。
- ✗ 不写死 仓名/路径/教程位置/SOC(每次扫描发现 +
AskUserQuestion)。
- ✗ 代码事实 与 教学判断 分开标注,报告分两段,不混。
- ✗ 不改、不补、不跑、不探索文档(那是别的工具的事);本 skill 只诊断。
- ✗ 不凭空捏造:每条缺陷必带 代码位置 或 判例。
- ✓ 评分只定性(档 + 缺陷计数),不打数字分;只有可量化条可计数。
运行位置
纯静态评(读教程 + grep 代码)→ 本地即可,不需 NPU;若代码在远程,则在远程 grep 或把代码根同步回本地。默认不真跑,故无 build/install 副作用。
产物:tech-docs-report/tech-docs-guard/(每仓一子目录)
tech-docs-report/tech-docs-guard/<repo>/
├── doc_meta.json ← 教程路径 + 类型(教学型/流程型/API用法型) + 受众 + 代码根 + axes_evaluated(本轮评过的轴)
├── findings.json ← 机读:每条 = 类别/轴/形态·来源/证据等级或判例/三态/原文/改进建议/下一责任人(全部,不去重)
├── REPORT.md ← 体检报告 Markdown(定性档 + 事实问题段 + 教学判断段)
└── REPORT.html ← 体检报告 HTML(默认产出;卡片式/三态色标/折叠)
脚本
scripts/find_tutorials.py — 扫进阶教程候选(启发式 + 排除非教程)。
scripts/codecheck.py — 可量化对照:token 分诊 + grep/parse 代码 + 证据等级 + 三态(信得过的事实闸)。
scripts/linkcheck.py — T0 全文档死链/死锚(C1),确定性、~0 token。
scripts/support_table_check.py — T0 同算子多篇文档「产品支持表」自相矛盾(C5),确定性、~0 token。
references/problem-taxonomy.md — 问题分类清单(8 类 C1–C6 / J1–J2 + 三轴),finder 的 checklist。
templates/report-engine.html — HTML 报告引擎(华为风,CSS+JS 自包含,勿改);render_html 注入 DATA 即出报告。
scripts/_state.py — 路径/枚举 + findings.json·doc_meta.json 读写(两类分桶)+ 自校验闸 self_check_finding。
scripts/render_report.py — 渲染体检报告 MD + HTML(HTML = 引擎 + DATA 注入),强制过自校验闸 + 跨轴去重(TE-2)+ 未评标注(TE-1);纯 stdlib。
scripts/requirements.txt(仅 stdlib + 系统 grep)、tests/test_tech_docs_guard.py(15 用例)。
Failure modes
| 触发 | 行为 |
|---|
| 仓内无任何进阶教程 | 如实记「无进阶教程」(找得到轴覆盖度缺陷),出报告 |
| 抽出的物是占位符/外部命令/生成产物 | 不按字面判「对不上」,按分诊规则处理 |
| 某教学缺陷过不了 steelman | 不报(它其实站得住) |
| 想判「概念讲错」但只有 LLM 直觉、无外部反证 | 降级「疑似概念风险 / 需人工确认」,不写「确认」 |