Files
examination/docs/architecture.md
T
wonder d3cba0e23c feat: 初始化 CS 知识应试强化系统
- 纯 HTML/CSS/JS 单页应用,支持填空题和选择题交互
- 5 个主题共 100 道题(GC/JVM、AI 结构化输出、记忆管理、幻觉、工具链)
- 按主题组织、按题型拆分的 JSON 数据结构
- JSON Schema 校验 + 提示词模板 + 题型模板
- 自定义导入功能(粘贴/上传 JSON)
- 项目文档(需求 + 架构)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-02 18:22:20 +08:00

357 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 架构文档
## 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`
```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`
```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`
```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`)
```json
{
"answer": ["老", "Old"],
"answer_rule": "any"
}
```
- `answer`: string[],可接受的答案列表
- `answer_rule`: `"any"`(任一匹配) | `"all"`(全部匹配) | `"ordered"`(按序匹配)
#### 单选题 (`single_choice`)
```json
{
"options": { "A": "选项A", "B": "选项B", "C": "选项C", "D": "选项D" },
"answer": "B"
}
```
#### 多选题 (`multiple_choice`)
```json
{
"options": { "A": "...", "B": "...", "C": "...", "D": "..." },
"answer": ["A", "C"]
}
```
#### 判断题 (`true_false`)
```json
{ "answer": true }
```
#### 简答题 (`short_answer`)
```json
{
"answer": "参考答案文本",
"keywords": ["关键词1", "关键词2"],
"scoring_rubric": "评分标准说明"
}
```
#### 代码阅读题 (`code_reading`)
```json
{
"code": "int x = 1;\nprintf(\"%d\", x);",
"language": "c",
"sub_questions": [
{ "index": 1, "type": "single_choice", "question": "...", "options": {...}, "answer": "A", "explanation": "..." }
]
}
```
#### 场景分析题 (`scenario`)
```json
{
"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 状态管理
```javascript
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 对话)
1. 打开 `schema/prompt-template.md`,复制提示词模板
2. 替换 `{topic_name}`、`{question_type}`、`{count}` 等变量
3. 将提示词发送给 LLM(ChatGPT / Claude 等)
4. 获取 JSON 输出后,粘贴到对应题型文件中
5. 更新 `meta.json` 的 `stats` 字段
6. 刷新前端页面
### 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 内部流程:
1. 读取 `meta.json` 获取主题上下文
2. 调用 LLM 生成题目(使用 schema 约束)
3. 校验输出是否符合 `question.schema.json`
4. 写入对应题型文件
5. 更新 `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. 扩展指南
### 新增主题
1. 创建 `topics/{new-slug}/` 目录
2. 创建 `meta.json`
3. 按题型创建题目 JSON 文件
4. 更新 `topics/index.json`
### 新增题型
1. 在 `schema/question.schema.json` 的 `definitions.question.type.enum` 中添加新类型
2. 添加对应的 `allOf` 条件分支定义字段约束
3. 在前端 `typeLabel()` 中添加映射
4. 在前端 `renderQuestionCard()` 中添加渲染逻辑
5. 在 `schema/templates/` 中添加示例模板