Files
2026-06-06 05:21:10 +00:00

7.8 KiB
Executable File
Raw Permalink Blame History

name, description
name description
quiz-html 把题目数组生成一个**可独立运行的网页练习页**HTML 文件)。当用户完成 quiz-mastery 的「从资料出题」或「从文件提取题目」流程后,应主动询问是否需要"在网页里练习",确认后调用本 skill 把题目注入模板,生成 HTML 给用户。也支持用户直接说"把这些题做成网页/HTML/练习页"时触发。**不处理**:出题(→ quiz-mastery、评分→ quiz-mastery、长期复习计划→ study-buddy

网页题库生成器 (Quiz HTML Builder)

把一组题目 JSON → 一个单文件 HTML 练习网页,包含:

  • 📂 分类筛选(学科 / 子模块)+ 学习状态筛选(已掌握 / 未做 / 错题)
  • 🎯 4 种题型支持:选择 / 判断 / 填空 / 简答
  • 🤖 答题自动标记,错题自动归入错题本(首次错误给一次重试机会)
  • ⌨️ 完整键盘快捷键A/B/C/D · Enter · 方向键 · Space
  • 📝 模拟考模式(限时 + 一次性提交 + 成绩页)
  • 🌓 明暗主题切换 · localStorage 持久化 · 移动端适配

核心触发场景

场景 1quiz-mastery 出题/导入完成后主动询问

这是本 skill 的主要入口。当 quiz-mastery 完成以下任一流程:

  • 「从资料出题」:generate_from_material.py → 生成题目 JSON → service.import_questions() 入库
  • 「从题目文件提取」:import_quiz.py → 解析出题目 JSON → 入库

quiz-mastery 出题完成、向用户展示题目前,主动问一句

"题目准备好啦~ 要不要我把它们生成一个网页练习页?你可以在浏览器里慢慢做,错题会自动记下来,还能切换主题、模拟考试 🎯"

用户说"要 / 好 / 生成网页 / 来一个 / 嗯"任一肯定意思 → 调用本 skill。 用户说"不用 / 算了 / 直接在这里做" → 走原本的对话练习流程。

场景 2用户直接要求生成网页

触发关键词:

  • "把这些题做成网页"、"做个 HTML 练习页"、"生成一个题库网页"
  • "我想在浏览器里练"、"做个网页版"
  • "把题目导出成 HTML"

调用方式

一句话总结

python3 scripts/build_quiz_html.py <题目JSON文件> [--title "..." --open]

标准流程

  1. 拿到题目 JSON(数组,每项是一道题)

    • 来源 Aquiz-mastery 出题后的 LLM 输出(系统已是标准格式)
    • 来源 B用户直接粘贴的题目数组
    • 来源 C从数据库读取的题目quiz-mastery 的 data/sessions/<sid>/questions.json
  2. 写到临时 JSON 文件

    import json, tempfile
    from pathlib import Path
    tmp = Path(tempfile.mkdtemp()) / "questions.json"
    tmp.write_text(json.dumps(questions, ensure_ascii=False), encoding="utf-8")
    
  3. 调用脚本

    python3 ~/Desktop/studybuddy_4.0/skills/quiz-html/scripts/build_quiz_html.py \
        /tmp/xxx/questions.json \
        --title "📚 物理 · 热学练习" \
        --output ~/Desktop/quiz_物理热学_20260518.html \
        --open
    
  4. 解析返回 JSON

    {
      "success": true,
      "output_path": "/Users/.../quiz_xxx.html",
      "question_count": 8,
      "title": "📚 物理 · 热学练习",
      "subtitle": "共 8 题 · 选择×5 · 判断×2 · 填空×1 · 物理",
      "id": "q_1779091201",
      "size_bytes": 63752
    }
    
  5. 告诉用户:把 HTML 路径报给用户,提示「已经在浏览器打开了,可以开始练啦

题目 JSON 字段标准

完全兼容 quiz-mastery 输出格式,新增可选字段 category / memory_tip

字段 必填 说明
type single_choice / true_false / fill_blank / short_answer
prompt 题干。也兼容 question 字段(自动转换)
options 选择题必填 ["A. xxx", "B. yyy", ...]
answer 选择题填字母;判断题填 "True"/"False";填空/简答填文本
explanation 推荐 解析强烈建议填K12 学生需要)
knowledge_point 推荐 知识点名(侧边栏二级分组用)
category 推荐 分类路径,用"学科 / 子模块"格式"物理 / 电学""数学 / 分数"
level 可选 难度 1-3
memory_tip 可选 记忆口诀会用橙色卡片高亮显示K12 神器)

