From 0fbdefb6264e217a9afc4201e6eb43c53489282f Mon Sep 17 00:00:00 2001 From: wonder Date: Wed, 2 Sep 2026 21:09:10 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=20README=EF=BC=8C?= =?UTF-8?q?=E5=88=A0=E9=99=A4=20docs/=20=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - README 重写:补充实际目录结构、当前题目清单、部署方式、设计原则 - 删除 docs/architecture.md 和 docs/requirements.md(内容已整合到 README) --- README.md | 125 +++++++++----- docs/architecture.md | 401 ------------------------------------------- docs/requirements.md | 87 ---------- 3 files changed, 79 insertions(+), 534 deletions(-) delete mode 100644 docs/architecture.md delete mode 100644 docs/requirements.md diff --git a/README.md b/README.md index fe5c4a5..e32cf1e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🎯 CS 知识应试强化系统 -基于纯 HTML + CSS + JS 的计算机科学知识应试训练平台。 +零依赖、纯前端的计算机科学知识应试训练平台。题目以 JSON 文件存储于 Git 仓库,通过单文件 SPA 提供交互式刷题体验。 ## 快速开始 @@ -10,69 +10,102 @@ python3 -m http.server 8080 # 浏览器打开 http://localhost:8080 ``` +无需安装任何依赖,无需构建步骤。 + ## 项目结构 ``` -├── index.html # 前端入口(单文件 SPA) -├── topics/ # 题目数据 -│ ├── index.json # 主题索引 -│ └── {topic-slug}/ -│ ├── meta.json # 主题元信息 -│ ├── fill_blank.json # 填空题 -│ └── single_choice.json # 单选题 -├── schema/ # JSON Schema 与模板 -│ ├── question.schema.json # 题目校验 Schema -│ ├── prompt-template.md # LLM 生成提示词模板 -│ └── templates/ # 各题型示例模板 -└── .ref/ # 参考数据(不提交 git) +├── index.html # 单文件 SPA(HTML + CSS + JS,约 1100 行) +├── topics/ # 题目数据 +│ ├── index.json # 主题索引(前端启动时加载) +│ └── qunar-ai-fullstack/ # 题目分组:去哪儿 AI 全栈面试 +│ ├── gc-jvm/ # GC / JVM / 三色标记 +│ ├── ai-structured-output/ # AI 结构化输出 / Agent 架构 +│ ├── ai-memory/ # Agent 记忆管理 / 冲突消解 +│ ├── ai-hallucination/ # AI 幻觉 / 评估体系 / 标准 +│ └── ai-tooling/ # AI 工具选型 / Harness / 综合 +├── schema/ # 数据规范 +│ ├── question.schema.json # JSON Schema(题目校验) +│ ├── prompt-template.md # LLM 生成提示词模板 +│ └── templates/ # 各题型示例模板(7 种) +├── Dockerfile # nginx:alpine 静态站点容器 +└── .gitea/workflows/deploy.yml # Gitea Actions 自动部署流水线 ``` -## 数据格式 - -每个主题是一个独立目录,包含: -- **meta.json** — 主题描述、标签、统计数据 -- **{题型}.json** — 按题型拆分的题目文件 - -题目文件顶层结构: -```json -{ - "topic": "gc-jvm", - "type": "fill_blank", - "schema_version": "1.0.0", - "questions": [...] -} -``` - -详见 [schema/question.schema.json](schema/question.schema.json)。 +每个子主题目录包含: +- **meta.json** — 主题元信息与题目文件列表 +- **fill_blank.json** — 填空题 +- **single_choice.json** — 单选题 ## 支持的题型 -| 题型 | 代码 | 说明 | -|------|------|------| -| 单选题 | sc | 4 选 1 | -| 多选题 | mc | 多选多 | -| 判断题 | tf | 对/错 | -| 填空题 | fb | 填写空白 | -| 简答题 | sa | 开放式回答 | -| 代码阅读 | cr | 阅读代码回答问题 | -| 场景分析 | sn | 分析技术场景 | +| 题型 | 代码 | 交互方式 | +|------|------|----------| +| 单选题 | `sc` | 点击选项,即时判定 | +| 多选题 | `mc` | 勾选多个选项 | +| 判断题 | `tf` | 对 / 错 二选一 | +| 填空题 | `fb` | 内联文本输入,支持模糊匹配 | +| 简答题 | `sa` | 开放式作答,关键词自检 | +| 代码阅读 | `cr` | 代码块 + 嵌套子问题 | +| 场景分析 | `sn` | 场景描述 + 嵌套子问题 | + +## 当前题目 + +| 子主题 | 题目数 | 覆盖内容 | +|--------|--------|----------| +| GC / JVM / 三色标记 | 20 | JVM 堆模型、GC 算法、三色标记、CMS/G1/ZGC、GC Roots | +| AI 结构化输出 / Agent 架构 | 20 | 结构化输出方法、ReAct/Reflexion 模式、约束解码 | +| Agent 记忆管理 / 冲突消解 | 20 | 记忆分层架构、淘汰策略、冲突检测与消解 | +| AI 幻觉 / 评估体系 / 标准 | 20 | 幻觉分类、Critic 架构、Context Engineering、RAG | +| AI 工具选型 / Harness / 综合 | 20 | 工具选型、Harness 架构、可靠性工程、效率分析 | + +> 共 5 个子主题,100 道题目(每主题 10 填空 + 10 单选)。 ## 添加新题目 -1. 在 `topics/` 下创建 `{topic-slug}/` 目录 +1. 在 `topics/{group-slug}/` 下创建 `{topic-slug}/` 目录 2. 创建 `meta.json`(参考已有主题) 3. 按题型创建 JSON 文件(参考 `schema/templates/`) 4. 更新 `topics/index.json` 5. 刷新页面即可 -## 使用 LLM 批量生成题目 -参考 [schema/prompt-template.md](schema/prompt-template.md) 中的提示词模板。 +## 使用 LLM 生成题目 -## 自定义导入 +每个题目卡片右上角有 **📋 复制提示词** 按钮,可将题目格式化为提示词复制到剪贴板,粘贴到任意 AI 工具获取解析。 -在页面侧边栏点击"📥 导入题目",可粘贴 JSON 或上传文件临时导入。 +批量生成参考 [schema/prompt-template.md](schema/prompt-template.md) 中的提示词模板,支持一次生成多个题型。 -## License +## 导入题目 -MIT +在页面侧边栏点击 **📥 导入题目**,可粘贴 JSON 或上传 `.json` 文件临时导入(仅当前会话有效)。 + +## 部署 + +### Docker + +```bash +docker build -t examination-site . +docker run -d -p 8080:80 examination-site +``` + +### Gitea Actions(自动) + +推送到 `main` 分支自动触发部署流水线,构建镜像并启动容器。 + +### 本地开发 + +任意静态文件服务器即可,无需 Node.js 或构建工具: + +```bash +python3 -m http.server 8080 +# 或 +npx serve . +``` + +## 设计原则 + +- **零依赖** — 纯 HTML + CSS + JS,无框架、无构建工具、无 npm +- **数据即代码** — 题目以 JSON 文件存储于 Git,版本可追溯 +- **单文件应用** — 整个前端在一个 `index.html` 中,便于部署和分发 +- **Meta/题目分离** — `meta.json` 稳定不变,题目文件按题型拆分,支持并行生成无冲突 \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md deleted file mode 100644 index 086396b..0000000 --- a/docs/architecture.md +++ /dev/null @@ -1,401 +0,0 @@ -# 架构文档 - -## 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": "qunar-ai-fullstack", - "name": "去哪儿 AI 面 — AI 全栈方向", - "description": "覆盖 JVM/GC、AI Agent 架构、工具链、幻觉治理等核心考察领域", - "subtopics": [ - { - "slug": "gc-jvm", - "name": "GC / JVM / 三色标记", - "description": "...", - "path": "topics/gc-jvm", - "stats": { "total": 20, "by_type": { "fill_blank": 10, "single_choice": 10 } } - } - ] - } - ] -} -``` - -- `topics[]` — 顶层主题列表,每个主题是一个手风琴(Accordion)分区 - - `slug` / `name` / `description` — 主题标识与展示信息 - - `subtopics[]` — 子主题列表,隶属于该顶层主题 - - `path` — 子主题数据目录路径 - - `stats` — 题目数量统计 -- 前端以 Accordion 形式渲染:默认全部折叠,同时只展开一个 - -### 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 │ -│ │ │ -│ ▼ 去哪儿.. │ ┌─ Tabs ─────────────────┐ │ -│ · gc-jvm │ │ 全部 | 填空 | 选择 |.. │ │ -│ · ai-so │ └────────────────────────┘ │ -│ · ai-mm │ ┌─ Toolbar ──────────────┐ │ -│ ▶ 其他主题 │ │ 重置 全部显示 提交全部 │ │ -│ │ └────────────────────────┘ │ -│ │ ┌─ Question Card ────────┐ │ -│ ──────── │ │ #1 [📋复制] ★★★ │ │ -│ 📥 导入 │ │ 题干 [____] │ │ -│ │ │ [检查] [显示答案] │ │ -│ │ │ 💡 解析... │ │ -│ │ └────────────────────────┘ │ -└────────────┴─────────────────────────────┘ - ▼ = 展开中 ▶ = 折叠中(Accordion 模式) -``` - -### 4.2 数据流 - -``` -页面加载 - │ - ▼ -fetch topics/index.json ──→ 渲染侧边栏 Accordion(默认全折叠) - │ - │ 用户展开某主题 + 点击子主题 - ▼ -fetch topics/{slug}/meta.json ──→ 获取 question_files 列表 - │ - ▼ -fetch topics/{slug}/{type}.json (并行) ──→ 合并 questions 数组 - │ - ▼ -renderQuiz() ──→ 渲染 Tab 栏 + 按当前 Tab 过滤题目卡片 - │ - │ 用户交互(选择/输入/检查/显示答案/切换 Tab/复制题目) - ▼ -answers / activeTab 状态更新 ──→ re-render - -复制题目流程: - 用户点击 [📋 复制题目] ──→ copyQuestionPrompt(qId) - ──→ 按题型组织提示词(题干 + 选项/代码/子问题) - ──→ navigator.clipboard.writeText() ──→ 按钮变为 ✅ 已复制 - -导入提示词流程: - 用户打开导入弹窗 ──→ 点击 [📋 复制 AI 生成提示词] - ──→ 选择题型 ──→ 预览提示词模板 ──→ 复制到剪贴板 - ──→ 粘贴到外部 AI ──→ 获取 JSON ──→ 粘贴回导入框 -``` - -### 4.3 状态管理 - -```javascript -// 题型配置(常量) -const QUESTION_TYPES = { - fill_blank: { label: '填空', color: '--type-fill_blank' }, - single_choice: { label: '选择', color: '--type-single_choice' }, - // ... -}; - -// 应用状态 -let topicGroups = []; // 顶层主题列表(含 subtopics) -let expandedGroup = null; // 当前展开的顶层主题 slug(Accordion) -let currentTopic = null; // 当前选中的子主题 slug -let currentQuestions = []; // 当前子主题的所有题目 -let answers = {}; // qId → { value, correct, revealed } -let customQuestions = []; // 通过导入功能临时添加的题目 -let activeTab = 'all'; // 当前 Tab:'all' 或题型名称 -``` - -### 4.4 题型配置与渲染 - -题型颜色通过 CSS 变量定义在 `:root` 中,新增题型只需: -1. 在 `QUESTION_TYPES` 添加配置 -2. 在 `:root` 添加 `--type-{name}` 变量 -3. CSS 自动生效(通过 `.q-card.type-{name}` 规则) - -| 题型 | 渲染方式 | 判定逻辑 | 边框颜色变量 | -|------|----------|----------|--------------| -| fill_blank | 题干中的 `______` 替换为 `` | `matchFillAnswer()` 根据 `answer_rule` 匹配 | `--type-fill_blank` | -| single_choice | 选项列表,radio 样式 | `value === answer` | `--type-single_choice` | -| multiple_choice | 选项列表,checkbox 样式 | 数组比较 | `--type-multiple_choice` | -| true_false | 两个大按钮 | `value === answer` | `--type-true_false` | -| short_answer | `