Files
huihuiSquare/digital-avatar-app/docs/IMAGE_MEDICAL_UNDERSTANDING_DESIGN.md

185 lines
7.5 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.
# 数字分身图片与病例理解详细设计
## 1. 目标与边界
本功能让数字分身在私聊和公开分享聊天中接收图片,并围绕图片内容继续使用现有的“标准答题对 -> 分身独立知识库 -> Qwen 兼容模型”链路回答。
第一期支持 JPEG、PNG、WebP,覆盖以下场景:
1. 普通照片、截图、图表和界面图片的内容理解。
2. 病例、处方、检查单、检验报告等图片文档的文字和表格提取。
3. X 光、CT、MRI 等医学影像的客观可见内容描述。
第一期不把通用视觉模型的输出当作医学诊断,不自动把图片或病例写入知识库,不保存原图供长期访问,也不支持 DICOM 原始影像。
## 2. 核心原则
- **资料优先级不变**:标准答题对最高,分身独立知识库其次,图片识别结果属于待核对的会话资料,最后才由模型组织表达。
- **病例最小留存**:应用不把原图写入业务存储,上传内容在内存中归一化并调用视觉服务;数据库只保存结构化结果和必要元数据。
- **严格隔离**:每条图片记录必须绑定 `avatar_id`,私聊校验分身所有者,公开聊天校验分享令牌对应的分身。
- **不确定性显式化**:OCR 看不清、表格列错位、医学影像无法确认时必须指出待核对项,不允许补齐缺失内容。
- **可计量**:视觉理解和病例 OCR 分别计入分身所有者的积分消耗,失败时释放预留积分。
- **可降级**:OCR 失败但通用视觉结果有效时仍可回答;视觉主调用失败则不进入聊天发送。
## 3. 总体流程
```text
用户选择图片
-> 前端本地预览
-> 私聊/公开图片上传接口
-> 文件大小、MIME、真实格式、像素数校验
-> 自动旋转、缩放、去 EXIF、统一 JPEG
-> 通用视觉模型分类并输出结构化 JSON
-> 若为病例/检查单,再调用 OCR 模型精确转录
-> 保存结构化结果,不持久化原图
-> 返回 attachmentId
-> 用户发送文字 + attachmentIds
-> 标准答题对匹配
-> 用文字 + 图片提取结果检索独立知识库
-> 把标准答案、知识片段、图片资料注入系统上下文
-> Qwen SSE 流式回答
```
## 4. 模型编排
### 4.1 通用视觉模型
默认 `qwen3.6-flash`,可在后台数字分身专用模型配置中修改。输入为归一化后的 Base64 Data URL,要求返回 JSON:
```json
{
"category": "general_image|document|medical_document|medical_image",
"summary": "客观、完整的图片描述",
"visible_text": "图片中可确认的文字",
"key_facts": ["事实1", "事实2"],
"uncertainties": ["无法确认的内容"],
"medical": {
"document_type": "",
"patient_info": {},
"chief_complaint": "",
"findings": [],
"measurements": [],
"doctor_advice": ""
}
}
```
模型提示词禁止诊断、补全被遮挡文字、猜测患者身份和输出模型信息。
### 4.2 病例 OCR
当 `category=medical_document` 时追加调用 `qwen-vl-ocr`,按原布局转录文字和表格。OCR 文本优先替换通用视觉输出中的 `visible_text`,但保留通用视觉模型提供的分类、摘要和不确定项。
### 4.3 医学影像
当 `category=medical_image` 时只保存客观描述,不输出疾病结论、分期、用药或治疗方案。聊天提示词必须要求结合正规影像报告和医生意见,并显示“图片识别结果仅供辅助,不能替代医生诊断”。
## 5. 数据模型
新增 `chat_attachments`:
| 字段 | 说明 |
|---|---|
| `id` | 不可猜测的附件 ID |
| `avatar_id` | 所属数字分身,强制隔离 |
| `filename` | 原文件名,去除路径 |
| `mime_type` / `file_size` | 上传元数据 |
| `status` | `processing / ready / failed` |
| `category` | 图片分类 |
| `summary` | 通用视觉摘要 |
| `extracted_text` | 可确认文字/OCR 结果 |
| `structured_data` | 结构化 JSON |
| `warning` | 不确定项和医学提示 |
| `vision_model` / `ocr_model` | 实际调用模型 |
| `created_at` / `used_at` | 创建和最近使用时间 |
不保存公开原图 URL。应用层不落盘原图;框架上传缓冲在请求结束时关闭,处理结果在 24 小时后自动清理。
## 6. API 设计
### 6.1 上传并解析
- `POST /api/avatar/{avatar_id}/chat/images`
- `POST /api/public/avatar/{share_token}/chat/images`
- `multipart/form-data: file`
成功返回:
```json
{
"id": "attachment-id",
"filename": "病例.jpg",
"status": "ready",
"category": "medical_document",
"summary": "门诊检查单",
"warning": "部分手写内容需要人工核对"
}
```
### 6.2 聊天
原聊天接口增加:
```json
{
"message": "请帮我看看异常指标",
"attachmentIds": ["attachment-id"],
"history": [
{"role": "user", "content": "上一条问题", "attachmentIds": ["attachment-id"]}
]
}
```
当前消息最多 3 张图,历史最多引用最近 3 个不同附件。后端只读取与当前 `avatar_id` 相同且状态为 `ready` 的记录。
## 7. 安全与隐私
- 单图最大 8MB,解码后最大 1600 万像素,最长边归一化到 4096 像素以内。
- 使用 Pillow 验证真实图片格式并防止解压炸弹;重新编码时清除 EXIF、GPS 和其他元数据。
- 图片不会写入 FastAPI `StaticFiles` 或知识库目录,模型请求和日志不得输出 Base64 内容。
- 日志只记录附件 ID、分身 ID、状态、耗时和模型,不记录图片 Base64、OCR 全文、病例内容或 API Key。
- 公开分享上传仍消耗分身所有者积分;余额不足时拒绝视觉调用。
- 生产环境需要补充用户授权、数据处理协议、存储地域和模型供应商留存策略确认。
## 8. 前端交互
- 输入框左侧增加图片按钮,支持相册选择和移动端拍照。
- 选择后显示本地缩略图和“正在识别图片”,识别完成前禁止发送。
- 用户可删除待发送图片;发送后图片保留在当前会话气泡中,但刷新页面后不恢复原图。
- 病例和医学影像在输入区及回答下方显示辅助提示,不使用恐吓式红色告警。
- 上传或识别失败时保留文字输入,明确提示重新选择图片,不产生空白消息。
## 9. 配置
数字分身专用模型配置新增:
- `vision_model_version`,默认 `qwen3.6-flash`
- `ocr_model_version`,默认 `qwen-vl-ocr`
环境变量兜底:
```dotenv
VISION_MODEL=qwen3.6-flash
VISION_OCR_MODEL=qwen-vl-ocr
VISION_MAX_OUTPUT_TOKENS=2048
VISION_TIMEOUT_SECONDS=90
VISION_TOKEN_RESERVE=12000
CHAT_IMAGE_MAX_BYTES=8388608
CHAT_IMAGE_MAX_PIXELS=16000000
CHAT_ATTACHMENT_RETENTION_HOURS=24
CHAT_ATTACHMENT_CLEANUP_MINUTES=60
```
视觉调用复用数字分身专用配置的 `api_base_url` 和 `api_key`,不额外复制密钥。
## 10. 验收标准
1. 普通照片、截图和图表能够返回与图片一致的描述并支持追问。
2. 病例图片可以提取标题、患者字段、检查结果、异常指标和医生意见,模糊内容明确标记待核对。
3. 上传后服务器业务目录不残留原图,响应和日志不包含 Base64 或完整病例正文。
4. A 分身无法引用 B 分身附件;公开分享令牌无法访问其他分身附件。
5. 有图片时标准答题对仍作为最高优先级事实,知识库命中次之。
6. 视觉与 OCR 积分分别结算,失败调用释放预留积分。
7. SSE 打字效果、Markdown、用户头像、公开分享和纯文本聊天均无回归。
8. CT、MRI、X 光回答不作确定诊断,并显示人工复核提示。