PDF to Quiz
核心价值:传 PDF → 出 JSON → 渲染 HTML,全自动,一键完成。
端到端使用流程
用户提供 PDF 路径后,必须先确认需求再开工,按以下顺序执行:
Phase 0: 确认需求(必须执行,不可跳过)
在提取 PDF 之前,用 AskUserQuestion 工具询问以下配置。
第一轮:题型 + 题量:
{
"questions": [
{
"question": "需要哪些题型?",
"header": "题型",
"multiSelect": true,
"options": [
{"label": "单选题", "description": "4选1,考察知识记忆"},
{"label": "多选题", "description": "多选,考察综合理解"},
{"label": "判断题", "description": "正误判断,考察概念辨析"},
{"label": "填空题", "description": "关键词填空,考察术语和定义"}
]
},
{
"question": "生成多少道题?",
"header": "题量",
"options": [
{"label": "20 道(快速测试)", "description": "适合快速摸底"},
{"label": "50 道(标准练习)(Recommended)", "description": "覆盖核心知识点"},
{"label": "100 道(完整题库)", "description": "全面覆盖,适合正式备考"}
]
}
]
}
第二轮:考试倒计时(题型和题量确认后):
{
"questions": [
{
"question": "是否需要考试倒计时?",
"header": "计时",
"options": [
{"label": "不需要(练习模式)(Recommended)", "description": "无时间限制,适合学习"},
{"label": "60 分钟", "description": "模拟正式考试节奏"},
{"label": "120 分钟", "description": "长考模式,适合题量较大时"}
]
}
]
}
根据用户选择构建 prompt 参数:
- 题型 → 动态生成 type_mix_instruction。全选时:"Mix question types: approximately 40% single_choice, 20% multi_choice, 20% true_false, 20% fill_blank";部分选择时:"Only generate these types: {selected_types}, approximately {ratios}"
- 题量 → 提取数字作为 {count},同时作为 meta.total_questions
- 倒计时 → 提取分钟数传给 render_quiz.py --exam N。选"不需要"则不传 --exam
确认后立即进入 Phase 1,不要再次确认。
Phase 1: 提取 PDF 文本
两套方案,按优先级:
优先:opendataloader-pdf(复杂 PDF,含表格/图表)
调用 Skill 工具加载 opendataloader-pdf,按它的指令提取 PDF 为 Markdown。保留表格结构和格式。
备选:pdf_extract.py(简单文本型 PDF)
python scripts/pdf_extract.py <pdf_path> --output <output.txt>
纯 Python (pypdf),输出清洗后纯文本。脚本位于 skill 目录的 scripts/pdf_extract.py。
将提取结果保存为临时文件。
Phase 2: 生成习题 JSON
参考 references/prompt_guide.md 中的 prompt 模板和 JSON schema。
关键步骤:
1. 读取 prompt_guide.md 获取格式规范和 system prompt
2. 将 PDF 文本嵌入 prompt
3. 要求 LLM 只输出纯 JSON(无 markdown fence)
4. 保存至 <pdf名称>_quiz.json
JSON 题型(schema 详见 prompt_guide.md):
| 题型 | type 值 | answer 格式 | options |
|---|---|---|---|
| 单选题 | 单选 或 single_choice |
"B" |
4 个选项 |
| 多选题 | 多选 或 multi_choice |
["A","C"] |
4+ 选项 |
| 判断题 | 判断 或 true_false |
true/false |
无需 options |
| 填空题 | 填空 或 fill_blank |
["关键词"] |
无需 options |
质量要求(必须遵守):
- 干扰项必须合理,不能明显错误
- 解析必须引用原文内容
- 四种题型混合(约 40% 单选、20% 多选、20% 判断、20% 填空)
- 题目均匀覆盖全文档,不集中在开头
- 每道题都必须有 explanation 字段
验证:检查 JSON 是否包含 meta.title、meta.total_questions,以及每题 id/type/stem/answer/explanation 字段。
Phase 3: 渲染交互式 HTML
python scripts/render_quiz.py <quiz.json> --output <quiz.html> [--exam 120]
scripts/render_quiz.py 位于本 skill 目录下,运行时解析为 skill 安装路径。
参数说明:
- --exam N:启用考试模式,N 分钟倒计时
- --no-exam:强制练习模式(无计时器)
- 不带参数时默认练习模式
HTML 功能:
- 单题卡片视图,左右键切换
- 考试模式:倒计时器(最后 10 分钟警告,最后 5 分钟闪烁)
- 题号导航网格(展开/收起),已答/未答/对/错四色标记
- 题型标签页(全部/单选/多选/判断/填空)
- 筛选器(全部/未答/错题)
- localStorage 断点续答,刷新页面不丢进度
- 提交后显示分数面板 + 每题解析
- 重新作答按钮
- 移动端响应式
Phase 4: 交付
输出目录:当前工作目录下的 quiz_output/<日期>_<PDF名称>/
交付文件:
- *_quiz.json — 标准化题库,可复用、可存档
- *_quiz.html — 自包含交互试卷
用 preview_url 展示 HTML,用 deliver_attachments 交付两个文件。
依赖
| 依赖 | 类型 | 说明 |
|---|---|---|
pypdf |
Python 包 | pdf_extract.py 的 PDF 解析库,运行 pip install pypdf |
opendataloader-pdf |
可选 Skill | 复杂 PDF(含表格/图表)的增强提取。未安装时自动降级到 pdf_extract.py |
无外部 API、无云服务依赖。
JSON 生命周期
同一份 JSON 可以:
- 用任意版本 quiz_template.html 重新渲染(换皮肤、加功能)
- 导出为 Anki apkg(未来扩展)
- 用其他工具渲染成 Markdown/PDF/Word 试卷
- 作为题库存档,换科目只需换 JSON
脚本
scripts/pdf_extract.py— PDF 纯文本提取(pypdf)scripts/render_quiz.py— JSON → 交互式 HTML,支持--exam模式
资源
assets/quiz_template.html— 自包含 HTML 模板,支持考试模式 + 题号导航 + 断点续答 + 错题筛选references/prompt_guide.md— LLM 出题 prompt 工程 + JSON schema 规范