# 手把手教程：用 dsh-research-check 在你交稿前替你检查一遍

这份教程假设你**从来没接触过这个插件**，跟着做一遍大概 15 分钟。
每一步都给了命令和**预期看到的结果**，所以你不会不知道自己做对没有。

教程分三个场景，按需要看：

| 场景 | 适合谁 | 跳转 |
|---|---|---|
| **A. 检查一篇论文**（完整流程） | 参加竞赛、投稿、写学位论文 | [开始](#场景-a检查一篇论文) |
| **B. 检查一个软件交付包** | 交付代码、项目验收 | [跳转](#场景-b检查一个软件交付包) |
| **C. 只查"数字有没有改漏"** | 已经交了稿，只想核对数字 | [跳转](#场景-c只查数字有没有改漏) |

---

# 准备：装好工具（约 5 分钟）

## 1. 确认你机器上有 Python

打开终端（Windows 按 `Win + R` 输入 `cmd` 回车），输入：

```
python --version
```

**预期**：`Python 3.13.x` 之类，**版本要 ≥ 3.10**。没装就去 https://www.python.org/downloads/ 装（安装时**勾选 Add Python to PATH**）。

## 2. 装检查需要的库

```
pip install pymupdf openpyxl pillow python-docx
```

这四个分别负责：读 PDF、读 Excel、读图片分辨率、读 Word 文档。装完不用管。

## 3. 拿到插件

**方式一：用 DeepSeek Harness（推荐）**

```
dsh plugin --profile web add dsh-research-check
```

装完**重启 DSH**，之后你直接对 AI 说"帮我检查论文格式"就行。

**方式二：直接用命令行**（不装 DSH 也能用）

```
git clone https://github.com/mikasa-servent/dsh-research-check.git
cd dsh-research-check
```

后面的命令都在这个目录里执行。

> 💡 两种方式都能用同样的命令行工具。教程用**命令行**演示，因为它最直观；
> 如果你用方式一，把命令换成对 AI 说一句话即可。

---

# 场景 A：检查一篇论文

假设你的工作目录长这样（换成你自己的文件名即可）：

```
我的论文/
├── 格式规范.doc        ← 赛会/期刊给的要求文件
├── 论文.tex            ← LaTeX 源码（或你的 Word 文档）
├── 论文.pdf            ← 编译出来的 PDF
├── 数据.xlsx           ← 要一起交的结果文件
├── 支撑材料.zip         ← 要一起交的材料包
└── 图表/               ← 图片目录
```

## 第 1 步：把要求文件变成"能自动核对的清单"

先切到你的论文目录：

```
cd /d "C:\我的论文"
```

然后执行（把 `<插件目录>` 换成插件的实际路径）：

```
python "<插件目录>\python\spec_build.py" ^
    --requirements 格式规范.doc ^
    --out specs\我的要求.json ^
    --profile academic ^
    --name "我的论文格式要求"
```

**预期输出**（类似这样）：

```json
{
  "ok": true,
  "out": "specs\\我的要求.json",
  "name": "我的论文格式要求",
  "profile": "academic",
  "rules": 19,
  "bySeverity": { "hard": 15, "soft": 4, "info": 0 },
  "checks": ["max_pages", "abstract_first_page", "manifest_matches_archive", ...],
  "needsReview": [
    "行距：行距要求已尝试从源码判定；若以 Word 交付，需人工核对段落行距设置。"
  ]
}
```

**怎么读这个结果**：

- `rules: 19` = 从要求文件里提取出 19 条**能自动检查**的规则
- `hard: 15` = 其中 15 条属于"违反就报错"
- `needsReview` = 机器判断不了的、需要你自己确认的（比如行距）

## 第 2 步：人工复核清单（**这步别跳过**）

用记事本打开 `specs\我的要求.json`，重点看三样：

1. **数字对不对**——比如 `"limit": 30` 是不是"正文 30 页"？`"limit": 20971520` 是不是 20 MB？
2. **每条规则的 `source`**——它引用的是要求文件里的原话，看一眼确认没理解错；
3. **哪些参数是空的**——比如：

```json
{
  "id": "gen.required_files",
  "params": { "required": [] }     ← 空的！这条检查跑起来会报"没检查"
}
```

把空参数填上。例如要求文件说"必须提交 论文.pdf、数据.xlsx、代码.zip"，就改成：

```json
{ "required": ["论文.pdf", "数据.xlsx", "代码.zip"] }
```

> ⚠️ **不用怕填错**：参数没填时它会如实报 `skipped`（"这条我没查"），**不会假装通过**。

## 第 3 步：跑检查

```
python "<插件目录>\python\check_spec.py" ^
    --spec specs\我的要求.json ^
    --root . ^
    --doc 论文.tex ^
    --pdf 论文.pdf ^
    --files 数据.xlsx ^
    --archive 支撑材料.zip ^
    --assets 图表
```

参数含义（都可以省略，省略的就不查）：

| 参数 | 给什么 | 用于哪些检查 |
|---|---|---|
| `--doc` | LaTeX 源码 | 行距、字号、目录、章节数 |
| `--pdf` | 编译出来的 PDF | 页数、摘要、空白页、图表引用 |
| `--files` | 要交的零散文件 | 文件大小、Word/Excel 属性里的身份信息 |
| `--archive` | 材料压缩包 | 压缩包体积、内容与清单是否一致 |
| `--assets` | 图片目录 | 图片格式、分辨率、命名 |

**预期输出**是一个 JSON。看不惯 JSON 就加一个 `--json` 之外的用法：

```
python "<插件目录>\tests\run_spec_check.py" --spec specs\我的要求.json
```

它输出**中文表格**：

```
规格：我的论文格式要求 v1.0.0（19 条规则）
判定：fail   {'error': 1, 'warning': 0, 'info': 2, 'pass': 15, 'skipped': 1}
-----------------------------------------------------------------
[ok  ] hard  正文页数上限          正文（附录自第 31 页起）30 页 / 上限 30 页
[ok  ] hard  摘要不超过一页        摘要（含关键词）在 1 页内
[FAIL] hard  文档属性不得含身份信息   属性命中：{'creator': '张三'}
[ok  ] soft  图表必须被引用        全部被引用
[skip] hard  必备文件齐备          规则未列出必须提交的文件（params.required）
```

## 第 4 步：看懂结果，逐条处理

| 标记 | 含义 | 你要做什么 |
|---|---|---|
| `pass` ✓ | 通过 | 不用管 |
| `error` ✗ | **违反硬性要求** | **必须改**，改完重新检查 |
| `warning` ! | 提醒 | 自己判断要不要改（通常是软性要求） |
| `skipped` - | **没检查** | 缺输入或参数没填——**补上或转人工，别当通过** |
| `info` | 人工清单 | 需要你自己确认的事项 |

每条失败都会带上 `source`，也就是要求文件里的原话，你可以拿着它对账：

```
需修正 1 条：
  · 文档属性不得含身份信息 —— …所有文件中不能有显示参赛者身份和所在学校及赛区的信息…
```

## 第 5 步：常见修法（照着做）

**① 文档属性里有身份信息**（最常见的违规）

Excel/Word 的属性里存着作者名，肉眼看不见：

```bash
# 看看哪些文件的属性有问题
python "<插件目录>\python\check_hygiene.py" --files 数据.xlsx 说明.docx
```

**注意这个检查的能力边界**——它会分两种情况报：

| 属性里写的内容 | 结果 | 说明 |
|---|---|---|
| 含身份关键词（学校、大学、学院、赛区、指导教师、姓名、学号、邮箱、"企业用户"…） | **error ✗** | 确定为身份泄露，必须清 |
| 只写了个人名（如"张三"） | **warning !** | 关键词表认不出裸人名，需要**你自己看一眼** |

所以：`warning` 里如果显示了属性值，请打开文件确认一下——是个人信息就清掉。

清法：Excel/WPS 打开 → 文件 → 信息 → 检查文档 → 删除个人信息 → 保存；
或者用脚本批量清（清空 `creator` / `lastModifiedBy` / `Company` 三个字段）。

**② 页数超了**

改排版或删内容。注意**附录不算正文**——检查器会自动识别"附录"标题并把后面的页排除。

**③ 压缩包和清单对不上**

论文附录里列的文件，要和压缩包里**逐个一致**。要么补文件，要么改清单。

**④ 图表没被引用**

正文里要写"如图 3 所示"这样的引用。没被引用的图表会被判为多余。

## 第 6 步：改完再跑一遍，直到全绿

```
python "<插件目录>\tests\run_spec_check.py" --spec specs\我的要求.json
```

**目标**：`error: 0`。剩下的 `skipped` 和 `info` 人工确认一遍即可交稿。

---

# 场景 B：检查一个软件交付包

假设你要交付一个项目，甲方给了"交付验收标准.docx"。

## 第 1 步：生成规则（注意 `--profile software`）

```
cd /d "D:\我的项目"
python "<插件目录>\python\spec_build.py" ^
    --requirements 验收标准.docx ^
    --out specs\验收要求.json ^
    --profile software ^
    --name "某项目交付验收标准"
```

## 第 2 步：检查交付内容

```
python "<插件目录>\python\check_spec.py" ^
    --spec specs\验收要求.json ^
    --root . ^
    --files README.md LICENSE CHANGELOG.md run.log ^
    --archive 交付包.zip
```

**软件场景会重点查**（这些是甲方退回的高频原因）：

| 检查 | 为什么重要 |
|---|---|
| 必备文件齐备 | 缺 `README.md` / `LICENSE`，甲方拿到手不知道怎么用、法务上也不能用 |
| 变更记录 | 缺 `CHANGELOG.md`，出问题没法定位是哪个版本引入的 |
| 日志里的报错 | 交付日志里留着 `Traceback`、`ERROR:`，等于自证没测过 |
| 压缩包清单一致 | 清单与实际不符，会被认为材料不实 |

**预期输出**：

```
[ok  ] hard  源码包必备文件       必需文件齐备
[FAIL] hard  交付代码不得含报错标记  命中：['Traceback (most recent call last)', 'ERROR:']
[ok  ] soft  必须有变更记录       必需文件齐备
```

---

# 场景 C：只查"数字有没有改漏"

这个场景**最有用**，因为它抓的错误最难自查：你改了图表，忘了改正文。

## 第 1 步：建台账，记下关键数字和来源

```
cd /d "C:\我的论文"
node "<插件目录>\lib\ledger-cli.js" teach ^
    --ledger 台账.json ^
    --paper 论文.tex ^
    --unit-filter 万元 ^
    --min-abs 100
```

**预期**：它会把文稿里所有"带单位的数字"连同**它所在的整句话**登记下来：

```
{
  "ok": true,
  "candidates": 130,
  "added": 6,
  "note": "候选条目已登记；请把 key 改成语义名并补上 source 程序路径，再用于 verify。"
}
```

打开 `台账.json`，你会看到类似：

```json
{
  "key": "auto.论文.tex.p0.3",
  "value": 1521.6,
  "unit": "万元",
  "source": "论文.tex",
  "anchor": "全年总费用从 1536.4 万元降到 1521.6 万元"
}
```

**这一步的价值在于**：它把"改稿前后的两个值"抓在同一句话里（1536.4 与 1521.6）——
这种地方最容易漏改其中一个。

## 第 2 步：整理台账（把 `key` 改成人能看懂的名字）

把 `auto.论文.tex.p0.3` 改成 `q3.total_cost`，把 `source` 改成"哪个程序算出来的"：

```json
{
  "key": "q3.total_cost",
  "value": 1521.6,
  "unit": "万元",
  "source": "code/q3.py",
  "anchor": "全年总费用"
}
```

## 第 3 步：核对

```
node "<插件目录>\lib\ledger-cli.js" verify ^
    --ledger 台账.json ^
    --paper 论文.pdf ^
    --near
```

**两种结果**：

```
# 没问题
{ "verdict": "pass", "checked": 6, "missing": 0 }

# 有问题（这个例子是真实发生过的）
{
  "verdict": "fail",
  "missing": 1,
  "findings": [
    {
      "key": "q3.total_cost",
      "expected": 1521.6,
      "message": "台账值 1521.6万元 在文档中未找到：可能是改写文字时漏改，或台账未随稿更新。"
    }
  ]
}
```

## 第 4 步：按提示修

- `missing` → 台账里的数字在文稿里找不到 → **很可能你改掉了正文但没同步台账**，或者反过来；
- `--near` 给出的"同一位置的相似数值" → 例如台账说 1521.6，正文同一个地方写着 1536.4 → **这就是漏改**。

---

# 遇到问题怎么办

| 现象 | 原因 | 解决 |
|---|---|---|
| `NO_PYTHON` | 没装 Python 或没加到 PATH | 装 Python 3.10+，勾选 Add to PATH |
| 输出中文乱码 | 旧版本 | 升级到 1.4.1+ |
| `skipped` 很多 | 没给对应的输入文件 | 按上面参数表补 `--pdf` / `--files` / `--archive` |
| 规则提取不全 | 要求文件写法特殊 | 打开生成的 spec，手动补几条（格式照抄现有的） |
| 检查结果与预期不符 | 规则参数不对 | 检查 spec 里的 `params`，比如页数上限是不是写成了别的数 |

---

# 记住三件事就够了

1. **要求 → 规格**：把要求文件喂给 `spec_build.py`，得到一份能自动核对的清单（每个项目只做一次）；
2. **交稿前跑一遍** `check_spec.py`，把 `error` 全部清掉，`skipped` 和 `info` 人工确认；
3. **改了数字就核对台账**：`ledger verify`，它能抓出"图表改了、正文没改"这种最难自查的错。

祝顺利交稿 🎯
