# AI 助学与 AI 助评设计 ## 目标与范围 在学生实训任务页面增加两个独立的 AI 功能: - **AI 助学**:基于实训背景、目标、要求和学生当前作答,给出诊断、已有优点、待改进点和行动建议;不产生分数。 - **AI 助评**:基于相同信息自主形成 3 至 5 个评价维度,给出百分制整数分数、维度得分与依据、总体评语、优点和改进建议。 本期不接入成绩中心。助评成功时,只将结果同步到用户-任务作答记录的 `ai_assessment_score` 字段。 每个学生在每个实训任务中,AI 助学和 AI 助评各成功使用一次。两项功能的结果均需持久化;学生之后修改答案不影响已生成的报告与分数。 ## 现有上下文 - 后端:`link_commerce`,Java/Spring Boot/MyBatis。 - 前端:`e-commerce-internet`,Vue;公共实训页为 `src/views/training/GenericTrainingPage.vue`。 - 用户-任务作答记录:`student_training_answer`,对应 `StudentTrainingAnswer`,已保存学生、教学班、任务和步骤答案。 - 大模型:千问。服务端调用,前端不得接触 API Key。 ## 数据设计 新增 `ai_training_evaluation` 表。每条记录对应一个学生在一个教学班的一个实训任务,包含该任务的一次助学和一次助评。 ### 公共关联字段 - `id` - `student_user_id` - `teaching_class_id` - `task_id` - `task_key` - `create_time`、`update_time` 以 `(student_user_id, teaching_class_id, task_key)` 建立唯一索引,用于并发保护和保证每任务仅一条 AI 评价记录。 ### 助学字段 - `help_status`:`NOT_STARTED`、`PROCESSING`、`SUCCEEDED`、`FAILED` - `help_task_snapshot`:任务背景、目标和要求的 JSON 快照 - `help_answer_snapshot`:调用时的四步答案 JSON 快照 - `help_report_json`:结构化助学报告 - `help_raw_response`:千问原始响应,仅用于故障排查 - `help_model`、`help_completed_at`、`help_error_message` ### 助评字段 - `assessment_status`:与助学相同的状态集 - `assessment_task_snapshot`、`assessment_answer_snapshot` - `assessment_score`:0 至 100 的整数 - `assessment_report_json`:结构化助评报告 - `assessment_raw_response`、`assessment_model`、`assessment_completed_at`、`assessment_error_message` 在 `student_training_answer` 新增可空整数字段 `ai_assessment_score`。仅当 AI 助评调用成功且结果通过校验后回写此字段。 ## 接口设计 - `GET /api/student/training-tasks/{taskKey}/ai-evaluation`:返回当前学生该任务的助学、助评状态及已保存报告。 - `POST /api/student/training-tasks/{taskKey}/ai-evaluation/help`:生成或返回 AI 助学报告。 - `POST /api/student/training-tasks/{taskKey}/ai-evaluation/assessment`:生成或返回 AI 助评报告和分数。 所有接口依据登录态确定学生身份,并验证任务属于该学生所在教学班。请求体不接受用户 ID、任务内容或答案,后端自行读取当前任务与作答记录,以避免客户端篡改评价输入。 调用前必须至少存在一项非空步骤答案;否则返回明确的业务错误。 ## 调用流程与幂等性 1. 后端鉴权,读取任务和当前作答,校验至少填写了一项答案。 2. 以用户、教学班、任务键获取或创建 `ai_training_evaluation` 记录。 3. 对所调用的功能检查状态:`SUCCEEDED` 直接返回已保存报告;`PROCESSING` 返回处理中;`NOT_STARTED` 或 `FAILED` 原子地置为 `PROCESSING`。 4. 将本次任务内容和四步答案序列化为不可变快照。 5. 在数据库事务外调用千问,避免长连接占用事务;完成后再更新该功能对应的状态和结果。 6. 响应格式、分数和维度校验通过后置为 `SUCCEEDED`;助评同时回写 `student_training_answer.ai_assessment_score`。 7. 超时、供应商错误、模型返回非预期 JSON 或校验失败时置为 `FAILED` 并保存有限长度错误信息,不写成绩;学生可重试该功能。 唯一索引与状态条件更新共同保证双击或并发请求最多产生一次有效模型调用。失败不消耗该项机会;成功后该项功能永久锁定。 ## 千问配置与输出契约 在后端 YAML 中配置 `ai.qwen` 的接口地址、模型、超时和 API Key。真实密钥放入本地 `application-local.yml`,该文件必须加入 `.gitignore`;提交的 `application.yml` 仅保留结构或环境变量占位符。 ### 助学 JSON ```json { "overallDiagnosis": "...", "strengths": ["..."], "improvementAreas": [{"area": "...", "feedback": "..."}], "recommendedActions": ["..."] } ``` ### 助评 JSON ```json { "score": 86, "overallComment": "...", "criteria": [ {"name": "...", "maxScore": 30, "score": 25, "rationale": "..."} ], "strengths": ["..."], "improvements": ["..."] } ``` 助评提示词要求模型自主生成 3 至 5 个适合该任务的评价维度;所有 `maxScore` 之和与所有 `score` 之和必须均为 100,`score` 为 0 至 100 的整数。后端负责二次校验。 ## 前端交互 在 `GenericTrainingPage` 增加统一 AI 操作区,适用于所有实训任务。 - 未填写任何步骤答案时,助学与助评按钮置灰,并提示“请至少填写一项答案后再使用”。 - 两个按钮分别展示“剩余 1 次”或“已使用”。 - 调用前显示确认框,明确告知会用当前答案创建不可更新的快照。 - 某项调用处理中,只锁定该项按钮;另一个功能仍可用。 - 助学成功后展示整体诊断、优点、待改进项和行动建议。 - 助评成功后展示总分、分项维度及得分、评分依据、优点和改进建议。 - 页面加载、刷新或重新进入任务时读取并展示已保存报告;成功的项目保持禁用。 - 失败时显示友好错误和重试入口,不显示不完整报告。 模型输出只作为普通文本/受控结构化数据渲染,禁止通过 `v-html` 直接注入模型文本。 ## 权限、错误处理与测试 - 学生只能读取和调用自己的任务记录;服务端不得信任客户端传入的用户、班级或任务内容。 - 原始模型输出仅用于受限故障排查,不返回前端;错误信息应截断并脱敏。 - 覆盖以下测试:未答题拦截、助学/助评分别限一次、失败可重试、并发只调用一次、答案修改后历史快照不变、助评成绩回写、权限隔离、响应校验和前端按钮状态。 ## 验收标准 同一学生在同一实训任务中可各成功生成一份助学和助评报告;助评显示 0 至 100 的整数总分和可解释的分项依据;两个报告和调用时答案快照在刷新后仍可读取;助评成绩已写入该用户-任务作答记录;前端与版本库均不含真实千问密钥。