diff --git a/docs/03_api_design.md b/docs/03_api_design.md index 070b02e..231a77d 100644 --- a/docs/03_api_design.md +++ b/docs/03_api_design.md @@ -1,6 +1,6 @@ # 医疗问诊 Agent API 文档 -本文档面向前端联调,描述当前 FastAPI 后端已保留和可调用的接口。 +本文档面向前端联调,描述当前 FastAPI 后端可调用接口。训练模式和教学互动模式按页面模块分开书写;即使底层复用同一路由,文档中也在对应模块下分别列出,便于前端按页面开发。 公网基础地址: @@ -24,7 +24,13 @@ X-Entry-Scene: vue_frontend X-Request-Id: <可选> ``` -`Authorization` 使用 Django 用户中心签发的 access token。FastAPI 会转发 token 到 Django `/api/user/users/me/`,返回 200 后以 Django 用户 `id` 作为本服务的 `user_id`。 +参数说明: + +| 参数 | 位置 | 是否必填 | 说明 | +|---|---|---:|---| +| `Authorization` | Header | 是 | Django 用户中心签发的 access token,格式必须为 `Bearer ` | +| `X-Entry-Scene` | Header | 建议填 | 入口场景,例如 `vue_frontend`、`production_vue`、`mac_vue_dev` | +| `X-Request-Id` | Header | 否 | 前端生成的请求 ID,便于日志追踪 | 普通 JSON 接口统一返回: @@ -53,7 +59,7 @@ data: {"key":"value"} | 接口名称 | url | api | methods | params(入参) | response(返回参数) | |---|---|---|---|---|---| -| 当前用户信息 | `http://8.160.178.88/fastapi/api/v1/auth/me` | `/api/v1/auth/me` | `GET` | Header:`Authorization` 必填,格式 `Bearer `;`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://8.160.178.88/fastapi/api/v1/auth/me` | `/api/v1/auth/me` | `GET` | Header:`Authorization` 必填,格式 `Bearer `;`X-Entry-Scene` 建议填写 | `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` 用户状态 | 请求示例: @@ -74,11 +80,8 @@ curl -X GET "http://8.160.178.88/fastapi/api/v1/auth/me" \ "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, @@ -88,50 +91,40 @@ curl -X GET "http://8.160.178.88/fastapi/api/v1/auth/me" \ } ``` -## 3. 训练页面接口 - -### 3.1 推荐配置信息 +## 3. 病例基础接口 | 接口名称 | 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` 可选项 | +| 病例列表 | `http://8.160.178.88/fastapi/api/v1/cases` | `/api/v1/cases` | `GET` | Query:`department_id` 选填,科室 ID;`training_type` 选填,训练类型;`mode` 选填,交互模式 | `data.items[]` 病例列表,包含 `case_id`、`title`、`department_name`、`difficulty`、`chief_complaint` 等 | +| 病例详情 | `http://8.160.178.88/fastapi/api/v1/cases/{case_id}` | `/api/v1/cases/{case_id}` | `GET` | Path:`case_id` 必填,病例 ID | `data.case_id` 病例 ID;`data.title` 病例标题;`data.chief_complaint` 主诉;`data.supported_modes` 支持模式;`data.exam_item_types` 可用检查类型 | -返回示例: +说明:病例接口只读平台数据库中的已发布病例,不提供病例新增、删除、PDF 解析接口。 -```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": {} - } -} -``` +## 4. 训练模式 API -### 3.2 训练配置信息 +本节用于训练页面,包括推荐配置、自定义配置、新建会话、流式问诊、练习提示、检查申请、诊断治疗提交、评价生成、评价详情和 PDF 下载。 + +### 4.1 训练配置 | 接口名称 | 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` 性格 | +| 推荐配置信息 | `http://8.160.178.88/fastapi/api/v1/training-config/recommended` | `/api/v1/training-config/recommended` | `GET` | Query:`case_id` 必填,病例 ID | `data.case_id` 病例 ID;`data.recommended` 默认配置值;`data.recommended_labels` 默认配置中文名;`data.options` 可选项 | +| 训练配置信息 | `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 新建会话 +`patient_config` 可选值: + +| 字段 | 是否必填 | 允许值 | 说明 | +|---|---:|---|---| +| `visit_environment` | 是 | `outpatient`、`emergency`、`ward` | 门诊、急诊、病房 | +| `age_group` | 是 | `child`、`youth`、`middle_aged`、`elderly` | 儿童、青年、中年、老年 | +| `education_level` | 是 | `primary_or_below`、`secondary`、`higher` | 小学及以下、中等教育、高等教育 | +| `personality` | 是 | `calm`、`anxious`、`impatient`、`cooperative`、`suspicious` | 平和、焦虑、急躁、配合、多疑 | + +### 4.2 新建训练会话 | 接口名称 | 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` 实际使用的病人配置 | +| 新建会话 | `http://8.160.178.88/fastapi/api/v1/sessions` | `/api/v1/sessions` | `POST` | Body:`case_id` 必填,病例 ID;`training_type` 必填,当前使用 `diagnosis_treatment`;`mode` 必填,当前训练模式使用 `practice`,兼容旧值 `novice`;`score_type` 必填,`percentage` 或 `five_point`;`patient_config` 选填,病人初始化配置 | `data.session_id` 会话 ID;`data.session_code` 会话编码;`data.status` 当前阶段;`data.patient_opening` AI 病人开场白;`data.patient_config` 实际使用配置 | 请求示例: @@ -150,66 +143,117 @@ curl -X GET "http://8.160.178.88/fastapi/api/v1/auth/me" \ } ``` -### 3.4 流式会话 +### 4.3 流式会话 | 接口名称 | 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` 错误 | +| 流式会话 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/chat/stream` | `/api/v1/sessions/{session_id}/chat/stream` | `POST` | Path:`session_id` 必填,会话 ID;Body:`message` 必填,1-2000 字,医学生问诊内容 | SSE:`message_delta` AI 病人回复增量;`message_done` 完成事件;`error` 错误事件 | + +请求示例: + +```json +{ + "message": "孩子发热几天了?最高体温多少?" +} +``` SSE 返回示例: ```text event: message_delta -data: {"delta":"发热有4天了,最高39度多。"} +data: {"delta":"发热有4天了,最高烧到39度多。"} event: message_done -data: {"latency_ms":1200,"first_token_ms":300,"model":"deepseek-chat","fallback_used":false} +data: {"latency_ms":1200,"first_token_ms":300,"model":"deepseek-v4-pro","fallback_used":false} ``` -### 3.5 王主任练习提示 +### 4.4 王主任练习提示 | 接口名称 | 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` 错误 | +| 王主任练习提示 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/hints/stream` | `/api/v1/sessions/{session_id}/hints/stream` | `POST` | Path:`session_id` 必填,会话 ID;Body:`scope` 选填,固定 `current_conversation`;`last_user_message` 选填,最后一句用户问题 | SSE:`hint_delta` 提示文本增量;`hint_done` 完成事件;`error` 错误事件 | +| 结构化练习提示 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/hints` | `/api/v1/sessions/{session_id}/hints` | `POST` | Path:`session_id` 必填;Body:`scope` 选填,固定 `current_conversation`;`last_user_message` 选填 | `data.hints[]` 提示;`data.missing_dimensions[]` 缺失维度;`data.next_questions[]` 下一步问题;`data.recommended_orders[]` 推荐检查 | -### 3.6 检查列表和结果 +说明:当前前端主要使用流式提示接口,结构化提示接口作为备用能力保留。 + +### 4.5 体格检查 | 接口名称 | 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` | 同上 | +| 体格检查列表获取 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/physical-exams` | `/api/v1/sessions/{session_id}/physical-exams` | `GET` | Path:`session_id` 必填,会话 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` 必填,例如 `lung_auscultation` | `data.item_code` 检查编码;`data.item_name` 检查名称;`data.item_type` 检查类型;`data.result_text` 检查结果;`data.result_structured` 结构化结果;`data.is_key` 是否关键检查;`data.is_abnormal` 是否异常;`data.already_ordered` 是否已申请;`data.context_written` 是否写入上下文 | -### 3.7 阶段提交 +### 4.6 辅助检查 | 接口名称 | 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` | +| 辅助检查列表获取 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/auxiliary-exams` | `/api/v1/sessions/{session_id}/auxiliary-exams` | `GET` | Path:`session_id` 必填,会话 ID | `data.items[]` 当前病例可用辅助检查项;每项包含 `item_code`、`item_name`、`item_type` | +| 辅助检查某项结果 | `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` | `data.item_code` 检查编码;`data.item_name` 检查名称;`data.item_type` 检查类型;`data.result_text` 检查结果;`data.result_structured` 结构化结果;`data.is_key` 是否关键检查;`data.is_abnormal` 是否异常;`data.already_ordered` 是否已申请;`data.context_written` 是否写入上下文 | -## 4. 教学互动接口 +说明:检查结果只来自数据库 `case_exam_item`,不会由 LLM 编造。同一会话重复申请同一 `item_code` 时后端幂等返回已有结果。 + +### 4.7 阶段提交 | 接口名称 | 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[]` | +| 完成问诊 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/complete-inquiry` | `/api/v1/sessions/{session_id}/complete-inquiry` | `POST` | Path:`session_id` 必填,会话 ID | `data.session_id` 会话 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` | -## 5. 评价和个人中心接口 +诊断提交示例: + +```json +{ + "primary_diagnosis": "支气管肺炎", + "differential_diagnoses": ["毛细支气管炎", "支气管哮喘急性发作", "上呼吸道感染"], + "diagnosis_basis": "患儿发热、咳嗽、喘息,肺部湿啰音,炎症指标升高,胸片提示肺部感染,符合儿童支气管肺炎表现。" +} +``` + +治疗提交示例: + +```json +{ + "treatment_principle": "抗感染、止咳平喘、改善氧合、严密观察病情变化。", + "treatment_measures": "根据病情选择抗感染治疗,必要时雾化吸入缓解喘息,监测体温、呼吸、血氧和精神反应。", + "risk_plan": "关注低氧、呼吸困难加重、持续高热、精神反应差、脱水等情况。", + "communication": "向家属说明肺炎病情、用药注意事项、观察指标和复诊或住院指征。", + "follow_up": "治疗后复查体温、呼吸、血氧和必要炎症指标,症状加重时及时就诊。" +} +``` + +### 4.8 训练模式生成评价 | 接口名称 | url | api | methods | params(入参) | response(返回参数) | |---|---|---|---|---|---| -| 训练记录列表 | `http://8.160.178.88/fastapi/api/v1/evaluations?page=1&page_size=10` | `/api/v1/evaluations` | `GET` | Query:`page` 选填,页码,从1开始,默认1;`page_size` 选填,每页数量,1-100,默认10 | `data.items[]` 当前用户完整训练后的评价记录;`data.pagination` 分页信息 | -| 训练记录详情 / 评价详情 | `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` 文件流,浏览器可直接下载 | +| 训练模式生成评价 | `http://8.160.178.88/fastapi/api/v1/sessions/{session_id}/evaluation` | `/api/v1/sessions/{session_id}/evaluation` | `POST` | Path:`session_id` 必填,会话 ID;Body:`score_type` 选填,`percentage` 或 `five_point` | `data.evaluation_id` 评价 ID;`data.score_type` 分数类型;`data.total_score` 总分;`data.dimension_scores[]` 维度评分;`data.score_details[]` 评分明细;`data.errors[]` 问题;`data.improvement_plan[]` 改进建议;`data.overall_comment` 总评 | -PDF 下载前端写法: +请求示例: + +```json +{ + "score_type": "percentage" +} +``` + +### 4.9 训练模式获取评价详情 + +| 接口名称 | url | api | methods | params(入参) | response(返回参数) | +|---|---|---|---|---|---| +| 训练模式获取评价详情 | `http://8.160.178.88/fastapi/api/v1/evaluations/{evaluation_id}` | `/api/v1/evaluations/{evaluation_id}` | `GET` | Path:`evaluation_id` 必填,训练模式生成评价后返回的评价 ID | `data.session_id` 会话 ID;`data.case_id` 病例 ID;`data.case_title` 病例标题;`data.total_score` 总分;`data.dimension_scores[]` 维度评分;`data.score_details[]` 评分明细;`data.pdf_file_path` PDF 路径 | + +说明:该接口底层与教学互动评价详情复用,但训练页面应按训练模式评价详情使用。 + +### 4.10 训练模式下载 PDF + +| 接口名称 | url | api | methods | params(入参) | response(返回参数) | +|---|---|---|---|---|---| +| 训练模式下载 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` 必填,训练模式评价 ID | `application/pdf` 文件流,浏览器可直接下载 | + +前端下载示例: ```ts -async function downloadEvaluationPdf(baseUrl: string, token: string, evaluationId: number) { +async function downloadTrainingPdf(baseUrl: string, token: string, evaluationId: number) { const response = await fetch(`${baseUrl}/api/v1/evaluations/${evaluationId}/download-pdf`, { method: "GET", headers: { @@ -222,19 +266,112 @@ async function downloadEvaluationPdf(baseUrl: string, token: string, evaluationI const url = URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; - link.download = `evaluation-${evaluationId}.pdf`; + link.download = `training-evaluation-${evaluationId}.pdf`; link.click(); URL.revokeObjectURL(url); } ``` -## 6. AI 学习助手接口 +## 5. 教学互动 API -该接口用于普通用户医学知识问答。后端优先检索本机构知识库;如果机构知识库未初始化、Milvus / embedding 暂不可用或未命中来源,接口仍会继续调用 LLM,回答开头会声明“未检索到本机构知识库参考,以下为大模型通用学习回答。” +本节用于教学互动页面。教学互动不走训练问诊会话,不调用 `POST /api/v1/sessions`。前端先获取教学题列表,用户答题后直接生成教学互动评价。 + +### 5.1 获取教学列表 | 接口名称 | 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` 错误 | +| 教学互动获取教学列表 | `http://8.160.178.88/fastapi/api/v1/teaching/cases/{case_id}/items` | `/api/v1/teaching/cases/{case_id}/items` | `GET` | Path:`case_id` 必填,病例 ID | `data.case` 病例摘要;`data.teaching_goal` 教学目标;`data.teacher_guide` 教学指导;`data.scoring_focus` 评分重点;`data.questions[]` 题目列表,包含题干、选项、答案、解析文本和视频 | + +`data.questions[]` 字段: + +| 字段 | 说明 | +|---|---| +| `question_id` | 题目 ID | +| `question_type` | 题型,当前多为 `single_choice` | +| `stem` | 题干 | +| `options[]` | 选项数组,包含 `key` 和 `text` | +| `answer` | 标准答案 | +| `analysis` | 解析文本 | +| `video` | 教学视频,包含 `title` 和 `url` | +| `knowledge_points[]` | 知识点 | + +### 5.2 教学互动生成评价 + +| 接口名称 | url | api | methods | params(入参) | response(返回参数) | +|---|---|---|---|---|---| +| 教学互动生成评价 | `http://8.160.178.88/fastapi/api/v1/teaching/evaluation` | `/api/v1/teaching/evaluation` | `POST` | Body:`case_id` 必填,病例 ID;`answers[]` 必填,作答数组;`score_type` 选填,`percentage` 或 `five_point` | `data.evaluation_id` 评价 ID;`data.session_id` 教学互动内部会话 ID;`data.total_score` 总分;`data.dimension_scores[]` 维度评分;`data.score_details[]` 评分明细;`data.errors[]` 错误项;`data.improvement_plan[]` 改进建议 | + +请求示例: + +```json +{ + "case_id": 1, + "score_type": "percentage", + "answers": [ + { + "question_id": "q1", + "selected_answer": "A" + }, + { + "question_id": "q2", + "selected_answer": "C" + } + ] +} +``` + +### 5.3 教学互动获取评价详情 + +| 接口名称 | url | api | methods | params(入参) | response(返回参数) | +|---|---|---|---|---|---| +| 教学互动获取评价详情 | `http://8.160.178.88/fastapi/api/v1/evaluations/{evaluation_id}` | `/api/v1/evaluations/{evaluation_id}` | `GET` | Path:`evaluation_id` 必填,教学互动生成评价后返回的评价 ID | `data.session_id` 教学互动内部会话 ID;`data.case_id` 病例 ID;`data.case_title` 病例标题;`data.total_score` 总分;`data.dimension_scores[]` 维度评分;`data.score_details[]` 评分明细;`data.pdf_file_path` PDF 路径 | + +说明:该接口底层与训练模式评价详情复用,但教学互动页面应按教学互动评价详情使用。 + +### 5.4 教学互动下载 PDF + +| 接口名称 | url | api | methods | params(入参) | response(返回参数) | +|---|---|---|---|---|---| +| 教学互动下载 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` 必填,教学互动评价 ID | `application/pdf` 文件流,浏览器可直接下载 | + +前端下载示例: + +```ts +async function downloadTeachingPdf(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 = `teaching-evaluation-${evaluationId}.pdf`; + link.click(); + URL.revokeObjectURL(url); +} +``` + +## 6. 个人中心 API + +个人中心用于展示当前用户已经完整生成评价的训练记录和教学互动记录。 + +| 接口名称 | url | api | methods | params(入参) | response(返回参数) | +|---|---|---|---|---|---| +| 训练记录列表 | `http://8.160.178.88/fastapi/api/v1/evaluations?page=1&page_size=10` | `/api/v1/evaluations` | `GET` | Query:`page` 选填,页码,从 1 开始,默认 1;`page_size` 选填,每页数量,1-100,默认 10 | `data.items[]` 当前用户完整训练后的评价记录;`data.pagination.page` 当前页;`data.pagination.page_size` 每页数量;`data.pagination.total` 总数;`data.pagination.total_pages` 总页数;`data.pagination.has_next` 是否有下一页;`data.pagination.has_prev` 是否有上一页 | +| 训练记录详情 / 评价详情 | `http://8.160.178.88/fastapi/api/v1/evaluations/{evaluation_id}` | `/api/v1/evaluations/{evaluation_id}` | `GET` | Path:`evaluation_id` 必填,评价 ID | 完整评价详情,训练模式和教学互动共用 | + +## 7. AI 学习助手 API + +该接口用于普通用户医学知识问答。后端优先检索本机构知识库;如果机构知识库未初始化、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` 必填,1-1000 字;`top_k` 选填,1-10;`score_threshold` 选填,0-1 | SSE:`retrieval_done` 检索状态;`answer_delta` 回答增量;`answer_done` 完成事件;`error` 错误事件 | 请求示例: @@ -246,45 +383,26 @@ async function downloadEvaluationPdf(baseUrl: string, token: string, evaluationI } ``` -命中知识库时: - -```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. 后台预留:内容管理员知识库接口 +## 8. 内容管理员知识库 API 该组接口是后台内容管理员能力,学生端不展示上传入口。当前阶段保留接口和数据结构,后续生产环境接入完整 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` | +| 上传知识库 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` 文档 ID;`data.task_id` 任务 ID;`data.status` 文档状态;`data.parse_status` 解析状态;`data.embedding_status` 向量状态;`data.chunk_count` 分片数;`data.collection_name` Milvus 集合 | | 知识库文档列表 | `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. 常见错误码 +## 9. 健康检查 API -| HTTP状态 | code | 含义 | +| 接口名称 | url | api | methods | params(入参) | response(返回参数) | +|---|---|---|---|---|---| +| 存活检查 | `http://8.160.178.88/fastapi/health/live` | `/health/live` | `GET` | 无需认证 | 服务存活状态 | +| 就绪检查 | `http://8.160.178.88/fastapi/health/ready` | `/health/ready` | `GET` | 无需认证 | 服务就绪状态,包含配置、数据库、Redis 等检查结果 | + +## 10. 常见错误码 + +| HTTP 状态 | code | 含义 | |---:|---|---| | 401 | `AUTH_CREDENTIAL_REQUIRED` | 缺少 `Authorization` | | 401 | `AUTH_USER_INVALID` | token 无效、过期或 Django 返回非 200 |