File size: 13,267 Bytes
5eb6890
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# 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**: 自动生成用户上传内容的摘要。