# Tech Docs Guard

> 评估 CANN 算子仓的「进阶教程 / 开发指南」类文档质量——通读文档 + 对照算子代码**静态**查证(默认不跑),按五轴(找得到/信得过/学得会/可操作/读得懂)找出 漏讲/讲不清/过时/对不上代码/概念讲错,产出带证据与改进建议的体检报告(MD + HTML)。涉及「评进阶教程 / 开发指南文档质量 / 文档对不对得上代码 / 教程审稿 / tutorial 体检 / 文档信不信得过」等意图时使用。只评不改不跑,只对着文档与代码出诊断。

- Skill: `ascend-ai-coding/tech-docs-guard` (Agent Skill, multi-file: 15 files)
- Install (CLI): `npx skillmds@latest add ascend-ai-coding/tech-docs-guard`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ascend-ai-coding/tech-docs-guard/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: ascend-ai-coding (https://skillmd.com/u/ascend-ai-coding)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/ascend-ai-coding/tech-docs-guard

---


# tech-docs-guard

**模拟一个挑剔但讲证据的审稿人:通读进阶教程,对照代码查证它「看得懂 / 跑得通 / 信得过」,把「漏讲 / 讲不清 / 过时 / 对不上代码 / 讲错」逐条带证据写成体检报告。**

一句话:进阶教程的目的是「**教得会**」。本 skill 默认**不跑**——靠**读懂教程 + 拿代码当裁判**做静态评估,而不是真机执行。

## ⚠ 本 skill 的三条灵魂(不可违背)

1. **不打玄学分**。主观判断(讲不清 / 教不会 / 讲错)**flag 之前先 steelman**——先替这段文字辩护到最强(「有没有一种读法这里其实没问题?」),辩不过去才算缺陷;报的话必须给**判例**(读者会卡在哪 + 原文 + 改进建议),并标「教学判断(非代码事实)」。
2. **grep 不到 ≠ 编造**。对照代码只能证明「字符串出现过/没出现」,不能证明它是当前有效入口。结论**三态**:`确认对不上`(有强证据反证)/ `疑似过时`(静态没找到,但可能生成/外部/分支)/ `未找到静态证据`(存疑,不指控)。**只有强证据才写「确认」。**
3. **按「实际开发者影响」判,不按「机械字面对照」判**。报一条(尤其升 blocker)前自问:**正常开发者照这文档做,真会被卡住吗?还是他会理解意图、自然适配?** 文档里大量是**示意/演示**(教某个写法、给个例子),不是要逐字粘贴。**只有文档明确要求「把这段粘贴/替换进某文件」的【规定式】内容、照做真出错,才升 blocker;【示意式】内容(如「这样加一行 PRINTF 打印」)里变量名/签名与某真实文件对不上 → 读者会自然适配 → 至多 misleading、通常不报。** 别把「逐字符照抄能否编译」当唯一标准——那会制造一堆实际影响不大的误报。

> 这个 skill **只评、不改、不跑、不探索**:真跑教程/算子、改写文档、准备环境都是别的工具的事;本 skill 只对着文档和代码出诊断。

## When to invoke

- 「评一下 ops-X 的算子开发指南 / 进阶教程写得行不行」
- 「这教程跟代码对得上吗 / 信不信得过」
- 「按教程能不能学会 / 哪里讲不清 / 哪里漏了」
- 任何「审进阶教程文档质量」的请求

## Inputs（零硬编码,每次会话发现或询问）

- **目标仓 + 代码根**:从 CWD 发现候选仓(有 `docs/` 的子目录),或用户给绝对路径。对照代码需要仓的源码根。

- **待评文档**:**不写死路径**——每仓目录/命名不一样、还会变,故**每次自行扫描发现**:

  ```bash
  cd skills/agent-tools/tech-docs-guard
  python3 -m scripts.find_tutorials <repo_root> --under docs --json  # 【默认范围】列 <repo>/docs/ 下全部技术 .md
  # python3 -m scripts.find_tutorials <repo_root> --json             # (无 --under)全仓找进阶教程启发式,非默认范围
  ```

- **不假定** SOC / 版本:教程若声明前提(CANN 版本/SOC),以教程为准来核「版本适配」。

## 评估框架（五轴最小核）

| 层      | 轴       | 看什么                                                  |
| ------ | ------- | ---------------------------------------------------- |
| 前置     | **找得到** | 该教程是否存在、入口能否导航到(断链/标题误导/目录不可达)                       |
| **主评** | **信得过** | 命令/flag/路径/配置默认值/函数签名/讲错 → **对照代码,走分级证据 + 三态**       |
| 辅评     | **学得会** | 可迁移性 / 心智模型 / 讲「为什么」 / audience-fit(按教程类型,**不必太严格**) |
| 限定     | 可操作     | 只报**静态阻断项**(默认不跑,**不下「能跑通」结论**)                      |
| 表达     | 读得懂     | 只报**影响理解**的术语/结构/模糊决策点                               |

**缺陷 = 形态 × 来源**:形态 `缺 / 糊 / 错 / 冗`;「错」的来源 `对不上代码 / 过时 / 概念讲错 / 自相矛盾`。

**指标第一分类(决定怎么判)**:

|       | 可量化(确定性)                | 不可量化(教学判断)              |
| ----- | ----------------------- | ----------------------- |
| 怎么判   | 规则 / grep / parse / AST | LLM 阅读 + **先 steelman** |
| 能下的结论 | 确认对不上 / 一致(强证据)         | 最多「疑似 / 教学判断」,**绝不写确认** |
| 报告    | 事实问题,**先列**,可计数         | 教学判断,**后列**,带标签,只定性     |
| 自校验   | 必带 代码位置 / 匹配串           | 必带 判例 + steelman 通过     |

## Workflow

### P0 — 发现并确认「目标仓 + 代码根 + 待评教程」(中文交互)

1. 发现候选仓(CWD 下含 `docs/` 的子目录)+ 仓源码根。
2. **范围默认只取根 `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>`。
3. 没扫到任何进阶教程 → 如实记「该仓无进阶教程」(覆盖度缺口,属「找得到」轴缺陷),出报告。

### 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`(默认双格式):

```bash
cd skills/agent-tools/tech-docs-guard
python3 -m scripts.render_report --repo <repo> [--format both|html|md]   # 默认 both,同目录出 .md + .html
```

> **报告默认出 HTML**:`render_html` 吐自包含引擎 `templates/report-engine.html`(华为风 · CSS+JS,勿改)+ 注入从 findings 映射的 `DATA` 数组——顶部双汇总条、阻断横幅、按文件速览、筛选、分组卡片(红绿对照图)、修改清单全由引擎 JS **现算**。卡片按 P2.1 四件套(问题/后果/图示/修复)+ 三轴徽章(严重度·确定度·类型)呈现;保留 `REPORT.md` 备 diff/PR 引用。

**必备模块**:

0. **覆盖标注(TE-1)**:`doc_meta.axes_evaluated` 记本轮真评过的轴;**未评过的轴在总评标「本轮未评」而非「合格」**,不把覆盖缺口伪装成通过。某轴 finder 失败/未产出务必如实(别让空轴假装合格)。
1. **总评**:五轴各给**定性档**(合格 / 有缺陷 / 不合格 / 本轮未评)+ 缺陷计数(**仅可量化条计数**)+ **开发者影响分布**(🔴阻断 / 🟠误导 / ⚪瑕疵,阻断优先修、瑕疵可缓);一句话结论;教程类型/受众。
2. **事实问题(可量化)** —— 先列:每条 `原文 / 轴 / 形态·来源 / 证据等级 / 代码位置 / 三态 / 改进建议`。
3. **教学判断(不可量化)** —— 后列,带「教学判断」标签:每条 `原文 / 判例(读者会卡在…) / 改进建议`;概念讲错附外部反证或「疑似」。
4. **每条统一「干净交接」格式**:`原文 + 类别(可量化/不可量化) + 证据或判例 + 三态结论 + 开放问题(没能确证的) + 下一责任人(文档作者)`。

> **自校验闸**(render 强制):可量化条必带 代码位置/匹配串;不可量化条必带 判例 + steelman 痕迹。缺则该条**不准进报告**(标记待补),防止玄学批评和无证据指控混进去。
>
> **跨轴去重(TE-2)**:多个 finder 在同一教程行命中同一处(如信得过 + 读得懂各报一遍)时,render 按 `(类别, 教程行号)` 折叠,保留证据最强一条、其余记 `also_hit`,五轴计数不虚高。findings.json 保留全部(非破坏式),只在报告层去重。

### 批量 / 全仓模式（按算子分组,实测省 ~50% token）

评**多篇算子文档**时,**别一篇一个 finder**——按算子分组,**一个 finder 评一个算子的全部文档**:分类清单 + 该算子代码只载一次,几篇文档共摊那 ~74K 固定开销(实测每篇 82K→26~39K,**约省一半**;还能跨本算子文档抓出复制粘贴/支持表矛盾,更准)。

1. **发现 + 分组**:找含 `op_host` 的算子目录,把其下所有 `.md` 归到该算子;中央文档(`docs/zh/...`,无算子可分组)逐篇评。
2. **逐算子 finder**:一次 Read 该算子全部文档 + grep 其代码一次,对照 `references/problem-taxonomy.md` 挑问题。
3. 每条 finding 带 **`doc`**(指明哪一篇)+ category + impact + 三态。
4. **先跑 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 直觉、无外部反证 | 降级「疑似概念风险 / 需人工确认」,不写「确认」 |


