# Vocab Reading Coach

> 单词短文陪练助手 (vocabulary reading coach)。帮背单词书（四级/考研/雅思等）的用户： 导入词书文件（PDF/TXT/CSV 自动转 words.jsonl）、按用户进度（以单词定位）生成英文陪练短文、 管理练习记录和拓展词。本 skill 独立于任何平台，脚本路径均相对本 skill 目录。 Use when the user mentions 背单词、单词书、词书、导入词书、PDF 转词库、生成短文/阅读练习、 陪练、复习单词，or uploads a wordbook file (PDF/TXT/CSV/Excel) wanting it converted to a word database, or reports their vocabulary progress like "我背到 abandon 这个词了" / "从 X 词背到 Y 词了". Also use for English reading passages generated from a known word list, vocabulary practice tracking, and wordbook JSONL conversion.

- Skill: `xu-watermelon/vocab-reading-coach` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add xu-watermelon/vocab-reading-coach`
- Raw SKILL.md: https://api.skillmd.com/api/skills/xu-watermelon/vocab-reading-coach/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: xu-watermelon (https://skillmd.com/u/xu-watermelon)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/xu-watermelon/vocab-reading-coach

---


# 单词短文陪练助手 (Vocab Reading Coach)

帮用户在阅读中巩固单词：导入词书 → 按进度生成英文短文 → 跟踪练习记录。

> 本 skill 是**跨平台的独立 skill**（Claude / opencode / 其他 agent 均可加载）。
> 下文所有脚本路径均相对于本 skill 所在目录；数据文件在**用户当前工作目录**。

## 数据文件（都在当前工作目录，缺失时按"首次使用"处理）

| 文件 | 格式 | 说明 |
|---|---|---|
| `words.jsonl` | 每行一个 JSON：`{"id","page","word","phonetic","pos","meaning","example"}` | 词库。`page` 是**印刷页码**（不是 PDF 页号），`id` 是递增整数（=词书顺序，选词范围的依据） |
| `practiced_log.json` | `{"words": {"单词": {"count": 次数, "last": "YYYY-MM-DD"}}}` | 练习记录（`last` 支撑遗忘曲线调度；兼容旧的纯次数格式，脚本读入时自动升级） |
| `extension_words.json` | `{"单词": {"pos","meaning","example"}}` | 已有拓展词（新拓展词不得与之重复） |

## 模式一：导入词书

用户提供词书文件（PDF / TXT / CSV）时：

1. 运行脚本（会生成 words.jsonl + import_report.txt + page_probe.txt 三个文件）：
   ```
   python <本skill目录>/scripts/import_wordbook.py <词书文件> --out words.jsonl
   ```
   已知偏移可直接指定（如新东方四级词根+联想：`--pdf-offset 9`，即印刷页码 = PDF页码 - 9）。
2. 脚本缺 pdfplumber 依赖时会打印安装命令，直接帮用户执行 `pip install pdfplumber`。
   若安装失败（Python 版本过新），降级方案：你用 read 工具直接逐段读 PDF 提取文本（仅适合小文件），
   或请用户把词书导出为 TXT/CSV 再导入。
3. **页码判定（AI 主导）**
   - 注意：选词范围由 `id`（词书顺序）决定，**页码不影响选词正确性**；
     `page` 只用于输出 frontmatter 的进度标记，因此核对是**建议项**而非阻塞项
   - 报告显示自动探测可靠 → 抽样核对可简化（问用户 1~2 页确认即可）
   - 不可靠或存疑 → **你读 `page_probe.txt`**（全书均匀抽样 6 页的页首/页尾原文，很小），
     从中判断印刷页码规律：页脚独立数字、"第X页"标记、章节头推算等，得出偏移量 N
   - 探针信息不够时，用 read 工具直接读原 PDF 的某几页确认（每次只读几页，不会爆上下文）
   - 文本层完全没有页码线索 → 请用户随手翻实体书，报 2 个页码 + 该页第一个单词，
     你对照 words.jsonl 里该词所在的 PDF 页，算出偏移 N
   - 得出 N 后用 `--pdf-offset N` 重新导入，让全书页码统一修正；实在核不准就先记录页码存疑，
     不阻塞后续使用
4. **实体书终审**：读 `import_report.txt` 中的「页码抽样核对表」，
   让用户打开实体书核对每个抽样页的词条。任何一页不符 → 回到第 3 步修正。
5. 修复失败条目：报告里解析失败/存疑的词条附有原始文本，
   把它们手动整理进 `words.jsonl` —— 只修失败的部分，不要重新解析全部。
6. 向用户汇报：总词数、成功率、页码映射方式、核对结果。

原则：脚本做批量提取，**你做页码判断和兜底修复**。不要试图自己通读整本 PDF——
几千个词条会耗尽上下文，而且又慢又容易漏。

## 模式二：生成陪练短文

触发：用户报告进度（"背到 abandon 了"）或要求生成短文。

1. 读取 3 个数据文件（哪个不存在就告知用户，并跳过对应规则）。
2. **确定选词范围**（`id` 即词书顺序，范围都是闭区间）：
   - 用户给**一个单词 A** → 范围 = 词库开头 到 A（`id ≤ id(A)`），即"A 之前的所有内容"
   - 用户给**两个单词 A、B** → 范围 = A 到 B 之间（自动按词库顺序排列：`min(id) ≤ id ≤ max(id)`）
   - 单词不在 words.jsonl 里 → 告知用户并请其确认写法；顺序颠倒的两个词直接静默排序，不必追问
3. 确定其他参数（用户没说就用默认值，不要反复追问）：
   - 篇数：默认 3 篇
   - 每篇长度：默认 250~350 词
   - 主题：默认 AI科技 / 电影 / 历史 各一篇
4. 选词，优先级从高到低：
   - **词库词**：只从范围内的词里选；**配额：每篇 10~15 个**（范围大就优先未练过的，
     并按 id 顺序均匀覆盖，保证多期短文逐段扫过整个范围，而不是反复啃同一段）
   - **拓展词**：词库之外的新词，每篇 6~8 个，「比目标词书稍高但日常常用」；不得与 `extension_words.json` 已有词重复。
     拓展词的释义/例句由你**直接给出**（写在文末 EXT 表）；对拿不准的词可临时联网搜索核对，但不要为此拖慢生成
5. **生成内容必须落盘为本地 .md 文件，不能只输出在对话里**：
   - 默认保存到当前工作目录，文件名 `YYYY-MM-DD.md`（取 frontmatter 的 date）
   - **归档约定：草稿即正式稿**——同一期修改直接改这个文件，不另存副本；
     "已确认"的唯一标志是 practiced_log 里有没有本期记录
   - 用户对文件名/保存位置有要求时，按用户要求保存
   - 保存后在对话里只给简要报告（文件路径、篇数、选了多少词库词/拓展词），
     用户要看全文再展示
6. **按 [`references/output_format.md`](references/output_format.md) 的格式写作，且必须运行校验器**：
   frontmatter 的 `page` 填**范围末词所在的印刷页码**（从 words.jsonl 自动查得，作为本期进度标记）。
   落盘后运行校验器（权威标准，替代手工逐项核对）：
   ```
   python <本skill目录>/scripts/check_passage.py <文件.md> --word <边界词> [--word2 <第二边界词>]
   ```
   有错误必须修复后重跑，直到 `[OK] 校验通过`；警告（字数、缺中文标题等）酌情处理。
   校验项包括：frontmatter、编号连续、翻译标记、词库词真实存在且在范围内、
   EXT 表双向一致、每篇字数。
7. 用户确认满意后，更新记录（确认前不要更新 —— 他可能还要改）：
   ```
   python <本skill目录>/scripts/update_records.py practiced --words "选中词逗号分隔"
   python <本skill目录>/scripts/update_records.py ext --file <本次拓展词临时json>
   ```
   practiced 会记录 `last` 日期，作为遗忘曲线调度的依据。

## 模式三：进度查询

用脚本统计（不要手工对 JSONL）：
```
python <本skill目录>/scripts/update_records.py progress --word <边界词> [--word2 <第二边界词>]
```
输出：范围内词数、已练/未练与覆盖率、最久没练的词（遗忘曲线重点）。
最久没练的词在下次生成时优先复现。

## 硬性规则

- 短文里的词库词必须真实存在于 `words.jsonl` 且落在选词范围内
- 每个 `==拓展词==` 必须出现在文末 `## EXT` 表里，格式 `单词 | 词性 | 中文释义 | 例句`（例句可空但要保留竖线占位）
- `date` 用 YYYY-MM-DD；`page` 是数字（范围末词的印刷页码）
- 中文翻译里可以给对应词加 `**` / `==` 标记（方便中英对照，非必需）

