Files
fastapi/docs/03_api_design.md

301 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 医疗问诊 Agent API 文档
本文档面向前端联调,描述当前 FastAPI 后端已保留和可调用的接口。
公网基础地址:
```text
http://8.160.178.88/fastapi
```
本地调试地址:
```text
http://127.0.0.1:9000
```
## 1. 通用规则
除健康检查外,所有业务接口都需要携带:
```http
Authorization: Bearer <access_token>
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
{
"code": "OK",
"message": "success",
"data": {}
}
```
前端判断成功规则:
- HTTP 状态码为 `2xx`
- `code` 等于 `OK`
- 业务数据从 `data` 读取
SSE 流式接口不返回上述 JSON 包装,而是返回:
```text
event: <event_name>
data: {"key":"value"}
```
## 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` 可选,建议 `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` 用户状态 |
请求示例:
```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
{
"code": "OK",
"message": "success",
"data": {
"user_id": "37",
"source": "django_user_center",
"username": "13700000099",
"display_name": "Swagger测试",
"tenant_id": "1",
"role": "student",
"phone": "13700000099",
"avatar": "",
"gender": 0,
"institution_id": 1,
"institution_name": "某医院",
"department_id": 1,
"department_name": "儿科",
"status": 1
}
}
```
## 3. 训练页面接口
### 3.1 推荐配置信息
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|---|---|---|---|---|---|
| 推荐配置信息 | `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` 可选项 |
返回示例:
```json
{
"code": "OK",
"message": "success",
"data": {
"case_id": 1,
"recommended": {
"visit_environment": "outpatient",
"age_group": "child",
"education_level": "higher",
"personality": "calm"
},
"recommended_labels": {
"visit_environment": "门诊",
"age_group": "儿童",
"education_level": "高等教育",
"personality": "平和"
},
"options": {}
}
}
```
### 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": 1,
"training_type": "diagnosis_treatment",
"mode": "practice",
"score_type": "percentage",
"patient_config": {
"visit_environment": "outpatient",
"age_group": "child",
"education_level": "higher",
"personality": "calm"
}
}
```
### 3.4 流式会话
| 接口名称 | 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` 错误 |
SSE 返回示例:
```text
event: message_delta
data: {"delta":"发热有4天了,最高39度多。"}
event: message_done
data: {"latency_ms":1200,"first_token_ms":300,"model":"deepseek-chat","fallback_used":false}
```
### 3.5 王主任练习提示
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|---|---|---|---|---|---|
| 王主任练习提示 | `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` 错误 |
### 3.6 检查列表和结果
| 接口名称 | url | api | methods | params(入参) | response(返回参数) |
|---|---|---|---|---|---|
| 体格检查列表获取 | `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 阶段提交
| 接口名称 | 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` |
## 4. 教学互动接口
| 接口名称 | 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}/api/v1/evaluations/${evaluationId}/download-pdf`, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
"X-Entry-Scene": "vue_frontend",
},
});
if (!response.ok) throw new Error("PDF 下载失败");
const blob = await response.blob();
const url = URL.createObjectURL(blob);
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 | 含义 |
|---:|---|---|
| 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 用户中心超时或不可达 |