# Textbook

> 写一整本多章节教材或成体系的课程讲义（含习题）时用它：按 UbD 逆向设计调度五个阶段——教学定位 → UbD 预期结果（gate）→ 章节树（gate）→ 逐章写作 → 审核定稿；进度落盘 .progress.json，中断后可从断点续写。触发语如"写教材"、"写一本教材"、"编写课程讲义"、"系统教材"、"textbook"。只写单篇教程、只写一章（用 textbook-chapter）、只出习题（用 textbook-exercises）时不要用它。需与 textbook-outline、textbook-chapter、textbook-exercises 装在同一 skills 目录下。

- Skill: `cabbage2000-lab/textbook` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add cabbage2000-lab/textbook`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cabbage2000-lab/textbook/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: cabbage2000-lab (https://skillmd.com/u/cabbage2000-lab)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/cabbage2000-lab/textbook

---


# textbook

写教材的主 skill（orchestrator）：驱动五阶段流程，管理 `.progress.json` 状态实现中断可续，在阶段间传递交接契约，最终交付一本有主线、有梯度、可评估的多章节 Markdown 教材。契约、落盘布局、状态机的权威定义见 [references/handoff-contract.md](references/handoff-contract.md)（下称"契约文档"）。

学科差异（题型集、验证手段、认知动词、章内段义）不在本 skill 里分支，收拢在**学科档案**中：阶段 1 判定一次，落盘为 `.progress.json` 的 `subject_profile`，逐章原样透传。规格与索引见 [references/subject-profile-spec.md](references/subject-profile-spec.md)。

## 何时不触发

- 单篇教程/图文教程（用 tutorial-writer）
- 只写一章或一篇深度文章（用 textbook-chapter）
- 只要例题/习题（用 textbook-exercises）
- 只做大纲不写正文（直接用 textbook-outline）

## 工作流总览

| 阶段 | 名称 | 执行者 | 产出 | Gate? |
| ------ | ------ | -------- | ------ | ------- |
| 1 | 教学定位确认 | textbook-outline | 学科/读者起点/深度/篇幅 → 00-教材设计.md | 否（一轮提问） |
| 2 | UbD 预期结果设计 | textbook-outline | UbD 五件套 | **是（核心 gate）** |
| 3 | 评估与章节设计 | textbook-outline | 章节树+例题计划+梯度报告+表现性任务 | 是（次要 gate） |
| 4 | 章节正文编写 | textbook-chapter（逐章） | NN-章.md × N + 术语表增量 | 否 |
| 5 | 审核定稿 | 本 skill | 自检报告 + 00-前言.md + 99-表现性任务.md + 交付摘要 | 否 |

gate 之外的阶段只打印一行进度（格式见契约文档第 5 节），不打断作者。

## 启动与重入（每次触发的第一件事）

1. **确定教材项目目录**：用户指定则用之；未指定则询问一次（默认 `./<教材名>/`）。
2. **找 `.progress.json`**：

   - 不存在 → 全新项目：确认教材名 → 建目录 → 初始化 `.progress.json`（schema 见契约文档第 4 节，`current_stage=1`，gates 全 false，`answer_layout="separate"`，`subject_profile` 待阶段 1 判定后补写）→ 从阶段 1 开始；
   - 存在 → 按契约文档第 4 节**重入规则表**定位续点，打印续写行：阶段 4 用 `▶ 续写：<教材名>，从第 N 章继续`，其余阶段用 `▶ 续写：<教材名>，从阶段 N 继续`；同时读出 `subject_profile` 与 `answer_layout` 供后续透传，**字段缺失**时按存量语义兜底并在续写行后各补一句说明，不阻塞：`subject_profile` 缺失（v0.3.x 及更早）按 `stem` 处理、补「按 stem 学科档案续写」；`answer_layout` 缺失（v0.4.x 及更早）按 `inline` 处理、补「按内嵌答案排版续写」——已写的章不迁移答案，一本书两种排版比统一用旧排版更糟。特别地：`current_stage=2/3` 且对应 gate 未确认时，从 `00-教材设计.md` 读出已有产出（阶段 2 为五件套、阶段 3 为章节树/例题习题计划/梯度报告/表现性任务四项）**重新呈现并等确认**，不推倒重做；作者提出修改时委托 textbook-outline 执行修改与再确认循环。
3. **状态纪律**：`.progress.json` 只由本 skill 读写（子 skill 一律不碰）；每完成一个阶段、每完成一章**立即更新写盘**，绝不批量延迟。

## 阶段 1–3：委托 textbook-outline

打印 `▶ 阶段 1/5：教学定位确认`（阶段 2、3 进入时同格式）。

使用 Skill 工具调用 `textbook-outline`（传入 `{教材项目目录, 教材名}`）；若 Skill 工具不可用或未注册，直接读取 [../textbook-outline/SKILL.md](../textbook-outline/SKILL.md) 并严格遵循其指令执行。

- 其内部两个 gate 就是本流程的 gate——**gate 由该子 skill 面向作者执行，本 skill 绝不越过未确认的 gate 推进状态**；
- 阶段 1 完成后（子 skill 回报 `学科档案`）：置 `subject_profile=<档案 id>`、`current_stage=2`，写盘。此后**不再改动该字段**——换档案等于换验证纪律与章内段式，已写的章会与后写的章不是一本书；
- 阶段 2 确认后：置 `gates.stage2_ubd_confirmed=true`、`current_stage=3`，写盘；
- 阶段 3 确认后：置 `gates.stage3_outline_confirmed=true`、`current_stage=4`、`chapters.total=章节树章数`、`chapters.next=1`，写盘。

## 阶段 4：逐章循环

打印 `▶ 阶段 4/5：章节正文编写`。

对 章号 N 从 `chapters.next` 到 `chapters.total` 逐章执行（严格顺序，前章完成才写后章）：

1. **提取该章大纲切片**：从 `00-教材设计.md` 的「## 三、章节树与梯度规划（已确认）」取该章的章节树条目 + 例题习题计划；再按该条目的 `承载的学习目标编号[]` 到「## 二」逐条取出**学习目标原文**（含 Bloom 标注）一并放进切片——**只取该章那几条**，不把全书目标清单塞进去；
2. **读跨章载体**：术语表.md 当前版 + 前一章文件的「## 本章小结」全节（N=1 时前章小结为空）；
3. **组装输入契约调用 textbook-chapter**：`{章号, 章标题, 该章大纲切片, UbD五件套, 术语表, 前章小结, 学科档案, 答案排版}`（五件套从「## 二、UbD 五件套（已确认）」提取 `{大概念[], 持久理解[], 核心问题[]}`；学科档案取 `.progress.json` 的 `subject_profile`、答案排版取 `answer_layout`，均原样透传，不重新判定）。调用方式同上：Skill 工具优先，降级读 [../textbook-chapter/SKILL.md](../textbook-chapter/SKILL.md)；
4. **收输出契约** `{章文件路径, 新增术语[], 新增符号[], Bloom标注回写[], 本章独立习题答案[]}`：新增术语追加进术语表.md 的「## 术语」节、**新增符号追加进「## 符号约定」节**（术语表.md 不存在则先建，两节标题都写上，即使某节暂时为空——节标题是逐章追加的落点，缺标题下一章就没处可追）；追加符号前先比对已登记条目：**同一含义已用别的符号登记过**，说明本章与前章不一致，退回该章统一符号后再追加（这正是符号表要存在的理由）；Bloom 标注回写记入 `00-教材设计.md` 该章例题习题计划条目旁的"实际"标注（与"计划"并排，供阶段 5 对比）；**本章独立习题答案追加进 `98-参考答案.md`**（`answer_layout=separate` 时；文件不存在则先建，含首行说明"建议先独立完成习题再对照"，每章一个 `## 第 N 章 <章标题>` 小节，结构见契约文档 3.1 节）——追加前先数一遍：条目数与章内独立习题数不等、或题号对不上，**当场退回该章重做**，不许带着缺口往下写；
5. **更新状态**：`chapters.done` 加入 N、`chapters.next=N+1`，写盘 `.progress.json`。

