docs: 更新出题批题后端对接指南 v1.2 — 同步实际行为
- 移除20题上限说明,改为无上限+50题警告 - 修正文件/向量库不存在时的响应格式(total=0,非404) - 添加认证模式说明(生产模式直接放行) - 添加智能出题接口文档(/exam/generate-smart) - 添加填空题student_answer格式校验说明 - 更新错误码表,移除不存在的FILE_NOT_FOUND - 添加Q5/Q6常见问题 - 响应示例修正status_code为2020
This commit is contained in:
@@ -8,6 +8,11 @@
|
||||
| `/exam/generate-smart` | POST | 生成题目(AI 自动分析文档结构出题) | 120秒 |
|
||||
| `/exam/grade` | POST | 批阅答案 | 60秒 |
|
||||
|
||||
> **2026-07-03 变更**:
|
||||
> 1. 移除出题总题数 20 道上限,超过 50 道时返回警告(不影响出题)
|
||||
> 2. 填空题批阅增加 `student_answer` 格式校验(必须为字符串列表)
|
||||
> 3. 认证错误状态码修正(仅 `DEV_MODE=true` 时生效,见 [认证说明](#认证模式说明))
|
||||
>
|
||||
> **2026-06-05 变更**:`/exam/grade` 请求字段 `question_content` 已重命名为 `content`(破坏性变更)。详见 [出题批阅接口变更说明(2026-06-05)](出题批阅接口变更说明(2026-06-05).md)。
|
||||
|
||||
---
|
||||
@@ -27,9 +32,10 @@ Content-Type: application/json
|
||||
|------|------|------|------|
|
||||
| `file_path` | string | ✅ | 文档路径(相对于 documents 目录) |
|
||||
| `collection` | string 或 string[] | ✅ | 向量库名称,支持数组(按优先级顺序检索,找到文件即停止) |
|
||||
| `question_types` | object | ✅ | 题型及数量 |
|
||||
| `question_types` | object | ✅ | 题型及数量,**无上限**(超过 50 道时服务端返回警告但仍正常出题) |
|
||||
| `difficulty` | int | ❌ | 难度等级 1-5,默认 3 |
|
||||
| `request_id` | string | ❌ | 请求ID,相同ID返回缓存结果(幂等性) |
|
||||
| `exclude_stems` | string[] | ❌ | 排除已有题目的题干列表,避免重复出题(最多 100 条) |
|
||||
|
||||
**请求示例:**
|
||||
|
||||
@@ -64,12 +70,15 @@ Content-Type: application/json
|
||||
{
|
||||
"success": true,
|
||||
"status": "success",
|
||||
"status_code": 2011,
|
||||
"message": "出题完成",
|
||||
"status_code": 2020,
|
||||
"message": "出题成功",
|
||||
"data": {
|
||||
"request_id": "uuid-xxx",
|
||||
"total": 10,
|
||||
"source_chunks_used": 25,
|
||||
"requested_types": {"single_choice": 3, "fill_blank": 2},
|
||||
"actual_types": {"single_choice": 3, "fill_blank": 2},
|
||||
"warnings": [],
|
||||
"questions": [
|
||||
{
|
||||
"question_type": "single_choice",
|
||||
@@ -89,7 +98,8 @@ Content-Type: application/json
|
||||
},
|
||||
"source_trace": {
|
||||
"document_name": "薪酬制度.docx",
|
||||
"chunks_count": 3
|
||||
"page_numbers": [1],
|
||||
"sources": [{"chunk_id": "...", "page": 1, "section": "...", "snippet": "..."}]
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -97,17 +107,30 @@ Content-Type: application/json
|
||||
}
|
||||
```
|
||||
|
||||
**失败响应:**
|
||||
**⚠️ 文件/向量库不存在时的响应:**
|
||||
|
||||
当 `file_path` 在指定 `collection` 中找不到,或 `collection` 不存在时,接口**不会返回错误**,而是返回空结果:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"status": "failed",
|
||||
"error_code": "FILE_NOT_FOUND",
|
||||
"message": "文件不存在"
|
||||
"success": true,
|
||||
"status": "success",
|
||||
"status_code": 2020,
|
||||
"message": "出题成功",
|
||||
"data": {
|
||||
"request_id": null,
|
||||
"total": 0,
|
||||
"questions": [],
|
||||
"requested_types": {"single_choice": 1},
|
||||
"actual_types": {},
|
||||
"warnings": ["single_choice: 请求 1 道,实际生成 0 道"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **后端注意**:必须检查 `data.total` 是否 > 0 来判断出题是否成功,不能仅依赖 `success` 字段。
|
||||
```
|
||||
|
||||
### 2.3 返回字段说明
|
||||
|
||||
**RAG 服务返回的字段(后端需存储):**
|
||||
@@ -148,11 +171,63 @@ Content-Type: application/json
|
||||
|
||||
| 错误码 | HTTP | 说明 |
|
||||
|--------|------|------|
|
||||
| `FILE_NOT_FOUND` | 404 | 指定文件不存在 |
|
||||
| `COLLECTION_NOT_FOUND` | 404 | 指定向量库不存在 |
|
||||
| `NO_CONTENT` | 400 | 文件内容为空,无法出题 |
|
||||
| `LLM_ERROR` | 500 | LLM 调用失败 |
|
||||
| `PARSE_ERROR` | 500 | 解析失败 |
|
||||
| `MISSING_PARAMS` | 400 | 缺少必填参数(file_path / collection / question_types) |
|
||||
| `INVALID_PARAMS` | 400 | 参数校验失败(题型无效、难度越界、总题数≤0 等) |
|
||||
| `EXAM_ERROR` | 500 | 出题过程异常(LLM 调用失败、解析错误等) |
|
||||
|
||||
> **注意**:文件不存在或向量库不存在时,不会返回错误码,而是返回 `success=true` + `total=0` + `warnings`(见上方说明)。后端应检查 `total > 0`。
|
||||
|
||||
### 2.6 智能出题接口(/exam/generate-smart)
|
||||
|
||||
与 `/exam/generate` 的区别:不需要传 `question_types`,AI 自动分析文档后决定题型和数量。
|
||||
|
||||
```
|
||||
POST /exam/generate-smart
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**请求体字段说明:**
|
||||
|
||||
| 字段 | 类型 | 必需 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `file_path` | string | ✅ | 文档路径 |
|
||||
| `collection` | string 或 string[] | ✅ | 向量库名称 |
|
||||
| `difficulty` | int | ❌ | 难度等级 1-5,默认 3 |
|
||||
| `max_total` | int | ❌ | AI 出题总数上限,不传则不限制 |
|
||||
| `exclude_stems` | string[] | ❌ | 排除已有题目的题干列表 |
|
||||
| `request_id` | string | ❌ | 请求ID |
|
||||
|
||||
**请求示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"file_path": "111/卷烟货源组织管理办法.docx",
|
||||
"collection": "111",
|
||||
"difficulty": 3,
|
||||
"max_total": 10,
|
||||
"request_id": "smart-uuid-xxx"
|
||||
}
|
||||
```
|
||||
|
||||
**响应:** 与 `/exam/generate` 格式相同,额外包含 `ai_analysis` 字段(AI 分析结果)。
|
||||
|
||||
---
|
||||
|
||||
### 认证模式说明
|
||||
|
||||
RAG 服务支持两种认证模式,由环境变量 `DEV_MODE` 控制:
|
||||
|
||||
| 模式 | DEV_MODE | 认证行为 |
|
||||
|------|----------|----------|
|
||||
| **生产模式** | `false` | 认证网关**直接放行**,不校验 Header。权限由后端服务完全控制 |
|
||||
| **开发模式** | `true` | 支持 `Authorization: Bearer mock-token-admin` 模拟登录,无 Header 时使用默认测试用户 |
|
||||
|
||||
**当前服务器为生产模式**(`DEV_MODE=false`),因此:
|
||||
- `Authorization` Header 会被忽略
|
||||
- 不会返回 `401 UNAUTHORIZED` 或 `403 FORBIDDEN`
|
||||
- 后端服务应自行完成用户认证和权限校验,再调用 RAG 出题/批阅接口
|
||||
|
||||
> 开发模式下,认证错误会返回正确的业务状态码(`UNAUTHORIZED=4001`、`FORBIDDEN=4002`),HTTP 状态码分别为 401/403。
|
||||
|
||||
---
|
||||
|
||||
@@ -182,6 +257,12 @@ Content-Type: application/json
|
||||
| `student_answer` | any | ✅ | 学生答案 | 学生提交 |
|
||||
| `max_score` | number | ✅ | 满分 | 后端数据库 |
|
||||
|
||||
> **填空题 `student_answer` 格式要求**(2026-07-03 新增校验):
|
||||
> - 必须为 **字符串数组**,如 `["答案1", "答案2"]`
|
||||
> - 不是列表(如传了字符串 `"答案1"`)→ 该题直接得 0 分,`grading_status` 为 `"failed"`
|
||||
> - 列表中某项不是字符串(如传了数字 `123`)→ 该题直接得 0 分
|
||||
> - 校验失败不影响其他题目的正常批阅
|
||||
|
||||
**请求示例:**
|
||||
|
||||
```json
|
||||
@@ -366,8 +447,11 @@ Content-Type: application/json
|
||||
|
||||
| 错误码 | HTTP | 说明 |
|
||||
|--------|------|------|
|
||||
| `INVALID_ANSWER_FORMAT` | 400 | 答案格式不正确 |
|
||||
| `GRADING_ERROR` | 500 | 批阅过程出错 |
|
||||
| `MISSING_PARAMS` | 400 | 缺少 answers 字段 |
|
||||
| `INVALID_PARAMS` | 400 | answers 非数组、question_type 无效等 |
|
||||
| `GRADE_ERROR` | 500 | 批阅过程出错 |
|
||||
|
||||
> **填空题格式错误不返回错误码**:当 `student_answer` 格式不合法时,该题返回 `grading_status: "failed"` + `score: 0`,但接口整体仍返回 `success: true`。后端应检查每道题的 `grading_status` 字段。
|
||||
|
||||
---
|
||||
|
||||
@@ -464,8 +548,23 @@ Content-Type: application/json
|
||||
- 设置 60 秒超时
|
||||
- 主观题较多时适当延长
|
||||
|
||||
### Q5: 出题数量有上限吗?
|
||||
|
||||
2026-07-03 起,出题接口**不再限制总题数**。服务端会在请求数超过 50 道时记录警告日志,但不影响出题。建议:
|
||||
- 单次出题不超过 30 道(LLM 生成耗时与题数成正比,30 道约需 5-8 分钟)
|
||||
- 超过 30 道建议分批调用
|
||||
- 设置 120 秒以上超时
|
||||
|
||||
### Q6: 填空题学生答案传错了会怎样?
|
||||
|
||||
2026-07-03 起,填空题增加了格式校验:
|
||||
- `student_answer` 不是列表 → 该题得 0 分,`grading_status = "failed"`
|
||||
- 列表中某项不是字符串 → 该题得 0 分
|
||||
- 校验失败不影响同一请求中其他题目的批阅
|
||||
- 接口整体仍返回 `success: true`,需检查每道题的 `grading_status`
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v1.1
|
||||
**更新时间**: 2026-05-17
|
||||
**文档版本**: v1.2
|
||||
**更新时间**: 2026-07-03
|
||||
**相关文档**: [后端对接规范.md](./后端对接规范.md)
|
||||
|
||||
Reference in New Issue
Block a user