d3cba0e23c
- 纯 HTML/CSS/JS 单页应用,支持填空题和选择题交互 - 5 个主题共 100 道题(GC/JVM、AI 结构化输出、记忆管理、幻觉、工具链) - 按主题组织、按题型拆分的 JSON 数据结构 - JSON Schema 校验 + 提示词模板 + 题型模板 - 自定义导入功能(粘贴/上传 JSON) - 项目文档(需求 + 架构) Co-Authored-By: Claude Code <noreply@anthropic.com>
12 KiB
12 KiB
架构文档
1. 系统总览
┌─────────────────────────────────────────────────────┐
│ 用户浏览器 │
│ ┌───────────────────────────────────────────────┐ │
│ │ index.html (单文件 SPA) │ │
│ │ ┌─────────┐ ┌──────────┐ ┌─────────────┐ │ │
│ │ │ 导航栏 │ │ 做题区域 │ │ 导入模态框 │ │ │
│ │ └────┬────┘ └─────┬────┘ └──────┬──────┘ │ │
│ └───────┼─────────────┼──────────────┼──────────┘ │
└──────────┼─────────────┼──────────────┼─────────────┘
│ fetch │ fetch │ JSON.parse
▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ topics/ (数据层) │
│ ├── index.json ← 主题索引 │
│ └── {topic-slug}/ │
│ ├── meta.json ← 主题元信息(稳定) │
│ ├── fill_blank.json ← 填空题集 │
│ └── single_choice.json ← 单选题集 │
└─────────────────────────────────────────────────────┘
▲
│ git push / pull
▼
┌─────────────────────────────────────────────────────┐
│ Agent / LLM (生成层) │
│ ├── Claude Code Skill (generate / validate) │
│ ├── LLM + 提示词模板 (schema/prompt-template.md) │
│ └── JSON Schema 校验 (schema/question.schema.json) │
└─────────────────────────────────────────────────────┘
2. 目录结构
examination/
├── index.html # 前端入口(单文件 SPA)
├── topics/ # 题目数据
│ ├── index.json # 主题索引
│ └── {topic-slug}/ # 主题目录
│ ├── meta.json # 主题元信息
│ ├── fill_blank.json # 填空题
│ ├── single_choice.json # 单选题
│ ├── multiple_choice.json # 多选题(可选)
│ ├── true_false.json # 判断题(可选)
│ ├── short_answer.json # 简答题(可选)
│ ├── code_reading.json # 代码阅读题(可选)
│ └── scenario.json # 场景分析题(可选)
├── schema/ # Schema 与模板
│ ├── question.schema.json # 题目 JSON Schema(Draft-07)
│ ├── prompt-template.md # LLM 生成提示词模板
│ └── templates/ # 各题型示例
│ ├── single_choice.json
│ ├── multiple_choice.json
│ ├── true_false.json
│ ├── fill_blank.json
│ ├── short_answer.json
│ ├── code_reading.json
│ └── scenario.json
├── docs/ # 文档
│ ├── requirements.md # 需求文档
│ └── architecture.md # 架构文档(本文件)
├── .gitignore # 排除 .ref/
└── README.md
3. 数据模型
3.1 主题索引 — topics/index.json
{
"version": "1.0.0",
"updated": "2026-09-02",
"topics": [
{
"slug": "gc-jvm",
"name": "GC / JVM / 三色标记",
"description": "...",
"path": "topics/gc-jvm",
"stats": {
"total": 20,
"by_type": { "fill_blank": 10, "single_choice": 10 }
}
}
]
}
前端加载此文件渲染主题列表,stats 字段用于展示题目数量。
3.2 主题元信息 — topics/{slug}/meta.json
{
"slug": "gc-jvm",
"name": "GC / JVM / 三色标记",
"description": "JVM 堆内存模型、GC 算法、三色标记法、垃圾收集器",
"tags": ["jvm", "gc", "heap"],
"difficulty_range": [1, 5],
"schema_version": "1.0.0",
"question_files": ["fill_blank", "single_choice"],
"stats": {
"total": 20,
"by_type": { "fill_blank": 10, "single_choice": 10 }
}
}
question_files列出该主题包含的题型文件名(不含.json后缀)- 前端根据此列表动态加载对应的题目文件
stats在每次生成/追加题目后由 Agent 更新
3.3 题目文件 — topics/{slug}/{type}.json
{
"topic": "gc-jvm",
"type": "fill_blank",
"schema_version": "1.0.0",
"generated": "2026-09-02T00:00:00Z",
"questions": [ /* 题目数组 */ ]
}
每种题型一个文件,支持多 Agent 并行写入不同题型文件而无冲突。
3.4 题目对象
公共字段(所有题型必有)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
string | ✅ | 格式 {type_short}-{seq},如 fb-001 |
type |
enum | ✅ | 题型标识 |
difficulty |
integer | ✅ | 1-5 |
tags |
string[] | ✅ | 细粒度知识点标签 |
question |
string | ✅ | 题干 |
explanation |
string | ✅ | 解析 |
source |
string | ❌ | 来源 |
related |
string[] | ❌ | 关联题目 id |
填空题 (fill_blank)
{
"answer": ["老", "Old"],
"answer_rule": "any"
}
answer: string[],可接受的答案列表answer_rule:"any"(任一匹配) |"all"(全部匹配) |"ordered"(按序匹配)
单选题 (single_choice)
{
"options": { "A": "选项A", "B": "选项B", "C": "选项C", "D": "选项D" },
"answer": "B"
}
多选题 (multiple_choice)
{
"options": { "A": "...", "B": "...", "C": "...", "D": "..." },
"answer": ["A", "C"]
}
判断题 (true_false)
{ "answer": true }
简答题 (short_answer)
{
"answer": "参考答案文本",
"keywords": ["关键词1", "关键词2"],
"scoring_rubric": "评分标准说明"
}
代码阅读题 (code_reading)
{
"code": "int x = 1;\nprintf(\"%d\", x);",
"language": "c",
"sub_questions": [
{ "index": 1, "type": "single_choice", "question": "...", "options": {...}, "answer": "A", "explanation": "..." }
]
}
场景分析题 (scenario)
{
"context": "一个电商系统在高峰期出现超卖问题...",
"code": null,
"sub_questions": [
{ "index": 1, "type": "short_answer", "question": "...", "answer": "...", "keywords": [...], "explanation": "..." }
]
}
3.5 ID 编码规则
{type_short}-{sequence}
fb - 001
| type_short | 题型 |
|---|---|
sc |
single_choice |
mc |
multiple_choice |
tf |
true_false |
fb |
fill_blank |
sa |
short_answer |
cr |
code_reading |
sn |
scenario |
4. 前端架构
4.1 页面结构
┌──────────────────────────────────────────┐
│ Header: 🎯 CS 知识应试强化 │
├────────────┬─────────────────────────────┤
│ Sidebar │ Main Content │
│ │ │
│ 📚 主题 │ ┌─ Toolbar ──────────────┐ │
│ · gc-jvm │ │ 进度 ✅ ❌ ⏳ 按钮组 │ │
│ · ai-so │ └────────────────────────┘ │
│ · ai-mm │ ┌─ Progress Bar ─────────┐ │
│ · ai-he │ └────────────────────────┘ │
│ · ai-at │ ┌─ Question Card ────────┐ │
│ │ │ #1 填空 ★★★ │ │
│ ──────── │ │ 题干 [____] │ │
│ 📥 导入 │ │ [检查] [显示答案] │ │
│ │ │ 💡 解析... │ │
│ │ └────────────────────────┘ │
│ │ ┌─ Question Card ────────┐ │
│ │ │ ... │ │
│ │ └────────────────────────┘ │
└────────────┴─────────────────────────────┘
4.2 数据流
页面加载
│
▼
fetch topics/index.json ──→ 渲染侧边栏主题列表
│
│ 用户点击主题
▼
fetch topics/{slug}/meta.json ──→ 获取 question_files 列表
│
▼
fetch topics/{slug}/{type}.json (并行) ──→ 合并 questions 数组
│
▼
renderQuiz() ──→ 按题型渲染题目卡片
│
│ 用户交互(选择/输入/检查/显示答案)
▼
answers 状态更新 ──→ re-render ──→ 更新统计
4.3 状态管理
let topics = []; // 从 index.json 加载的主题列表
let currentTopic = null; // 当前选中的主题 slug
let currentQuestions = []; // 当前主题的所有题目(合并自多个题型文件)
let answers = {}; // qId → { value, correct, revealed }
let customQuestions = []; // 通过导入功能临时添加的题目
4.4 题型渲染逻辑
| 题型 | 渲染方式 | 判定逻辑 |
|---|---|---|
| fill_blank | 题干中的 ______ 替换为 <input> |
matchFillAnswer() 根据 answer_rule 匹配 |
| single_choice | 选项列表,radio 样式 | value === answer |
| multiple_choice | 选项列表,checkbox 样式 | 数组比较 |
| true_false | 两个大按钮 | value === answer |
| short_answer | <textarea> |
关键词匹配(辅助) |
| code_reading | 代码块 + 子题列表 | 按子题类型分别判定 |
| scenario | 场景描述 + 子题列表 | 按子题类型分别判定 |
5. 生成工作流
5.1 非 Agent 环境(手动 LLM 对话)
- 打开
schema/prompt-template.md,复制提示词模板 - 替换
{topic_name}、{question_type}、{count}等变量 - 将提示词发送给 LLM(ChatGPT / Claude 等)
- 获取 JSON 输出后,粘贴到对应题型文件中
- 更新
meta.json的stats字段 - 刷新前端页面
5.2 Agent 环境(Claude Code Skill)
/examination generate --topic gc-jvm --type fill_blank --count 10
/examination validate --file topics/gc-jvm/fill_blank.json
/examination batch-generate --topic gc-jvm --types fill_blank,single_choice
Skill 内部流程:
- 读取
meta.json获取主题上下文 - 调用 LLM 生成题目(使用 schema 约束)
- 校验输出是否符合
question.schema.json - 写入对应题型文件
- 更新
meta.json和index.json的stats
5.3 多 Agent 并行生成
Agent 1 ──→ topics/gc-jvm/fill_blank.json
Agent 2 ──→ topics/gc-jvm/single_choice.json
Agent 3 ──→ topics/gc-jvm/multiple_choice.json
由于每种题型写入独立文件,多个 Agent 可并行生成同一主题的不同题型而无写冲突。
6. 扩展指南
新增主题
- 创建
topics/{new-slug}/目录 - 创建
meta.json - 按题型创建题目 JSON 文件
- 更新
topics/index.json
新增题型
- 在
schema/question.schema.json的definitions.question.type.enum中添加新类型 - 添加对应的
allOf条件分支定义字段约束 - 在前端
typeLabel()中添加映射 - 在前端
renderQuestionCard()中添加渲染逻辑 - 在
schema/templates/中添加示例模板