示例

[
  {
    "type": "single_choice",
    "prompt": "下列关于并联电路电流规律的说法,正确的是(    )。",
    "options": [
      "A. 干路电流等于各支路电流之差",
      "B. 干路电流等于各支路电流之和",
      "C. 各支路电流相等",
      "D. 干路电流大于任一支路电流的两倍"
    ],
    "answer": "B",
    "explanation": "并联电路中,**干路电流等于各支路电流之和**I = I₁ + I₂ + ...",
    "knowledge_point": "并联电路电流规律",
    "category": "物理 / 电学",
    "level": 1,
    "memory_tip": "🧠 并联看路口:进多少、出多少,电流不会消失"
  }
]

设计原则

1. 自动 category让筛选有意义

如果题目缺 category 字段,最好补上(哪怕基于学科推断)。否则所有题都堆到"通用"分类下,分类筛选就废了。

2. category 用"学科 / 子模块"

  • "物理 / 电学""物理 / 热学" → 顶部出 4 个细分类 chip
  • "物理" → 只出 1 个,子模块在侧栏体现,但筛选粒度变粗

3. 知识点和分类不是同一层

  • category = 横向分类(哪个学科/章节),用于顶部 chips 筛选
  • knowledge_point = 细粒度知识点,用于左侧栏二级分组

4. 输出文件命名

默认输出到题目 JSON 同目录,文件名 quiz_<title_slug>_<时间戳>.html建议显式传 --output,放到 ~/Desktop/ 或一个固定目录方便用户找。

工作示例quiz-mastery 衔接全流程)

# 1. quiz-mastery 已完成出题,拿到题目数组
questions = [
    {"type": "single_choice", "prompt": "...", "options": [...], "answer": "A",
     "explanation": "...", "knowledge_point": "...", "category": "物理 / 电学"},
    # ...
]

# 2. agent 问用户:"要不要做成网页版?"
# 3. 用户:"要"
# 4. agent 写临时文件 + 调用 skill

import json, subprocess, tempfile
from pathlib import Path

tmp_dir = Path(tempfile.mkdtemp(prefix="quiz_"))
qjson = tmp_dir / "questions.json"
qjson.write_text(json.dumps(questions, ensure_ascii=False), encoding="utf-8")

output = Path.home() / "Desktop" / "quiz_物理电学.html"

result = subprocess.run([
    "python3",
    str(Path.home() / "Desktop/studybuddy_4.0/skills/quiz-html/scripts/build_quiz_html.py"),
    str(qjson),
    "--title", "📚 物理 · 电学练习",
    "--output", str(output),
    "--open",
], capture_output=True, text=True)

info = json.loads(result.stdout)
# info["output_path"] = "/Users/.../Desktop/quiz_物理电学.html"

然后告诉用户:

「已经做好啦~ 网页已自动打开 路径:~/Desktop/quiz_物理电学.html 慢慢做,做完会自动记录错题,下次可以筛"错题"专门攻克 💪

与其他 skill 的边界

任务 用谁
从资料出题 quiz-mastery
从文件提取题目 quiz-mastery
评分、掌握度追踪、艾宾浩斯安排 quiz-mastery
把题目做成网页给用户在浏览器练 quiz-html(本 skill
学习计划、长期跟进 study-buddy

失败处理

  • exit 1:参数错误 / 文件不存在 / 模板缺失 → 报错给用户,让用户检查路径
  • exit 2JSON 格式问题 / 题目数据非法 → 告诉用户哪几题被跳过,提示检查字段
  • 部分题被 skip 但有合法题:仍会成功生成,但 stderr 会列出被跳过的题,需要在回复里告知用户「跳过了 N 题,原因 XXX」