From 9fabe39897fbce73e2f34570ffc4ef6d91ffe0a4 Mon Sep 17 00:00:00 2001 From: iven Date: Sat, 25 Apr 2026 12:29:00 +0800 Subject: [PATCH] =?UTF-8?q?docs(ai):=20erp-ai=20=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E8=A7=84=E6=A0=BC=20=E2=80=94=20AI=20?= =?UTF-8?q?=E6=99=BA=E8=83=BD=E5=88=86=E6=9E=90=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 erp-ai 模块完整设计文档,涵盖: - 模块架构(独立 crate,AiProvider trait 抽象) - 请求驱动 SSE 流式管道 + 混合管道演进路线 - 数据脱敏与安全防护层 - Prompt 数据库管理 + 版本控制 - 4 种分析场景(化验单/趋势/方案/摘要) - 3 张数据库表设计 - 4 Phase 扩展路线图 --- .../specs/2026-04-25-erp-ai-module-design.md | 399 ++++++++++++++++++ 1 file changed, 399 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-25-erp-ai-module-design.md diff --git a/docs/superpowers/specs/2026-04-25-erp-ai-module-design.md b/docs/superpowers/specs/2026-04-25-erp-ai-module-design.md new file mode 100644 index 0000000..e6d9787 --- /dev/null +++ b/docs/superpowers/specs/2026-04-25-erp-ai-module-design.md @@ -0,0 +1,399 @@ +# erp-ai 模块设计规格 + +> 日期: 2026-04-25 | 状态: 设计审批通过,待实施 +> 技术架构演进方向: 实时能力层 → AI 智能分析流 + +--- + +## 1. 背景与目标 + +HMS 健康管理平台已完成全部基础模块和健康业务模块的开发。为提升患者端体验、降低医患沟通成本,引入 **AI 智能分析能力**,让患者在小程序端即可获得化验单解读、健康趋势分析、个性化体检方案和报告摘要等 AI 驱动的自助服务。 + +**核心目标:** +- 患者按需获取 AI 流式解读,无需等待医生电话 +- 模型无关的 AI Gateway,支持多提供商切换和 A/B 测试 +- 严格数据脱敏,PII 不离开服务器 +- Prompt 模板数据库化管理,支持版本控制和回滚 +- 架构预留异步分析管道,平滑演进到混合模式 + +--- + +## 2. 模块定位 + +### 2.1 在 HMS 架构中的位置 + +``` +erp-core (ErpModule trait + EventBus + AppState) + ↑ +erp-health ──publish──→ {patient.lab-report.created, health.vital-signs.updated, ...} + ↑ +erp-ai (NEW) ──subscribe──→ health 事件 (Phase 3 预留) + ──publish──→ {ai.analysis.completed, ai.analysis.failed} + ↑ +erp-server (组装入口) +``` + +### 2.2 为什么是独立模块而非内嵌 + +- AI 是跨横切平台能力,非健康专属(未来消息、工作流、客服都可能用) +- 遵循 CLAUDE.md 铁律:业务 crate 之间禁止直接依赖 +- 通过 EventBus + `HealthDataProvider` trait 获取数据,模块边界清晰 +- 提供商切换、成本管理、脱敏策略全部内聚在 erp-ai 内部 + +--- + +## 3. 架构设计 + +### 3.1 Crate 结构 + +``` +crates/erp-ai/ +├── Cargo.toml +└── src/ + ├── lib.rs # 模块入口, ErpModule impl + ├── error.rs # AiError → AppError + ├── provider/ # AI 提供商抽象 + │ ├── mod.rs # AiProvider trait 定义 + │ ├── claude.rs # Claude API 实现 + │ ├── openai.rs # OpenAI API 实现 (Phase 2) + │ └── config.rs # 提供商配置 & 路由策略 + ├── pipeline/ # 分析管道 + │ ├── mod.rs # AnalysisPipeline trait + │ ├── request.rs # 请求驱动管道 (Phase 1, SSE) + │ └── async.rs # 异步管道 (Phase 3, stub) + ├── sanitization/ # 数据脱敏层 + │ ├── mod.rs # DeIdentificationService + │ └── rules.rs # 脱敏规则 + ├── prompt/ # Prompt 管理 + │ ├── mod.rs # PromptManager trait + │ └── template.rs # 模板渲染引擎 + ├── entity/ # SeaORM Entity + │ ├── ai_prompt.rs + │ ├── ai_analysis.rs + │ └── ai_usage.rs + ├── service/ # 业务逻辑 + │ ├── analysis.rs # AnalysisService (核心编排) + │ ├── prompt.rs # PromptService (CRUD + 版本) + │ └── usage.rs # UsageService (用量追踪) + └── handler/ # Axum 路由 + ├── mod.rs + ├── analysis.rs # SSE 流式分析端点 + ├── prompt.rs # Prompt 管理 CRUD + └── usage.rs # 用量统计端点 +``` + +### 3.2 核心抽象 + +```rust +/// AI 提供商 trait +#[async_trait] +pub trait AiProvider: Send + Sync { + async fn stream_generate(&self, req: GenerateRequest) -> Result>; + async fn generate(&self, req: GenerateRequest) -> Result; + fn name(&self) -> &str; + async fn health_check(&self) -> Result; +} + +/// 分析管道 trait (Phase 1: RequestPipeline; Phase 3: + AsyncPipeline) +pub trait AnalysisPipeline: Send + Sync { + fn analyze(&self, ctx: AnalysisContext) -> impl Stream; +} + +/// 数据脱敏 trait +pub trait DataSanitizer: Send + Sync { + fn sanitize(&self, data: &serde_json::Value) -> Result; +} +``` + +### 3.3 erp-core 扩展 + +```rust +/// 新增到 erp-core,由 erp-health 实现 +pub trait HealthDataProvider: Send + Sync { + async fn get_report_by_id(&self, tenant_id: Uuid, report_id: Uuid) -> AppResult; + async fn get_vital_signs(&self, tenant_id: Uuid, patient_id: Uuid, metrics: &[String], range: TimeRange) -> AppResult>; + async fn get_patient_summary(&self, tenant_id: Uuid, patient_id: Uuid) -> AppResult; + async fn get_full_report(&self, tenant_id: Uuid, report_id: Uuid) -> AppResult; +} + +/// 新增事件类型 +pub enum AiEvent { + AnalysisCompleted { analysis_id: Uuid, patient_id: Uuid, analysis_type: String }, + AnalysisFailed { analysis_id: Uuid, error: String }, +} + +/// 新增权限码 +pub const AI_PERMISSIONS: &[&str] = &[ + "ai.analysis.request", + "ai.analysis.view", + "ai.analysis.manage", + "ai.prompt.list", + "ai.prompt.manage", + "ai.usage.view", + "ai.admin.provider", +]; +``` + +--- + +## 4. 数据流设计 + +### 4.1 请求驱动管道 (Phase 1) + +``` +患者点击"AI解读" → POST /api/v1/ai/analyze/lab-report + → 鉴权 (JWT → tenant_id + user_id) + → 权限检查 (ai.analysis.request) + → 加载数据 (via HealthDataProvider trait) + → DeIdentificationService.sanitize() + → PromptManager.render(template, sanitized_data) + → AiProvider.stream_generate(prompt) + → SSE 流式返回给前端 + → 存储完整结果到 ai_analysis_results + → 记录用量到 ai_usage_logs + → 发布 ai.analysis.completed 事件 +``` + +### 4.2 SSE 事件格式 + +``` +event: chunk +data: {"content": "您的血常规检查中,", "index": 1} + +event: metadata +data: {"model": "claude-sonnet-4-6", "tokens": {"input": 856, "output": 423}, "duration_ms": 3200} + +event: done +data: {"analysis_id": "uuid-xxx", "status": "completed"} +``` + +### 4.3 四种分析场景 + +| 场景 | 端点 | 输入 | Prompt 模板 | +|------|------|------|------------| +| 化验单解读 | `POST /ai/analyze/lab-report` | report_id | lab_report_interpretation | +| 趋势分析 | `POST /ai/analyze/trends` | patient_id + metrics + 时间范围 | health_trend_analysis | +| 个性化方案 | `POST /ai/analyze/checkup-plan` | patient_id | personalized_checkup_plan | +| 报告摘要 | `POST /ai/analyze/report-summary` | report_id | report_summary_generation | + +--- + +## 5. 数据库设计 + +### 5.1 ai_prompts + +| 列 | 类型 | 说明 | +|----|------|------| +| id | UUID v7 | 主键 | +| tenant_id | UUID | 租户 | +| name | VARCHAR(100) | 模板标识 | +| description | TEXT | 用途描述 | +| system_prompt | TEXT | 系统角色 Prompt | +| user_prompt_template | TEXT | 用户 Prompt 模板 ({{variable}} 占位符) | +| variables_schema | JSONB | 模板变量 JSON Schema | +| model_config | JSONB | {provider, model, temperature, max_tokens} | +| version | INT | 语义版本(自增) | +| is_active | BOOLEAN | 当前激活版本 | +| category | VARCHAR(50) | analysis / summary / suggestion | +| tags | JSONB | 标签数组 | +| + 标准审计字段 | | tenant_id, created_at, updated_at, created_by, updated_by, deleted_at, version | + +### 5.2 ai_analysis_results + +| 列 | 类型 | 说明 | +|----|------|------| +| id | UUID v7 | 主键 | +| tenant_id | UUID | 租户 | +| patient_id | UUID | 患者 | +| analysis_type | VARCHAR(50) | lab_report / trend / checkup_plan / report_summary | +| source_ref | VARCHAR(200) | 来源引用 | +| prompt_id | UUID | 关联 Prompt | +| prompt_version | INT | Prompt 版本号 | +| model_used | VARCHAR(100) | 实际模型 | +| input_data_hash | VARCHAR(64) | SHA-256(缓存键) | +| sanitized_input | JSONB | 脱敏输入快照(审计) | +| result_content | TEXT | AI 完整输出 | +| result_metadata | JSONB | tokens/耗时/模型信息 | +| status | VARCHAR(20) | pending / streaming / completed / failed | +| error_message | TEXT | 失败原因 | +| + 标准审计字段 | | | + +### 5.3 ai_usage_logs + +| 列 | 类型 | 说明 | +|----|------|------| +| id | UUID v7 | 主键 | +| tenant_id | UUID | 租户 | +| provider | VARCHAR(50) | claude / openai / local | +| model | VARCHAR(100) | 具体模型 | +| analysis_type | VARCHAR(50) | 分析类型 | +| input_tokens | INT | | +| output_tokens | INT | | +| duration_ms | INT | | +| cost_cents | INT | 费用(分) | +| is_cache_hit | BOOLEAN | | +| created_at | TIMESTAMP | | + +--- + +## 6. 数据脱敏与安全 + +### 6.1 脱敏规则 + +- **移除**: 姓名、身份证号、手机号、地址、出生日期、医生姓名 +- **泛化**: 精确年龄 → 年龄段 (18-30, 30-40, 40-50, ...) +- **保留**: 科室、检验指标、诊断编码、用药记录、家族史 + +### 6.2 安全防护层 + +1. **速率限制**: 患者端 10次/天/人,管理端 100次/小时/租户 (Redis Token Bucket) +2. **输入验证**: schema 校验,租户隔离校验 +3. **Prompt 注入防护**: JSON 序列化注入,不做字符串拼接 +4. **输出过滤**: 正则扫描处方药推荐/诊断结论,强制追加免责声明 +5. **审计日志**: sanitized_input 保留脱敏快照 + +### 6.3 降级策略 + +``` +缓存命中 → 直接返回 +缓存未命中 + AI 可用 → 正常 SSE +缓存未命中 + AI 不可用 + 有旧版本 → 返回旧结果 + 标注 +缓存未命中 + AI 不可用 + 无历史 → 本地规则引擎(50 条常见指标) +``` + +--- + +## 7. API 设计 + +``` +/api/v1/ai/ +├── analyze/ +│ ├── POST /lab-report SSE 化验单解读 +│ ├── POST /trends SSE 健康趋势分析 +│ ├── POST /checkup-plan SSE 个性化体检方案 +│ └── POST /report-summary SSE 报告摘要生成 +├── analysis/ +│ ├── GET /history JSON 分析历史列表 +│ └── GET /:id JSON 分析详情 +├── prompts/ (需 ai.prompt.manage) +│ ├── GET / JSON Prompt 列表 +│ ├── POST / JSON 新建 Prompt +│ ├── GET /:id JSON Prompt 详情 +│ ├── PUT /:id JSON 编辑 (自动+1版本) +│ ├── POST /:id/activate JSON 激活指定版本 +│ ├── GET /:id/versions JSON 版本历史 +│ └── POST /:id/rollback JSON 回滚 +├── usage/ (需 ai.usage.view) +│ ├── GET /stats JSON 用量统计 +│ ├── GET /costs JSON 费用明细 +│ └── GET /models JSON 模型分布 +└── admin/ + ├── GET /providers JSON 提供商状态 + ├── PUT /providers/:name/config JSON 更新配置 + └── POST /providers/:name/test JSON 连通性测试 +``` + +--- + +## 8. 前端设计 + +### 8.1 小程序 (Phase 1) + +- 报告详情页新增「AI 智能解读」卡片,引导点击 +- 新增 AI 解读展示页,SSE 逐字流式渲染 +- 历史解读列表(点击查看过往分析) + +### 8.2 Web 管理后台 (Phase 2) + +- AI Prompt 管理页面:列表/编辑/版本历史/diff 对比/回滚 +- AI 用量统计仪表盘:按天/模型/场景维度 +- 提供商状态与配置管理 + +--- + +## 9. 扩展路线图 + +### Phase 1 — MVP (约 2-3 周) + +- erp-ai crate 骨架 + ErpModule 实现 +- AiProvider trait + Claude SSE 实现 +- DeIdentificationService +- PromptManager + 3 张表 + migration +- 4 个分析端点 +- 缓存 + 降级规则引擎 +- 小程序 AI 解读功能 +- 速率限制 + 审计日志 + +### Phase 2 — 运营强化 (约 2 周) + +- Web Prompt 管理完整 UI +- 版本 diff 对比 + 回滚 +- 用量统计仪表盘 +- OpenAI 提供商实现 +- 成本告警 +- 分享功能 + +### Phase 3 — 混合管道 (约 2-3 周) + +- AsyncAnalysisPipeline 实现 +- EventBus 订阅 health 事件 +- 后台预分析队列 +- 消息中心通知集成 +- WebSocket StreamingProvider 实现 +- 本地模型对接 (Ollama/vLLM) + +### Phase 4 — 智能化 (持续) + +- Prompt A/B 测试 +- 分析效果评分 +- 多轮对话式解读 +- 多模态输入 (OCR) +- 知识库 RAG + +### Phase 1 架构预留点 + +| 预留点 | 位置 | 做法 | +|--------|------|------| +| AnalysisPipeline trait | pipeline/mod.rs | RequestPipeline 唯一实现,Phase 3 加 AsyncPipeline | +| StreamingProvider trait | provider/mod.rs | SSE 唯一实现,Phase 3 加 WebSocket | +| AnalysisContext.trigger | pipeline/mod.rs | 枚举 Request \| Event,Phase 3 加 Event | +| HealthDataProvider trait | erp-core | erp-health 实现,erp-ai 注入使用 | +| 事件发布 | service/analysis.rs | 完成后发布事件,Phase 1 无消费者也发布 | +| model_config 字段 | ai_prompts 表 | 每模板独立配置 provider/model | + +--- + +## 10. 关键文件清单 + +| 区域 | 文件 | 操作 | +|------|------|------| +| erp-core | `src/trait.rs` | 新增 HealthDataProvider trait | +| erp-core | `src/event.rs` | 新增 ai.* 事件类型 | +| erp-core | `src/permission.rs` | 新增 ai.* 权限码 | +| erp-health | `src/ai_provider.rs` | 新增 HealthDataProvider impl | +| erp-ai | 整个 crate | 新建 | +| erp-server | `src/main.rs` | 注册 AiModule | +| erp-server/migration | 新增 migration | 3 张表 | +| apps/miniprogram | 报告详情页 + 解读页 | 新增/修改 | +| apps/web | Prompt 管理页面 | Phase 2 新增 | + +--- + +## 11. 验证方案 + +### 后端验证 +- `cargo check` — 全 workspace 编译通过 +- `cargo test -p erp-ai` — 单元测试覆盖 provider/sanitization/prompt/service +- 启动后端服务,通过 curl 测试 SSE 端点流式输出 +- 通过 Swagger UI 测试 Prompt CRUD 和用量统计端点 + +### 小程序验证 +- 打开报告详情页,确认「AI 解读」卡片展示 +- 点击触发 SSE 流式渲染,确认逐字输出效果 +- 测试缓存命中(第二次请求秒返回) +- 测试降级(停止 AI 服务后请求,确认降级提示) + +### 安全验证 +- 确认发送给 AI 的数据不包含 PII +- 确认速率限制生效(超过 10 次返回 429) +- 确认审计日志完整记录