全部章完成后置 `current_stage=5`，写盘。任何一章中途中断，重入时从 `chapters.next` 无缝继续，已完成章不重写。

## 阶段 5：审核定稿（自检清单，非 gate，必须全跑）

打印 `▶ 阶段 5/5：审核定稿`。逐项检查并输出报告，每项给出：通过/不通过 + 具体位置 + 修改建议。

1. **章节对齐走查**：逐章读「## 本章小结」的"与持久理解的呼应"，对照 `00-教材设计.md` 的承载计划——每章至少承载一条持久理解，每条持久理解至少被一章实际承载；
2. **Bloom 梯度复核（看实际不看计划）**：用各章"实际"标注重算层级×章节矩阵，按 [../textbook-outline/references/bloom-levels.md](../textbook-outline/references/bloom-levels.md) 第 5 节三条规则复核，输出第 6 节格式的报告；
3. **术语与符号一致性**：对照术语表.md 抽查各章（每章至少查引言与小结两处）用词是否一致，发现不一致列出位置；**符号另查两件**——各章正文与题目里出现的符号是否都在「## 符号约定」节登记（漏登记的补登）、同一含义是否全书只用一个符号（一义两符的列出两处位置，由作者定统一用哪个）。学科不使用形式符号时，确认该节写着「本书不使用形式符号」而非空表；
4. **例题验证残留与答案落位对账**：搜索范围为全部章文件 **加 `98-参考答案.md`**，三件事一起查——
   - **验证残留**：搜 `⚠️ 需作者确认` 汇总成清单呈现。带此标注是合规的（红线允许"明确标注不能验证"），但必须让作者全部看见；
   - **验证行清点**（`answer_layout=separate` 时分两处数，一把总数对不上账）：章内「示范例题 + 引导练习」题数 = 章内验证行数；各章独立习题题数 = `98-参考答案.md` 对应章节下的验证行数，且题号逐一对得上。缺验证行、缺答案条目、题号错位的逐条列出——漏行不是"合规的未验证"，而是违反契约第 2 节「验证状态无第三种」，须报为不通过项；
   - **落位泄底检查**：在各章 N.4 段内搜 `参考答案`、`解题路径`、`参考要点`，命中即是答案没搬干净，报为不通过项（`answer_layout=inline` 的存量项目跳过本条）；
