Skip to content
Back to skills

Exam Pipeline

ASecurity

高校期末试卷后半程全流程辅助:试卷审核(A/B 卷等价性、知识点覆盖、难度分值匹配、歧义与答案唯一性、题目间相互提示)、参考答案与评分细则(rubric)、考后成绩分析(得分率/区分度/分数段分布,逐题改进建议)、归档材料(试卷审批表、试卷分析报告、平时分依据表)。当教师说「审核这套试卷」「帮我审一下 AB 卷是不是等值」「出评分细则」「这题怎么给分才公平」「考后成绩分析」「帮我算一下每道题的区分度」「这题是不是太简单了」「写试卷分析报告」「期末归档材料帮我整理一下」时使用。Triggers: 审核这套试卷、出评分细则、考后成绩分析、试卷归档材料、AB卷等值、区分度、得分率、试卷分析报告、参考答案、给分标准、平时分依据表、期末归档。

  • 11 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 20, 2026
educationpythongobash

Security analysis

A100/100

Scanned October 20, 2026

npx -y skills add EtherealMingo/university-teacher-skills --skill exam-pipeline --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Exam Pipeline?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Exam Pipeline
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/etherealmingo-exam-pipeline/badge)](https://www.skillsdirectory.com/skills/etherealmingo-exam-pipeline)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: exam-pipeline
description: "高校期末试卷后半程全流程辅助:试卷审核(A/B 卷等价性、知识点覆盖、难度分值匹配、歧义与答案唯一性、题目间相互提示)、参考答案与评分细则(rubric)、考后成绩分析(得分率/区分度/分数段分布,逐题改进建议)、归档材料(试卷审批表、试卷分析报告、平时分依据表)。当教师说「审核这套试卷」「帮我审一下 AB 卷是不是等值」「出评分细则」「这题怎么给分才公平」「考后成绩分析」「帮我算一下每道题的区分度」「这题是不是太简单了」「写试卷分析报告」「期末归档材料帮我整理一下」时使用。Triggers: 审核这套试卷、出评分细则、考后成绩分析、试卷归档材料、AB卷等值、区分度、得分率、试卷分析报告、参考答案、给分标准、平时分依据表、期末归档。"
---

# 期末试卷后半程流水线(审核 → 细则 → 分析 → 归档)

> **Goal**:把教师手上从「题已经出完了」到「材料交教务处归档」之间的四段活干完:
> 审卷、写评分细则、考后成绩分析、整理归档材料。
> **产出全部是初稿**。评分细则里的分值、最终成绩的判定、归档结论一律留人工确认位 ——
> 这是本包的红线,AI 不给终稿。

## 何时使用

- 「题出好了,你帮我审一遍,看有没有歧义 / 答案是不是唯一」
- 「A 卷 B 卷难度是不是一样,会不会不公平」
- 「这题的知识点有没有覆盖全大纲」
- 「出个评分细则,我怕学生来查分的时候说不清」
- 「考试考完了,帮我做成绩分析,看看哪道题出得不好」
- 「这题区分度多少?是不是该淘汰」
- 「帮我写《试卷分析报告》,教务处要」
- 「归档要交哪些材料,帮我做个审批表和平时分依据表」

**不适用**:出题本身(那是 `quiz-generator` 的活);平时过程性评价的设计(那是 `classroom-live`);
学生成绩单的正式录入与上报(教务系统的事,本技能不代做)。

**上游衔接**:`quiz-generator` 出完题 → 本技能接阶段一。若教师直接甩来一份 Word 试卷,
跳过上游直接从阶段一开始。

## 底座(禁止重写)

| 路径 | 用途 |
|---|---|
| `skills/office-layer/SKILL.md` | **文件产出唯一通道**,四条命令的用法与铁律 |
| `skills/office-layer/scripts/xlsx_kit.py` | **`analyze` 已实现成绩分析**:得分率/区分度/分数段/偏度峰度 + 原生图表;`build` 出归档表格 |
| `skills/office-layer/scripts/docx_kit.py` | `md` 出 Word;`comment` 写 **Word 原生批注**(试卷审核意见直接批在卷面上);`spec` 出带人工确认位的排版稿;`inspect` 自检 |
| `skills/ibook-skills/question-writing/` | 上游出题能力,**阶段一与之衔接**;其题目格式即本技能的审核输入 |
| `skills/ibook-skills/question-writing/references/distractor-writing-guide.md` | 干扰项质量四条标准(可信性/教育价值/区分性/公平性),审选择题时直接引用 |
| `skills/education-skills/edu-learning-analytics/` | `learning-analytics.md`(学习分析口径)、`competency-based-assessment.md`(能力本位评量)、`peer-assessment.md`(量规思路) |
| `skills/k12-teacher-skills/k12-check-for-understanding/` | 检查理解的设计思路,审「题目是否真在考理解而非背记」时参考 |

**环境准备(首次使用必做,已实测)**:

```bash
bash skills/office-layer/bootstrap.sh     # 创建 skills/office-layer/.venv 并装依赖
PY="skills/office-layer/.venv/bin/python"
export MPLCONFIGDIR=/tmp/mplcache && mkdir -p /tmp/mplcache   # 受限环境必须有可写缓存目录
```

## 前置信息收集(intake,一次性问完)

沿用 `awesome-benzi` 的 `question-batch` 思路:**开头的 intake 一次问完,不要边做边问**。
缺信息时用安全默认值继续,并在交付物里标注哪里用了默认值。

1. **课程与考试基本信息**:课程名、课程代码、开课单位、学期、学生层次(本科/研究生/高职)、
   考试形式(闭卷/开卷/机考/大作业)、考试时长、考生人数
2. **试卷文件**:A 卷、B 卷(Word 或 Markdown);已有的双向细目表(有则给,无则本技能据大纲生成)
3. **依据**:课程教学大纲 / 考试大纲(**知识点清单是覆盖面检查的前提**,尽量要)
4. **分值结构**:题型、题数、各题满分(告诉我是「每题满分」还是「每大题满分」)
5. **评分口径**:学校是否要求「言之成理即可」的开放题,是否有统一的平时分折算比例
6. **成绩数据**(阶段三才需要):含表头的成绩表 xlsx —— 说明第几列是学号、第几列起是各题得分
7. **归档要求**:学院/教务处指定的表格模板或清单(有则照做,无则用本技能默认栏目并在交付物标注)
8. **敏感数据处置约定**:教师是否同意先用脱敏表分析(**默认走脱敏,见「脱敏」一节**)

**最快路径**:只要教师给了「试卷 + 各题满分 + 成绩表」,阶段一、二、三都能跑;
缺大纲时覆盖面检查退化为「内部一致性检查」并在报告里注明。

## 工作流

### 阶段一 · 试卷审核

**输入**:A/B 卷(docx/md)、各题满分、教学大纲知识点清单(可选)、`quiz-generator` 的输出(若从上游来)
**动作**:按下面六张检查表逐项过,把每条不通过的项写成审核意见
**输出**:`试卷审核意见.docx`(**用 docx_kit 的 `comment` 写成 Word 原生批注**,教师打开就看到批注气球)
+ `试卷审核检查表.xlsx`(逐项结论)
**退出条件**:所有标记为【阻断】的项清零,或教师明确书面确认「已知悉并接受」

#### 检查表 1 · A/B 卷等价性(公平性底线)

| # | 检查点 | 判定标准 | 不通过 |
|---|---|---|---|
| 1.1 | 题型结构一致 | 两卷题型、题数、题序完全相同 | 【阻断】 |
| 1.2 | 逐题满分一致 | 第 i 题满分两卷完全相同,总分相同 | 【阻断】 |
| 1.3 | 考点覆盖重合 | 两卷覆盖的核心考点重合率 ≥ 80%,且各自 100% 覆盖核心考点 | 【阻断】 |
| 1.4 | 认知层次分值分布 | 识记/理解/应用/分析各层次分值占比,两卷差 ≤ 5 个百分点 | 需修改 |
| 1.5 | 预估难度均值 | 两卷全卷预估难度 P 之差 ≤ 0.05 | 需修改 |
| 1.6 | 预估用时 | 两卷预估总用时之差 ≤ 考试时长的 5% | 需修改 |
| 1.7 | 无原题直搬 | 除明示的等价替换题外,两卷不得有完全相同的题干 | 【阻断】 |
| 1.8 | 上下文无串味 | A 卷某题的题干/材料不得出现在 B 卷另一题的答案中 | 【阻断】 |

> 等价性判定的证据只有「题型/分值/考点/预估难度」四项可客观核对,**认知层次与难度是估计值**,
> 报告里必须写成「预估」并留 【待教师确认:A/B 卷是否认定等值】。

#### 检查表 2 · 知识点覆盖面

| # | 检查点 | 判定标准 | 不通过 |
|---|---|---|---|
| 2.1 | 核心考点覆盖率 | 大纲标为「掌握/重点」的知识点,被考比例 = 100% | 【阻断】 |
| 2.2 | 总体覆盖率 | 被考知识点数 / 大纲知识点数 ≥ 80% | 需修改 |
| 2.3 | 章节分值 vs 课时 | 各章分值占比与该章课时占比偏差 ≤ ±5 个百分点 | 需修改 |
| 2.4 | 无单章独大 | 任一章节分值占比 ≤ 30% | 需修改 |
| 2.5 | 无超纲 | 无未讲授内容、无大纲外知识点 | 【阻断】 |
| 2.6 | 无「讲了不考」 | 重点章节不得整章零分值 | 需修改 |
| 2.7 | 题型—目标匹配 | 考「应用/分析」的考点不应只用选择/填空覆盖 | 需修改 |

产出建议用双向细目表呈现:**知识点 × 认知层次 × 题型 × 分值** 四维矩阵(xlsx)。

#### 检查表 3 · 难度与分值匹配

| # | 检查点 | 判定标准 | 不通过 |
|---|---|---|---|
| 3.1 | 全卷预估难度 | 期末卷预估平均 P 落在 0.60–0.75 | 需修改 |
| 3.2 | 难度梯度 | 题序上由易到难,前 1/3 题 P ≥ 0.7(保底分) | 需修改 |
| 3.3 | 分值—难度相称 | 高分值题(≥ 15 分)应为应用/综合分析题,P 落在 0.40–0.70 | 需修改 |
| 3.4 | 无低分高难 | 分值 ≤ 5 分的题 P 不应 < 0.3(性价比失真) | 需修改 |
| 3.5 | 时间预算 | Σ(各题预估用时) ≤ 考试时长 × 0.9(留 10% 复查) | 【阻断】 |
| 3.6 | 分值粒度 | 分值均为 0.5 的整数倍;单题满分 ≤ 20 | 需修改 |
| 3.7 | 及格线可达 | 按预估难度推算,中位数学生应能拿到 60% 以上 | 需修改 |

时间预算按题型给经验值:选择题 1–2 分钟/题,填空 2 分钟,简答 5–8 分钟,计算 8–15 分钟,
论述/综合 15–25 分钟。**这条最容易出事**,估完必须写进审核意见。

#### 检查表 4 · 题目表述歧义

| # | 检查点 | 判定标准 | 不通过 |
|---|---|---|---|
| 4.1 | 指令动词唯一 | 一题只用一个指令词(「计算」「证明」「简述」「比较」不得混用) | 需修改 |
| 4.2 | 指代明确 | 「其」「该」「上述」必须能找到唯一先行词 | 需修改 |
| 4.3 | 条件充分 | 已知条件足以解题,且条件之间不矛盾 | 【阻断】 |
| 4.4 | 单位统一 | 全卷单位制统一;关键量必须带单位 | 需修改 |
| 4.5 | 精度要求 | 计算题须写明有效数字/小数位要求;未写默认保留 2 位并写明 | 需修改 |
| 4.6 | 否定词 | 全卷「不」「错误」「除外」等否定表述 ≤ 1 处/题,且加粗 | 需修改 |
| 4.7 | 图表可引用 | 图表有编号,被题干文字显式引用;图内文字可读 | 需修改 |
| 4.8 | 选项同构 | 选择题各选项长度、结构、语法形式大致平行(见 distractor 指南) | 需修改 |
| 4.9 | 无绝对化陷阱 | 不靠「以上都对/都不对」「总是/从不」制造迷惑 | 需修改 |
| 4.10 | 答题空间 | 答题留白与该题分值、书写量相称 | 需修改 |

#### 检查表 5 · 答案唯一性

| # | 检查点 | 判定标准 | 不通过 |
|---|---|---|---|
| 5.1 | 单选唯一 | 单选题有且仅有 1 个正确项,其余 3 项均可被明确证伪 | 【阻断】 |
| 5.2 | 多选规则明示 | 多选题必须在题干写明「多选、少选、错选如何给分」 | 【阻断】 |
| 5.3 | 判断题可判定 | 无「半对半错」的表述,不依赖未给出的前提 | 【阻断】 |
| 5.4 | 填空答案唯一 | 每空答案唯一,或已列出全部可接受写法 | 【阻断】 |
| 5.5 | 主观题可复现 | 参考答案能被独立推导,不依赖某一特定解题路径 | 【阻断】 |
| 5.6 | 计算题数值唯一 | 在给定精度下结果唯一;多解情况须在题干中限定 | 【阻断】 |
| 5.7 | 开放题有要点 | 开放式题必须给「评分要点」而非唯一答案,并注明「言之成理即可」 | 需修改 |
| 5.8 | 干扰项有效 | 每个干扰项对未掌握的学生有可信性,且不因表述与正确项不同而暴露 | 需修改 |

> 5.1–5.6 任一项不过 = **这道题会直接引发查分纠纷**,必须在开考前改掉,不能带进考场。

#### 检查表 6 · 题目间相互提示(答案泄露)

| # | 检查点 | 判定标准 | 不通过 |
|---|---|---|---|
| 6.1 | 题干不泄答案 | 后一题题干/选项不得包含前一题的正确答案 | 【阻断】 |
| 6.2 | 选项不跨题复现 | 某题的选项文本不得原样出现在另一题的题干中作为已知条件 | 【阻断】 |
| 6.3 | 小问不提前泄底 | 计算题各小问不得提前给出前一小问的结论(除题型明确设计为「台阶式」) | 需修改 |
| 6.4 | 材料不含答案句 | 阅读/案例分析材料中不得直接含答案原句 | 【阻断】 |
| 6.5 | 术语互不提示 | 名词解释的答案词不得出现在其他题的题干中 | 需修改 |
| 6.6 | 前后题不互推 | 不得出现「做对第 5 题就必然做对第 6 题」的强相关设计 | 需修改 |
| 6.7 | 选项字母分布 | 正确答案的选项字母分布无规律(A/B/C/D 各占 20%–30%) | 需修改 |

> 6.1–6.4、6.6 属于**结构性缺陷**,靠改表述无法修复,必须换题或换材料。
> 6.1/6.2/6.4 一旦命中,直接按【阻断】处理并给出替换建议。

#### 审核意见的落盘方式

把每条意见写成批注 JSON,锚点用**试卷正文里的原文片段**(逐字一致),批注直接钉在卷面上:

```bash
PY="skills/office-layer/.venv/bin/python"
export MPLCONFIGDIR=/tmp/mplcache && mkdir -p /tmp/mplcache

# 1) 先把试卷(md 稿)转成 docx
$PY skills/office-layer/scripts/docx_kit.py md \
    --in 试卷A.md --out 试卷A_待审.docx --title "2025-2026学年第一学期期末考试试卷(A卷)"

# 2) 写审核批注(anchor 必须是正文里逐字存在的片段)
cat > 审核意见.json <<'EOF'
[
  {"anchor": "已知条件如下,求该电路的等效电阻。",
   "text": "【审核·需修改】未规定有效数字位数,学生保留 2 位或 3 位都可自辩。建议在题干补『结果保留两位有效数字』。"},
  {"anchor": "下列关于热力学第二定律的说法,正确的是",
   "text": "【审核·阻断】选项 C 与第 7 题题干中的表述实质等价,构成跨题提示。建议将选项 C 改为『孤立系统熵不减』之外的其他错误表述。"},
  {"anchor": "论述题:试述 XX 理论对当代实践的意义。",
   "text": "【审核·需修改】开放题未给评分要点。本技能阶段二将补出要点框架,请教师确认【待教师确认:要点及其分值】。"}
]
EOF
$PY skills/office-layer/scripts/docx_kit.py comment \
    --in 试卷A_待审.docx --out 试卷A_审核意见.docx \
    --comments 审核意见.json --author "试卷审核"

# 3) 自检:确认批注真的落盘了
$PY skills/office-layer/scripts/docx_kit.py inspect --in 试卷A_审核意见.docx
```

**实测注意(踩过的坑)**:`anchor` 必须匹配 docx **渲染后**的正文文本。
Markdown 里写成有序列表 `2. 计算题 已知……` 时,`2. ` 会被渲染成列表编号而消失,
用整行当锚点会失败并让脚本**以退出码 2 结束**(返回 JSON 里进 `failed`)。
正确做法是只取句子本身(如 `计算题 已知条件如下,求XXX。`)作锚点。
**不要忽略退出码 2**,逐条修正锚点后重跑。

### 阶段二 · 参考答案 + 评分细则(rubric)

**输入**:审过的试卷、各题满分、题型清单、学校的给分习惯(是否给步骤分)
**动作**:按题型用不同的细则结构拆得分点,见下表
**输出**:`参考答案与评分细则.docx`
**退出条件**:每题的「得分点分值之和 = 该题满分」(脚本外人工核对一遍),且教师确认过开放题要点

#### 评分细则表结构(统一骨架)

| 题号 | 满分 | 得分点 | 分值 | 得分标准(什么情况给分) | 常见错误扣分 | 人工确认位 |
|---|---|---|---|---|---|---|
| 一.1 | 2 | 正确答案 A | 2 | 选 A 得 2 分 | 选 B(混淆 XX 与 YY)不得分 | — |
| 二.1(1) | 4 | 正确写出公式 | 2 | 公式正确即给,未代入不扣 | 公式写颠倒扣 2 | — |
| 二.1(2) | 4 | 正确代入数据 | 1 | 数值与单位均对给 1 | 漏单位扣 0.5 | — |
| 二.1(3) | 4 | 计算结果正确 | 1 | 结果保留 2 位有效数字 | 精度不符扣 0.5 | 【待教师确认:是否给步骤分】 |
| 三.1 | 12 | 要点①……、要点②…… | 4+4 | 要点齐、有论据 | 只列要点无论据,每点扣 1 | 【待教师确认:开放式论述给分尺度】 |
| 三.1 | 12 | 逻辑与结构 | 2 | 层次清晰、有论证链 | 条理混乱扣 1 | — |
| 三.1 | 12 | 语言与规范 | 2 | 术语准确、无硬伤 | 术语错误每处扣 0.5,最多扣 2 | — |

**硬性约束**:每题「分值」列求和必须等于「满分」列,**差 0.5 分都不行** ——
这是查分时最容易被抓的点,交付前逐题核一遍。

#### 客观题 vs 主观题的细则差异

| 维度 | 客观题(选择/判断/填空) | 主观题(简答/论述/计算/证明/设计) |
|---|---|---|
| 得分点粒度 | 以「题」或「空」为单位,二元给分 | 以「步骤」或「要点」为单位,分步/分点给分 |
| 是否给部分分 | 一般不给;多选须明示部分给分规则 | 必须给,且要写清「错到哪一步止步」 |
| 常见错误列举 | 干扰项对应的典型误解(见 distractor 指南) | 缺步骤、跳步、单位/精度、术语误用、结论未回应题干 |
| 争议高发点 | 多选的部分给分、填空题的等价写法、错别字 | 方法不同但结果对、结果错但方法对、开放题的「言之成理」 |
| 细则长度 | 短,一题一行 | 长,一题一张子表 |

#### 计算题 vs 论述题的细则差异

| 维度 | 计算题 | 论述题 |
|---|---|---|
| 拆分逻辑 | **按解题链拆分**:建模/公式 → 代入 → 演算 → 结果(含单位与精度) | **按内容+形式拆分**:内容要点分 + 逻辑结构分 + 表达规范分 |
| 分值配比 | 公式/方法分 40–50%,代入与演算 30%,结果 20–30% | 内容要点 60–70%,逻辑结构 15–20%,语言规范 15–20% |
| 等效方法 | 必须写明「其他正确方法同等给分」,并给出至少一种备选解法 | 不设唯一答案,给「必须出现的关键词/论据清单」,缺一扣一 |
| 错到底怎么给 | 中间步骤错但后续方法正确 → 给方法分(「**错误传导不重复扣分**」须写明) | 观点错误但有论证 → 观点分不给,逻辑分可给 |
| 典型扣分项 | 单位缺失、有效数字不符、只写结果无过程、乱用公式 | 只罗列无论证、答非所问、通篇套话、术语错用 |

#### 评分细则的红线

- **不替教师定分**。每个有争议的给分尺度后必须挂 `【待教师确认:……】`,
  尤其是:是否给步骤分、开放式论述的给分尺度、多选部分给分规则、卷面分/印象分是否存在。
- **不虚构评分标准**。学校若有统一评分规范,以教师提供的为准;没有就写
  「按学校/学院相关规定执行,请教师核对」,**不引具体条款号**。
- 细则里的参考答案是**教师卷的初稿**,交付时必须说「这是初稿,请逐题核对参考答案与分值分配」。

### 阶段三 · 考后成绩分析(本技能的核心可执行部分)

**输入**:成绩表 `scores.xlsx`(第 1 行表头;第 1 列学号;第 `first-q-col` 列起为各题得分)
**动作**:调用 `xlsx_kit.py analyze`(已实测通过),读返回 JSON,翻译成改进建议
**输出**:`成绩分析.xlsx`(三个工作表 + 两张原生柱状图)
**退出条件**:返回 JSON 无 `error` 字段,且 `students` 与实考人数一致

#### 命令与参数含义

```bash
PY="skills/office-layer/.venv/bin/python"
export MPLCONFIGDIR=/tmp/mplcache && mkdir -p /tmp/mplcache

$PY skills/office-layer/scripts/xlsx_kit.py analyze \
    --in scores.xlsx --out analysis.xlsx \
    --id-col 1 --first-q-col 3 \
    --full-marks '[10,10,15,15,10,20,10,10]'
```

| 参数 | 含义 | 本场景取值与坑 |
|---|---|---|
| `--in` | 输入成绩表 xlsx | **先用脱敏表**,见下节 |
| `--out` | 输出分析工作簿 xlsx | 建议命名 `成绩分析.xlsx` |
| `--sheet` | 指定工作表名 | 缺省取第一个工作表;成绩在第二个 sheet 时必须显式指定 |
| `--id-col` | 标识列号(1 起) | 只用于标识,不参与计算。填学号列(脱敏后是匿名 ID 列) |
| `--total-col` | 总分列号 | **有正式总分列就填**;不填则用各题之和当总分。若卷面有平时分折算,两者会不一致,须想清楚用哪个 |
| `--first-q-col` | 第一道题得分所在列号 | **最高频出错点**。若第 1 列学号、第 2 列姓名、第 3 列起是 Q1,则填 `3` |
| `--n-questions` | 只分析前 N 题 | 缺省分析到最后一列。末尾若混有「总分」「备注」列,**必须用这个参数截断**,否则会把总分当成一道题算 |
| `--full-marks` | 各题满分 JSON 数组 | **必须给**,顺序与题目列严格一一对应。缺省时会取该题在全班的最高分当满分 —— 一旦无人满分,得分率就被系统性高估,**不要依赖缺省** |

数组写法与题号对应关系(务必在给教师的说明里写出来):

```
题目列:  Q1   Q2   Q3   Q4   Q5   Q6   Q7   Q8
满分:    10   10   15   15   10   20   10   10
JSON:  --full-marks '[10,10,15,15,10,20,10,10]'
```

#### 返回 JSON 与三个工作表

实测返回(40 人、8 题样例):

```json
{
  "students": 40,
  "questions": 8,
  "total_stats": {"n": 40, "mean": 67.475, "sd": 16.814, "min": 40.0, "max": 98.0,
                  "skew": 0.063, "kurt": -1.15},
  "weak_questions": ["Q5"],
  "hard_questions": [],
  "easy_questions": ["Q5"],
  "out": "analysis.xlsx"
}
```

输出工作簿三个工作表(实测表结构):

**① 逐题分析**(1 行表头 + 每题 1 行,附「逐题得分率与区分度」柱状图)

| 列 | 含义 |
|---|---|
| 题号 | 取表头文字(如 `Q1`);**表头写清楚题号,否则报告里对不上题** |
| 满分 | 来自 `--full-marks` |
| 平均分 | 该题全班平均得分 |
| 得分率P | = 平均分 / 满分,即**难度 P** |
| 高分组得分率 | 总分前 27% 学生在该题的平均得分率 |
| 低分组得分率 | 总分后 27% 学生在该题的平均得分率 |
| 区分度D | = 高分组得分率 − 低分组得分率 |
| 评价 | 脚本自动给结论,含难度过高/过低提示 |

**`区分度D < 0.2` 的整行会被自动高亮**(黄色底纹)—— 这是「这道题没区分出学生水平」的信号。

**② 总体概况**(10 项)

考生数、平均分、标准差、最高分、最低分、及格率(≥ 总分的 60%)、偏度、峰度、高分组成员数、低分组成员数。

**③ 分数段分布**(5 段,附柱状图)

`90-100%`、`80-89%`、`70-79%`、`60-69%`、`60% 以下` 各段人数与占比。
注意:分数段按「占总分比例」划分,与实际卷面分数段在总分非 100 分时不一致,报告里要说明口径。

#### 判读标准

**难度 P = 得分率(越大越容易)**

| P 区间 | 判读 | 处理 |
|---|---|---|
| P ≥ 0.90 | 太容易 | 脚本归入 `easy_questions`;期末卷中此类题不宜超过 20% |
| 0.70 ≤ P < 0.90 | 偏易 | 合格,适合作为保底题 |
| 0.40 ≤ P < 0.70 | 适中 | 期末卷主体应落在此区间 |
| 0.30 ≤ P < 0.40 | 偏难 | 复核题意是否清楚、是否超纲、时间是否够 |
| P < 0.30 | 太难 | 脚本归入 `hard_questions`;优先查「题意不清」和「教学未覆盖」 |

**区分度 D = 高分组得分率 − 低分组得分率(高低分组各取总分前/后 27%)**

| D 区间 | 判读 | 处理 |
|---|---|---|
| D ≥ 0.40 | 优良 | 保留,可入题库 |
| 0.30 ≤ D < 0.40 | 良好 | 保留 |
| 0.20 ≤ D < 0.30 | 尚可,**需修改** | 微调题干或选项后复用 |
| D < 0.20 | **应淘汰** | 脚本归入 `weak_questions` 并高亮;按下方决策表处理 |

**分布形态快评(偏度 / 峰度)**

| 指标 | 参考 | 含义 |
|---|---|---|
| 偏度 \|skew\| ≤ 0.5 | 近似对称 | 成绩分布均衡 |
| 偏度 > 0.5 | 右偏(低分多) | 试卷偏难,或教学效果整体不佳 |
| 偏度 < −0.5 | 左偏(高分多) | 试卷偏易,区分不足 |
| 峰度 ≈ 0 | 接近正态 | 理想 |
| 峰度 < 0(实测 −1.15) | 平坦分布 | 分数分散、两极分化明显 |
| 峰度 > 0 | 尖峰分布 | 分数集中,区分度普遍偏低 |

> 偏度/峰度只是**正态性快评**,样本量小(< 30 人)时不稳定,
> 报告里必须写「仅供参考,样本量 ____ 人」。

#### 返回 JSON → 教师改进建议(决策表)

脚本只给题号列表,**「淘汰还是改编」这个判断由下面这张表决定,不能直接照搬『应淘汰』三个字**:

| JSON 字段 | 触发条件 | 先看什么 | 结论 |
|---|---|---|---|
| `weak_questions` | D < 0.20 | 看该题 P | ↓ 见下三行 |
| ↳ | | P ≥ 0.90(人人都对) | **淘汰或改造**:作为保底题保留,或改成有迷惑项的变式;不能原样复用 |
| ↳ | | P ≤ 0.30(人人都错) | **先查原因再决定**:① 题意是否有歧义 ② 是否超纲/未讲 ③ 时间是否够。<br>属①③ → **改编**(改表述/加时限)后复用;属② → 该题本身无效,**淘汰**并作为教学反思 |
| ↳ | | 0.30 < P < 0.90 但 D 低 | **重编选项**:典型原因是干扰项无人选(形同虚设)或选项有隐含提示。改干扰项后复用 |
| `hard_questions` | P ≤ 0.30 | 与 `weak_questions` 交叉看 | 同时 D 低 → 优先怀疑**题意不清/超纲**;D 高 → 题目有效但偏难,可保留在压轴位或降分 |
| `easy_questions` | P ≥ 0.90 | 与 `weak_questions` 交叉看 | 同时 D 低 → **确认为「白送分题」**,建议淘汰或提高难度;D 仍高 → 属正常保底题,保留 |

**给教师的落款写法(示例,必须留确认位)**:

> 第 5 题(满分 10 分):得分率 P = 0.92,区分度 D = 0.06,**判定为「白送分题」**。
> 高分组与低分组得分率几乎无差别,说明该题未能区分学生水平。
> 建议:本题可保留作为保底题,但下学期不宜再原样使用;建议改为在选项中加入「XX 与 YY 的混淆项」的变式。
> 【待教师确认:第 5 题处理方式 —— □保留作为保底题  □改编后复用  □淘汰出库】

#### 《试卷分析报告》怎么写

用 `docx_kit.py md` 从 Markdown 生成 docx。报告结构固定为九节:

1. **课程与考试基本信息** — 课程名/代码、开课单位、学期、授课对象、考试形式、考试时长、实考人数、命题教师
2. **命题依据与试卷结构** — 依据大纲章节、题型结构表(题型/题数/分值/占比)、双向细目表(知识点 × 认知层次 × 分值)
3. **成绩总体概况** — 直接抄「总体概况」表:平均分、标准差、最高/最低分、及格率、偏度、峰度
4. **分数段分布** — 直接抄「分数段分布」表 + 柱状图,并注明「分数段按占总分比例划分」
5. **逐题分析** — 抄「逐题分析」表(含 P、D、评价),高亮行在正文里用文字点名
6. **问题试题诊断与处理意见** — 逐题写诊断 + 处理建议(用上面的决策表),**每题带 `【待教师确认:处理方式】`**
7. **教学反思与改进措施** — 由分析结果倒推(如「第 6 题得分率 0.28,反映 XX 章节的 YY 概念讲解不足,下学期拟增加 Z」)
   —— **这一节的因果解释必须由教师确认,AI 只根据「题号 ↔ 知识点」的映射提出候选假设**
8. **命题改进建议** — 难度结构、分值配比、时间预算、A/B 卷等价性四方面的改进方向
9. **附表** — 附件清单,注明哪份含学生个人信息

**第 7 节的纪律**:不得写「因为教师讲得不透」这类对教师的评价性归因,
只写客观现象(「该题得分率偏低」)+ 候选原因清单,由教师自己选。

#### 生成与自检

```bash
# 报告正文(先写 md,再转 docx)
$PY skills/office-layer/scripts/docx_kit.py md \
    --in 试卷分析报告.md --out 试卷分析报告.docx \
    --title "2025-2026学年第一学期《XX》期末试卷分析报告"

# 自检:读回段落/表格/字数
$PY skills/office-layer/scripts/docx_kit.py inspect --in 试卷分析报告.docx
```

### 阶段四 · 归档材料

**输入**:阶段一~三的全部产出、学校的归档清单(可选)、平时成绩记录
**动作**:按下面栏目表生成材料,缺的数据一律留 `【待补:……】`
**输出**:四份归档件(见下)+ `归档材料清单.xlsx`
**退出条件**:清单逐项勾选完毕,且每份材料都标注了是否含个人信息

#### 材料 1 · 试卷审批表(docx)

```bash
$PY skills/office-layer/scripts/docx_kit.py md --in 试卷审批表.md --out 试卷审批表.docx --title "试卷审批表"
```

栏目:课程名称 / 课程代码 / 开课单位 / 学期 / 授课对象(专业·年级·班级)/ 考试形式(闭卷·开卷·机考)/
考试时长 / A·B 卷使用说明 / 命题教师(签名·日期)/ **命题依据**(大纲章节)/ **试题结构表**(题型·题数·分值·占比)/
**预估难度与预估用时** / 试题来源(自编·题库·改编,及比例)/ 参考答案与评分细则是否完备 /
**审核人意见**(签名·日期)/ **教研室主任意见**(签名·日期)/ **学院审批意见**(盖章·日期)/ 备注

> 签字栏一律留空并写 `【待补:签名】`、`【待补:日期】`,**AI 绝不代签、绝不代填日期**。

#### 材料 2 · 试卷分析报告(docx)

即阶段三的产出,九节结构见上。

#### 材料 3 · 平时分依据表(xlsx,用 `xlsx_kit.py build`)

先写规格 JSON,再 `build`:

```bash
cat > 平时分依据表.json <<'EOF'
{"sheets": [
  {"name": "平时分依据表",
   "header": ["学号","姓名","考勤(10)","作业(20)","课堂表现(10)","实验/实践(20)","小测(20)","平时分小计(100)","折算比例","计入总评","备注"],
   "rows": [["【待补:学号】","【待补:姓名】","","","","","","","","",""]],
   "widths": [14,10,10,10,12,14,10,14,10,10,20]}
]}
EOF
$PY skills/office-layer/scripts/xlsx_kit.py build --spec 平时分依据表.json --out 平时分依据表.xlsx
$PY skills/office-layer/scripts/xlsx_kit.py inspect --in 平时分依据表.xlsx     # 自检
```

栏目说明:各分项标题里的括号写满分值;`折算比例` 指平时分占总评的比例(如 30%);
`计入总评` 为折算后的分数;`备注` 写缓交/免修/特殊情况的依据。
**分项与权重以教师提供的课程考核方案为准**,AI 不得自拟权重,需在交付说明里请教师核对。

#### 材料 4 · 归档材料清单(xlsx)

| 序号 | 材料名称 | 文件名 | 格式 | 页数/行数 | 份数 | 是否含学生个人信息 | 存放位置 | 备注 |
|---|---|---|---|---|---|---|---|---|
| 1 | 试卷(A/B 卷) | 试卷A.docx / 试卷B.docx | docx | 【待补】 | 1 | 否(无姓名学号) | 试卷袋 | |
| 2 | 参考答案与评分细则 | 参考答案与评分细则.docx | docx | 【待补】 | 1 | 否 | 试卷袋 | |
| 3 | 试卷审批表 | 试卷审批表.docx | docx | 【待补】 | 1 | 否 | 试卷袋 | 待补签名 |
| 4 | 试卷审核意见 | 试卷A_审核意见.docx | docx | 【待补】 | 1 | 否 | 试卷袋 | 含原生批注 |
| 5 | 学生成绩登记表 | 成绩登记表.xlsx | xlsx | 【待补】 | 1 | **是** | 教务系统/密封 | 请注意保管 |
| 6 | 成绩分析 | 成绩分析.xlsx | xlsx | 【待补】 | 1 | 是(若未脱敏) | 【待补】 | 建议用脱敏版归档 |
| 7 | 试卷分析报告 | 试卷分析报告.docx | docx | 【待补】 | 1 | 否 | 试卷袋 | |
| 8 | 平时分依据表 | 平时分依据表.xlsx | xlsx | 【待补】 | 1 | **是** | 【待补】 | 请注意保管 |
| 9 | 试卷样卷(含学生答卷) | 【待补】 | 纸质 | 【待补】 | 【待补】 | **是** | 试卷袋 | 按学院要求抽取 |

## 脱敏(敏感数据处理,本技能的强制环节)

成绩、学号、姓名属个人信息。**默认走脱敏路径**:先在本地把成绩表匿名化,再交给分析脚本。

### 为什么要脱敏

`analyze` 在计算上**完全不需要姓名和真实学号** —— 它只要「若干道题的得分」。
把姓名带进分析链路没有任何收益,却让文件名、终端历史、中间产物全都染上个人信息。

### 脱敏怎么操作(已实测)

把原表转成「匿名 ID + 各题得分」的表,再做分析:

```bash
PY="skills/office-layer/.venv/bin/python"
export MPLCONFIGDIR=/tmp/mplcache && mkdir -p /tmp/mplcache

# 步骤 1:匿名化。id_col=学号列,first_q_col=第一题得分列
$PY - 成绩表.xlsx 成绩表_脱敏.xlsx 1 3 <<'PY'
import sys, openpyxl
src, out, id_col, first_q_col = sys.argv[1], sys.argv[2], int(sys.argv[3]), int(sys.argv[4])
wb = openpyxl.load_workbook(src, data_only=True)
ws = wb[wb.sheetnames[0]]
rows = list(ws.iter_rows(values_only=True))
nw = openpyxl.Workbook(); ns = nw.active; ns.title = "scores"
ns.append(["匿名ID"] + list(rows[0][first_q_col - 1:]))     # 丢弃姓名列,只留题号列
for i, r in enumerate(rows[1:], 1):
    if r is None or all(v is None or v == "" for v in r):
        continue
    ns.append([f"S{i:03d}"] + list(r[first_q_col - 1:]))
nw.save(out)
print(f"脱敏完成:{out}({ns.max_row - 1} 行,姓名与学号列已剔除)")
PY

# 步骤 2:用脱敏表分析(注意 first-q-col 变成了 2,因为只剩「匿名ID + 各题」两段)
$PY skills/office-layer/scripts/xlsx_kit.py analyze \
    --in 成绩表_脱敏.xlsx --out 成绩分析.xlsx \
    --id-col 1 --first-q-col 2 \
    --full-marks '[10,10,15,15,10,20,10,10]'
```

**实测验证**:同一份 40 人数据,脱敏前(`--first-q-col 3`)与脱敏后(`--first-q-col 2`)
返回的 `total_stats` 完全一致(mean 67.475、sd 16.814、skew 0.063、kurt −1.15),
`weak_questions` / `easy_questions` 均为 `["Q5"]` —— **脱敏不影响任何分析结论**。

脱敏前后 `--first-q-col` 会变(少了一列),这是最容易出错的地方,**必须重算这个参数**。

### 脱敏的六条纪律

1. **只在本机处理**。成绩表、答卷扫描件不上传到任何云端服务(含在线 OCR、在线翻译、在线表格)。
2. **先脱敏再分析**。原始含名表只在教师本机存在,分析链路只碰匿名表。
3. **报告里用匿名代号**。正文写「学生 S012」,不写姓名;举个体例子时说明「已匿名」。
4. **外发只发聚合结果**。给同事/教研室看的是平均分、得分率、区分度这类**聚合指标**,
   不发给逐人明细表。
5. **中间文件任务结束后删除**。清单:`成绩表_脱敏.xlsx`、`analysis.xlsx`、`scores.xlsx` 副本、
   以及转 docx 过程中产生的临时 md/json。交付时**主动提醒教师删除**,并给出具体文件清单。
6. **交付说明必须写明**:「本文件含学生个人信息,请注意保管」——
   每个含个人信息的交付物(成绩登记表、平时分依据表、未脱敏的成绩分析)都要带这一句。

> 若教师坚持用含名表分析:照做,但在交付说明里明确标注该文件含个人信息,
> 并提醒归档时使用脱敏版、原始表单独密封保管。

## 产出物

| 文件 | 阶段 | 内容 | 含个人信息 |
|---|---|---|---|
| `试卷A_审核意见.docx` | 一 | 试卷正文 + **Word 原生批注**(六张检查表的逐条意见) | 否 |
| `试卷B_审核意见.docx` | 一 | 同上 | 否 |
| `试卷审核检查表.xlsx` | 一 | 六张检查表逐项结论(通过/需修改/阻断) | 否 |
| `双向细目表.xlsx` | 一 | 知识点 × 认知层次 × 题型 × 分值 | 否 |
| `参考答案与评分细则.docx` | 二 | 题号/满分/得分点/分值/得分标准/常见错误扣分 表 | 否 |
| `成绩分析.xlsx` | 三 | 逐题分析 / 总体概况 / 分数段分布 + 两张柱状图 | 否(用脱敏表生成) |
| `试卷分析报告.docx` | 三 | 九节结构 + 逐题诊断与改进建议 | 否 |
| `试卷审批表.docx` | 四 | 审批栏目 + 签字位(留空待补) | 否 |
| `平时分依据表.xlsx` | 四 | 学号/姓名/各分项/小计/折算/计入总评/备注 | **是** |
| `成绩登记表.xlsx` | 四 | 学生成绩登记(若教师需要) | **是** |
| `归档材料清单.xlsx` | 四 | 9 项材料的完整性核对表 + 个人信息标注 | 否 |

所有文件产出**一律走 `skills/office-layer/`**,禁止文本框拼表格、禁止手写 OOXML、
禁止拿 `.md` 当交付物(除非教师明确只要 Markdown)。

## 红线

1. **不虚构学生数据**。成绩、学号、姓名只用教师提供的文件;缺则留
   `【待补:……】` 并向教师索要。**绝不生成看起来像真的成绩** —— 哪怕是为了"演示"。
2. **不替教师定分**。评分细则的分值分配、开放题给分尺度、问题试题的淘汰/改编决定、
   最终成绩判定,一律留 `【待教师确认:……】`。AI 只出草稿,不给终稿。
3. **不代签、不代填日期**。审批表所有签字栏与日期栏留 `【待补:签名】`/`【待补:日期】`。
4. **不引具体政策条款号**。只写「按学校/学院相关规定执行」并提示教师核对。
5. **敏感数据只在本机处理**。不上传、不外发;脱敏为默认路径;
   任务结束主动给出中间文件删除清单。
6. **交付说明必须含个人信息告知**。含个人信息的文件一律注明
   「本文件含学生个人信息,请注意保管」。
7. **不修改教师提供的原始材料**。所有过程文件放临时目录(如 `/tmp/`),
   不覆盖原试卷、原成绩表。
8. **`analyze` 的结论不等于教学质量评价**。区分度低只能说明「这道题没区分出学生水平」,
   **不得**据此写「教师教学效果差」这类归因;归因永远留给教师。
9. **不忽略非零退出码**。`docx_kit comment` 退出码 2 = 有锚点未命中,必须逐条修好再交付。

## 自检清单

**阶段一**
- [ ] 六张检查表是否逐项过完(等价性/覆盖面/难度分值/歧义/答案唯一/相互提示)
- [ ] 标记【阻断】的项是否已清零,或教师书面确认接受
- [ ] 时间预算是否算过,Σ预估用时 ≤ 考试时长 × 0.9
- [ ] 批注是否真的落盘(`docx_kit inspect` 的 `comments` 数 > 0)
- [ ] `comment` 命令退出码是否为 0(非 0 = 有锚点未命中)

**阶段二**
- [ ] 每题「得分点分值之和 = 该题满分」是否逐题核过
- [ ] 计算题是否写明「错误传导不重复扣分」和「其他正确方法同等给分」
- [ ] 论述题是否给出要点清单 + 逻辑分 + 表述分的三段配比
- [ ] 有争议的给分尺度是否都挂了 `【待教师确认:……】`

**阶段三**
- [ ] 是否用脱敏表分析(默认路径)
- [ ] `--first-q-col` 是否重算过(脱敏后列号会变)
- [ ] `--full-marks` 是否给了,且数组顺序与题目列一一对应
- [ ] 表尾若有总分/备注列,是否用 `--n-questions` 截断
- [ ] 返回 JSON 是否无 `error`,`students` 是否等于实考人数
- [ ] 三个工作表是否都在(逐题分析/总体概况/分数段分布)
- [ ] `weak_questions` / `hard_questions` / `easy_questions` 是否逐个翻译成了处理建议
- [ ] 样本量 < 30 人时,偏度峰度结论是否标注了「仅供参考」
- [ ] 是否**没有**写对教师教学效果的负面归因

**阶段四**
- [ ] 审批表签字栏与日期栏是否留空为 `【待补】`
- [ ] 平时分权重是否来自教师提供的考核方案(不是自拟)
- [ ] 归档清单是否逐项标注了「是否含学生个人信息」
- [ ] 含个人信息的交付物是否都带了「请注意保管」提示

**通用**
- [ ] 引用的 底座路径是否都用 `ls` 验证过存在
- [ ] 所有文件产出是否都走了 `skills/office-layer/` 的脚本
- [ ] 是否给出了中间文件删除清单
- [ ] 交付时是否明确说了「这是初稿,请重点核对 X/Y/Z」
  (特别是:参考答案、分值分配、问题试题处理方式、平时分权重)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.