Back to skills
SKILL.md
Quiz Generator
ASecurity高校教师出题与测评辅助:按知识点清单规划题量、命制八种题型、生成 A/B 卷、输出双向细目表与复习闪卡,并把题目打包交给 exam-pipeline 做审卷与考后分析。当教师说「出一套题」「编几道练习题」「随堂小测」「帮我出 A/B 卷」「这个知识点出三道题」「期末试卷命题」「给我一份双向细目表」「把题做成能复习的题库」时使用。产出的是**待审题目初稿**,全部题目必须经教师逐题审核后才能进考场。Triggers: 出一套题、编几道练习题、随堂小测、出 A/B 卷、期末命题、单元测验、补考卷、练习题、题库、双向细目表、细目表、闪卡、复习卡、考点覆盖、题量分配、选择题干扰项、判断题、计算题、案例分析题、论述题。
- 11 stars
- 0 votes
- 1 copy
- 1 view
- Added October 20, 2026
Security analysis
100/100npx -y skills add EtherealMingo/university-teacher-skills --skill quiz-generator --agent claude-codeAre you the author of Quiz Generator?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/etherealmingo-quiz-generator)---
name: quiz-generator
description: "高校教师出题与测评辅助:按知识点清单规划题量、命制八种题型、生成 A/B 卷、输出双向细目表与复习闪卡,并把题目打包交给 exam-pipeline 做审卷与考后分析。当教师说「出一套题」「编几道练习题」「随堂小测」「帮我出 A/B 卷」「这个知识点出三道题」「期末试卷命题」「给我一份双向细目表」「把题做成能复习的题库」时使用。产出的是**待审题目初稿**,全部题目必须经教师逐题审核后才能进考场。Triggers: 出一套题、编几道练习题、随堂小测、出 A/B 卷、期末命题、单元测验、补考卷、练习题、题库、双向细目表、细目表、闪卡、复习卡、考点覆盖、题量分配、选择题干扰项、判断题、计算题、案例分析题、论述题。"
---
# 出题与测评(quiz-generator)
> **Goal**:把教师的「教学大纲 / 章节知识点 / 一份教材材料」变成一套**结构可查、覆盖可证、难度可控**的试卷与题库初稿——
> 每道题都标好了「考哪个知识点、什么题型、什么认知层次、预计多难、几分」,
> 并输出双向细目表与 A/B 卷等价性校验结果。
> **出的题一律是待审稿,不是终稿**:进考场前必须由教师逐题过一遍。
## 何时使用
- 「出一套题」「期末试卷命题」「帮我出一份期中卷」
- 「编几道练习题」「这个知识点给我出三道题」(题库/作业/练习用)
- 「随堂小测」「课前测」「课后测」(3–5 题,5 分钟量级)
- 「帮我出 A/B 卷」「要两套难度一样的」「补考卷」
- 「给我一份双向细目表」「考点覆盖情况怎么样」「题量怎么分配」
- 「这套题的难度配比对吗」「选择题干扰项再想想」
- 「把这些题做成能反复复习的题库 / 闪卡」
**不适用**(走别的技能):
| 教师想干的事 | 该走 |
|---|---|
| 已经有试卷,要审卷、出评分细则、考后成绩分析、归档 | `exam-pipeline`(本技能**下游**,见「交接协议」) |
| 只是课堂上现场提问、要一条递进提问链、把互动记录算平时分 | `classroom-live` |
| 要教案、课件、教学设计 | `lesson-plan` / `lecture-slides` |
| 要的是课程知识结构图、术语表、FAQ | `learning-graph-generator` / `glossary-generator` / `faq-generator`(均为本包 `skills/` 下的底座技能) |
## 底座(禁止重写)
引用前已 `ls` 验证存在。
| 路径 | 用途 | 本技能怎么用 |
|---|---|---|
| `skills/ibook-skills/question-writing/SKILL.md` | **出题主干方法**:布鲁姆分布分档、概念优先级(Priority 1/2/3)、答案位置均衡、每题必带解析、题目 JSON 结构、质量评分与校验 10 条 | 直接照搬其**方法论与数据结构**,产出物换成中文试卷与 xlsx |
| `skills/ibook-skills/question-writing/references/distractor-writing-guide.md` | **干扰项写作指南**:四个质量维度(可信/有教学价值/能区分/公平)、四类误解型干扰项、四种构造法(相关概念/部分定义/程度差异/时序错位)、0–1 干扰项质量分、按布鲁姆层级举例、修订策略 | 阶段三写选择题时逐条对照,红线级引用 |
| `skills/ibook-skills/learning-graph-generator/` | 知识点依赖图生成,含 CIS(概念影响力)计算与 `validate-learning-graph.py` / `analyze-graph.py` | 教师给的是整门课大纲时,先用它把知识点抽成带依赖的清单,再据此分配题量 |
| `skills/ibook-skills/course-description-analyzer/` | 课程描述完整性校验 + **布鲁姆学习成果**抽取 | 阶段一抽取认知层次目标的依据 |
| `skills/ibook-skills/glossary-generator/SKILL.md` | ISO 11179 式术语定义(精确、简洁、非循环) | 名词解释、术语配对题、填空题答案的唯一性判据 |
| `skills/ibook-skills/faq-generator/` | 教材问答对 + 分类分级导出 JSON | 复习型题库的题干改写来源之一 |
| `skills/learning-education/study-skill/references/fsrs-spaced-repetition.md` | **FSRS 间隔重复协议**:D/S/R 三值、1–4 评分、`add`/`schedule`/`review`/`status` 命令、卡片存储路径、每次复习上限 3 条的混合复习模型 | 阶段七「题目转闪卡」直接按此协议执行 |
| `skills/learning-education/study-skill/scripts/fsrs/` | FSRS 调度器 **Go 源码**(`add/schedule/review/status`,输出 JSON)。⚠️ 仓库不含编译产物,需 Go ≥1.22 自行 `go build`;无 Go 时走阶段七的降级方案 | 闪卡排程 |
| `skills/learning-education/thinking-toolkit/methods/01-socratic-inquiry.md` | 苏格拉底式追问:区分「事实 / 解释 / 价值判断 / 目标」,只问能改变结论的问题,最多 6 问 | 论述题、案例分析题的**小问链**设计(由浅入深逐问逼出论证) |
| `skills/education-skills/edu-learning-analytics/references/competency-based-assessment.md` | **双向细目表**范式(认知层次 × 内容维度 × 建议比例)、素养导向题型分类(情境选择题 / 非连续文本题 / 探究实作题 / 议题讨论题 / 跨领域整合题) | 阶段二细目表与情境题命制的结构模板 |
| `skills/education-skills/edu-learning-analytics/references/peer-assessment.md` | 评分规准(Rubric)设计、评量者训练与标竿范例 | 阶段六评分要点的结构(但完整 rubric 归 `exam-pipeline`) |
| `skills/k12-teacher-skills/k12-check-for-understanding/SKILL.md` | **理解性检查(CFU)**:1–3 个精准形成性题目,干扰项**必须来自有据可查的学生常见错误**;「学生回答 → 下一步教学动作」的教师指引;学生版/教师版分离 | 随堂小测与「教学前摸底题」的命制纪律;干扰项来源的取证要求 |
| `skills/k12-teacher-skills/k12-check-for-understanding/references/verification.md` | 交付前验证协议 | 阶段四质量门的分层校验思路 |
| `skills/office-layer/` | **文件产出唯一通道**:`scripts/docx_kit.py`(`md` / `spec` / `comment` / `inspect`)、`scripts/xlsx_kit.py`(`build` / `analyze` / `inspect`)、`bootstrap.sh` | 试卷 docx、细目表 xlsx、审核批注 |
**许可证注意**:`question-writing` 等 ibook 系列底座的上游仓库**无 LICENSE 文件**(见 `THIRD_PARTY_NOTICES.md`),依法默认保留全部权利。
因此本技能**只借鉴其方法论思路,不整段复制其英文原文、模板文本或代码**进任何交付物;交付物一律用中文重写。
**环境准备**(`.venv` 尚未创建时):
```bash
bash skills/office-layer/bootstrap.sh
PY="skills/office-layer/.venv/bin/python"
export MPLCONFIGDIR=/tmp/mplcache && mkdir -p /tmp/mplcache # 受限环境必需
```
## 前置信息收集(intake,一次性问完)
**一次性问完,不要边做边问。** 把下面 13 项合并成**一个**问题批次(沿用 `awesome-benzi` 的 `question-batch` 思路)抛给教师。
信息不全时**用下表安全默认值继续**,并在交付说明里逐条标出「本次用了默认值」。
| # | 要问的 | 为什么必须问 | 缺省时怎么走 |
|---|---|---|---|
| 1 | **学科**(以及是否含计算/编程/实验操作) | 决定题型可行域(文科少计算题,工科多计算与设计题) | 从材料自动判定,标注「按材料推断为 X 学科」 |
| 2 | **课程名**(+课程代码、学分、学时) | 试卷卷头与细目表表头 | 用材料中的课程名;无则 `【待补:课程名】` |
| 3 | **知识点范围**:给大纲 / 给教材目录 / 给章节号 / 给已写好的知识点清单 | 这是出题的**唯一依据**,本技能不自己发明考点 | 无大纲时:从教师给的材料逐节抽取,抽完**回读给教师确认**后才出题 |
| 4 | **题量**:总题数,或「总分 + 各题型分值」 | 决定细目表格数与每题配分 | 随堂小测 3–5 题;单元测 15–20 题;期末 25–35 题 |
| 5 | **题型要求**:哪几种题型、各占多少分 | 题型与认知层次强相关(见「题型设计参考」) | 按用途默认(见 §题型设计参考 末尾的「按用途默认配比」) |
| 6 | **难度要求**:目标平均分、易中难比例、是否要有压轴题 | 决定难度预估与分值匹配 | 易:中:难 = 3:5:2;目标平均分默认 75±5(客观题为主卷型);主观题分值占比 >40% 时改按 65±5,见「命题质量原则 §4」卷型口径 |
| 7 | **认知层次要求**:是否按布鲁姆比例、有无上限(如「低年级不要出创造层」) | 决定层次分布硬约束 | 识记 20% / 理解 30% / 应用 30% / 分析 20% |
| 8 | **学生层次**:本科低年级 / 本科高年级 / 研究生 / 专升本 / 留学生(中文授课)/ 高职 | 决定语言难度、情境复杂度、题干的默认知识假设 | 按「本科高年级」走,并在交付说明标注 |
| 9 | **是否要 A/B 卷**(几套、是否需要选项乱序、是否需要答题卡) | 决定是否走阶段五的双卷生成与等价性校验 | 默认**不出** A/B 卷(教师没要求就不加工作量);若为期末考试则**主动提醒**是否需要 |
| 10 | **用途与场合**:随堂小测 / 单元测 / 期中 / 期末 / 补考 / 作业练习 / 长期题库 | 决定正式度、题型配比、是否要密封线与答题卡 | 默认「作业练习卷」 |
| 11 | **考试时长与允许工具**:分钟数、闭卷/开卷、可否用计算器/公式表 | 决定计算题数据是否「算得完」、论述题小问个数 | 默认 120 分钟、闭卷、不允许计算器 |
| 12 | **学校/学院格式要求**:试卷头模板、密封线、得分栏、页眉页脚、A3/A4 双面 | 决定 docx 排版方式(`md` 还是 `spec`) | 用通用卷头(见产出物一节),标注「结构为通用模板,请对照贵校教务处模板调整」 |
| 13 | **产出物要哪些**:试卷 docx / 参考答案 docx / 细目表 xlsx / 题库 JSON / 闪卡包 / 是否要一并交 `exam-pipeline` | 决定交付清单 | 默认交付「试卷 docx + 参考答案 docx + 双向细目表 xlsx + 题库 JSON」 |
> **重要纪律**:第 3 项和第 13 项**不能靠猜**。知识点范围若完全拿不到,只做「从材料抽知识点 → 回读确认」这一步就停,
> 不要凭空造考点——高校正式考试编造考点是教学事故。
## 工作流
每一阶段都写明 **输入 → 动作 → 输出 → 退出条件**。前一阶段退出条件不满足,不进下一阶段。
### 阶段〇 · 环境与底座校验
- **输入**:无。
- **动作**:
1. `ls skills/office-layer/scripts/` 与 `ls skills/office-layer/.venv/bin/python`,确认产出通道可用;缺 `.venv` 先跑 `bootstrap.sh`。
2. `ls skills/ibook-skills/question-writing/references/`,确认干扰项指南在位。
3. 建工作目录 `quiz-<课程名简写>-<日期>/`,过程文件全放这里。
- **输出**:可用环境 + 工作目录。
- **退出条件**:`docx_kit.py`、`xlsx_kit.py` 存在;`skills/office-layer/.venv/bin/python` 可执行(`--help` 有输出)。
### 阶段一 · 知识点清单化
- **输入**:教师给的大纲 / 目录 / 章节材料(intake 第 3 项)。
- **动作**:
1. 优先顺序:**现成知识点清单 > 教学大纲章节条目 > 教材目录 > 教师给的材料正文**。逐级降级时必须说明依据来源。
2. 按 `learning-graph-generator` 的思路建**依赖关系**(哪个知识点是哪个的前置),只在教师给了整门课范围时才做全图;单章出题只列同层知识点即可。
3. 给每个知识点打**重要度**,供阶段二分配题量:
| 级别 | 判据 | 建议配题权重 |
|---|---|---|
| A 核心 | 出现在课程目标/章节标题/考纲「掌握」条目;是其他知识点的前置 | 3 |
| B 支撑 | 有独立小节、有例题、有术语定义 | 2 |
| C 了解 | 只在引言/扩展/史料中出现,属于背景 | 1(也可只出 0–1 题或不考) |
4. 输出 `知识点清单.xlsx`:`编号 | 知识点 | 所属章节 | 重要度 | 前置知识点 | 对应的学习成果(布鲁姆层次)`。
5. **回读给教师确认**,明确问一句「有没有漏掉的必考点,有没有我列进来但你不打算考的」。
- **输出**:`知识点清单.xlsx`(含 20–80 条不等的知识点行)。
- **退出条件**:教师确认知识点清单;清单里每一条都能指向材料中的具体位置(章节号/页码/小节名)。
### 阶段二 · 题量规划与双向细目表
- **输入**:确认后的 `知识点清单.xlsx`、intake 第 4/5/6/7 项。
- **动作**:
1. **总题量 → 各知识点配题数**,按权重分摊并做整数化:
```
某知识点配题数 = 总题量 × (该知识点权重 / 全部权重之和)
A 级知识点:四舍五入后若为 0,强制提到 1 题(核心考点不许 0 题)
C 级知识点:四舍五入后可保留 0 题(了解性内容不必占分)
```
2. **按认知层次分摊**:把每个知识点的题数再分到布鲁姆层次上,命中 intake 第 7 项的目标比例(默认 识记 20% / 理解 30% / 应用 30% / 分析 20%),允许 ±5 个百分点。
低年级课程可把「分析」降到 10%,把余量给「理解」。
3. **按题型落格**:每个「知识点 × 层次」格子选一个合适题型(选型规则见「题型设计参考」);
**同一份正式试卷里,同一知识点不要在完全相同的层次上重复出同型题**(补考/题库除外)。
4. **配分**:用「认知层次基准分 × 作答时长系数」定分(见「命题质量原则 §4」),全卷合计必须精确等于总分。
5. 生成**双向细目表**(阶段产出物 `双向细目表.xlsx`),两个维度:纵轴知识点、横轴题型×认知层次,
每格填「题号 / 题数 / 分值」,并在右侧出小计与占比。示例:
| 知识点 | 重要度 | 单选(识记) | 单选(理解) | 多选(应用) | 填空(识记) | 计算(应用) | 简答(分析) | 合计题数 | 合计分值 | 占比 |
|---|---|---|---|---|---|---|---|---|---|---|
| 牛顿第一定律 | A | Q1 / 1 / 2 | | | Q6 / 1 / 2 | | | 2 | 4 | 4% |
| 牛顿第二定律 | A | | Q2 / 1 / 3 | Q8 / 1 / 4 | | Q12 / 1 / 12 | | 3 | 19 | 19% |
| 动量守恒 | A | | | | | Q13 / 1 / 12 | Q18 / 1 / 10 | 2 | 22 | 22% |
| 角动量守恒 | C | | Q3 / 1 / 3 | | | | | 1 | 3 | 3% |
6. 校验三条硬约束,不满足就回到第 1 步重排:
- **每格都有题**:正式试卷里「某知识点在认知层次 X 上应该有题但细目表格子为空」要显式说明理由。
- **总分吻合**:各格分值之和 = 卷面总分。
- **层次比例吻合**:层次占比与目标偏差 ≤ 5pp。
- **输出**:`双向细目表.xlsx`(同一文件内另含「题型分布」「层次分布」「难度预估」「答案位置校验」四个工作表)。
- **退出条件**:三条硬约束全过;细目表打印/导出后可读,教师能一眼看出「哪个考点占了多少分」。
### 阶段三 · 逐题命制
- **输入**:`双向细目表.xlsx`(每一格就是要出的一道或几道题的规格)、知识点对应材料。
- **动作**:
1. **逐格出题,不跳格**。每道题先写内部字段(这是后面所有校验与交接的数据基础):
```json
{
"id": "Q07",
"kp": "牛顿第二定律",
"kp_level": "A",
"type": "计算",
"bloom": "应用",
"score": 12,
"est_difficulty": 0.65,
"stem": "题干全文",
"options": {"A": "…", "B": "…", "C": "…", "D": "…"},
"answer": "B",
"explanation": "为什么这个是答案,其他项错在哪",
"scoring_points": ["正确写出受力分析式(4 分)", "代入数值并解出 a=2 m/s²(5 分)", "单位与方向正确(3 分)"],
"source": "教材第 3 章 §3.2 / 教师提供的讲义 p.12",
"material_sentences": ["用于出题的材料原句(内部留档,不写进试卷)"],
"common_misconceptions": ["把合力当某一个力", "忘记方向的正负号"],
"distractor_quality": 0.85,
"review_status": "待教师审核"
}
```
2. **选择题/判断题的干扰项,逐项对照 `distractor-writing-guide.md`**:
干扰项必须能说出「它对应哪一条学生常见错误」,说不出来就重写(见「命题质量原则 §1」)。
3. **情境题按 `competency-based-assessment.md` 的五类题式选型**:情境选择题 / 非连续文本题(图表判读)/ 探究实作题 / 议题讨论题 / 跨领域整合题。
4. **主观题的小问链按苏格拉底式追问思路设计**:小问要能区分「事实、解释、价值判断、目标」,
前一问的答案必须被后一问用到,禁止「(1) 写出定义 (2) 谈谈你的看法」这种互不相干的小问。
5. 每题写完立刻回填细目表实际信息(题号、实际难度预估),**不要等全卷写完再补**。
6. 写解析:说明正确项为什么对、每个干扰项错在哪、对应哪个知识点。解析同时是**讲评素材**,别写成「正确答案是 B」。
- **输出**:`题库.json`(全部题目内部字段)+ 每题对应的 `试卷草稿.md` 片段。
- **退出条件**:细目表每一格都有对应题目;每题的 `stem / answer / explanation / scoring_points / source` 字段非空;
`source` 能指向教师提供的具体材料位置(指不到就留 `【待补:依据出处】`)。
### 阶段四 · 质量门自检
- **输入**:`题库.json`。
- **动作**:
**第 1 步 · 跑自动检查**。把下面这段脚本**原样**存成工作目录里的 `quiz_audit.py`(仅用标准库,不需要 venv;**顶格保存,不要带缩进**),然后按下面的命令行运行。它会输出题型/层次/答案位置分布与层次偏差、题干重复与雷同、**正确项比干扰项明显长**、**用了「以上都不对」凑数**、知识点未覆盖清单:
```python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""quiz_audit.py — 出题质量门自检(仅标准库)
用法: python3 quiz_audit.py 题库.json [识记:20,理解:30,应用:30,分析:20] [知识点清单.txt]
"""
import json, re, sys, collections
def norm(s):
return re.sub(r"[\s,。、;:?!,.;:?!()()【】\[\]「」\"'']+", "", str(s or ""))
def main():
if len(sys.argv) < 2:
sys.exit("用法: python3 quiz_audit.py 题库.json [识记:20,理解:30,...] [知识点清单.txt]")
qs = json.load(open(sys.argv[1], encoding="utf-8"))["questions"]
target = {}
if len(sys.argv) > 2 and sys.argv[2].strip():
for kv in sys.argv[2].split(","):
if ":" in kv:
k, v = kv.split(":", 1)
target[k.strip()] = float(v)
n = len(qs)
if not n:
sys.exit("题库为空")
print(f"题量 {n} 题|总分 {sum(float(q.get('score') or 0) for q in qs):g} 分")
for field, label in (("type", "题型"), ("bloom", "认知层次"), ("answer", "答案位置"), ("kp", "知识点")):
cnt = collections.Counter(str(q.get(field) or "(空)") for q in qs)
print(f"\n[{label}] {len(cnt)} 类")
for k, v in cnt.most_common():
pct = v * 100.0 / n
line = f" {k}: {v} 题 ({pct:.0f}%)"
if field == "bloom" and k in target:
d = pct - target[k]
line += f"|目标 {target[k]:.0f}%|偏差 {d:+.0f}pp {'OK' if abs(d) <= 5 else '<<超差'}"
print(line)
seen, seen12, flagged = {}, {}, []
for q in qs:
stem = norm(q.get("stem"))
if not stem:
flagged.append((q.get("id"), "题干为空"))
continue
if stem in seen:
flagged.append((q.get("id"), f"题干与 {seen[stem]} 完全重复"))
else:
seen[stem] = q.get("id")
p12 = stem[:12]
if p12 in seen12:
flagged.append((q.get("id"), f"题干前 12 字与 {seen12[p12]} 雷同"))
else:
seen12[p12] = q.get("id")
for q in qs:
opts, ans = q.get("options") or {}, q.get("answer")
if not isinstance(opts, dict) or ans not in opts or len(opts) < 3:
continue
lens = {k: len(str(v)) for k, v in opts.items()}
others = [v for k, v in lens.items() if k != ans]
avg = sum(others) / len(others)
if avg > 0 and lens[ans] > avg * 1.4:
flagged.append((q.get("id"),
f"正确项长度 {lens[ans]} 字,为干扰项均值 {avg:.1f} 的 {lens[ans]/avg:.1f} 倍,答案可能被长度泄露"))
if any("以上都对" in str(v) or "以上都不对" in str(v) for v in opts.values()):
flagged.append((q.get("id"), "使用了「以上都对/都不对」凑数选项"))
if len(sys.argv) > 3:
plan = [l.strip() for l in open(sys.argv[3], encoding="utf-8") if l.strip() and not l.startswith("#")]
tested = {norm(q.get("kp")) for q in qs}
miss = [p for p in plan if norm(p) not in tested]
cov = (len(plan) - len(miss)) * 100.0 / len(plan)
print(f"\n[知识点覆盖] 计划 {len(plan)} 个|已覆盖 {len(plan)-len(miss)} 个|覆盖率 {cov:.0f}%")
for m in miss:
print(f" 未覆盖: {m}")
print(f"\n[问题清单] {len(flagged)} 条")
for qid, msg in flagged:
print(f" {qid}: {msg}")
print("\n结论: " + ("通过(0 条问题)" if not flagged else "未通过,逐条修正后重跑"))
main()
```
跑法(知识点清单每行一个知识点):
```bash
printf '牛顿第一定律\n牛顿第二定律\n动量守恒\n' > 知识点清单.txt
python3 quiz_audit.py 题库.json "识记:20,理解:30,应用:30,分析:20" 知识点清单.txt
```
脚本会报出:题型/层次/答案位置分布与层次偏差、题干重复与雷同、**正确项比干扰项明显长**、
**用了「以上都不对」凑数**、知识点未覆盖清单。
**第 2 步 · 人工过「命题缺陷十查」**(脚本查不出的部分,必须逐条看,见「命题质量原则 §2」):
否定式题干、题干暗示、语法不平行、绝对化词、选项互相包含、「下列哪项**不**属于」、
答案可在题干或别题中找到、主观题分值与小问数不匹配、开卷题在闭卷卷里、跨知识点串题导致两处给分。
**第 3 步 · 读回结构核对**:`docx_kit.py inspect` / `xlsx_kit.py inspect`(交付前必做,见阶段八)。
- **输出**:`出题自检报告.md`(脚本原始输出 + 人工十查的逐条结论 + 每条问题的处理动作)。
- **退出条件**:脚本「问题清单」为 0 条,且人工十查每一条都写了「已查,无问题」或「已修正(说明)」。
**有未处理项就不交付。**
### 阶段五 · A/B 卷生成与等价性校验
**仅在 intake 第 9 项为「要 A/B 卷」时执行。**
- **输入**:通过质量门的 `题库.json` + `双向细目表.xlsx`。
- **动作**:
1. **等价性五要素**(A 卷与 B 卷必须同时满足,缺一不算等价):
| 要素 | 要求 | 怎么做到 |
|---|---|---|
| 同知识点 | 每个知识点的题数与占分百分比差 ≤ 2pp | 两卷共用同一张细目表,逐格对照 |
| 同认知层次 | 每个层次的题数完全一致(或差 ≤ 1 题且占比差 ≤ 3pp) | 层次是格子的另一个维度,配题时锁定 |
| 同难度 | 两卷全卷难度预估均值差 ≤ 0.03;单题难度差 ≤ 0.05 | 见「难度预估」公式,逐题算 |
| 同分值 | 总分相同;每题分值序列可不同但**各题型分值合计相同** | 抄同一份配分方案 |
| 不同题面 | 情境、数值、问法、选项内容都不同;**不是同一道题换选项顺序** | 见第 2 步 |
> **明确禁止**:「同一套题,把选项顺序打乱当 B 卷」「把 A 卷题号重排当 B 卷」。
> 这既不是等价性设计,也挡不住抄袭——学生只要看答案字母就知道对方卷子的对应题。
> 选项乱序只能作为**额外的防抄袭措施**叠加在真正的 B 卷之上。
2. **B 卷生成法(同格异构)**,对每个格子换轨:
- **换情境**:A 卷「电梯加速上升」→ B 卷「汽车刹车」。
- **换数值**:把 2kg/4N 换成 3kg/9N,并保证计算量相当(别一边心算一边要解方程)。
- **换问法**:A 卷「求加速度」→ B 卷「求所受合力」。
- **换可选性**:A 卷单选 → B 卷多选**不允许**(题型变了就不是同格);应保持题型不变。
- **换干扰项但不换错误概念**:两卷同一题考的学生误区应来自同一组常见错误(如都考「把合力当某一个力」)。
3. **选项乱序**(若教师要求):每道选择题独立打乱选项位置,用脚本或手工重排后**逐题核对答案字母同步更新**。
答案位置分布 A/B/C/D 各占 25%±5%(沿用 `skills/ibook-skills/question-writing/SKILL.md` 的答案均衡要求),
不得出现连续 3 题同字母、不得 A-B-A-B 循环。
4. **等价性校验**(四步,全部留痕):
- ① 两卷各跑一遍 `quiz_audit.py`,层次分布、题型分布、答案位置分布逐项对照,偏差超表即不合格。
- ② 用同一张细目表逐格填两卷题号,输出 **A/B 对照表**(xlsx 工作表「AB卷对照」):
行 = 知识点 × 层次,列 = `A卷题号 | A卷分值 | A卷难度 | B卷题号 | B卷分值 | B卷难度 | 难度差 | 合格?`。
- ③ 全卷难度均值、各题型分值合计、题量逐项比对,写出差值。
- ④ **人工逐题读一遍**:确认两卷没有「同一道题换皮」、没有「B 卷某题的答案能从 A 卷题干里读出来」。
5. 生成防泄题提示:A/B 卷文件名与卷头**都要写清卷别**,交印时说明「两卷不得同场混用不同卷别」。
- **输出**:`试卷A.docx`、`试卷B.docx`、`参考答案A/B.docx`、`AB卷对照表.xlsx`、`等价性校验报告.md`。
- **退出条件**:等价性五要素逐项给出「实测差值」,全部在容差内;对照表无空格;人工逐题复核完成。
### 阶段六 · 参考答案与评分要点
- **输入**:`题库.json` 的 `answer` / `explanation` / `scoring_points`。
- **动作**:
1. 客观题:给出答案字母/正误,附**解析**(为什么对、每个干扰项错在哪、考的是哪个知识点)。
2. 主观题:按**得分点拆分**给评分要点,每个得分点标分值,分值合计必须等于该题满分;
算例另附**典型错误与扣分口径**(如「只写公式不代入扣 3 分」)。
3. 允许一题多解的题(计算、编程、证明),**每一类解法都要给一档评分口径**,不要让阅卷人自己判断。
4. 留人工确认位:`【待教师确认:第 X 题第 (2) 问的给分口径是否按此执行】`。
5. 本阶段只做**面向阅卷的评分要点**;完整的评分细则(rubric,含等级描述、阅卷培训口径、样卷标竿)
交 `exam-pipeline` 做(见「交接协议」)。
- **输出**:`参考答案与评分要点.docx`。
- **退出条件**:评分要点每题分值合计 = 该题满分;每道主观题至少有 2 个可独立判分的得分点;人工确认位已写入。
### 阶段七 · 复习型题库与 FSRS 闪卡
**仅在 intake 第 10 项含「题库/练习/复习」或教师明确要求时执行。**
- **输入**:`题库.json`。
- **动作**:
1. **先把题目转成「原子卡」**,不是把整道选择题抄成一张卡。转换规则:
| 原题 | 拆成几张卡 | 卡正面 | 卡背面 |
|---|---|---|---|
| 一道考查 2 个知识点、含 3 个干扰项的选择题 | 1 + 干扰项数 | 「正常工作时,X 与 Y 的关系是?」 | 答案 + 一句话理由 |
| 同上,另一个考点「为什么不是 Z」 | +1 | 「有人说 Z 也对,错在哪?」 | 该干扰项对应的**具体错误概念**及其纠正 |
| 计算题 | 2 | ①「这类题的解题步骤是什么」②「本题关键代换是哪一步」 | 步骤 / 代换 |
| 判断题 | 1 | 把判断句改成选择题式提问 | 判断 + 理由 |
| 论述题 | 按小问数 | 每个小问一张 | 要点骨架(不是全文) |
**遮挡原则**:一张卡只问一件事,正面不能出现答案线索,背面必须能在 20 秒内读完。
判断题的卡正面**不要保留原句**(原句含答案),改成「X 与 Y 的关系是什么」。
2. 卡片加入 FSRS,按 `skills/learning-education/study-skill/references/fsrs-spaced-repetition.md` 的协议执行。
> ⚠️ **先做前置检查**:上游 `scripts/fsrs/` 里是 **Go 源码**(`go.mod` / `cmd/` / `internal/`),
> 其 `.gitignore` 忽略了编译产物 `/fsrs`,**仓库并不附带可执行文件**。
> 本机若未安装 Go 工具链,下面的命令会直接报 `No such file or directory`。
```bash
# 前置检查:二进制在不在?没在就尝试构建
FSRS_DIR="skills/learning-education/study-skill/scripts/fsrs"
FSRS_BIN="$FSRS_DIR/fsrs"
if [ ! -x "$FSRS_BIN" ]; then
if command -v go >/dev/null 2>&1; then
(cd "$FSRS_DIR" && go build -o fsrs ./cmd/...) # 需 Go >= 1.22(见其 go.mod)
else
echo "未安装 Go 工具链,无法构建 FSRS 调度器 → 走下面的降级方案" >&2
fi
fi
```
构建成功后按上游协议使用:
```bash
FSRS_STORE=复习包/.fsrs/cards.json
"$FSRS_BIN" add "kp-牛顿第二定律" "牛顿第二定律" 2 # <id> <主题> <初始难度 1-10>
"$FSRS_BIN" schedule # 查今天到期的卡
"$FSRS_BIN" review "kp-牛顿第二定律" 3 # 复习结果 1=忘了 2=难 3=记得 4=容易
"$FSRS_BIN" status # 全部卡片概览
```
**降级方案(无 Go 时)**:不要假装命令能用。改为按 `fsrs-spaced-repetition.md` 的
D/S/R 三值与 1–4 评分口径,**用表格手工排程**——在 `复习包/闪卡排程表.xlsx` 中为每张卡
记录 `首次学习日 / 当前间隔 / 难度 / 上次评分 / 下次复习日`,并按「评分 1→次日、2→2 天、
3→按当前间隔×2、4→按当前间隔×2.5」推进。同时在 `闪卡导入说明.md` 里注明
「本包按 FSRS 口径手工排程,如需自动调度请安装 Go 后构建上游二进制」。
这条降级路径必须写进交付说明,**不得让教师以为拿到了自动化排程**。
无论走哪条路:初始难度直接取该题 `est_difficulty` 的映射(`est_difficulty ≤0.5 → 8`、
`0.5–0.7 → 5`、`>0.7 → 3`),别把所有卡都设成同一个值——FSRS 靠它算首次间隔。
每次复习呈现**最多 3 条**,单次不超过 5 分钟(沿用 study-skill 的混合复习模型)。
3. 卡片 JSON 与题库 JSON 用 `card_id` 关联,便于「某道题答错 → 找到对应卡片 → 加强复习」。
- **输出**:`复习包/题库.json`(卡字段:`card_id / kp / front / back / difficulty / source_qid`)、
`复习包/.fsrs/cards.json`、`闪卡导入说明.md`(怎么用 FSRS 命令、怎么在考前一天集中复习)。
- **退出条件**:每张卡正面不泄露答案;卡数与知识点覆盖对得上;且 `fsrs status` 能列出全部卡片**(走降级方案时为:`复习包/闪卡排程表.xlsx` 覆盖全部卡片,且交付说明已注明「手工排程」)**。
### 阶段八 · 交付(office-layer 唯一通道)
- **输入**:阶段三~七的全部产物。
- **动作**:
```bash
PY="skills/office-layer/.venv/bin/python"
# 试卷(Markdown 草稿 → docx;卷头用 Markdown 表格写「题号/一/二/三/总分」得分栏)
$PY skills/office-layer/scripts/docx_kit.py md \
--in 试卷A.md --out 试卷A.docx \
--title "【待补:学校名】20XX—20XX学年第一学期《【待补:课程名】》期末考试试卷(A卷)"
$PY skills/office-layer/scripts/docx_kit.py inspect --in 试卷A.docx
# 参考答案与评分要点
$PY skills/office-layer/scripts/docx_kit.py md --in 参考答案A.md --out 参考答案与评分要点A.docx
# 需要页眉页脚 / 密封线说明 / 人工确认位的《命题说明与审核单》走 spec
$PY skills/office-layer/scripts/docx_kit.py spec --spec 命题说明.json --out 命题说明与审核单.docx
# 双向细目表 / 覆盖矩阵 / 难度预估 / 答案位置校验 / AB卷对照(多工作表 + 原生图表)
$PY skills/office-layer/scripts/xlsx_kit.py build --spec 细目表.json --out 双向细目表.xlsx
$PY skills/office-layer/scripts/xlsx_kit.py inspect --in 双向细目表.xlsx
```
细目表 spec 结构(`xlsx_kit.py build` 支持 `sheets[].{name,header,rows,freeze,widths,chart}`):
```json
{"sheets": [
{"name": "双向细目表",
"header": ["知识点","重要度","题型","认知层次","题号","题数","分值","占分比","难度预估"],
"rows": [["牛顿第二定律","A","计算","应用","Q12",1,12,"12%",0.60]],
"freeze": true},
{"name": "知识点覆盖矩阵",
"header": ["知识点","重要度","识记","理解","应用","分析","合计题数","合计分值"],
"rows": [["牛顿第二定律","A",0,1,2,0,3,19]]},
{"name": "难度预估",
"header": ["题号","题型","预计难度 P","满分","预计平均得分"],
"rows": [["Q12","计算",0.60,12,7.2]],
"chart": {"type": "bar", "title": "各题预计难度", "value_col": 3, "height": 9, "width": 18}},
{"name": "答案位置校验",
"header": ["选项位置","题数","占比","合格线(25%±5%)"],
"rows": [["A",6,"24%","合格"]]}]}
```
1. **写完必须 `inspect` 读回**:确认段落数、表格数、图表数、字数符合预期,别交一个空壳 docx。
2. 卷面检查(打印预览视角):题号连续无跳号;得分栏与题号对应;跨页处不把一道题劈两半;
主观题留够作答空间(简答 ≥6 行、论述/案例 ≥10 行或注明「另附答题纸」)。
3. 交付说明里写清:本次用了哪些默认值、哪些字段是 `【待补:…】`、**「本文件为出题初稿,全部题目须经教师逐题审核后方可进考场」**。
- **输出**:见「产出物」一节的文件清单 + `交付说明.md`。
- **退出条件**:每个 docx/xlsx 都 `inspect` 通过;三种占位(`【待补:…】`、`【待教师确认:…】`、`【待补:依据出处】`)在交付说明里被列出。
### 阶段九 · 交接给 exam-pipeline
- **输入**:阶段八的全部交付文件。
- **动作**:按「与 exam-pipeline 的交接协议」一节打包,写到同一个交接目录,并把字段清单核对一遍。
- **输出**:`handoff/` 目录(含 `manifest.json`)。
- **退出条件**:`manifest.json` 里每个文件路径都存在且非空;`questions` 数组条数 = 细目表题数;
下游需要的字段没有空值(除显式标注 `【待补】` 的)。
## 题型设计参考(八种题型)
每种题型给出 **适用场景 / 命题要点 / 好题标准 / 常见命题缺陷**。出题时按细目表的格子查这一节。
### 1. 单项选择题
- **适用场景**:覆盖面最广的客观题。识记、理解、应用三个层次都能用;一次考一个明确结论。适合题量大、要覆盖多考点的正式考试。
- **命题要点**:
- 题干是一个**完整的问题或未完成的陈述**,不写「下列说法正确的是」这种无指向的开头(除非考概念辨析,且选项是互斥表述)。
- 一题只考**一个**知识点、**一个**结论。要考两个考点就出两题。
- 选项 4 个(不得 3 个凑数、不得 5 个以上混排),长度基本相当,语法与题干衔接一致。
- 正确项**位置随机**,全卷 A/B/C/D 各约 25%。
- 每个干扰项对应一条可写出来的学生常见错误。
- **好题标准**:
- [ ] 读完题干就知道要回答什么,不用猜出题人意图
- [ ] 正确项是唯一可辩护的答案(另有人能"说得通"就是废题)
- [ ] 三个干扰项各自对应不同类的错误概念,删掉任一都会让题目变简单
- [ ] 不会做的学生靠常识/排除法也蒙不出来,但学懂了的学生一定选得对
- [ ] 选项无「以上都对/都不对」,无绝对化词(一定/绝不/完全)
- **常见命题缺陷**:
- ❌ 「以上都不对」凑第四个选项 → 题目退化成三选一,且掩盖干扰项设计失败
- ❌ 正确项明显最长/最详细/唯一带修饰语 → 答案被长度泄露
- ❌ 选项互相包含(「A 与 B」「A 或 B」)→ 逻辑上多解
- ❌ 题干本身已含答案线索(「在牛顿**第二**定律 F=ma 中,加速度与合力的关系是…」)
- ❌ 靠刁钻细节或单位符号区分(考的是记忆而非理解)
- ❌ 否定式题干「下列哪项**不属于**」→ 见「命题质量原则 §2」
### 2. 多项选择题
- **适用场景**:辨析"几个说法各自对错"的场合;理解与分析层次;考查概念的边界(哪些属于、哪些不属于、哪些条件必须满足)。
- **命题要点**:
- 正确项数量**事先规定**(常见 2 项或 2–3 项),并在卷头**写明评分规则**(全对得满分 / 漏选得部分分 / 多选不得分)。
- 每个选项都应当**独立可判**(对就是对、错就是错),不得靠"程度"或"见仁见智"定对错。
- 干扰项与正确项必须同质同层:要么都是条件、要么都是例子、要么都是定义要素,不许混。
- 题量不宜多(一份期末卷 2–4 题),分值不超过总分 20%。
- **好题标准**:
- [ ] 评分规则印在卷头,学生知道怎么得分
- [ ] 每个选项都能独立判真假,不需要考虑其他选项
- [ ] 正确答案数符合预设(如 2 项),不是"恰好一个选项全对"的单选题伪装
- [ ] 漏选一个正确项、多选一个错误项,都能反映不同理解缺陷
- **常见命题缺陷**:
- ❌ 正确项数是 1 → 与单选题重复,白白增加阅卷成本
- ❌ 选项之间互为条件("若 A 对则 B 对")→ 组合起来无唯一答案
- ❌ 部分选项边界模糊("通常""有时"),学生无法判断
- ❌ 不写评分规则 → 全对/漏选/多选三种情况教师自己都要现场想
- ❌ 题干用「以下哪些是…」却只有一个是教材原文表述,其余是同义改写 → 考的是措辞不是知识
### 3. 填空题
- **适用场景**:术语、公式、关键数值、步骤名的精确记忆(识记层);覆盖密度高、阅卷快。
- **命题要点**:
- 一空只填**一个**确定答案,答案是**唯一且无歧义**的(同义表述要预先列出可接受写法)。
- 空格处挖的是**术语/结论/公式的关键部分**,不要挖连接词、虚词、标点。
- 空格数量与分值匹配(通常每空 1–2 分),一题不要超过 5 空。
- 需要单位、正负号、有效数字的,题干里明确要求("结果保留两位有效数字并注明单位")。
- **好题标准**:
- [ ] 空格的答案唯一;若有多种正确写法,参考答案里列全
- [ ] 不挖掉答案就会让题目变成照抄教材原句(**不得直接照搬教材原题/原句**)
- [ ] 上下文足够推断出该填什么类型的答案(术语?数值?公式?)
- [ ] 空格位置不影响句子的语法可读性
- **常见命题缺陷**:
- ❌ 一空多解或答案可推断出多个合理值 → 阅卷无法统一口径
- ❌ 挖掉的字数暗示答案长度(短线长短不一)
- ❌ 直接抄教材原句挖空 → 违反红线(见「红线」第 1 条)
- ❌ 前后两句互相给出答案(前面填了 X,后面那空就是 X 的同义)
- ❌ 数值题不要求单位/精度,学生答案五花八门
### 4. 判断题
- **适用场景**:快速检验概念边界与常见误解(理解层),适合随堂小测与形成性检查。
- **命题要点**:
- 陈述句必须**非真即假、可证伪**,不许出现"基本正确""大体上成立"这种中间态。
- **真、假两类的数量大致均衡**(约各半),且真假在卷面上无规律排列。
- 错误陈述要**错在关键概念上**(正是学生容易搞混的那一点),不要错在无关紧要的修饰词上。
- 要求写理由时,分值要拆开(判断 1 分 + 理由 2 分),并在卷头写明。
- **好题标准**:
- [ ] 判定为假时,能一句话说清错在哪个概念(这句就是解析)
- [ ] 真假分布均衡,看不出规律
- [ ] 陈述不使用"总是""绝不""一切"这类词来制造错误(那是送分)
- [ ] 加"说明理由"时,理由的判分口径可操作
- **常见命题缺陷**:
- ❌ 用绝对化词造错("所有物体都…")→ 学生一看就选错,零区分度
- ❌ 全部为真(或全部为假)→ 学生全打勾就得满分
- ❌ 陈述含歧义表述 → 硬判"对"或"错"都站不住
- ❌ 把两个独立命题用"并且"拼起来,一半对一半错 → 判分无意义
- ❌ 只判不说明理由,考不出理解深度
### 5. 简答题
- **适用场景**:理解与分析层;要求用自己的话说明概念、关系、原因、区别;比填空题更能看出学生是否真懂。
- **命题要点**:
- 一问一答,**题面指明要答几点**("从三个方面说明…""写出两条区别"),避免学生漫天写。
- 标准答案给**要点清单**,每个要点独立给分,不要求文字与教材一致。
- 限定作答篇幅("不超过 200 字"),防止写满页碰分。
- 分值 4–8 分为宜;超过 10 分应拆成多个小问。
- **好题标准**:
- [ ] 答案要点能列成 3–5 条,条条可独立判分
- [ ] 题面限定了答题方向与数量,学生知道答到什么程度
- [ ] 不需要长篇论述就能答全(长篇论述是论述题的事)
- [ ] 得分点与分值一一对应,无"酌情给分"这类模糊空间
- **常见命题缺陷**:
- ❌ 「谈谈你对 X 的理解」→ 没有边界,无法统一评分
- ❌ 答案要点几十条,阅卷时只能"看着给" → 违反 `exam-pipeline` 的可操作评分口径
- ❌ 题目本身就能从题干推出答案(自问自答式题干)
- ❌ 简答题里塞了需要计算或设计的内容 → 题型错配
- ❌ 只给"参考答案"不给得分点拆分 → 阅卷人各自为政
### 6. 计算题
- **适用场景**:应用与分析层;理工、经管、统计类课程的核心题型。
- **命题要点**:
- 数据要**算得完**:按 intake 第 11 项时长,中等水平学生 3–5 分钟一题;三步以上的代入要给中间数。
- 必须规定精度与单位(有效数字、单位、方向),并在参考答中给出**扣分口径**。
- 题干给出**必要的已知条件**,且条件不多不少(多给条件会误导,少给条件做不出)。
- **分层设问**:(1) 列式/建模(2) 求解(3) 讨论结果合理性,让部分会做的学生也能拿分。
- 数值要合理:别出现加速度 10⁹ m/s² 这种脱离物理常识的结果;除不尽时预设"保留两位小数"。
- **好题标准**:
- [ ] 正确答案可复算(教师自己按参考答案算一遍结果一致)
- [ ] 每一步都有独立得分点,写对过程但不写答案能得部分分
- [ ] 允许一题多解时,每种解法都有对应评分口径
- [ ] 不需要计算器也能完成(若闭卷且不允许计算器)
- [ ] 结果有物理/经济意义(不是纯数字游戏)
- **常见命题缺陷**:
- ❌ 数据除不尽又没规定精度 → 学生答案千奇百怪,阅卷无法统一
- ❌ 漏给单位或坐标系约定 → 符号正负无法判定
- ❌ 只给最终答案分,不看过程 → 鼓励背答案
- ❌ 计算量过大(纯算术苦工),把懂物理的学生挡在时间之外
- ❌ 数据凑得太巧妙(答案正好是整数)→ 学生反推出题人的数字游戏,实际没懂
- ❌ 题干条件与问题不匹配(给了用不上的条件,或有条件没说)
### 7. 论述题
- **适用场景**:分析、评价、创造层;考查论证能力、多角度思考、学科语言表达。适合人文社科、教育学、管理学等课程的高分值题。
- **命题要点**:
- 题面要给出**作答角度或要求**("结合 X 理论,从 A、B 两个层面分析…"),并说明能否结合课程外材料。
- 用**小问链**降低评分难度:3 个递进小问(是什么 → 为什么 / 怎么分析 → 你怎么评价),
小问按苏格拉底式追问设计——后一问必须用到前一问的结论,且能区分事实/解释/价值判断。
- 评分按**能力维度分档**(如"论证结构 10 分 / 理论运用 8 分 / 语言规范 2 分"),每档写出等级描述。
- 分值 ≥15 分,且**必须留足作答空间**或注明用答题纸。
- **好题标准**:
- [ ] 题面限定了论述范围与角度,但**不预设结论**(不许"论述 X 的先进性"这种诱导式提问)
- [ ] 小问层层递进,前一问是后一问的前提
- [ ] 分档评分标准(优秀/良好/合格/不合格)四档描述可操作,两位教师评同一份卷能得相近分数
- [ ] 不查资料(闭卷)也能完整作答,不需要记忆冷僻文献
- [ ] 不要求引用具体文献(教师没给的都不许学生"必须引用",也不许 AI 替题面编文献)
- **常见命题缺陷**:
- ❌ 「谈谈你的看法」→ 无评分锚点
- ❌ 题面已经暗示立场("为什么说 X 是正确的")→ 封闭式假论述
- ❌ 一道 20 分大题不给任何结构提示 → 区分的是写作速度而非理解
- ❌ 小问之间互不相干((1) 定义 (2) 举例 (3) 你的感想)→ 不是论证链,是三道小题拼盘
- ❌ 要求"结合课程文献"但教师从未提供文献清单 → 学生无从下手
- ❌ 只写"言之成理即可" → 与 `exam-pipeline` 的评分细则无法对接
### 8. 案例分析题
- **适用场景**:应用、分析、评价层;把真实/拟真情境交给学生诊断与决策。适合医学、法学、教育学、管理学、社会工作、工程故障诊断等。
- **命题要点**:
- 案例要有**完整情境**:背景、已有信息、约束条件、待决问题;必要数据以表格/图表给出(非连续文本题式)。
- 案例**可以是真实改编,但必须脱敏**:不得含真实姓名、单位、病历号、案件号;改编处不虚构具体数据与结论。
- 设问按**临床/实务决策链**递进:识别问题 → 分析成因 → 提出方案 → 论证方案与风险。
- 标注案例来源:`【案例来源:教师提供 / 公开报道改编(写明来源)/ 为教学目的拟制】`。
**不得虚构来源**、不得编造真实机构与真实数据。
- 分值 15–25 分;评分按"问题识别 / 理论运用 / 方案可行性 / 风险与伦理"分维度给分。
- **好题标准**:
- [ ] 案例本身信息充足,学生不需要额外查资料就能作答
- [ ] 案例不含真实可识别身份信息
- [ ] 多个设问共享同一案例,形成完整决策链
- [ ] 允许存在多个合理方案,评分口径写"论证质量"而非"标准答案"
- [ ] 案例来源如实标注,拟制案例也明确写"为教学目的拟制"
- **常见命题缺陷**:
- ❌ 案例是"套了外衣的简答题"(换个人名问同一个定义)
- ❌ 案例信息不足,学生只能凭常识猜 → 考不出课程内容
- ❌ 案例来源不明或编造来源 → 违反「不虚构引用来源」红线
- ❌ 只给一个设问「请分析该案例」→ 无作答结构
- ❌ 案例涉及真实机构/个人的负面评价 → 教学伦理问题
### 按用途默认配比(intake 第 5 项缺省时用)
| 用途 | 题量 | 题型配比建议 | 层次配比 |
|---|---|---|---|
| 随堂小测 / 课前测 | 3–5 题 | 单选 3 + 判断 1 + 简答 1 | 识记 30 / 理解 50 / 应用 20(覆盖当前一次课的知识点,**不追求全课覆盖**) |
| 单元测 | 15–20 题 | 单选 40% + 多选 10% + 填空 15% + 判断 10% + 简答 15% + 计算/案例 10% | 识记 25 / 理解 30 / 应用 30 / 分析 15 |
| 期中 | 20–25 题 | 单选 30% + 多选 10% + 填空 15% + 简答 20% + 计算/案例 25% | 识记 20 / 理解 30 / 应用 30 / 分析 20 |
| 期末 | 25–35 题 | 单选 25% + 多选 10% + 填空 10% + 判断 5% + 简答 20% + 计算/案例/论述 30% | 识记 20 / 理解 25 / 应用 30 / 分析 20 / 评价 5 |
| 补考 | 与正考同 | 同正考题型配比,**同知识点同层次**,全部换题面 | 与正考同分布 |
| 练习题库 | 不限 | 以单选+填空为主,便于自测 | 可放宽,练习卷不必严格配比 |
## 命题质量原则
### 1. 干扰项设计
直接按 `skills/ibook-skills/question-writing/references/distractor-writing-guide.md` 执行,落到本技能的纪律:
**干扰项必须有来源。** 每写一个干扰项,回答一句「它对应哪条学生常见错误」。
来源优先级(沿用 `k12-check-for-understanding` 对"有据可查的常见错误"的要求):
1. 教师提供的**往年错题记录 / 作业错例 / 课堂提问中的典型错答**(最强证据,优先用)
2. 教师提供的**教学经验说明**("学生总把 X 和 Y 搞混")
3. 学科内**公认的典型误解**(如物理的"力是维持运动的原因"、统计的"p 值等于原假设为真的概率"、编程的"值传递与引用传递混淆")
4. 由**知识点的邻近概念**构造(把相邻概念的属性安到本概念上)
四条都拿不到时,**留空并标注** `【待教师补充:本知识点学生的典型错误】`,不要凑选项。
**四类构造法**(来自指南,直接用):
| 构造法 | 说明 | 例(滑轮/受力) |
|---|---|---|
| 部分真理 | 换个语境就成立,但不回答本题 | 「合力为零则加速度为零」(对,但答非所问) |
| 反向 | 把关系方向颠倒 | 「绳子张力等于物重」↔「物重等于张力」(在加速系统里错) |
| 近似术语 | 用相邻概念的名词 | 「动量」↔「动能」、「相关」↔「因果」 |
| 典型错误 | 学生算错的中间结果 | 忘记方向正负号得出的负值 |
**禁用项**(红线级):
- ❌ 「以上都对 / 以上都不对」(除非是全卷唯一一题且明确要考"全称判断",一般不批)
- ❌ 玩笑项、无意义项、明显不可能项("紫色的大象")
- ❌ 与正确项**同义**的干扰项(会造成两个正确项)
- ❌ 语法与题干不衔接、长度明显偏离
- ❌ 用绝对化词(一定/绝不/完全)来制造的"送分型错误项"
**干扰项质量分**(0–1,沿用指南口径):可信 0.8+、有教学价值、公平。
每题三个干扰项取平均,**全卷平均 ≥0.80**;低于 0.6 的干扰项必须重写,并在自检报告里列出改写前后对照。
### 2. 题面与选项的"泄露"防治(人工十查)
| # | 查什么 | 不合格的样子 | 怎么改 |
|---|---|---|---|
| 1 | 否定式题干 | 「下列**不属于**…」「以下**错误**的是」 | 改成正面提问,或把否定词加粗并在卷头提示 |
| 2 | 题干暗示 | 题干里出现正确项的关键词;长篇铺垫最后才问 | 把铺垫压到最短,把关键词从中性化 |
| 3 | 答案长度泄露 | 正确项最长/最详细/唯一带从句 | 四项长度差控制在 ±20% 内(脚本会报 >1.4 倍) |
| 4 | 语法不平行 | 选项 A 是名词短语、B 是完整句 | 统一句式(都以"的…"或都从动词起) |
| 5 | 选项互相包含 | 「A」「A 与 B」并列 | 让选项互斥;要考组合就改成多选 |
| 6 | 跨题泄露 | 第 3 题题干里有第 7 题的答案 | 全卷串读一遍,按考点扫描重复表述 |
| 7 | 卷内自答 | 题干里的数据直接给出答案 | 重新设计数据或增加一步推理 |
| 8 | 主观题分值与小问数不匹配 | 20 分只问一句 | 拆小问,或将分值降到与学生工作量相称 |
| 9 | 全卷无压轴 / 全卷无易题 | 全是中等题 → 区分度集中在同一水平段 | 回阶段二重排难度 |
| 10 | 与教材原题雷同 | 题干、数据、选项与教材例题逐一对应 | 换情境/换数值/换问法;**禁止照搬(红线)** |
> 第 1、3、6 条是高校考试最常被督导挑出来的问题,务必逐条留痕。
### 3. 认知层次分布(布鲁姆)
**默认目标比例**(intake 第 7 项):
| 层次 | 目标占比 | 典型指令动词 | 适配题型 |
|---|---|---|---|
| 识记 | **20%** | 写出、列举、识别、命名、陈述 | 单选、填空、判断 |
| 理解 | **30%** | 解释、说明、比较、区分、举例 | 单选、多选、填空、简答、判断 |
| 应用 | **30%** | 计算、求解、运用…解决、实施 | 计算、单选、案例分析、多选 |
| 分析 | **20%** | 分析、诊断、找出原因、辨别关系 | 案例分析、简答、论述、单选 |
| (评价 / 创造) | 0%(需要时从分析里让出,总计 ≤10%) | 评价、判断、设计、提出方案 | 论述、案例分析、设计题 |
容差 **±5 个百分点**;单份试卷的层次占比需与 intake 第 7 项一致,改比例必须回改细目表。
**按学生层次调整**:
| 学生层次 | 建议比例(识记/理解/应用/分析以上) |
|---|---|
| 本科低年级 / 高职 | 30 / 35 / 25 / 10 |
| 本科高年级 | 20 / 30 / 30 / 20 |
| 研究生 | 10 / 20 / 30 / 40(含评价与创造) |
| 专升本 / 补修 | 35 / 35 / 20 / 10 |
| 留学生(中文授课) | 30 / 35 / 25 / 10(并降低题干语言复杂度,专业术语保留中文+附原文) |
**判断陷阱**:一个题目的层次由**学生要做的思维动作**决定,不由知识点难度决定。
"写出牛顿第二定律的表达式"再难也是识记;"判断这三个情境中哪个满足第二定律的适用条件"是理解或应用。
出完题后回头自检一句:「这道题允许学生靠背诵作答吗?」能背就说明层次标高了。
### 4. 难度预估与分值匹配
**难度预估公式**(P = 预计得分率,越大越容易;与 `office-layer/scripts/xlsx_kit.py analyze` 的实测口径一致,便于考后对比):
```
P_预估 = 基础难度系数(按层次) − 结构惩罚项
识记 0.90 理解 0.78 应用 0.65 分析 0.50 评价/创造 0.40
结构惩罚(可累加,每项 0.05,最多 0.20):
· 需要两步以上推理
· 情境陌生、需要自己建模
· 数值需要取整/开方
· 题干较长(>120 字)
· 需要跨知识点综合
```
各题**预计平均得分 = P_预估 × 该题满分**;全卷预计平均分应落在 intake 第 6 项的目标分 ±5 分内。
不落在区间内就调题:把最难题移到下个层次 / 减一个情境 / 增加已知条件。
**目标分的卷型口径(先定口径,再校验)**:上面公式的层次系数对应的是**得分率**,
不是难度等级。按层次目标配比(识记 20/理解 30/应用 30/分析 20)直算,客观题为主
的卷型(客观题分值占比 ≥60%)全卷预估均值约 75,对应默认目标 **75±5**;
**主观题占比高的卷型(简答/计算/案例/论述合计 >40%)全卷预估均值天然落在 60–70**,
此时应把目标分改为 **65±5**(intake 第 6 项由教师确认),不要为了让预估「达标」
而虚报 P 值或砍高阶题——高阶题少、预估均值低,是卷型特征,不是命题失误。
预估与目标不一致时的处理顺序:①确认卷型口径是否选对 → ②真偏高就调题 →
③真偏低就向教师说明并改目标分,留 `【待教师确认:目标分口径】`。
**易中难比例**:`P ≥ 0.75 为易`、`0.50 ≤ P < 0.75 为中`、`P < 0.50 为难`;
默认 **易:中:难 = 3:5:2**(按题数占比,不是分值占比)。
**分值匹配原则**:
1. **分值 = 作答时长配额 × 单位分**。以 100 分为例:
| 题型 | 每题基准分 | 说明 |
|---|---|---|
| 单选 | 2–3 分 | 1–1.5 分钟/题 |
| 多选 | 4–5 分 | 2–2.5 分钟/题 |
| 填空 | 每空 1–2 分 | 0.5–1 分钟/空 |
| 判断 | 1–2 分(要理由则 3–4 分) | 0.5–1 分钟/题 |
| 简答 | 4–8 分 | 4–6 分钟/题 |
| 计算 | 8–15 分 | 6–12 分钟/题 |
| 案例分析 | 15–25 分 | 15–25 分钟/题 |
| 论述 | 15–25 分 | 20–30 分钟/题 |
2. 全卷**作答时间合计 ≤ 考试时长的 85%**,留出检查时间。超了就减题量,不要压缩分值(压分值会让阅卷口径变形)。
3. 层次分值与分值配额**分开看**:高分值题不等于高难度题;一道 20 分的案例分析可以只到"分析"层。
4. 分值分配表要与细目表**双向对齐**:细目表各格分值之和 = 卷面总分 = 各题型分值之和。
5. 考后把实测 P(`xlsx_kit.py analyze` 给出)与预估 P 对比,写入《预估偏差说明》回填题库,
下一轮出题直接用历史实测值校准——这是本技能越用越准的关键。
### 5. 卷内一致性
- 同一份卷子里,**不同题目之间不得互相提示答案**(查第 6 条)。
- 同一知识点的多道题,层次要有梯度(识记 → 应用),不要三道都是识记。
- 全卷题干语言风格统一(都用"求…"或都用"请说明…"),不要前松后紧。
- 术语与符号全卷统一(前面用 F 后面不能变成 f;前面用"加速度"后面不能变成"加速率")。
- 卷头必须写明:考试时长、总分、闭卷/开卷、可否用计算器、多项选择题的评分规则。
## 按知识点覆盖出题(题量规划方法)
### 1. 知识点从哪里来(优先级降级链)
```
① 教师给的知识点清单 / 考纲(最优先,直接用)
② 教学大纲的章节条目 + 学习成果(抽成知识点,回读确认)
③ 教材目录 + 每节的小标题(抽成知识点,回读确认)
④ 教师给的讲义/材料正文 → 按小节抽知识点(抽完必须回读确认,且标注"由材料自动抽取")
```
③④ 两种情况下,用 `skills/ibook-skills/learning-graph-generator/` 的思路建知识点依赖,
并用 `skills/ibook-skills/course-description-analyzer/` 抽取布鲁姆层次的学习成果;
若教师只给一章,不必生成全图。
### 2. 从知识点清单到题量的算法
```
步骤 1 给每个知识点定级(A 核心 / B 支撑 / C 了解),权重 A=3 B=2 C=1
步骤 2 算总权重 W = Σ权重
步骤 3 该知识点题数 n_i = round(总题量 × 权重_i / W)
步骤 4 整数化修正:
A 级 n_i < 1 → 提到 1(核心考点不许 0 题)
C 级 n_i ≤ 0.4 → 归 0(了解性内容不必占分)
修正后的合计与总题量的差,用"优先级顺序"补/减:
补:先给 A 级中权重最高且题数最少的;减:先减 C 级
步骤 5 每个知识点的 n_i 题再分到布鲁姆层次,命中全局层次比例
步骤 6 每格选一个题型(按「题型设计参考」的适配表)
步骤 7 配分(按「命题质量原则 §4」的基准分)
```
**题量参考线**(不是硬性规定,看 intake 第 4 项):
| 场合 | 题量 | 单个知识点平均题数 |
|---|---|---|
| 随堂小测 | 3–5 | 1(只覆盖本次课 2–3 个知识点) |
| 单元测 | 15–20 | 1.5–2 |
| 期中/期末 | 25–35 | 2–4(A 级知识点 3–4 题,C 级 0–1 题) |
| 题库/练习 | 不限 | 每知识点 3–5(含变式) |
### 3. 覆盖矩阵(知识点 × 题型 × 认知层次)
**这就是阶段二的产出核心**。表格形式(xlsx 工作表「知识点覆盖矩阵」),每格填**题数**(括号里填题号):
| 知识点 | 重要度 | 单选·识记 | 单选·理解 | 多选·应用 | 填空·识记 | 简答·分析 | 计算·应用 | 案例·分析 | 合计题数 | 合计分值 | 占分比 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 牛顿第一定律 | A | 1(Q1) | 1(Q5) | | 1(Q9) | | | | 3 | 8 | 8% |
| 牛顿第二定律 | A | | 1(Q2) | 1(Q8) | | | 1(Q12) | | 3 | 19 | 19% |
| 牛顿第三定律 | A | | 1(Q3) | | | 1(Q16) | | | 2 | 8 | 8% |
| 动量守恒 | A | | | | | | 1(Q13) | 1(Q18) | 2 | 22 | 22% |
| 角动量守恒 | C | | 1(Q4) | | | | | | 1 | 3 | 3% |
| **合计** | | **1** | **4** | **1** | **1** | **2** | **2** | **1** | **12** | **60** | **100%** |
**覆盖率怎么报**(写进自检报告):
```
知识点覆盖率 = 已出题的知识点数 / 知识点清单总数
A 级知识点覆盖率必须 = 100%(核心考点一题不落)
全卷覆盖率:随堂小测按"本次课知识点"算(要求 100%)
期中期末按整门课清单算(要求 ≥70%,且未覆盖的必须是 C 级)
```
未覆盖的知识点**必须逐条列出并说明为什么不考**(如"本章不纳入期末范围""仅作阅读材料"),
不许静默省略——教师看到"没覆盖"才知道是设计选择还是遗漏。
### 4. 细目表 xlsx 的工作表结构
| 工作表 | 内容 |
|---|---|
| 双向细目表 | 行=题号,列=知识点/重要度/题型/认知层次/难度预估/分值/占分比/预计平均得分 |
| 知识点覆盖矩阵 | 上面那张交叉表(知识点 × 题型·层次) |
| 题型分布 | 各题型的题数、分值、占分比、建议区间、是否合格 |
| 层次分布 | 各认知层次的题数、分值、实际占比、目标占比、偏差(pp)、是否在 ±5pp 内 |
| 难度预估 | 逐题 P 值与预计平均得分 + 全卷预计平均分 + 易中难比例 + 原生柱状图 |
| 答案位置校验 | A/B/C/D 各位置题数、占比、是否在 25%±5%(多选与主观题不计入) |
## A/B 卷生成
### 1. 等价性要求(五要素,逐项必须可测量)
| 要素 | 量化容差 | 校验方式 |
|---|---|---|
| 同知识点 | 各知识点题数一致;占分比差 ≤ 2pp | 细目表逐格对照(AB卷对照表) |
| 同认知层次 | 各层次题数一致或差 ≤1 题,占比差 ≤ 3pp | `quiz_audit.py` 两卷输出对照 |
| 同难度 | 全卷预估 P 均值差 ≤ 0.03;单题差 ≤ 0.05 | 逐题 P 值求差 |
| 同分值 | 总分相同;各题型合计分值相同 | 题型分布表对照 |
| 不同题面 | 题干相似度低(前 12 字不得雷同);数据、情境、问法都不同 | 脚本雷同检测 + 人工逐题读 |
### 2. 生成流程
```
1. 复制细目表 → 作为两卷共用模板(这是保证等价的前提,不要各写一张)
2. 对每一格:先出 A 卷题,再按"同格异构"四换法(换情境/换数值/换问法/换干扰项)
出 B 卷题,并把两题的 kp / bloom / score / est_difficulty 保持同值
3. 若要求选项乱序:每卷独立乱序,逐题同步更新答案字母
4. 两卷各跑 quiz_audit.py + 生成 AB卷对照表
5. 人工逐题复核(这一步不能省,脚本查不出"换皮题")
6. 卷头分别标注"(A 卷)""(B 卷)",并注明"两卷等值,不得同场混用不同卷别"
```
### 3. 等价性校验报告要写什么
- 五要素逐项的**实测差值**(不是"应该差不多",要有数字)
- `AB卷对照表` 的行数与细目表格数一致(无空格)
- 两卷的题型分布、层次分布、答案位置分布并排对照表
- 脚本雷同检测结果(0 条为合格)
- 人工复核结论:逐题说明「B 卷该题与 A 卷的差异点在哪」(每个格子一句)
- 未达标项与处理动作(重出题 / 调整难度 / 换情境),以及处理后重跑的差值
### 4. 常见不合格情形
- ❌ 只是把 A 卷题号重排 → 不是 B 卷
- ❌ A/B 卷难度均值差了 0.1 以上(一门课平均分能差 8 分)
- ❌ B 卷某个知识点的题数比 A 卷少 1 题(考点覆盖不对等,学生申诉的常见由头)
- ❌ B 卷某题情境与 A 卷几乎一致,只改了数字 → 学生互相一看就穿
- ❌ 两卷多选评分规则写得不一样 → 即使题目等值,得分不具可比性
## 复习型题库与闪卡(引用 FSRS)
沿用 `skills/learning-education/study-skill/` 的 FSRS 间隔重复体系,把题目变成可长期复习的卡片。
### 1. 为什么不是"把题目存成题库"就够了
题目是**测评工具**(一次性、要计分),闪卡是**记忆工具**(重复出现、不计分)。
直接把选择题塞进复习只会让学生记住选项位置。所以要**拆卡**:
| 原则 | 做法 |
|---|---|
| 一卡一事 | 一道考两个考点的题拆成两张卡 |
| 正面不泄露 | 判断题的卡正面去掉原判断句,改成提问式 |
| 背面 20 秒可读完 | 只放答案 + 一句话理由,不放整段解析 |
| 干扰项变独立卡 | 每个干扰项对应一条常见错误,单独成卡:「有人说 X,错在哪?」 |
| 关联回原题 | 每张卡记 `source_qid`,学生答错原题时能定位到卡 |
### 2. 卡片字段与题库的关联
```json
{
"card_id": "kp-牛顿第二定律-c2",
"kp": "牛顿第二定律",
"front": "处于加速上升的电梯中,人对地板的压力与自身重力相比如何?",
"back": "更大。因为加速度向上,合力向上,地板支持力 N = m(g+a) > mg。",
"difficulty": 5,
"source_qid": "Q07",
"misconception": "认为压力始终等于重力"
}
```
`difficulty` 初值由原题的 `est_difficulty` 映射:`≤0.5 → 8`、`0.5–0.7 → 5`、`>0.7 → 3`(1–10 分制)。
### 3. FSRS 操作(照 `references/fsrs-spaced-repetition.md` 执行)
> ⚠️ 上游 `scripts/fsrs/` **只有 Go 源码**(`.gitignore` 忽略产物 `/fsrs`),仓库不带可执行文件,
> 本机亦无 Go 工具链。用之前先做前置检查,跑不通就走**手工排程降级方案**(见阶段七)。
```bash
FSRS_DIR="skills/learning-education/study-skill/scripts/fsrs"
FSRS_BIN="$FSRS_DIR/fsrs"
[ -x "$FSRS_BIN" ] || { command -v go >/dev/null 2>&1 \
&& (cd "$FSRS_DIR" && go build -o fsrs ./cmd/...) \
|| { echo "无 FSRS 二进制且无 Go → 改用手工排程" >&2; exit 6; }; }
FSRS_STORE=复习包/.fsrs/cards.json
"$FSRS_BIN" add "kp-牛顿第二定律-c1" "牛顿第二定律" 5 # 加卡
"$FSRS_BIN" schedule # 今天该复习哪些(due_count + cards)
"$FSRS_BIN" review "kp-牛顿第二定律-c1" 3 # 记录复习结果 1/2/3/4
"$FSRS_BIN" status # 全部卡概览
```
- 每次复习**最多呈现 3 条**、总时长 ≤5 分钟(study-skill 的混合复习模型),别一次性甩给学生几十张卡。
- 复习评分口径:1=完全忘记 2=很难想起 3=想起来了 4=轻松 → 对应 `第 D/S 值更新`,直接照协议传数字。
- 教师用法建议写进 `闪卡导入说明.md`:考前两周把到期卡集中复习;随堂小测答错率高的知识点,
把对应卡片 `difficulty` 手工调高(改初始值或做一次"Again"评分)。
### 4. 交付形态
- `复习包/题库.json`(全部卡片,含 `source_qid` 映射)
- `复习包/.fsrs/cards.json`(FSRS 状态存储;**仅在 FSRS 二进制可用的环境下产生**)
- `复习包/闪卡排程表.xlsx`(**无 Go / 二进制不可用时的降级产物**:手工排程表,见阶段七降级方案)
- `闪卡导入说明.md`(怎么用命令、怎么读 `schedule` 输出、怎么调难度;走降级方案时注明「按 FSRS 口径手工排程」)
## 与 exam-pipeline 的交接协议
`exam-pipeline` 是本技能的**直接下游**(出题 → 审卷 → 评分细则 → 考后分析 → 归档,见 `ROADMAP.md` P0-2)。
本技能**不做**审卷、不做完整评分细则、不做成绩分析——那是它的事。
> **现状说明**:`skills/exam-pipeline/SKILL.md` 目前**尚未创建**(属 ROADMAP 待开发项)。
> 因此本协议的**字段契约先按此定义冻结**:`exam-pipeline` 建成后必须按这些字段消费;
> 在它建成之前,教师按「手工交接」一步自行把文件交付给审卷人。
### 1. 交接时机
`quiz-generator` 的阶段八产出**已通过本技能质量门**的试卷初稿后立即交接,**不要等教师审完再交接**——
审卷本身就是 `exam-pipeline` 的职责,早交接才能早发现问题(题目歧义、覆盖缺口、A/B 不等值)。
### 2. 交接目录结构
```
handoff/
├── manifest.json # 机器可读的交接清单(字段见下)
├── 试卷A.docx / 试卷B.docx
├── 参考答案与评分要点A.docx / 参考答案与评分要点B.docx
├── 双向细目表.xlsx # 含 6 个工作表(见「按知识点覆盖出题 §4」)
├── AB卷对照表.xlsx # 只在有 A/B 卷时
├── 题库.json # 全部题目的内部字段(答案、解析、得分点、难度预估)
├── 出题自检报告.md
├── 知识点清单.xlsx
└── 交付说明.md
```
### 3. `manifest.json` 字段契约(**这是交接的核心**)
```json
{
"schema_version": "1.0",
"from": "quiz-generator",
"to": "exam-pipeline",
"generated_at": "20XX-XX-XX",
"course": {
"name": "【待补:课程名】",
"code": "【待补:课程代码】",
"credits": null,
"student_level": "本科高年级",
"exam_type": "期末",
"duration_minutes": 120,
"closed_book": true,
"calculator_allowed": false
},
"papers": [
{
"paper_id": "A",
"file": "试卷A.docx",
"answer_file": "参考答案与评分要点A.docx",
"total_score": 100,
"question_count": 30,
"estimated_mean_score": 74.5,
"difficulty_mix": {"易": 0.30, "中": 0.50, "难": 0.20},
"bloom_distribution": {"识记": 0.20, "理解": 0.30, "应用": 0.30, "分析": 0.20},
"type_distribution": {"单选": 0.25, "多选": 0.10, "填空": 0.10, "简答": 0.20, "计算": 0.35}
},
{
"paper_id": "B",
"file": "试卷B.docx",
"answer_file": "参考答案与评分要点B.docx",
"total_score": 100,
"question_count": 30,
"estimated_mean_score": 74.2,
"equivalence_check": {
"checked": true,
"kp_diff_max_pp": 0.0,
"bloom_diff_max_pp": 1.2,
"mean_difficulty_diff": 0.008,
"score_scheme_identical": true,
"passed": true
}
}
],
"questions": [
{
"id": "Q07",
"paper_id": "A",
"kp": "牛顿第二定律",
"kp_level": "A",
"chapter": "第3章 §3.2",
"type": "计算",
"bloom": "应用",
"score": 12,
"est_difficulty": 0.60,
"stem": "题干全文",
"options": null,
"answer": "见参考答案",
"explanation": "解析全文",
"scoring_points": [
{"point": "正确写出受力分析式", "score": 4},
{"point": "代入数值并解出 a=2 m/s²", "score": 5},
{"point": "单位与方向正确", "score": 3}
],
"common_misconceptions": ["把合力当某一个力", "忘记方向正负号"],
"source": "教师提供讲义 p.12(内部留档,不写进试卷)",
"review_status": "待教师审核",
"needs_rubric": true
}
],
"flags_for_downstream": [
{"question_id": "Q18", "flag": "主观题需完整评分细则(等级描述 + 标竿样卷)"},
{"question_id": "Q04", "flag": "干扰项来源为学科公认误解,缺教师本班错例,请审卷时确认"},
{"question_id": null, "flag": "角动量守恒(C级)仅 1 题,请确认是否纳入考试范围"}
],
"prompts_for_teacher": [
"全部题目须逐题审核后方可进考场(本包为初稿)",
"第 6 题无教师提供的本班错例,干扰项基于学科常见误解构造",
"卷头学校名/课程名为占位,请替换为本校教务处模板"
]
}
```
**必须传的字段(一个都不能空,空则显式写 `null` + `flags_for_downstream` 对应条目)**:
| 字段 | 为什么下游必须知道 |
|---|---|
| `questions[].id` | 下游的审卷意见、评分细则、考后逐题分析全靠它对齐 |
| `kp` / `kp_level` / `chapter` | 覆盖度复核与考后"哪个考点没掌握"的分析基础 |
| `type` / `bloom` / `score` | 细目表复核与层次偏差复核 |
| `est_difficulty` | 与考后实测难度 P 对比,做预估偏差校准 |
| `stem` / `options` / `answer` / `explanation` | 审卷(歧义、泄露、唯一性)的输入 |
| `scoring_points` | 下游生成完整评分细则(rubric)的骨架;缺则下游要重做一遍 |
| `common_misconceptions` | 下游做"错因归类"与讲评建议 |
| `source` | **审卷人核验是否照搬教材原题的唯一线索**(内部留档字段) |
| `review_status` | 标记是否已过教师人工审核 |
### 4. `exam-pipeline` 应回传什么(反向契约)
本技能期望下游回传以下内容,用于回流改进题库(教师可手工把文件放回工作目录):
| 回传文件/字段 | 用途 |
|---|---|
| `审卷意见.json`(逐题:`question_id` / 问题类型 / 严重级别 / 修改建议) | 逐题修正后重出;把反复出现的问题类型写进本技能的使用说明 |
| `评分细则A/B.docx`(含等级描述) | 归档;下次出同类主观题时参考等级描述写法 |
| `试卷分析报告.xlsx`(逐题难度 P 实测、区分度 D、分数段分布) | **回填预估偏差**:把实测 P 写入题库 `actual_difficulty` 字段 |
| `淘汰题清单`(D < 0.2 的题) | 从题库中标记淘汰,不再复用 |
| `学生错因归类.md` | 成为下一年该知识点的干扰项来源(第一优先级证据) |
回流后本技能要做的事(可选但强烈建议):把 `actual_difficulty` 与 `est_difficulty` 的偏差统计出来,
写进 `出题自检报告.md` 的「预估校准」小节——这是本技能唯一能让出题越来越准的机制。
### 5. 手工交接(`exam-pipeline` 未装时)
1. 把 `handoff/` 整个目录打包给审卷人(同教研室的另一位教师),并附 `manifest.json` 的 `prompts_for_teacher` 原文。
2. 审卷人按「命题缺陷十查」+ A/B 等价性五要素复核,逐条写意见。
3. **本技能绝不自称已审卷**:没有审卷意见就不能把稿件称为"定稿"。
## 产出物
全部 docx / xlsx 一律走 `skills/office-layer/`,禁止手写 OOXML、禁止用文本框拼表格、禁止只交 Markdown。
| 文件 | 通道 | 内容 |
|---|---|---|
| `试卷A.docx` / `试卷B.docx` | `docx_kit.py md` | 卷头(学校/学年学期/课程名/卷别/时长/总分/闭卷说明/多选评分规则 + 得分栏表格)、题目正文、答题空间 |
| `参考答案与评分要点A/B.docx` | `docx_kit.py md` | 客观题答案 + 逐题解析(含干扰项错因);主观题得分点拆分与扣分口径 |
| `命题说明与审核单.docx` | `docx_kit.py spec` | 命题依据(知识点清单/细目表引用)、层次与难度设计说明、**人工确认位**(`【待教师确认:本卷是否可付印】`) |
| `双向细目表.xlsx` | `xlsx_kit.py build` | 6 个工作表:双向细目表 / 知识点覆盖矩阵 / 题型分布 / 层次分布 / 难度预估(含原生柱状图)/ 答案位置校验 |
| `AB卷对照表.xlsx` | `xlsx_kit.py build` | 逐格对照 A/B 卷题号、分值、难度、差值、是否合格 |
| `题库.json` | 直接写 | 全部题目内部字段(`id/kp/type/bloom/score/est_difficulty/stem/options/answer/explanation/scoring_points/source/…`),含 `【待补:依据出处】` 占位 |
| `知识点清单.xlsx` | `xlsx_kit.py build` | 编号/知识点/章节/重要度/前置/学习成果 |
| `出题自检报告.md` | 直接写 | 脚本原始输出 + 命题缺陷十查逐条结论 + 知识点覆盖率 + 预估校准(有历史数据时) |
| `复习包/题库.json`、`复习包/.fsrs/cards.json`、`复习包/闪卡排程表.xlsx`、`闪卡导入说明.md` | 前两个直接写;排程表走 `xlsx_kit.py build` | 拆好的卡片、FSRS 状态(或降级的手工排程表)、使用说明 |
| `handoff/manifest.json` + 上述文件的副本 | 直接写 | 交 `exam-pipeline` 的机器可读清单 |
| `交付说明.md` | 直接写 | 本次用了哪些默认值、所有 `【待补:…】` / `【待教师确认:…】` 清单、审卷提示 |
**通用卷头模板**(`md` 通道用 Markdown 表格写,教师可对照本校模板替换):
```markdown
# 【待补:学校名】20XX—20XX学年第一学期
## 《【待补:课程名】》期末考试试卷(A卷)
考试形式:闭卷 考试时长:120 分钟 满分:100 分
(多项选择题评分规则:全部选对得满分,漏选得一半分,多选或错选不得分)
| 题号 | 一 | 二 | 三 | 四 | 五 | 总分 |
|---|---|---|---|---|---|---|
| 满分 | 20 | 10 | 20 | 20 | 30 | 100 |
| 得分 | | | | | | |
**考生须知**:请将答案写在答题纸指定位置;计算题需写出必要步骤,只写答案不得分。
```
> 试卷页眉页脚、密封线、装订线属学校模板差异,本层**不替你猜**:
> 用 `docx_kit.py spec` 出《命题说明与审核单》承载需要页眉页脚与人工确认位的部分,
> 试卷正文用 `md` 通道出,并在交付说明里写「卷头为通用模板,请对照贵校教务处模板调整」。
## 红线
1. **题干不得直接照搬教材原题。** 教材例题、课后习题、往年试卷的题干/数据/选项都必须改写:
换情境、换数值、换问法。若确实需要引用,须注明来源并取得教师确认。
`题库.json` 的 `source` 字段是审卷人核验这一点的唯一线索,**不得为空或伪造**。
2. **不虚构引用来源。** 案例来源、文献、政策条文、课程标准编号、教材页码一律不得编造。
教师给了才写;没给留 `【待补:依据出处】`。案例题一律标注
`【案例来源:教师提供 / 公开报道改编 / 为教学目的拟制】`,**不得写不存在的来源**。
3. **生成的题目必须由教师审核后方可使用。** 本技能产出的是**待审稿**。
题目、答案、评分要点都可能存在学科性错误,**未经教师逐题审核不得印卷、不得发给学生**。
每份产出的交付说明里必须有这句话。
4. **不生成学生数据。** 不得虚构班级名单、成绩、错题统计、学情分布。
没有教师提供的真实数据时,干扰项只能基于「学科公认的常见误解」构造,并显式标注缺教师本班错例。
5. **不替教师做判断性结论。** 不写「这套卷子难度合适」「学生应该能考到 80 分」这类结论性表述;
只给测算值与偏差,判断与确认留给教师(人工确认位 `【待教师确认:…】`)。
6. **不泄露答案到试卷面。** 试卷 docx 内不得残留答案字母、解析、得分点、干扰项设计说明。
答案与解析只出现在《参考答案》文件里。交付前用 `docx_kit.py inspect` 读回核对。
7. **不虚报质量门结论。** `quiz_audit.py` 的原始输出必须留档;有未处理问题项时**不得交付**,
也不得把「未通过」写成「基本通过」。
8. **A/B 卷不得以「同一套题换序」冒充。** 见「A/B 卷生成」的禁止条款。
9. **只抄袭方法论,不抄袭文本。** ibook 系列底座(`question-writing` 等)的上游仓库无 LICENSE 文件(见 `THIRD_PARTY_NOTICES.md`),
禁止把其英文原文、模板、代码整段搬进交付物;一切交付物用中文重写。
10. **敏感数据本地处理。** 如果教师提供了含学号/姓名/成绩的错例材料,只在本机处理,
不写入交付物、不外传;任务结束后提醒教师删除中间文件。
## 自检清单
交付前逐项过,**任一项不通过就不交付**。
**intake 与依据**
- [ ] 13 项前置信息一次性问完(不是边做边问)
- [ ] 知识点清单已回读给教师确认,每条能指向材料中的具体位置
- [ ] 用了默认值的项目都在交付说明里逐条列出
**规划**
- [ ] 双向细目表各格分值之和 = 卷面总分
- [ ] 认知层次实际占比与 intake 目标偏差 ≤ 5pp
- [ ] A 级知识点覆盖率 = 100%;未覆盖知识点已逐条说明理由
- [ ] 全卷作答时间 ≤ 考试时长 × 85%
- [ ] 全卷预计平均分落在 intake 目标分 ±5 分内(且目标分按 §4 卷型口径取 75±5 或 65±5,非主观题卷型硬套 75)
- [ ] 易:中:难比例符合要求(默认 3:5:2)
**命题质量**
- [ ] 每个干扰项都能说出对应的一条学生常见错误(或已标注 `【待教师补充:…】`)
- [ ] 无「以上都对/都不对」凑数项;无绝对化词送分项
- [ ] 正确项长度与干扰项均值之比 ≤1.4(脚本已核)
- [ ] 无否定式题干(或已加粗提示并在卷头说明)
- [ ] 选项语法平行、互斥、无同义项
- [ ] 全卷无跨题泄露;答案未出现在题干或别题中
- [ ] 每道主观题至少 2 个可独立判分的得分点,得分点分值合计 = 该题满分
- [ ] 术语与符号全卷统一
- [ ] 无任何题目照搬教材原题;每题 `source` 已填或显式占位
**质量门**
- [ ] `quiz_audit.py` 问题清单 = 0 条,原始输出已留档
- [ ] 「命题缺陷十查」逐条留痕(已查无问题 / 已修正 + 说明)
- [ ] 答案位置 A/B/C/D 各 25%±5%(多选与主观题不计入)
**A/B 卷(如适用)**
- [ ] 等价性五要素逐项有实测差值,全部在容差内
- [ ] AB 卷对照表无空格,行数 = 细目表格数
- [ ] 两卷无「换皮题」,人工逐题复核完成并留痕
- [ ] 两卷卷头都标注卷别与「不得同场混用不同卷别」
**闪卡(如适用)**
- [ ] 一张卡只问一件事;正面不泄露答案;背面 20 秒可读完
- [ ] 判断题卡已改写为提问式,未保留原判断句
- [ ] `difficulty` 由 `est_difficulty` 映射,不是全卡同值
- [ ] `fsrs status` 能列出全部卡片;每张卡有 `source_qid` 关联
- [ ] 若 FSRS 二进制不可用:已走降级方案出 `复习包/闪卡排程表.xlsx`,且交付说明明确写了「按 FSRS 口径手工排程,非自动调度」
**产出**
- [ ] 所有 docx/xlsx 由 `skills/office-layer/` 生成,且都跑过 `inspect` 读回核对
- [ ] 试卷 docx 内无答案、无解析、无得分点残留
- [ ] 题号连续无跳号;跨页未把题目劈成两半;主观题留足作答空间
- [ ] 三类占位(`【待补:…】` / `【待教师确认:…】` / `【待补:依据出处】`)已全部列进交付说明
- [ ] 交付说明含「本文件为出题初稿,全部题目须经教师逐题审核后方可进考场」
**交接**
- [ ] `handoff/manifest.json` 字段齐全,`questions` 条数 = 细目表题数
- [ ] 每个交接文件路径存在且非空
- [ ] `flags_for_downstream` 已列出所有需要下游注意的项(缺指标、需完整 rubric、覆盖疑问)
- [ ] 未自称「已审卷」「定稿」
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.