feat: add streaming learning assistant and knowledge base scaffolding
This commit is contained in:
+160
-295
@@ -1,19 +1,20 @@
|
||||
# 医疗问诊 Agent API 文档
|
||||
|
||||
> 当前文档只描述前端联调需要的后端能力。
|
||||
本文档面向前端联调,描述当前 FastAPI 后端已保留和可调用的接口。
|
||||
|
||||
## 1. 联调地址
|
||||
公网基础地址:
|
||||
|
||||
| 项目 | 地址 |
|
||||
|---|---|
|
||||
| 公网网关 | `http://8.160.178.88/fastapi` |
|
||||
| API Base URL | `http://8.160.178.88/fastapi/api/v1` |
|
||||
| Swagger | `http://8.160.178.88/fastapi/docs` |
|
||||
| OpenAPI JSON | `http://8.160.178.88/fastapi/openapi.json` |
|
||||
| 存活检查 | `http://8.160.178.88/fastapi/health/live` |
|
||||
| 就绪检查 | `http://8.160.178.88/fastapi/health/ready` |
|
||||
```text
|
||||
http://8.160.178.88/fastapi
|
||||
```
|
||||
|
||||
## 2. 通用规则
|
||||
本地调试地址:
|
||||
|
||||
```text
|
||||
http://127.0.0.1:9000
|
||||
```
|
||||
|
||||
## 1. 通用规则
|
||||
|
||||
除健康检查外,所有业务接口都需要携带:
|
||||
|
||||
@@ -23,6 +24,8 @@ X-Entry-Scene: vue_frontend
|
||||
X-Request-Id: <可选>
|
||||
```
|
||||
|
||||
`Authorization` 使用 Django 用户中心签发的 access token。FastAPI 会转发 token 到 Django `/api/user/users/me/`,返回 200 后以 Django 用户 `id` 作为本服务的 `user_id`。
|
||||
|
||||
普通 JSON 接口统一返回:
|
||||
|
||||
```json
|
||||
@@ -33,31 +36,34 @@ X-Request-Id: <可选>
|
||||
}
|
||||
```
|
||||
|
||||
前端判断规则:
|
||||
前端判断成功规则:
|
||||
|
||||
- HTTP 状态码为 `2xx`
|
||||
- `code` 等于 `OK`
|
||||
- 业务数据从 `data` 读取
|
||||
|
||||
SSE 流式接口不返回上述 JSON 包装,而是返回 `event + data` 事件流。
|
||||
SSE 流式接口不返回上述 JSON 包装,而是返回:
|
||||
|
||||
## 3. 前置接口
|
||||
```text
|
||||
event: <event_name>
|
||||
data: {"key":"value"}
|
||||
```
|
||||
|
||||
### 3.1 当前用户
|
||||
## 2. 用户鉴权
|
||||
|
||||
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|
||||
|---|---|---|---|---|---|
|
||||
| 当前用户 | `http://8.160.178.88/fastapi/api/v1/auth/me` | `/api/v1/auth/me` | `GET` | Header:`Authorization` 必填,格式 `Bearer <access_token>`;`X-Entry-Scene` 建议传。 | `data.user_id`、`data.username`、`data.display_name`、`data.role`、`data.phone`、`data.institution_id`、`data.department_id`、`data.status` 等 Django 用户中心字段。 |
|
||||
| 当前用户信息 | `http://8.160.178.88/fastapi/api/v1/auth/me` | `/api/v1/auth/me` | `GET` | Header:`Authorization` 必填,格式 `Bearer <access_token>`;`X-Entry-Scene` 可选,建议 `vue_frontend` | `data.user_id` 用户ID;`data.username` 用户名;`data.display_name` 显示名;`data.role` 用户角色;`data.institution_id` 机构ID;`data.institution_name` 机构名称;`data.department_id` 科室ID;`data.department_name` 科室名称;`data.status` 用户状态 |
|
||||
|
||||
请求示例:
|
||||
|
||||
```http
|
||||
GET /api/v1/auth/me
|
||||
Authorization: Bearer <access_token>
|
||||
X-Entry-Scene: vue_frontend
|
||||
```bash
|
||||
curl -X GET "http://8.160.178.88/fastapi/api/v1/auth/me" \
|
||||
-H "Authorization: Bearer <access_token>" \
|
||||
-H "X-Entry-Scene: vue_frontend"
|
||||
```
|
||||
|
||||
成功返回示例:
|
||||
返回示例:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -67,66 +73,37 @@ X-Entry-Scene: vue_frontend
|
||||
"user_id": "37",
|
||||
"source": "django_user_center",
|
||||
"username": "13700000099",
|
||||
"display_name": "测试用户",
|
||||
"display_name": "Swagger测试",
|
||||
"tenant_id": "1",
|
||||
"role": "student",
|
||||
"phone": "13700000099",
|
||||
"avatar": "",
|
||||
"gender": 0,
|
||||
"institution_id": 1,
|
||||
"institution_name": "测试机构",
|
||||
"department_id": 2,
|
||||
"institution_name": "某医院",
|
||||
"department_id": 1,
|
||||
"department_name": "儿科",
|
||||
"status": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 病例读取
|
||||
## 3. 训练页面接口
|
||||
|
||||
### 3.1 推荐配置信息
|
||||
|
||||
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|
||||
|---|---|---|---|---|---|
|
||||
| 病例列表 | `http://8.160.178.88/fastapi/api/v1/cases` | `/api/v1/cases` | `GET` | Query:`department_id` 选填,科室 ID;`training_type` 选填;`mode` 选填,允许 `practice`、`teaching`。 | `data.items[]`,包含 `id`、`title`、`department_id`、`difficulty`、`chief_complaint`、`has_teaching_video`、`has_quiz`。 |
|
||||
| 病例详情 | `http://8.160.178.88/fastapi/api/v1/cases/{case_id}` | `/api/v1/cases/{case_id}` | `GET` | Path:`case_id` 必填,病例 ID。 | 病例入口展示信息,不返回标准答案、隐藏病史、检查结果和评分规则。 |
|
||||
| 推荐配置信息 | `http://8.160.178.88/fastapi/api/v1/training-config/recommended` | `/api/v1/training-config/recommended` | `GET` | Query:`case_id` 必填,病例ID | `data.recommended` 推荐配置值;`data.recommended_labels` 推荐配置中文名;`data.options` 可选项 |
|
||||
|
||||
## 4. 训练页面接口
|
||||
|
||||
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|
||||
|---|---|---|---|---|---|
|
||||
| 推荐配置信息 | `http://8.160.178.88/fastapi/api/v1/training-config/recommended?case_id={case_id}` | `/api/v1/training-config/recommended` | `GET` | Query:`case_id` 必填,病例 ID。 | `data.recommended` 默认配置;`data.recommended_labels` 中文标签。 |
|
||||
| 训练配置信息 | `http://8.160.178.88/fastapi/api/v1/training-config/options?case_id={case_id}` | `/api/v1/training-config/options` | `GET` | Query:`case_id` 必填,病例 ID。 | `data.options` 全部可选项;`data.recommended` 推荐默认值。 |
|
||||
| 新建会话 | `http://8.160.178.88/fastapi/api/v1/sessions` | `/api/v1/sessions` | `POST` | Body:`case_id` 必填;`training_type` 必填;`mode` 必填,当前训练填 `practice`;`score_type` 选填,允许 `percentage`、`five_point`;`patient_config` 选填。 | `data.session_id`、`data.session_code`、`data.status`、`data.patient_opening`、`data.patient_config`。 |
|
||||
| 流式会话 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/chat/stream` | `/api/v1/sessions/{session_id}/chat/stream` | `POST` | Path:`session_id` 必填;Body:`message` 必填,医学生问句。 | SSE:`message_delta` 返回患者回复增量;`message_done` 返回耗时;`error` 返回错误。 |
|
||||
| 王主任练习提示 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/hints/stream` | `/api/v1/sessions/{session_id}/hints/stream` | `POST` | Path:`session_id` 必填;Body:`last_user_message` 选填;`scope` 选填,默认 `current_conversation`。 | SSE:`hint_delta` 返回一句话提示增量;`hint_done` 返回结束事件。 |
|
||||
| 体格检查列表获取 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/physical-exams` | `/api/v1/sessions/{session_id}/physical-exams` | `GET` | Path:`session_id` 必填。 | `data.items[]`,包含体格检查项 `item_code`、`item_name`、`item_type`。不返回结果。 |
|
||||
| 辅助检查列表获取 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/auxiliary-exams` | `/api/v1/sessions/{session_id}/auxiliary-exams` | `GET` | Path:`session_id` 必填。 | `data.items[]`,包含辅助检查项 `item_code`、`item_name`、`item_type`。不返回结果。 |
|
||||
| 体格检查某项结果 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/physical-exams/{item_code}` | `/api/v1/sessions/{session_id}/physical-exams/{item_code}` | `POST` | Path:`session_id` 必填;`item_code` 必填,必须属于体格检查。 | `data.result_text`、`data.result_structured`、`data.context_written`、`data.already_ordered`。 |
|
||||
| 辅助检查某项结果 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/auxiliary-exams/{item_code}` | `/api/v1/sessions/{session_id}/auxiliary-exams/{item_code}` | `POST` | Path:`session_id` 必填;`item_code` 必填,必须属于辅助检查。 | `data.result_text`、`data.result_structured`、`data.context_written`、`data.already_ordered`。 |
|
||||
| 完成问诊 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/complete-inquiry` | `/api/v1/sessions/{session_id}/complete-inquiry` | `POST` | Path:`session_id` 必填。至少完成一轮医生问诊。 | `data.session_id`、`data.status=diagnosis`。 |
|
||||
| 提交诊断 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/diagnosis` | `/api/v1/sessions/{session_id}/diagnosis` | `POST` | Path:`session_id` 必填;Body:`primary_diagnosis` 必填;`diagnosis_basis` 必填;`differential_diagnoses` 选填数组。 | `data.status=treatment`。 |
|
||||
| 提交治疗 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/treatment` | `/api/v1/sessions/{session_id}/treatment` | `POST` | Path:`session_id` 必填;Body:`treatment_principle`、`treatment_measures` 必填;`risk_plan`、`communication`、`follow_up` 选填。 | `data.status=evaluating`。 |
|
||||
| 生成评价 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/evaluation` | `/api/v1/sessions/{session_id}/evaluation` | `POST` | Path:`session_id` 必填;Body:`score_type` 选填,允许 `percentage`、`five_point`。必须已提交治疗。 | `data.evaluation_id`、`data.total_score`、`data.dimension_scores[]`、`data.score_details[]`、`data.overall_comment`。 |
|
||||
| 获取评价(详情) | `http://8.160.178.88/fastapi/api/v1/evaluations/{evaluation_id}` | `/api/v1/evaluations/{evaluation_id}` | `GET` | Path:`evaluation_id` 必填。只允许当前用户访问自己的评价。 | 评价详情,包含病例、总分、维度评分、评分明细、改进建议、PDF 路径。 |
|
||||
| 下载 PDF | `http://8.160.178.88/fastapi/api/v1/evaluations/{evaluation_id}/download-pdf` | `/api/v1/evaluations/{evaluation_id}/download-pdf` | `GET` | Path:`evaluation_id` 必填。Header:`Authorization` 必填。 | 成功时返回 `application/pdf` 文件流,浏览器可下载;失败时返回统一错误 JSON。 |
|
||||
|
||||
### 4.1 训练配置入参和返回示例
|
||||
|
||||
请求:
|
||||
|
||||
```http
|
||||
GET /api/v1/training-config/options?case_id=2
|
||||
Authorization: Bearer <access_token>
|
||||
X-Entry-Scene: vue_frontend
|
||||
```
|
||||
|
||||
返回:
|
||||
返回示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": "OK",
|
||||
"message": "success",
|
||||
"data": {
|
||||
"case_id": 2,
|
||||
"case_id": 1,
|
||||
"recommended": {
|
||||
"visit_environment": "outpatient",
|
||||
"age_group": "child",
|
||||
@@ -139,42 +116,28 @@ X-Entry-Scene: vue_frontend
|
||||
"education_level": "高等教育",
|
||||
"personality": "平和"
|
||||
},
|
||||
"options": {
|
||||
"visit_environment": [
|
||||
{"value": "outpatient", "label": "门诊"},
|
||||
{"value": "emergency", "label": "急诊"},
|
||||
{"value": "ward", "label": "病房"}
|
||||
],
|
||||
"age_group": [
|
||||
{"value": "child", "label": "儿童"},
|
||||
{"value": "youth", "label": "青年"},
|
||||
{"value": "middle_aged", "label": "中年"},
|
||||
{"value": "elderly", "label": "老年"}
|
||||
],
|
||||
"education_level": [
|
||||
{"value": "primary_or_below", "label": "小学及以下"},
|
||||
{"value": "secondary", "label": "中等教育"},
|
||||
{"value": "higher", "label": "高等教育"}
|
||||
],
|
||||
"personality": [
|
||||
{"value": "calm", "label": "平和"},
|
||||
{"value": "anxious", "label": "焦虑"},
|
||||
{"value": "impatient", "label": "急躁"},
|
||||
{"value": "cooperative", "label": "配合"},
|
||||
{"value": "suspicious", "label": "多疑"}
|
||||
]
|
||||
}
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 新建会话入参和返回示例
|
||||
### 3.2 训练配置信息
|
||||
|
||||
请求:
|
||||
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|
||||
|---|---|---|---|---|---|
|
||||
| 训练配置信息 | `http://8.160.178.88/fastapi/api/v1/training-config/options` | `/api/v1/training-config/options` | `GET` | Query:`case_id` 必填,病例ID | `data.options.visit_environment` 就诊环境;`data.options.age_group` 年龄段;`data.options.education_level` 文化程度;`data.options.personality` 性格 |
|
||||
|
||||
### 3.3 新建会话
|
||||
|
||||
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|
||||
|---|---|---|---|---|---|
|
||||
| 新建会话 | `http://8.160.178.88/fastapi/api/v1/sessions` | `/api/v1/sessions` | `POST` | Body:`case_id` 必填;`training_type` 必填,当前用 `diagnosis_treatment`;`mode` 必填,允许 `practice`、`teaching`;`score_type` 必填,允许 `percentage`、`five_point`;`patient_config` 可选,自定义病人配置 | `data.session_id` 会话ID;`data.case_id` 病例ID;`data.status` 当前阶段;`data.patient_config` 实际使用的病人配置 |
|
||||
|
||||
请求示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"case_id": 2,
|
||||
"case_id": 1,
|
||||
"training_type": "diagnosis_treatment",
|
||||
"mode": "practice",
|
||||
"score_type": "percentage",
|
||||
@@ -187,249 +150,151 @@ X-Entry-Scene: vue_frontend
|
||||
}
|
||||
```
|
||||
|
||||
返回:
|
||||
### 3.4 流式会话
|
||||
|
||||
```json
|
||||
{
|
||||
"code": "OK",
|
||||
"message": "success",
|
||||
"data": {
|
||||
"session_id": 12,
|
||||
"session_code": "sess_20260608120000_xxxx",
|
||||
"status": "inquiry",
|
||||
"patient_opening": "家长:医生,孩子发热咳嗽好几天了,昨天开始喘得厉害,精神也不太好。",
|
||||
"patient_config": {
|
||||
"values": {
|
||||
"visit_environment": "outpatient",
|
||||
"age_group": "child",
|
||||
"education_level": "higher",
|
||||
"personality": "calm"
|
||||
},
|
||||
"labels": {
|
||||
"visit_environment": "门诊",
|
||||
"age_group": "儿童",
|
||||
"education_level": "高等教育",
|
||||
"personality": "平和"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|
||||
|---|---|---|---|---|---|
|
||||
| 流式会话 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/chat/stream` | `/api/v1/sessions/{session_id}/chat/stream` | `POST` | Path:`session_id` 必填;Body:`message` 必填,医学生问诊内容 | SSE:`message_delta` AI病人回复增量;`message_done` 完成;`error` 错误 |
|
||||
|
||||
### 4.3 SSE 流式会话返回格式
|
||||
|
||||
请求:
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "孩子发热几天了?最高体温多少?"
|
||||
}
|
||||
```
|
||||
|
||||
返回:
|
||||
SSE 返回示例:
|
||||
|
||||
```text
|
||||
event: message_delta
|
||||
data: {"delta":"发热有4天了,"}
|
||||
|
||||
event: message_delta
|
||||
data: {"delta":"最高烧到39度多。"}
|
||||
data: {"delta":"发热有4天了,最高39度多。"}
|
||||
|
||||
event: message_done
|
||||
data: {"latency_ms":1800,"first_token_ms":500,"model":"deepseek-chat","fallback_used":false}
|
||||
data: {"latency_ms":1200,"first_token_ms":300,"model":"deepseek-chat","fallback_used":false}
|
||||
```
|
||||
|
||||
### 4.4 检查结果返回示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": "OK",
|
||||
"message": "success",
|
||||
"data": {
|
||||
"item_code": "blood_routine",
|
||||
"item_name": "血常规",
|
||||
"item_type": "lab",
|
||||
"result_text": "WBC 12.5×10^9/L,中性粒细胞比例72%,提示感染及炎症反应。",
|
||||
"result_structured": {
|
||||
"wbc": "12.5×10^9/L",
|
||||
"neutrophil": "72%"
|
||||
},
|
||||
"is_key": true,
|
||||
"is_abnormal": true,
|
||||
"context_written": true,
|
||||
"already_ordered": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
检查规则:
|
||||
|
||||
- 检查结果只来自数据库,不由 LLM 生成。
|
||||
- 检查结果会写入本次会话短期 memory 和评分依据。
|
||||
- 同一会话重复申请相同 `item_code` 时返回已有结果,`already_ordered=true`。
|
||||
|
||||
### 4.5 诊断和治疗提交示例
|
||||
|
||||
提交诊断:
|
||||
|
||||
```json
|
||||
{
|
||||
"primary_diagnosis": "支气管肺炎",
|
||||
"differential_diagnoses": ["支气管哮喘急性发作", "上呼吸道感染"],
|
||||
"diagnosis_basis": "结合发热、咳嗽、喘息、肺部湿啰音、胸片异常、炎症指标升高和血氧情况,符合儿童支气管肺炎表现。"
|
||||
}
|
||||
```
|
||||
|
||||
提交治疗:
|
||||
|
||||
```json
|
||||
{
|
||||
"treatment_principle": "抗感染、止咳平喘、改善氧合并严密观察病情变化。",
|
||||
"treatment_measures": "根据病情进行抗感染治疗,必要时雾化吸入缓解喘息,监测体温、呼吸和血氧。",
|
||||
"risk_plan": "关注低氧、呼吸困难加重、持续高热、精神反应差和脱水。",
|
||||
"communication": "向家属说明病情、用药注意事项、危险信号和复诊指征。",
|
||||
"follow_up": "治疗后复查体温、呼吸、血氧和必要炎症指标。"
|
||||
}
|
||||
```
|
||||
|
||||
## 5. 教学互动接口
|
||||
### 3.5 王主任练习提示
|
||||
|
||||
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|
||||
|---|---|---|---|---|---|
|
||||
| 获取教学列表(题目 选项 答案 解析文本 视频) | `http://8.160.178.88/fastapi/api/v1/teaching/cases/{case_id}/items` | `/api/v1/teaching/cases/{case_id}/items` | `GET` | Path:`case_id` 必填,必须存在 `teaching_case` 数据。 | `data.case` 病例摘要;`data.questions[]` 题目列表,包含 `stem`、`options[]`、`answer`、`analysis`、`video`。 |
|
||||
| 生成评价 | `http://8.160.178.88/fastapi/api/v1/teaching/evaluation` | `/api/v1/teaching/evaluation` | `POST` | Body:`case_id` 必填;`answers[]` 必填;`answers[].question_id` 必填;`answers[].selected_answer` 必填;`score_type` 选填。 | `data.session_id`、`data.evaluation_id`、`data.total_score`、`data.dimension_scores[]`、`data.score_details[]`、`data.overall_comment`。 |
|
||||
| 获取评价(详情) | `http://8.160.178.88/fastapi/api/v1/evaluations/{evaluation_id}` | `/api/v1/evaluations/{evaluation_id}` | `GET` | Path:`evaluation_id` 必填。 | 教学互动评价详情,结构与训练评价一致。 |
|
||||
| 下载 PDF | `http://8.160.178.88/fastapi/api/v1/evaluations/{evaluation_id}/download-pdf` | `/api/v1/evaluations/{evaluation_id}/download-pdf` | `GET` | Path:`evaluation_id` 必填。 | 返回 `application/pdf` 文件流。 |
|
||||
| 王主任练习提示 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/hints/stream` | `/api/v1/sessions/{session_id}/hints/stream` | `POST` | Path:`session_id` 必填;Body:`scope` 可选,默认 `current_conversation`;`last_user_message` 可选 | SSE:`hint_delta` 提示文本增量;`hint_done` 完成;`error` 错误 |
|
||||
|
||||
获取教学列表返回示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": "OK",
|
||||
"message": "success",
|
||||
"data": {
|
||||
"case": {
|
||||
"case_id": 2,
|
||||
"title": "支气管肺炎 - 6岁男性患儿",
|
||||
"chief_complaint": "发热、咳嗽4天,喘息1天"
|
||||
},
|
||||
"teaching_goal": "围绕儿科肺炎问诊、检查选择、诊断依据、治疗决策和医患沟通完成互动训练。",
|
||||
"questions": [
|
||||
{
|
||||
"question_id": "q1",
|
||||
"question_type": "single_choice",
|
||||
"stem": "该患儿最需要优先关注的病情严重程度指标是?",
|
||||
"options": [
|
||||
{"key": "A", "text": "体温峰值"},
|
||||
{"key": "B", "text": "血氧饱和度"}
|
||||
],
|
||||
"answer": "B",
|
||||
"analysis": "血氧饱和度能帮助判断低氧和肺炎严重程度。",
|
||||
"video": {"title": "儿童肺炎教学示例视频", "url": ""},
|
||||
"knowledge_points": ["严重程度评估", "血氧判断"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
生成教学评价请求示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"case_id": 2,
|
||||
"score_type": "percentage",
|
||||
"answers": [
|
||||
{"question_id": "q1", "selected_answer": "B"},
|
||||
{"question_id": "q2", "selected_answer": "A"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 6. 个人中心接口
|
||||
### 3.6 检查列表和结果
|
||||
|
||||
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|
||||
|---|---|---|---|---|---|
|
||||
| 训练记录列表 | `http://8.160.178.88/fastapi/api/v1/evaluations` | `/api/v1/evaluations` | `GET` | Header:`Authorization` 必填。 | `data.items[]` 当前用户完整训练后的评价记录,包含 `evaluation_id`、`case_title`、`score_type`、`total_score`、`created_at`、`pdf_exported`。 |
|
||||
| 训练记录详情(评价详情) | `http://8.160.178.88/fastapi/api/v1/evaluations/{evaluation_id}` | `/api/v1/evaluations/{evaluation_id}` | `GET` | Path:`evaluation_id` 必填。 | 完整评价详情,训练和教学互动评价共用。 |
|
||||
| 体格检查列表获取 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/physical-exams` | `/api/v1/sessions/{session_id}/physical-exams` | `GET` | Path:`session_id` 必填 | `data.items[]` 当前病例可用体格检查项 |
|
||||
| 辅助检查列表获取 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/auxiliary-exams` | `/api/v1/sessions/{session_id}/auxiliary-exams` | `GET` | Path:`session_id` 必填 | `data.items[]` 当前病例可用辅助检查项 |
|
||||
| 体格检查某项结果 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/physical-exams/{item_code}` | `/api/v1/sessions/{session_id}/physical-exams/{item_code}` | `POST` | Path:`session_id` 必填;`item_code` 必填,如 `lung_auscultation` | `data.item_code`;`data.item_name`;`data.result_text`;`data.already_ordered`;`data.context_written` |
|
||||
| 辅助检查某项结果 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/auxiliary-exams/{item_code}` | `/api/v1/sessions/{session_id}/auxiliary-exams/{item_code}` | `POST` | Path:`session_id` 必填;`item_code` 必填,如 `blood_routine`、`crp`、`chest_xray`、`oxygen_saturation` | 同上 |
|
||||
|
||||
训练记录列表返回示例:
|
||||
### 3.7 阶段提交
|
||||
|
||||
```json
|
||||
{
|
||||
"code": "OK",
|
||||
"message": "success",
|
||||
"data": {
|
||||
"items": [
|
||||
{
|
||||
"evaluation_id": 101,
|
||||
"case_title": "支气管肺炎 - 6岁男性患儿",
|
||||
"score_type": "percentage",
|
||||
"total_score": 82,
|
||||
"created_at": "2026-06-08T12:00:00",
|
||||
"pdf_exported": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|
||||
|---|---|---|---|---|---|
|
||||
| 完成问诊 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/complete-inquiry` | `/api/v1/sessions/{session_id}/complete-inquiry` | `POST` | Path:`session_id` 必填 | `data.status=diagnosis` |
|
||||
| 提交诊断 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/diagnosis` | `/api/v1/sessions/{session_id}/diagnosis` | `POST` | Path:`session_id` 必填;Body:`primary_diagnosis` 必填;`differential_diagnoses` 可选数组;`diagnosis_basis` 必填 | `data.status=treatment` |
|
||||
| 提交治疗 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/treatment` | `/api/v1/sessions/{session_id}/treatment` | `POST` | Path:`session_id` 必填;Body:`treatment_principle`、`treatment_measures`、`risk_plan`、`communication`、`follow_up` 均必填 | `data.status=evaluating` |
|
||||
| 生成评价 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/evaluation` | `/api/v1/sessions/{session_id}/evaluation` | `POST` | Path:`session_id` 必填;Body:`score_type` 可选,允许 `percentage`、`five_point` | `data.evaluation_id`;`data.total_score`;`data.score_details[]`;`data.report_summary` |
|
||||
|
||||
## 7. PDF 下载前端写法
|
||||
## 4. 教学互动接口
|
||||
|
||||
因为下载接口需要 Bearer token,前端不能直接使用普通 `<a href>`。使用 `fetch` 获取 blob 后触发下载:
|
||||
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|
||||
|---|---|---|---|---|---|
|
||||
| 获取教学列表 | `http://8.160.178.88/fastapi/api/v1/teaching/cases/{case_id}/items` | `/api/v1/teaching/cases/{case_id}/items` | `GET` | Path:`case_id` 必填 | `data.case` 病例信息;`data.questions[]` 题目、选项、答案、解析文本、视频 |
|
||||
| 教学互动生成评价 | `http://8.160.178.88/fastapi/api/v1/teaching/evaluation` | `/api/v1/teaching/evaluation` | `POST` | Body:`case_id` 必填;`answers[]` 必填,包含 `question_id` 和 `selected_answer`;`score_type` 可选 | `data.evaluation_id`;`data.session_id`;`data.total_score`;`data.score_details[]` |
|
||||
|
||||
## 5. 评价和个人中心接口
|
||||
|
||||
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|
||||
|---|---|---|---|---|---|
|
||||
| 训练记录列表 | `http://8.160.178.88/fastapi/api/v1/evaluations` | `/api/v1/evaluations` | `GET` | Query:`limit` 可选,默认20;`offset` 可选,默认0 | `data.items[]` 当前用户完整训练后的评价记录 |
|
||||
| 训练记录详情 / 评价详情 | `http://8.160.178.88/fastapi/api/v1/evaluations/{evaluation_id}` | `/api/v1/evaluations/{evaluation_id}` | `GET` | Path:`evaluation_id` 必填 | 完整评价详情,训练和教学互动共用 |
|
||||
| 导出 PDF | `http://8.160.178.88/fastapi/api/v1/evaluations/{evaluation_id}/export-pdf` | `/api/v1/evaluations/{evaluation_id}/export-pdf` | `POST` | Path:`evaluation_id` 必填 | `data.file_path`;`data.exported_at` |
|
||||
| 下载 PDF | `http://8.160.178.88/fastapi/api/v1/evaluations/{evaluation_id}/download-pdf` | `/api/v1/evaluations/{evaluation_id}/download-pdf` | `GET` | Path:`evaluation_id` 必填 | `application/pdf` 文件流,浏览器可直接下载 |
|
||||
|
||||
PDF 下载前端写法:
|
||||
|
||||
```ts
|
||||
async function downloadEvaluationPdf(baseUrl: string, token: string, evaluationId: number) {
|
||||
const response = await fetch(`${baseUrl}/evaluations/${evaluationId}/download-pdf`, {
|
||||
const response = await fetch(`${baseUrl}/api/v1/evaluations/${evaluationId}/download-pdf`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
"X-Entry-Scene": "vue_frontend",
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json().catch(() => null);
|
||||
throw new Error(error?.message || `PDF 下载失败:${response.status}`);
|
||||
}
|
||||
|
||||
if (!response.ok) throw new Error("PDF 下载失败");
|
||||
const blob = await response.blob();
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = `evaluation_${evaluationId}.pdf`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = `evaluation-${evaluationId}.pdf`;
|
||||
link.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
```
|
||||
|
||||
## 6. AI 学习助手接口
|
||||
|
||||
该接口用于普通用户医学知识问答。后端优先检索本机构知识库;如果机构知识库未初始化、Milvus / embedding 暂不可用或未命中来源,接口仍会继续调用 LLM,回答开头会声明“未检索到本机构知识库参考,以下为大模型通用学习回答。”
|
||||
|
||||
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|
||||
|---|---|---|---|---|---|
|
||||
| AI学习助手流式问答 | `http://8.160.178.88/fastapi/api/v1/learning-assistant/chat/stream` | `/api/v1/learning-assistant/chat/stream` | `POST` | Body:`question` 必填,2-1000字;`top_k` 可选,1-10;`score_threshold` 可选,0-1 | SSE:`retrieval_done` 检索状态;`answer_delta` 回答增量;`answer_done` 完成;`error` 错误 |
|
||||
|
||||
请求示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"question": "支气管肺炎的典型临床表现有哪些?",
|
||||
"top_k": 5,
|
||||
"score_threshold": 0.35
|
||||
}
|
||||
```
|
||||
|
||||
命中知识库时:
|
||||
|
||||
```text
|
||||
event: retrieval_done
|
||||
data: {"retrieval_hit":true,"sources":[{"document_id":1,"document_title":"诊断学第十版","file_name":"19.《诊断学》十版(1).pdf","page_start":123,"page_end":124,"chunk_uid":"doc1_chunk35_abcd1234","score":0.78,"quote":"原文片段..."}],"retrieval_error":null,"embedding_latency_ms":320,"search_latency_ms":40}
|
||||
|
||||
event: answer_delta
|
||||
data: {"delta":"支气管肺炎常见表现包括发热、咳嗽、喘息...【来源1】"}
|
||||
|
||||
event: answer_done
|
||||
data: {"model":"deepseek-chat","total_latency_ms":2300}
|
||||
```
|
||||
|
||||
未命中或知识库不可用时:
|
||||
|
||||
```text
|
||||
event: retrieval_done
|
||||
data: {"retrieval_hit":false,"sources":[],"retrieval_error":"当前机构知识库暂未初始化或检索不可用,已转为大模型通用学习回答。","embedding_latency_ms":null,"search_latency_ms":null}
|
||||
|
||||
event: answer_delta
|
||||
data: {"delta":"未检索到本机构知识库参考,以下为大模型通用学习回答。..."}
|
||||
|
||||
event: answer_done
|
||||
data: {"model":"deepseek-chat","total_latency_ms":1800}
|
||||
```
|
||||
|
||||
## 7. 后台预留:内容管理员知识库接口
|
||||
|
||||
该组接口是后台内容管理员能力,学生端不展示上传入口。当前阶段保留接口和数据结构,后续生产环境接入完整 PDF 解析、分片、embedding、Milvus 构建和异步任务。
|
||||
|
||||
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|
||||
|---|---|---|---|---|---|
|
||||
| 上传知识库 PDF | `http://8.160.178.88/fastapi/api/v1/knowledge-admin/documents/upload` | `/api/v1/knowledge-admin/documents/upload` | `POST` | `multipart/form-data`:`file` 必填,PDF 文件;`document_title` 可选;`document_category` 可选,允许 `textbook`、`guideline`、`manual`、`other`;`version` 可选,默认 `v1` | `data.document_id`;`data.task_id`;`data.status`;`data.parse_status`;`data.embedding_status`;`data.chunk_count`;`data.collection_name` |
|
||||
| 知识库文档列表 | `http://8.160.178.88/fastapi/api/v1/knowledge-admin/documents` | `/api/v1/knowledge-admin/documents` | `GET` | Header:内容管理员 token | `data.items[]` 本机构上传文档 |
|
||||
| 知识库文档详情 | `http://8.160.178.88/fastapi/api/v1/knowledge-admin/documents/{document_id}` | `/api/v1/knowledge-admin/documents/{document_id}` | `GET` | Path:`document_id` 必填;Header:内容管理员 token | 文档构建状态、分片数、错误信息 |
|
||||
|
||||
## 8. 常见错误码
|
||||
|
||||
| HTTP | code | 说明 |
|
||||
| HTTP状态 | code | 含义 |
|
||||
|---:|---|---|
|
||||
| 401 | `AUTH_CREDENTIAL_REQUIRED` | 缺少 Authorization。 |
|
||||
| 401 | `AUTH_USER_INVALID` | token 无效、过期或 Django 返回非 200。 |
|
||||
| 403 | `AUTH_USER_DISABLED` | Django 用户状态被禁用。 |
|
||||
| 503 | `AUTH_USER_CENTER_UNAVAILABLE` | Django 用户中心超时或不可达。 |
|
||||
| 404 | `CASE_NOT_FOUND` | 病例不存在、未发布或已停用。 |
|
||||
| 404 | `SESSION_NOT_FOUND` | 会话不存在或不属于当前用户。 |
|
||||
| 400 | `SESSION_STATUS_INVALID` | 当前状态不允许执行该操作。 |
|
||||
| 400 | `INQUIRY_REQUIRED` | 完成问诊前没有医生提问。 |
|
||||
| 400 | `DIAGNOSIS_REQUIRED` | 提交治疗前没有提交诊断。 |
|
||||
| 400 | `TREATMENT_REQUIRED` | 生成评价前没有提交治疗。 |
|
||||
| 404 | `ORDER_ITEM_NOT_FOUND` | 当前病例不存在该检查项。 |
|
||||
| 400 | `ORDER_ITEM_TYPE_MISMATCH` | 检查接口类型和检查项类型不匹配。 |
|
||||
| 404 | `EVALUATION_NOT_FOUND` | 评价不存在或不属于当前用户。 |
|
||||
| SSE error | `LLM_STREAM_TIMEOUT` | 流式问诊首段或总耗时超时。 |
|
||||
| SSE error | `LLM_STREAM_FAILED` | 流式模型调用失败。 |
|
||||
| 500 | `PDF_EXPORT_FAILED` | PDF 生成失败。 |
|
||||
|
||||
## 9. 当前保留接口清单
|
||||
|
||||
当前后端业务模块:
|
||||
|
||||
- 训练页面:推荐配置、训练配置、新建会话、流式会话、王主任练习提示、检查列表、检查结果、完成问诊、诊断、治疗、评价、评价详情、PDF 下载。
|
||||
- 教学互动:教学列表、教学评价、评价详情、PDF 下载。
|
||||
- 个人中心:训练记录列表、训练记录详情。
|
||||
| 401 | `AUTH_CREDENTIAL_REQUIRED` | 缺少 `Authorization` |
|
||||
| 401 | `AUTH_USER_INVALID` | token 无效、过期或 Django 返回非 200 |
|
||||
| 403 | `AUTH_USER_DISABLED` | Django 用户状态被禁用 |
|
||||
| 403 | `KNOWLEDGE_ADMIN_FORBIDDEN` | 当前用户不是内容管理员,不能使用后台知识库上传接口 |
|
||||
| 404 | `CASE_NOT_FOUND` | 病例不存在、未发布或已停用 |
|
||||
| 404 | `SESSION_NOT_FOUND` | 会话不存在或不属于当前用户 |
|
||||
| 400 | `SESSION_STATUS_INVALID` | 当前状态不允许执行该操作 |
|
||||
| 404 | `ORDER_ITEM_NOT_FOUND` | 当前病例不存在该检查项 |
|
||||
| 400 | `ORDER_ITEM_TYPE_MISMATCH` | 体格检查 / 辅助检查接口与检查项类型不匹配 |
|
||||
| 404 | `EVALUATION_NOT_FOUND` | 评价不存在或不属于当前用户 |
|
||||
| 502 | `LLM_STREAM_FAILED` | LLM 流式调用失败 |
|
||||
| 503 | `AUTH_USER_CENTER_UNAVAILABLE` | Django 用户中心超时或不可达 |
|
||||
|
||||
Reference in New Issue
Block a user