# 解答题拍照判分方案(设计决策记录) > 2026-08-06 用户授权:全部按推荐方案落地,无需逐项确认。本文档记录已确认的全部决策。 ## 一、目标 考试板块支持**数学解答题**(计算/解方程/应用题):孩子在纸上写完整解答过程,手机拍照上传,AI 视觉模型按评分点部分给分。首期试点一张**初一入学考(小升初分班考)卷**,现有 5 张月考卷不动。 ## 二、已确认决策(逐条) | # | 决策点 | 结论 | | --- | --- | --- | | 1 | 题型范围 | 困难档:解答题**过程判分**(不是只判最终答案) | | 2 | 作答输入 | **纸上手写 + 拍照**(不做屏幕手写、不做分步结构化输入) | | 3 | AI 模型 | **阿里云百炼 Qwen-VL**(qwen-vl-max),用户 Tokenplan 计费;经 OpenAI 兼容端点调用 | | 4 | 答题流程 | **混合模式**:客观题(选择/判断/填空)App 内作答;**解答题逐题拍照**,不做整页拍 | | 5 | 判分规则 | **部分给分 + 评分点(rubric)锚定**:AI 逐点评判,只能返回离散分数,不给自由打分权 | | 6 | 题目配图 | 原卷裁剪为主、SVG 兜底,存 `public/exam/<卷id>/`;几何题判分时**原图+孩子照片一起喂模型**。本期入学卷无图题 | | 7 | 内容生产 | **零人工**:抓卷/转录 → **双模型背靠背独立验算,不一致即丢弃**;本期因网络策略无法直抓教育站,内容改为**本地 Obsidian 数学素材 + 经典分班考题型按真实卷格式组卷**,已在试卷 summary 标注 | | 8 | 计分 | 分值跟随原卷;总分 = 客观题 + 解答题部分得分;**达标线保持 80%**;exam_record 存每题照片 URL + 评分点命中明细 | | 9 | 错题本 | v1 **只存不重做**:存题目 + 当时照片 + AI 评判 + 参考解答;保留手动"已掌握";重做重判放二期 | | 10 | 质量控制 | AI 返回状态:`ok / blank(空白) / blurry(模糊) / printed(印刷体拒判) / unrelated(无关内容)`;非手写拒判;**每人每天限 30 次判分**;客户端压缩照片 ≤2MB | | 11 | 时效 | 同步等待 + "AI 判分中"动画;失败自动重试 1 次,再失败允许单题重拍重交,不阻塞其它题 | | 12 | 范围 | 解答题只进考试板块;课时练习/周测暂不加 | ## 三、数据模型 ### QuizQ 扩展(`src/lib/quiz-parse.ts`) ```ts { type: "solve", stem: string, // 题干 figure?: string, // 配图路径(可选,本期不用) points: number, // 本题满分(分值跟随原卷) reference: string, // 完整参考解答(判后展示) rubric: { point: string; score: number }[], // 评分点,合计 = points explain: string // 讲解 } ``` ### 新表 `ai_grade_log`(迁移 0004) 判分审计 + 限频依据:child_user_id、paper_id、question_index、oss_key、status、earned、points、verdict(JSON:逐点命中+点评)、mock(是否演示判分)、created_at。 ### exam_record.answers 解答题条目:`{ type:"solve", qIndex, ossKey, earned, hits:[{point,score,hit,reason}] }`;客观题保持原样。**成绩以服务端 ai_grade_log 为准,不信任客户端上报的分数**(防篡改)。 ## 四、判分链路 ``` 孩子拍照 → 客户端压缩(≤2MB,canvas) → 服务端签发 OSS 直传 URL → PUT OSS → gradeSolve action:校验会话/限频(30/天) → 调百炼 Qwen-VL prompt = 题干 + (原图) + 参考解答 + 评分点 + 孩子照片 → 结构化 JSON:{status, hits:[{hit,reason}], earned, comment} → 写 ai_grade_log → 返回前端即时显示逐点得分 → 全卷提交 takeExam:客观题即时判 + 解答题取 ai_grade_log 最近一次 ok 判定 → 总分百分制,≥80 达标,错题(含照片)进 wrong_book,达标联动数学打卡 ``` - **无 DASHSCOPE_API_KEY 时进入演示判分(mock)**:返回确定性模拟判定并标记 `mock=true`,供本地开发/测试;生产必须在服务器 .env 配置真 key。 - OSS 未配置时(本地开发)走 `/api/dev-photo` 本地落盘回退,不影响生产。 ## 五、内容来源说明(本期入学卷) 本 session 网络策略拦截了对教育网站(学科网/组卷网/瑞文/51test 等)的直接抓取,无法获取原始真实卷页面。本期入学卷改为:**按真实分班考的卷面结构(填空+选择+计算+应用,满分 100)** 组卷,题目取自本地 Obsidian 数学素材库的经典题型(鸡兔同笼、工程、分数百分数、行程等,均带验算)。`sourceUrl` 置空并在 `summary` 注明。待网络恢复后可用同流程替换为真实卷转录。 ## 六、上线前待办(需用户) 1. 百炼控制台开通/确认 Tokenplan 覆盖 `qwen-vl-max`,取 API Key; 2. 服务器 `/opt/services/superjump/.env` 增加 `DASHSCOPE_API_KEY=...`,重建容器; 3. 跑 `npm run db:seed-exam` 灌入新卷(容器重建时自动 migrate)。