ClareVoiceV1 / docs /AI_Interface_Design_v2.2.md
ghazariann's picture
feat: RAG pipeline overhaul — reranker, better retrieval, UX improvements
5eb6890
# Smart Quiz AI 接口规范
**版本**: v2.2
**日期**: 2026-04-01
**状态**: Draft
**描述**: 本文档详细定义了 Smart Quiz 后端与 AI 服务端的新版交互标准,重点增强了可追溯性、数据结构规范性和错误处理机制。
---
## 1. 变更摘要 (Change Log)
1. **全局**: 所有响应新增 `meta` 字段(模型信息、耗时、Token 消耗)。
2. **Quiz 生成**:
- 移除 `options[].is_correct`
- 新增 `question_id`
- 新增 `correct_answers` 数组(支持单选、多选、判断)。
- 明确短答题必须返回 `explanation`
3. **错误处理**: 标准化 4xx/5xx 响应结构,引入 `error.type``error.reason`
4. **Quiz 评分**: 新增 `per_question_feedback`,提供每题得分与理由。
5. **新增recipe 评分**:
智能出题变更:取消原 configurations 下的 questionCount和 questionTypes,新增configurations.recipe 对象。
若生成了 SHORT_ANSWER 题,除了必备的 explanation 外,响应选项中还要支持返回带有评分标准的 rubric(json)。
智能判卷变更:在请求的 userAnswers 每一项数组元素中,新增支持附加可选字段 rubric: Object。在给主观题打分时,会把出题接口接收到的这条 rubric 传过去
6. **单题即时判题流程补充**:
submit 升级为单题提交时,后端调用 grade 接口可仅传 1 条 `userAnswers`;最后一题完成后再触发一次整卷汇总调用,生成全局 `feedbackSummary/recommendations`。
---
## 2. 通用规范
### 2.1 Meta 信息 (Traceability)
所有 API 成功响应(2xx)必须包含 `meta` 字段,用于监控模型表现和成本。
**响应结构示例**:
```json
{
"data": { ... },
"meta": {
"model": "gpt-4-turbo", // 模型名称
"model_version": "2024-04-09",// 模型版本日期
"prompt_version": "v2.1", // Prompt 版本
"temperature": 0.4, // 采样温度
"tokens_used": 1250, // 总 Token 消耗 (Prompt + Completion)
"latency_ms": 3500 // 服务端处理耗时 (ms)
}
}
```
---
## 3. 接口详情
### 3.1 智能出题 (Generate Quiz)
**变更点**: 数据结构重构,强化校验能力。
- **URL**: `{AI_SERVICE_URL}/ai/quiz/generate`
- **Method**: `POST`
- **Auth**: `Authorization: Bearer {API_KEY}`
**请求参数 (Request)**:
```json
{
"requestId": "req_unique_id_123",
"context": {
"courseId": 101,
"moduleId": 5,
"topics": ["if-else", "loops"]
},
"configurations": {
"recipe": {
"SINGLE_CHOICE": 3,
"TRUE_FALSE": 0,
"MULTIPLE_CHOICE": 1,
"SHORT_ANSWER": 1
},
"language": "EN"
}
}
```
**请求参数说明 (Request Fields)**:
| 字段名 | 类型 | 必选 | 描述 |
| :------------------------ | :-------- | :--- | :------------------------ |
| `requestId` | `String` | 是 | 溯源 ID,用于日志追踪 |
| `context` | `Object` | 是 | 教学上下文信息 |
| `context.courseId` | `Integer` | 是 | 课程 ID (Traceability) |
| `context.moduleId` | `Integer` | 否 | 模块 ID (Traceability) |
| `context.topics` | `Array` | 否 | 精确的主题列表 |
| `configurations` | `Object` | 是 | 生成配置 |
| `configurations.recipe` | `Object` | 是 | 题目生成配方 (题型: 题数) |
| `configurations.language` | `String` | 是 | 题目语言 (CN/EN) |
**字段备注 (Field Notes)**:
- `configurations.recipe`:
- 规定 AI 应该生成的具体题型及与其对应的题目数量。AI 模型需严格遵守该配置出题,对于不需要生成的题型可传 0 甚至省略其键。后端负责将教师设定好的配比翻译为配方。
- `context.topics`:
- **后端生成逻辑**: 若指定 `moduleId`,系统自动检索该模块下所有 **Unit** 的标题作为主题列表;若未指定或模块无单元,默认为 `["general"]`
- **传输处理**: 数组元素会被拼接为逗号分隔的字符串 (e.g., "Variables, Data Types") 传递给 AI 模型。
**响应 (Response)**:
```json
{
"data": {
"questions": [
{
"question_id": "ai_q_8f9a2", // [新增] 唯一标识
"type": "SHORT_ANSWER",
"content": "Explain polymorphism in OOP.",
"options": [],
"correct_answers": ["Ability to take many forms"],
"explanation": "Polymorphism allows objects to be treated as instances of their parent class.",
"rubric": { // [新增] 题目专门的评分标准(可选)
"keywords": ["inherit", "override", "many forms"],
"max_score": 10
}
},
{
"question_id": "ai_q_7b3c1",
"type": "MULTIPLE_CHOICE",
"content": "Select mutable types.",
"options": [
{ "label": "A", "content": "List" },
{ "label": "B", "content": "Tuple" },
{ "label": "C", "content": "Dictionary" }
],
"correct_answers": ["A", "C"]
}
]
},
"meta": { ... }
}
```
**字段校验规则 (Backend Validation)**:
1. **SINGLE_CHOICE**: `correct_answers` 长度必须为 **1**。
2. **MULTIPLE_CHOICE**: `correct_answers` 长度必须 **≥ 1**。
3. **TRUE_FALSE**: 必须包含 2 个选项 (True/False),且 `correct_answers` 长度为 **1**。
4. **SHORT_ANSWER**: `options` 为空,必须包含有效 `explanation`(作为参考答案)。
---
### 3.2 智能判卷 (Grade Quiz)
**变更点**: 增加逐题反馈详情,并支持单题即时判题与完卷汇总。
- **URL**: `{AI_SERVICE_URL}/ai/quiz/grade`
- **Method**: `POST`
- **Auth**: `Authorization: Bearer {API_KEY}`
**请求参数 (Request)**:
```json
{
"requestId": "req_unique_id_456",
"quizContext": {
"title": "Python Quiz",
"totalScore": 10.0,
"maxScore": 100.0
},
"userAnswers": [
{
"questionId": "501",
"questionContent": "What is Python?",
"userChoiceLabel": "A",
"correctChoiceLabel": "A",
"isCorrect": true
}
]
}
```
**请求参数说明 (Request Fields)**:
| 字段名 | 类型 | 必选 | 描述 |
| :------------------------------ | :------- | :--- | :------------------------------- |
| `requestId` | `String` | 是 | 溯源 ID |
| `quizContext` | `Object` | 是 | 测验背景信息 |
| `userAnswers` | `Array` | 是 | 用户作答数据,用于生成针对性建议 |
| `userAnswers[].questionId` | `String` | 是 | 题目唯一标识(后端用于回写对应题目) |
| `userAnswers[].questionContent` | `String` | 是 | 题目内容文本 |
| `userAnswers[].userChoiceLabel` | `String` | 否 | 客观题:用户选择的选项标签 |
| `userAnswers[].correctChoiceLabel` | `String` | 否 | 客观题:标准答案选项标签 |
| `userAnswers[].isCorrect` | `Boolean`| 否 | 客观题:后端预判是否正确 |
| `userAnswers[].userTextAnswer` | `String` | 否 | 用户对主观题的回答文本 |
| `userAnswers[].referenceAnswer` | `String` | 否 | 标准/参考答案 |
| `userAnswers[].rubric` | `Object` | 否 | (可选) 评分标准(如需精细评分) |
#### 3.2.1 单题即时判题调用约定
- 后端在学生每提交一道题时调用本接口,`userAnswers` 数组长度固定为 `1`
- 客观题与主观题都允许走 AI 评分与说明生成。
- `per_question_feedback[].question_id` 必须回传并可映射到入参中的 `userAnswers[].questionId`
#### 3.2.2 完卷汇总调用约定
- 当最后一题提交完成后,后端会再次调用本接口做整卷汇总。
- 此时 `userAnswers` 为整卷全量答案,用于生成全局 `feedbackSummary/recommendations`
**完卷汇总请求示例(全量 `userAnswers`)**:
```json
{
"requestId": "req_quiz_final_789",
"quizContext": {
"title": "Python Quiz",
"totalScore": 80.0,
"maxScore": 100.0
},
"userAnswers": [
{
"questionId": "501",
"questionContent": "What is Python?",
"userChoiceLabel": "A",
"correctChoiceLabel": "A",
"isCorrect": true
},
{
"questionId": "502",
"questionContent": "Explain MVC.",
"userTextAnswer": "Model View Controller...",
"referenceAnswer": "Design pattern...",
"rubric": {
"keywords": ["Model", "View", "Controller", "Separation of concerns"],
"max_score": 10
}
}
]
}
```
#### 3.2.3 职责边界与失败处理
- AI 负责输出每题分数与说明(`score``reasoning`)。
- 后端对外响应中的 `isCorrect`(客观题)由标准答案稳定比对生成,避免波动。
- 当 AI 超时/5xx 时,不应阻止后端保存用户答案;后端可将该题标记为待补判并允许重试。
**响应 (Response)**:
```json
{
"data": {
"overall_score": 85,
"feedback_summary": "Good understanding of OOP concepts.",
"per_question_feedback": [ // [新增] 逐题反馈
{
"question_id": "ai_q_8f9a2",
"score": 10,
"reasoning": "Correct. Class is indeed the blueprint."
},
{
"question_id": "ai_q_9c4d2",
"score": 5,
"reasoning": "Partially correct. You missed the edge case."
}
],
"recommendations": [ ... ]
},
"meta": { ... }
}
```
---
### 3.3 智能提示 (Generate Hint)
后端调用此接口请求 AI 对单道题目生成解题提示(不泄露答案)。
- **URL**: `{AI_SERVICE_URL}/ai/quiz/hint`
- **Method**: `POST`
- **Auth**: `Authorization: Bearer {API_KEY}`
**请求参数 (Request)**:
```json
{
"requestId": "req_unique_id_789",
"questionContext": {
"content": "Which keyword stops a loop?",
"options": [
{ "label": "A", "content": "stop" },
{ "label": "B", "content": "break" }
]
},
"type": "HINT"
}
```
**请求参数说明 (Request Fields)**:
| 字段名 | 类型 | 必选 | 描述 |
| :------------------------ | :------- | :--- | :------------- |
| `requestId` | `String` | 是 | 溯源 ID |
| `questionContext` | `Object` | 是 | 题目上下文 |
| `questionContext.content` | `String` | 是 | 题目文本 |
| `questionContext.options` | `Array` | 是 | 选项列表 |
| `type` | `String` | 是 | 请求类型: HINT |
**响应参数 (Response)**:
```json
{
"data": {
"hint": "Think about the command that completely terminates the execution."
},
"meta": {
"model": "gpt-4-turbo",
"tokens_used": 50,
"latency_ms": 800
}
}
```
**响应字段说明 (Response Fields)**:
| 字段名 | 类型 | 描述 |
| :---------- | :------- | :---------------- |
| `data.hint` | `String` | AI 生成的提示文本 |
---
## 4. 标准错误处理 (Error Handling)
当 AI 服务无法完成请求时,必须返回标准化的错误结构(非 2xx/200 OK)。
**错误响应结构**:
```json
{
"code": 422,
"error": {
"type": "INVALID_GENERATION", // 错误大类
"reason": "multiple_correct_answers_for_single_choice", // 具体原因
"details": "Question ai_q_8f9a2 has 2 correct answers." // 可选详情
},
"meta": { ... } // 即使失败也尽量返回 meta 以排查 tokens
}
```
**标准错误码对照表**:
| HTTP Status | error.type | 场景描述 | 处理建议 |
| :---------- | :------------------- | :----------------------------------------------- | :------------------------------------------- |
| **422** | `INVALID_GENERATION` | AI 生成内容不符合 Schema (如单选多答、JSON 损坏) | 后端可尝试重试 (Retry) 1-2 次 |
| **429** | `RATE_LIMIT` | 超出并发或 Token 配额 | 后端需进行指数退避重试 (Exponential Backoff) |
| **500** | `MODEL_ERROR` | 模型服务内部崩溃 | 记录日志,向前端返回通用错误 |
| **504** | `TIMEOUT` | 生成超时 (如 > 60s) | 视场景重试或降级处理 |
**常见 422 reason**:
- `json_parse_error`: 输出不是有效的 JSON。
- `missing_field`: 缺少必填字段(如 `correct_answers`)。
- `schema_violation`: 数据结构违规(如单选题给了 2 个答案)。
---
## 5. 待办事项 (Future Work)
以下功能规划在后续版本实现:
1. **Difficulty Target**: 基于 Bloom's Taxonomy 的难度分级控制。
2. **Grading Rubric**: 支持自定义评分标准(Rubric)。
3. **Advanced Trace**: 关联 Session/User/Attempt 上下文。
4. **Pedagogy Hint Strategy**: 提供渐进式提示策略(Scaffolding)。
5. **User Content Summary**: 自动生成用户上传内容的摘要。