18 KiB
18 KiB
医疗问诊 Agent API 文档
当前文档只描述前端联调需要的后端能力。
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 |
2. 通用规则
除健康检查外,所有业务接口都需要携带:
Authorization: Bearer <access_token>
X-Entry-Scene: vue_frontend
X-Request-Id: <可选>
普通 JSON 接口统一返回:
{
"code": "OK",
"message": "success",
"data": {}
}
前端判断规则:
- HTTP 状态码为
2xx code等于OK- 业务数据从
data读取
SSE 流式接口不返回上述 JSON 包装,而是返回 event + data 事件流。
3. 前置接口
3.1 当前用户
| 接口名称 | 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 用户中心字段。 |
请求示例:
GET /api/v1/auth/me
Authorization: Bearer <access_token>
X-Entry-Scene: vue_frontend
成功返回示例:
{
"code": "OK",
"message": "success",
"data": {
"user_id": "37",
"source": "django_user_center",
"username": "13700000099",
"display_name": "测试用户",
"tenant_id": "1",
"role": "student",
"phone": "13700000099",
"avatar": "",
"gender": 0,
"institution_id": 1,
"institution_name": "测试机构",
"department_id": 2,
"department_name": "儿科",
"status": 1
}
}
3.2 病例读取
| 接口名称 | 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。 |
病例入口展示信息,不返回标准答案、隐藏病史、检查结果和评分规则。 |
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 训练配置入参和返回示例
请求:
GET /api/v1/training-config/options?case_id=2
Authorization: Bearer <access_token>
X-Entry-Scene: vue_frontend
返回:
{
"code": "OK",
"message": "success",
"data": {
"case_id": 2,
"recommended": {
"visit_environment": "outpatient",
"age_group": "child",
"education_level": "higher",
"personality": "calm"
},
"recommended_labels": {
"visit_environment": "门诊",
"age_group": "儿童",
"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": "多疑"}
]
}
}
}
4.2 新建会话入参和返回示例
请求:
{
"case_id": 2,
"training_type": "diagnosis_treatment",
"mode": "practice",
"score_type": "percentage",
"patient_config": {
"visit_environment": "outpatient",
"age_group": "child",
"education_level": "higher",
"personality": "calm"
}
}
返回:
{
"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": "平和"
}
}
}
}
4.3 SSE 流式会话返回格式
请求:
{
"message": "孩子发热几天了?最高体温多少?"
}
返回:
event: message_delta
data: {"delta":"发热有4天了,"}
event: message_delta
data: {"delta":"最高烧到39度多。"}
event: message_done
data: {"latency_ms":1800,"first_token_ms":500,"model":"deepseek-chat","fallback_used":false}
4.4 检查结果返回示例
{
"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 诊断和治疗提交示例
提交诊断:
{
"primary_diagnosis": "支气管肺炎",
"differential_diagnoses": ["支气管哮喘急性发作", "上呼吸道感染"],
"diagnosis_basis": "结合发热、咳嗽、喘息、肺部湿啰音、胸片异常、炎症指标升高和血氧情况,符合儿童支气管肺炎表现。"
}
提交治疗:
{
"treatment_principle": "抗感染、止咳平喘、改善氧合并严密观察病情变化。",
"treatment_measures": "根据病情进行抗感染治疗,必要时雾化吸入缓解喘息,监测体温、呼吸和血氧。",
"risk_plan": "关注低氧、呼吸困难加重、持续高热、精神反应差和脱水。",
"communication": "向家属说明病情、用药注意事项、危险信号和复诊指征。",
"follow_up": "治疗后复查体温、呼吸、血氧和必要炎症指标。"
}
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 文件流。 |
获取教学列表返回示例:
{
"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": ["严重程度评估", "血氧判断"]
}
]
}
}
生成教学评价请求示例:
{
"case_id": 2,
"score_type": "percentage",
"answers": [
{"question_id": "q1", "selected_answer": "B"},
{"question_id": "q2", "selected_answer": "A"}
]
}
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 必填。 |
完整评价详情,训练和教学互动评价共用。 |
训练记录列表返回示例:
{
"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
}
]
}
}
7. PDF 下载前端写法
因为下载接口需要 Bearer token,前端不能直接使用普通 <a href>。使用 fetch 获取 blob 后触发下载:
async function downloadEvaluationPdf(baseUrl: string, token: string, evaluationId: number) {
const response = await fetch(`${baseUrl}/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}`);
}
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();
URL.revokeObjectURL(url);
}
8. 常见错误码
| 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 下载。
- 个人中心:训练记录列表、训练记录详情。