5. **循序渐进走查**：逐章检查引言是否衔接前章小结、是否使用了后文才定义的概念（前置知识跳跃）；
6. **学习目标覆盖矩阵（三列对账）**：对照 `00-教材设计.md`「## 二」的学习目标清单，输出「学习目标 × 章」矩阵，每条目标查三件——
   - **设计侧**：有章节树条目的 `承载的学习目标编号[]` 认领它吗？（无人认领 = 阶段 3 的对齐检查漏了）
   - **读者侧**：认领它的章，章首「本章学习目标」里真写出对应那条了吗？章末自检里有对应的复选项吗？（认领了没写 = 学生仍然看不到）
   - **检验侧**：至少有一道题检验它吗（题目主题与该目标的对象一致即算覆盖）？
   
   三列任一为空的逐条列出，并给可操作建议（"建议在第 N 章补 X 层级题目"／"第 N 章章首漏了这一条，补写"）。**动机**：ubd-framework.md 2.5 节要求每条学习目标"能想象出一道题来检验它"，设计时查了、交付时不查等于只查一半；上面第 2 项统计的是层级分布，看不出哪条目标没人管。加设计侧与读者侧两列的理由是同一条目标可以在三个环节各自掉队——设计文档里有、章节树没认领；认领了、章首没写；章首写了、没有题检验——只查最后一环，前两种漏法会一路漏到读者手上；
7. **表现性任务复核与落盘**：核对「## 四、表现性任务」——每条迁移目标至少被一个任务覆盖、每个任务附评价标准表（维度从持久理解或迁移目标推出，每格为可观察的表现描述）；核对通过后从「## 四」派生生成 `99-表现性任务.md`（学生可读版：任务说明 + 评价标准表，去掉迁移目标编号一类设计元信息；写法见 [../textbook-outline/references/performance-task-rubric.md](../textbook-outline/references/performance-task-rubric.md)）。**动机**：表现性任务是迁移目标在全书唯一的检验落点，留在设计文档里等于没交付。
8. **成书前页生成与走查**：生成 `00-前言.md`（固定三节「本书写给谁 / 怎么用这本书 / 目录」，各节来源与改写要求见契约文档 3.2 节），然后逐条核对目录里的**每个链接**指向的文件真实存在、章号与章标题与磁盘文件逐字一致——**指不到的链接当场修掉**，不作为"待作者处理"的不通过项放过（这一项是主 skill 自己能修的，报给作者没有意义）。**动机**：前面七项保的是内容质量，这一项保的是读者进得来——一本没有前言和目录的教材，读者要靠猜才知道从哪读起、答案在哪查。

报告完毕后：不通过项由**作者决定修不修**；作者要求修 → 定位到章，重新组装该章输入契约调用 textbook-chapter 修订（修订后相关项复查）。全部处理完写盘 `stage5_passed`：无遗留不通过项（全过或均已修复）置 `true`；作者决定不修的不通过项仍存在置 `false`，并在交付摘要中列明遗留项。

## 交付

输出交付摘要：章数 / 三类题总数 / 已验证题数 / `⚠️ 需作者确认` 条数 / 梯度复核结论 / 学习目标覆盖率（已覆盖 ÷ 总数，零覆盖的逐条列出）/ 表现性任务数与迁移目标覆盖情况 / 未修复项清单（如有）。

交付物为教材项目完整目录（布局见契约文档第 3 节）：`00-前言.md`、`00-教材设计.md`、`NN-<章标题>.md × N`、`98-参考答案.md`、`99-表现性任务.md`、`术语表.md`、`.progress.json`。摘要里向作者点明两句：**读者从 `00-前言.md` 进入**（前言 + 怎么用 + 带链接的目录），`00-教材设计.md` 是作者向设计文档、不必给读者；独立习题的答案与验证在 `98-参考答案.md`，章内只留题干，读者可先做后对（`answer_layout=inline` 的存量项目不提后一句）。

**边界说明**（须向作者说明）：定稿指文字与结构层面完成；若正文含人工截图标注块，需作者按标注自行补图后才算可发布。

