docs: 结构化题目编辑器+应用题答案判分模式设计文档
题型联动表单替代 JSON 文本域(首发 judge/choice/fill/solve); 应用题新增 judgeMode=answer(最终答案数组+归一化匹配秒判),rubric AI 判分共存。 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 4.5
parent
88c2ee8c52
commit
8de35e85c2
@@ -0,0 +1,92 @@
|
||||
# 结构化题目编辑器 + 应用题答案判分模式 - 设计文档
|
||||
|
||||
日期:2026-08-20
|
||||
状态:已批准
|
||||
|
||||
## 背景
|
||||
|
||||
`/parent/exams/[paperId]` 编辑页目前用**裸 JSON 文本域**录入题目,家长需手写 quiz JSON 数组(曾明确拒绝结构化表单,现转向)。同时用户对应用题判分提出新模式:孩子拍照上传解题过程 + 填写最终答案来判定对错(替代/补充现有 AI 逐评分点判分)。
|
||||
|
||||
现状事实(grilling 确认):
|
||||
|
||||
- 现有 86 道种子题 = choice 48 + fill 30 + solve 8,**judge/order/match 零数据**。
|
||||
- solve 题现状:孩子拍照 → 百炼 Qwen-VL 按 rubric 评分点逐点判分(ai-grade.ts,无 key 演示回退),照片与逐点判定进错题本。
|
||||
- 孩子端 QuizBlock 已支持全部 6 题型答题 + 对错反馈;fill 题的参考答案本身是**数组**(answers)。
|
||||
- 现有 svaeEqxamPaper 的 validateQuestionsJson 已做形状校验。
|
||||
|
||||
## 需求(已与用户确认)
|
||||
|
||||
1. **结构化编辑器**:试卷题目改为逐题表单(题型联动字段),不再手写 JSON。题目卡片流:新增/编辑/删除/上移/下移。
|
||||
2. **首发四种题型**:判断题/选择题/填空题/应用题(judge/order/match 暂不做,有数据时后置)。
|
||||
3. **应用题新增判定模式** `judgeMode: "answer"`:家长只填**最终答案数组**(复用 fill 的 answers 语义)+ 分值;孩子拍照解题过程 + 填最终答案,**归一化匹配秒级判对错**,不调 AI。
|
||||
4. **共存**:现有 rubric 模式(AI 逐点评分)保留,存量 8 道题零改动(`judgeMode` 缺省 = rubric)。
|
||||
5. 孩子端此模式下:拍照必填(进错题本),最终答案判对错;对 = 满分,错 = 0 分(不做部分给分,可解释)。
|
||||
|
||||
## 方案选择
|
||||
|
||||
- **方案 A(采用):结构化表单产出仍是 QuizQ JSON,存储/孩子端渲染零schema改动**
|
||||
- 编辑 UI 从 JSON textarea 换成题型联动表单;服务端校验扩展 judgeMode 分支;判分在现有 child 提交链路内按 judgeMode 分流。
|
||||
- 方案 B(弃):引入独立"题目表"(questions 拆表)→ 迁移 86 题、错题本/组卷/判分全部重写,收益为零。
|
||||
- 方案 C(弃):AI 判最终答案(取代归一化)→ 有延迟、依赖 key、判定无法对孩子解释;归一化数组对家庭场景足够。
|
||||
|
||||
## 设计
|
||||
|
||||
### 1. QuizQ 扩展(src/lib/quiz-parse.ts)
|
||||
|
||||
```ts
|
||||
// solve 新增可选字段(缺省即 rubric 老模式,向后兼容):
|
||||
judgeMode?: "rubric" | "answer";
|
||||
// judgeMode==="answer" 时复用:
|
||||
answers?: string[]; // 最终答案数组(与 fill 同字段语义,等价答法都填)
|
||||
// points 两种模式下都必须(分值);reference 为展示用参考解答
|
||||
```
|
||||
|
||||
### 2. 归一化判定 lib(新建 src/lib/answer-match.ts)
|
||||
|
||||
```ts
|
||||
// xuchao: 答案等价判定——数值类归一化(分数/小数/百分数互转),文本类去空格/全角/大小写
|
||||
export function normalizeAnswer(s: string): string;
|
||||
export function answersMatch(expected: string[], given: string): boolean; // 任一期望答案等价即中
|
||||
```
|
||||
|
||||
- 纯数字语义(`1/2`→`0.5`、`50%`→`0.5`、`0.50`→`0.5`,去尾零)互转比较。
|
||||
- 含字母/单位词(如 `10个`、`across`)按文本归一(去空白、全角→半角、小写)严格比较;等价形式靠家长在答案数组里补填。
|
||||
- **fill 现有判分不动**(grammar.ts `gradeOne`:trim+小写精确匹配)——归一化仅用于 judgeMode==="answer" 的应用题,避免改变既有周测/记录判分行为。
|
||||
|
||||
### 3. 孩子端判分流(exam/actions.ts takeExam + QuizBlock)
|
||||
|
||||
- `takeExam` 中 solve 题分流:
|
||||
- `judgeMode==="answer"`:`answersMatch(q.answers, 孩子填的答案)` → score=points(对)/0(错);判定与照片写 `solveSnap`(`hits:[{ point:"最终答案", score, hit, reason }]`),照片 OSS 照常上传。
|
||||
- 缺省/`rubric`:走现有 ai-grade 逐点评分,零改动。
|
||||
- QuizBlock solve 分支:answer 模式下拍照必填 + 显示最终答案 Input;rubric 模式现状不变。
|
||||
- 错题本:**零改动**(solveSnap 结构兼容;answerText 已对 solve 显示拍照与得分)。
|
||||
|
||||
### 4. 家长端结构化编辑器(/parent/exams/[paperId] 重构)
|
||||
|
||||
- PaperForm 拆为:试卷 MetaForm(现有字段,不动)+ `QuestionList`(题目卡片区)。
|
||||
- QuestionList:
|
||||
- 每题卡片:题型徽标 + 题干摘要 + 操作(编辑/上移/下移/删除)。
|
||||
- 「+ 新增题目」按钮;题型下拉(judge/choice/fill/solve 四项)。
|
||||
- QuestionForm 按 type 联动:
|
||||
- **judge**:题干 + 解析 + 对/错单选
|
||||
- **choice**:题干 + 选项列表(增/删/编辑,单选正确答案)+ 解析
|
||||
- **fill**:题干 + 参考答案数组(增/删/编辑)+ 解析
|
||||
- **solve**:题干 + 分值 + judgeMode 开关(rubric → 评分点列表(point/score)+ 参考解答;/ answer → 最终答案数组 + 参考解答可选)+ 解析
|
||||
- 非法时客户端给出对应提示(与服务端同文案);保存仍走现有 `saveExamPaper`(JSON 序列化 QuizQ 数组)。
|
||||
- 服务端 validateQuestionsJson 扩展:
|
||||
- solve:rubric 模式沿用现行(reference + points 必填);answer 模式要求 `answers` 非空数组 + points 必填,reference 可选;answer 模式不得带 rubric。
|
||||
- 其余题型校验不变。
|
||||
|
||||
### 5. 不改动
|
||||
|
||||
- DB schema(quiz JSON 存储不变)、ai-grade.ts、错题本 WrongRow、积分/达标规则、周测组卷。
|
||||
- 孩子端之外:seed、overview、记录管理全不动。
|
||||
|
||||
## 测试清单(手工,项目无自动化测试框架)
|
||||
|
||||
1. 编辑页:JSON 文本域消失,题目卡片流可新增/编辑/删除/上下移/保存。
|
||||
2. 四种题型表单字段联动正确;应用题的 rubric/answer 开关切换字段正确。
|
||||
3. 新建 answer 应用题(答案 0.5 与 1/2 都填):孩子端拍照 + 填 `1/2` → 判对满分;填 `2/3` → 判错 0 分,错题本含照片与判定。
|
||||
4. 存量 rubric 题:孩子照旧拍照 AI 逐点评分,进错题本逐点判定。
|
||||
5. 服务端校验:answer 模式缺 answers / rubric 模式缺 reference → 对应报错不保存。
|
||||
6. 部署 jump.hn12301.net 后线上复验。
|
||||
Reference in New Issue
Block a user