feat(ai): AI 健康管家 V2 基础设施 — 功能开关 + 角色沙箱准备 + 体征页 AI 趋势分析
- 迁移 000153: 新增 ai_feature_flags / ai_usage_daily / ai_suggestion_feedback 三张表, ai_tenant_configs 增加 billing_enabled 列, seed 12 个功能开关 + 2 个管理权限码 - 新增 FeatureFlagService: 5 分钟缓存 + DB 回退 + 即时更新 - VitalSignsTab 添加 AI 趋势分析按钮 (SSE 流式) - 新增 3 个 Entity (ai_feature_flags / ai_usage_daily / ai_suggestion_feedback) - AiState 扩展 feature_flags 字段 - 设计规格 + 讨论记录文档 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
119
docs/discussions/2026-05-18-ai-strategy-brainstorming.md
Normal file
119
docs/discussions/2026-05-18-ai-strategy-brainstorming.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# AI 功能战略方向发散式探讨
|
||||
|
||||
> 日期: 2026-05-18 | 参与者: 用户 + Claude
|
||||
|
||||
## 背景
|
||||
|
||||
HMS 健康管理平台综合评分 6.8/10,功能完整度 87%,但六维度分析评价 AI 为"有弹药没上膛"——底层能力完整(3 Provider + SSE 分析 + Copilot 引擎 + Agent Phase 0),用户触达断裂(4 个 SSE 端点无 UI 入口、客服"小华"仅为简单问答)。
|
||||
|
||||
在 AI Agent Phase 0 刚完成之际,对 AI 功能的五个维度进行全面发散式探讨,确定战略方向。
|
||||
|
||||
## 讨论维度与决策
|
||||
|
||||
### 维度 1:产品定位 — 统一入口"AI 健康管家"
|
||||
|
||||
**结论:统一入口"AI 健康管家"+ 分级沙箱隔离**
|
||||
|
||||
- 前端统一为一个入口——用户感知是"问小华"
|
||||
- 后端按角色创建隔离沙箱:患者沙箱、医护沙箱、管理沙箱
|
||||
- 每个沙箱有独立的 Tool 白名单、数据范围、Prompt 策略
|
||||
- 统一体验 ≠ 统一权限
|
||||
|
||||
**数据安全机制(5 层防护):**
|
||||
|
||||
| 风险层 | 防护措施 |
|
||||
|--------|----------|
|
||||
| 跨患者 | Tool 自动注入当前用户 patient_id,LLM 无法伪造 |
|
||||
| 跨租户 | session_id + tenant_id 双过滤,沿用现有中间件 |
|
||||
| 跨角色 | ToolRegistry.get_allowed_tools(role) 硬过滤,非 Prompt 约束 |
|
||||
| 越权 Tool | 后端按 role 限定可用 Tool 集合 |
|
||||
| Prompt 注入 | 输出层关键词检测 + 输入层 sanitize |
|
||||
|
||||
**三个角色沙箱定义:**
|
||||
|
||||
- **患者沙箱**:查自己体征/化验、科普知识、预约挂号。数据范围仅自己、输出脱敏。
|
||||
- **医护沙箱**:查所管患者、AI 分析、风险评分、文书辅助。数据范围本科室患者、含诊断信息。
|
||||
- **管理沙箱**:成本统计、用量趋势、效果分析、功能开关。数据范围本机构汇总、无个体数据。
|
||||
|
||||
### 维度 2:数据智能闭环 — 先打通最短路径
|
||||
|
||||
**结论:先 A(AI→用户可见),同步设计 B 数据结构,C 远期愿景**
|
||||
|
||||
- **A(1-2 周)**:Web 化验报告页"AI 解读"按钮 + 小程序体征页"AI 趋势分析"按钮。复用现有 SSE 端点,前端 3-5 天。
|
||||
- **B(2-4 周)**:Copilot 每日扫描高风险患者 → 生成洞察 → 消息中心推送 → 患者"采纳/忽略/咨询医生"反馈 → 数据写入 `ai_suggestion` 度量。
|
||||
- **C(3-6 个月)**:洞察 → 行动 → 效果追踪 → 模型优化的完整飞轮。
|
||||
|
||||
### 维度 3:多角色 AI 体验 — 角色 Prompt 为基础设施
|
||||
|
||||
**结论:A 必做,B 医护端最有价值,C 管理看板纳入第一阶段**
|
||||
|
||||
- **A(2-3 周)**:system_prompt 根据 user_role 动态组装。患者版温和通俗带情绪安抚、医护版专业简洁引用数据来源、管理版汇总对比。Tool Registry 按角色过滤。
|
||||
- **B(3-5 周)**:Web 后台右侧常驻 AI 侧边栏。查看患者档案时 AI 自动总结、随访页 AI 辅助生成小结。上下文感知的智能摘要,非对话模式。
|
||||
- **C**:合并到 AI 管理看板(见维度 5 + 跨维度决策)。
|
||||
|
||||
### 维度 4:技术架构 — 云端部署 + pgvector RAG + 在线/本地语音
|
||||
|
||||
**结论:纯云端部署,不调本地 LLM**
|
||||
|
||||
| 能力 | 技术选型 |
|
||||
|------|----------|
|
||||
| LLM 推理 | Claude / OpenAI(云端),Ollama 仅开发测试 |
|
||||
| RAG 知识库 | pgvector 扩展 PostgreSQL + 在线 Embedding API(text-embedding-3-small) |
|
||||
| 语音识别 | 在线:Whisper API / 讯飞;降级:Whisper.cpp (CPU) |
|
||||
| 语音合成 | 在线:OpenAI TTS / 讯飞;降级:edge-tts (免费) |
|
||||
|
||||
RAG 架构:知识文档 → 在线 Embedding API → pgvector 存储 → 用户提问 → 同款 Embedding → pgvector 语义检索 → Top-K 注入 Agent 上下文。
|
||||
|
||||
语音方案:默认在线 API(质量好、延迟低),降级时 CPU 本地(零成本、可接受延迟)。
|
||||
|
||||
### 维度 5 + 跨维度:AI 用量付费 + 综合管理看板
|
||||
|
||||
**结论:按机构(租户)颗粒度用量付费,管理看板与 AI 能力同步搭建**
|
||||
|
||||
**计费模式:**
|
||||
- 按机构月度 Token 用量阶梯计价
|
||||
- 基础 AI(本地规则引擎、Copilot 风险评分)不消耗 Token
|
||||
- 高级 AI(LLM 对话、化验解读、趋势分析)消耗 Token
|
||||
- 机构管理员可设预算上限和预警线
|
||||
|
||||
**管理看板模块:**
|
||||
|
||||
| 模块 | 内容 |
|
||||
|------|------|
|
||||
| 用量总览 | 调用量趋势、按角色/功能分布、峰值均值 |
|
||||
| 成本分析 | Token 消耗、按 Provider/功能类型、日/周/月、预算预警 |
|
||||
| 效果追踪 | 分析完成率、建议采纳率、异常检出率、人工干预率 |
|
||||
| 功能开关 | AI 分析(全局+按类型)、AI 聊天(全局+按角色)、AI 预警推送、RAG 知识检索、语音交互、Copilot 辅助 |
|
||||
| 配置管理 | Provider 配置、配额管理、Prompt 模板管理、知识库管理、告警阈值 |
|
||||
|
||||
**功能开关粒度:** 全局开关 + 按子功能开关,支持关闭单个功能而保留其他。
|
||||
|
||||
## 实施优先级共识
|
||||
|
||||
| 阶段 | 内容 | 工期 |
|
||||
|------|------|------|
|
||||
| **Phase 1A** | 打通 AI→用户可见(Web 化验 AI 解读按钮 + 小程序体征趋势分析按钮) | 1-2 周 |
|
||||
| **Phase 1B** | 角色分级 Prompt 策略 + Tool 权限沙箱 | 2-3 周 |
|
||||
| **Phase 1C** | AI 管理看板(用量/成本/效果/开关) | 2-3 周 |
|
||||
| Phase 1A/1B/1C 同步推进,1C 与 1A/1B 并行开发 |
|
||||
| **Phase 2A** | 医护端 AI 助手面板(侧边栏 + 患者摘要 + 随访辅助) | 3-5 周 |
|
||||
| **Phase 2B** | 洞察→推送→反馈闭环(Copilot 每日扫描 + 消息推送 + 采纳反馈) | 2-4 周 |
|
||||
| **Phase 3A** | RAG 知识库(pgvector + Embedding API + 语义检索 Tool) | 3-5 周 |
|
||||
| **Phase 3B** | 语音交互(在线为主 + CPU 降级) | 3-4 周 |
|
||||
| **远期** | 主动关怀引擎飞轮、多 Agent 协作、领域微调 | 6-12 个月 |
|
||||
|
||||
## 与现有 Agent 计划的关系
|
||||
|
||||
本次讨论的方向在已有 AI Agent 突破口设计(`docs/superpowers/specs/2026-05-18-ai-agent-breakthrough-design.md`)基础上扩展:
|
||||
|
||||
- Agent Phase 1-3 的 Tool 扩展、会话持久化、行动类 Tool **按原计划推进**
|
||||
- 新增:角色沙箱机制、管理看板、AI→UI 触点打通、RAG 知识库
|
||||
- 新增管理看板需要:`ai_feature_flags` 表(功能开关)、`ai_usage_daily` 聚合表(用量统计)
|
||||
- 计费相关:`ai_billing_records` 表(Token 消耗记录)、`ai_tenant_quotas` 扩展(月度预算)
|
||||
|
||||
## 待定事项
|
||||
|
||||
1. Embedding API 选型(OpenAI text-embedding-3-small vs 国内智谱/阿里)
|
||||
2. 语音服务商选型(讯飞 vs 阿里 Paraformer vs Whisper API)
|
||||
3. 管理看板是独立页面还是嵌入现有设置中心
|
||||
4. AI 用量付费的阶梯定价具体方案
|
||||
929
docs/superpowers/specs/2026-05-18-ai-health-butler-v2-design.md
Normal file
929
docs/superpowers/specs/2026-05-18-ai-health-butler-v2-design.md
Normal file
@@ -0,0 +1,929 @@
|
||||
# AI 健康管家 V2 设计规格
|
||||
|
||||
> **日期:** 2026-05-18 | **状态:** Draft | **范围:** erp-ai 角色沙箱 + 管理看板 + AI→UI 触点 + 计费 + 功能开关
|
||||
> **前置依赖:** AI Agent Phase 0(已完成)、讨论记录 `docs/discussions/2026-05-18-ai-strategy-brainstorming.md`
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
### 1.1 现状
|
||||
|
||||
HMS 的 AI 基础能力已具备(综合评分 6.8/10),但产品维度被评为"有弹药没上膛":
|
||||
|
||||
**已完成的能力:**
|
||||
|
||||
| 能力 | 实现状态 | 问题 |
|
||||
|------|----------|------|
|
||||
| 3 Provider(Claude/OpenAI/Ollama) | `AiProvider` trait + `ProviderRegistry` | 运行时每次 `get_provider("claude")` |
|
||||
| SSE 流式分析(化验/趋势/报告) | 4 个 SSE 端点 | **无 UI 入口** |
|
||||
| Copilot 引擎(风险评分/规则/洞察) | `CopilotEngine` + `InsightService` | **未触达用户** |
|
||||
| ReAct Agent + Function Calling | `AgentOrchestrator` + `ToolRegistry` + 1 Tool | Phase 0 完成,无角色隔离 |
|
||||
| 配额/成本管控 | `QuotaService` + `UsageService` + `CacheService` | 按月 Token 预算,无功能维度 |
|
||||
| AI 配置管理 | `config_resolver` + `AiConfigPage.tsx` | Agent/Provider/分析配置,无功能开关 |
|
||||
| 知识库框架 | KDIGO 规则 + 结构化源 | 无 RAG 语义检索 |
|
||||
|
||||
**核心断裂点:**
|
||||
|
||||
1. **AI 能力断裂** — 后端分析能力完整,但用户无法触发(4 个 SSE 端点无按钮)
|
||||
2. **角色无区分** — `chat_handler` 所有用户同一 Prompt、同一 Tool 集,无沙箱隔离
|
||||
3. **管控无度量** — `UsageService` 只有分析数量统计,无 Token 成本/功能维度/效果追踪
|
||||
4. **功能无开关** — `ai_tenant_configs` 有月度预算但无功能级启用/禁用
|
||||
|
||||
### 1.2 本次设计目标
|
||||
|
||||
基于 2026-05-18 五维度战略讨论的结论,本次设计覆盖 4 个模块:
|
||||
|
||||
| 模块 | 目标 | 优先级 |
|
||||
|------|------|--------|
|
||||
| **角色沙箱** | 统一入口"小华" + 按角色隔离的 Tool/Prompt/数据范围 | P0 |
|
||||
| **AI→UI 触点** | Web 化验 AI 解读 + 小程序体征趋势分析 | P0 |
|
||||
| **管理看板** | 用量/成本/效果/开关四位一体的 AI 管理中心 | P0 |
|
||||
| **计费基础设施** | 按机构月度用量的 Token 消耗记录和聚合 | P1 |
|
||||
|
||||
**与已有 Agent Phase 1-3 的关系:**
|
||||
|
||||
- Agent Phase 1(Tool 扩展)→ 本次设计为其增加角色权限过滤
|
||||
- Agent Phase 2(会话持久化)→ 本次设计为其增加管理看板的数据查询
|
||||
- Agent Phase 3(行动 Tool)→ 本次设计为其增加功能开关管控
|
||||
|
||||
### 1.3 设计原则
|
||||
|
||||
1. **安全优先** — 数据隔离通过后端硬约束实现,不依赖 Prompt 约束
|
||||
2. **复用现有** — `QuotaService`/`UsageService`/`HealthDataProvider` 全部复用
|
||||
3. **渐进交付** — Phase 1A/1B/1C 可并行,不阻塞
|
||||
4. **云端部署** — 生产环境只用云端 LLM,Ollama 仅开发测试
|
||||
|
||||
---
|
||||
|
||||
## 2. 角色沙箱架构
|
||||
|
||||
### 2.1 架构概览
|
||||
|
||||
当前 `chat_handler` 为所有用户构建相同的 `ToolRegistry` 和 `system_prompt`。改造为:
|
||||
|
||||
```
|
||||
┌──────────────────┐
|
||||
│ 统一入口 │
|
||||
│ POST /ai/chat │
|
||||
└────────┬─────────┘
|
||||
│ TenantContext (JWT)
|
||||
┌────────▼─────────┐
|
||||
│ SessionRouter │ ← 新增
|
||||
│ 根据 role 选择 │
|
||||
│ 沙箱配置 │
|
||||
└────────┬─────────┘
|
||||
│
|
||||
┌───────────────────┼───────────────────┐
|
||||
│ │ │
|
||||
┌────────▼────────┐ ┌───────▼────────┐ ┌───────▼────────┐
|
||||
│ 患者沙箱 │ │ 医护沙箱 │ │ 管理沙箱 │
|
||||
│ Prompt: 通俗温和 │ │ Prompt: 专业简洁│ │ Prompt: 汇总分析│
|
||||
│ Tools: 4 个 │ │ Tools: 7 个 │ │ Tools: 3 个 │
|
||||
│ 数据: 仅自己 │ │ 数据: 所管患者 │ │ 数据: 机构汇总 │
|
||||
└─────────────────┘ └────────────────┘ └────────────────┘
|
||||
```
|
||||
|
||||
### 2.2 SandboxConfig 定义
|
||||
|
||||
```rust
|
||||
/// 角色沙箱配置
|
||||
pub struct SandboxConfig {
|
||||
pub role: UserRole,
|
||||
pub system_prompt: String,
|
||||
pub allowed_tools: Vec<String>,
|
||||
pub data_scope: DataScope,
|
||||
pub output_filters: Vec<OutputFilter>,
|
||||
}
|
||||
|
||||
pub enum UserRole {
|
||||
Patient,
|
||||
MedicalStaff,
|
||||
Admin,
|
||||
}
|
||||
|
||||
pub enum DataScope {
|
||||
/// 仅自己关联的患者数据
|
||||
OwnOnly { patient_id: Uuid },
|
||||
/// 本科室/机构下的患者数据
|
||||
DepartmentScope { department_id: Option<Uuid> },
|
||||
/// 机构级汇总数据,无个体数据
|
||||
TenantAggregate,
|
||||
}
|
||||
|
||||
pub enum OutputFilter {
|
||||
/// 移除诊断术语(对患者隐藏)
|
||||
RemoveDiagnosisTerms,
|
||||
/// 追加"请以医生诊断为准"免责声明
|
||||
AppendDisclaimer,
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 三级沙箱详细定义
|
||||
|
||||
#### 患者沙箱
|
||||
|
||||
```yaml
|
||||
role: Patient
|
||||
system_prompt: |
|
||||
你是 HMS 健康管理平台的 AI 健康顾问"小华"。
|
||||
你面对的是患者本人,请遵循以下原则:
|
||||
1. 用通俗语言解释,避免医学术语
|
||||
2. 先共情再给建议,患者可能焦虑或恐惧
|
||||
3. 不要给出明确诊断,只解释数据含义
|
||||
4. 鼓励患者配合治疗,分享积极案例
|
||||
5. 任何建议后追加"具体请以医生诊断为准"
|
||||
allowed_tools:
|
||||
- query_patient_vitals # 查自己的体征数据
|
||||
- query_lab_reports # 查自己的化验报告
|
||||
- query_patient_profile # 查自己的基本信息
|
||||
- search_medical_knowledge # 科普知识检索
|
||||
data_scope: OwnOnly (patient_id from JWT)
|
||||
output_filters: [RemoveDiagnosisTerms, AppendDisclaimer]
|
||||
```
|
||||
|
||||
#### 医护沙箱
|
||||
|
||||
```yaml
|
||||
role: MedicalStaff
|
||||
system_prompt: |
|
||||
你是 HMS 健康管理平台的 AI 医疗助手。
|
||||
你面对的是医护人员,请遵循以下原则:
|
||||
1. 使用专业术语,提供数据来源引用
|
||||
2. 辅助决策但不替代诊断,标注置信度
|
||||
3. 风险评估引用 KDIGO 等标准
|
||||
4. 对异常值主动提示,给出临床意义
|
||||
5. 支持随访小结生成和文书辅助
|
||||
allowed_tools:
|
||||
- query_patient_vitals
|
||||
- query_lab_reports
|
||||
- query_patient_profile
|
||||
- query_appointments
|
||||
- analyze_lab_report # 触发 AI 化验解读
|
||||
- analyze_health_trends # 触发 AI 趋势分析
|
||||
- get_health_insights # 获取 Copilot 洞察
|
||||
data_scope: DepartmentScope (department_id from user profile)
|
||||
output_filters: []
|
||||
```
|
||||
|
||||
#### 管理沙箱
|
||||
|
||||
```yaml
|
||||
role: Admin
|
||||
system_prompt: |
|
||||
你是 HMS 健康管理平台的 AI 运营助手。
|
||||
你面对的是机构管理员,请遵循以下原则:
|
||||
1. 提供数据驱动的运营建议
|
||||
2. 对比分析不同时段/科室的指标变化
|
||||
3. 标注异常波动和潜在问题
|
||||
4. 建议优化措施并预估效果
|
||||
allowed_tools:
|
||||
- query_ai_usage_stats # AI 用量统计
|
||||
- query_ai_cost_stats # AI 成本统计
|
||||
- query_ai_effectiveness # AI 效果统计
|
||||
data_scope: TenantAggregate
|
||||
output_filters: []
|
||||
```
|
||||
|
||||
### 2.4 Tool 权限矩阵
|
||||
|
||||
| Tool 名称 | 患者 | 医护 | 管理员 | 阶段 |
|
||||
|-----------|------|------|--------|------|
|
||||
| `query_patient_vitals` | ✅ (仅自己) | ✅ (所管患者) | ❌ | Phase 0 ✅ |
|
||||
| `query_lab_reports` | ✅ (仅自己) | ✅ (所管患者) | ❌ | Phase 1 |
|
||||
| `query_patient_profile` | ✅ (仅自己) | ✅ (所管患者) | ❌ | Phase 1 |
|
||||
| `query_appointments` | ❌ | ✅ | ❌ | Phase 1 |
|
||||
| `analyze_lab_report` | ❌ | ✅ | ❌ | Phase 1 |
|
||||
| `analyze_health_trends` | ❌ | ✅ | ❌ | Phase 1 |
|
||||
| `get_health_insights` | ❌ | ✅ | ❌ | Phase 2 |
|
||||
| `search_medical_knowledge` | ✅ | ✅ | ❌ | Phase 3 |
|
||||
| `query_ai_usage_stats` | ❌ | ❌ | ✅ | Phase 1 |
|
||||
| `query_ai_cost_stats` | ❌ | ❌ | ✅ | Phase 1 |
|
||||
| `query_ai_effectiveness` | ❌ | ❌ | ✅ | Phase 2 |
|
||||
| `create_appointment` | ❌ | ❌ | ❌ | Phase 3 (行动类) |
|
||||
| `transfer_to_human` | ❌ | ❌ | ❌ | Phase 3 (行动类) |
|
||||
|
||||
### 2.5 SessionRouter 实现
|
||||
|
||||
`SessionRouter` 负责根据 JWT 中的用户角色构建沙箱配置:
|
||||
|
||||
```rust
|
||||
impl SessionRouter {
|
||||
pub fn resolve(&self, ctx: &TenantContext) -> SandboxConfig {
|
||||
match ctx.role.as_str() {
|
||||
"patient" => self.build_patient_sandbox(ctx),
|
||||
"doctor" | "nurse" => self.build_medical_sandbox(ctx),
|
||||
"admin" | "tenant_admin" => self.build_admin_sandbox(ctx),
|
||||
_ => self.build_patient_sandbox(ctx), // 默认最小权限
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**关键安全约束:**
|
||||
|
||||
1. `ToolContext.patient_id` — 患者角色从 JWT 提取(不可伪造),医护角色从请求参数获取(后端验证所管范围)
|
||||
2. `ToolRegistry::filter_by_role()` — 从全局注册表中过滤出角色允许的 Tool 子集
|
||||
3. `system_prompt` — 不由前端传递,由后端根据角色硬编码生成
|
||||
4. **输出过滤** — 患者角色追加免责声明、移除诊断术语(关键词替换,不依赖 LLM 自律)
|
||||
|
||||
### 2.6 chat_handler 改造
|
||||
|
||||
当前 `chat_handler` 在每次请求中内联创建 `ToolRegistry`。改造后:
|
||||
|
||||
```rust
|
||||
// 改造前
|
||||
let mut registry = ToolRegistry::new();
|
||||
registry.register(Arc::new(QueryPatientVitalsTool));
|
||||
|
||||
// 改造后
|
||||
let sandbox = session_router.resolve(&ctx);
|
||||
let registry = global_tool_registry.filter_by_role(&sandbox.allowed_tools);
|
||||
let system_prompt = sandbox.system_prompt.clone();
|
||||
```
|
||||
|
||||
`global_tool_registry` 在 `AiState` 初始化时一次性注册所有 Tool,后续请求只做过滤,无需重复创建。
|
||||
|
||||
### 2.7 AiState 扩展
|
||||
|
||||
```rust
|
||||
pub struct AiState {
|
||||
// ... 现有字段 ...
|
||||
pub global_tool_registry: Arc<ToolRegistry>, // 新增:全局 Tool 注册
|
||||
pub session_router: Arc<SessionRouter>, // 新增:会话路由
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. AI→UI 触点打通
|
||||
|
||||
### 3.1 问题
|
||||
|
||||
当前系统有 4 个 SSE 流式分析端点(化验解读、趋势分析、体检方案、报告摘要),但前端没有任何按钮或入口触发它们。AI 分析能力完全沉睡在后端。
|
||||
|
||||
### 3.2 触点设计
|
||||
|
||||
#### Web 端触点(2 个)
|
||||
|
||||
**触点 1:化验报告详情页"AI 解读"按钮**
|
||||
|
||||
位置:`LabReportDetail.tsx` 化验报告详情页,报告基本信息下方。
|
||||
|
||||
交互流程:
|
||||
```
|
||||
用户打开化验报告详情 → 看到"AI 智能解读"按钮 → 点击 →
|
||||
SSE 流式加载 → 逐字展示解读结果 → 完成后可折叠/展开
|
||||
```
|
||||
|
||||
技术实现:
|
||||
- 前端调用现有 `POST /api/v1/ai/analysis/stream` 端点(`analysis_type: "lab_report"`)
|
||||
- SSE 流复用现有 `AnalysisSseEvent` 协议
|
||||
- 解读结果展示为卡片组件,包含异常指标高亮
|
||||
- 调用前走 `QuotaService` 检查配额
|
||||
|
||||
**触点 2:患者体征页"AI 趋势分析"按钮**
|
||||
|
||||
位置:`PatientVitals.tsx` 患者体征页,体征图表区域上方。
|
||||
|
||||
交互流程:
|
||||
```
|
||||
医护查看患者体征 → 点击"AI 趋势分析" → 选择时间范围 →
|
||||
SSE 流式加载 → 展示趋势分析结果(异常模式/风险提示/建议)
|
||||
```
|
||||
|
||||
技术实现:
|
||||
- 调用 `POST /api/v1/ai/analysis/stream` 端点(`analysis_type: "trend"`)
|
||||
- 需传入 `patient_id` 和时间范围参数
|
||||
- 趋势分析结果以 Markdown 渲染,异常值用红色标注
|
||||
|
||||
#### 小程序触点(2 个)
|
||||
|
||||
**触点 3:体征记录页"AI 健康摘要"**
|
||||
|
||||
位置:小程序体征录入/查看页,体征数据下方。
|
||||
|
||||
交互:
|
||||
```
|
||||
用户查看体征记录 → 页面底部"AI 健康摘要"卡片 →
|
||||
非流式请求 → 展示最近 7 天体征的 AI 总结
|
||||
```
|
||||
|
||||
技术实现:
|
||||
- 新增端点 `GET /api/v1/ai/analysis/health-summary?patient_id=xxx`
|
||||
- 走非流式(小程序 SSE 支持有限),一次返回完整结果
|
||||
- 后端调用 `AnalysisService` 的趋势分析 + Copilot 风险评分
|
||||
- 返回结构化 JSON(包含 `summary_text` + `risk_level` + `suggestions[]`)
|
||||
|
||||
**触点 4:AI 聊天入口(复用已有 `/ai/chat`)**
|
||||
|
||||
位置:小程序首页悬浮按钮或 Tab 页内的"问小华"入口。
|
||||
|
||||
交互:与 Agent 聊天接口集成,角色自动识别为患者沙箱。
|
||||
|
||||
### 3.3 触点与 Agent 的集成
|
||||
|
||||
所有 AI→UI 触点共用以下基础设施:
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ 前端触点层 │
|
||||
│ Web 化验按钮 / Web 趋势按钮 / MP 摘要 / MP 聊天 │
|
||||
└───────────────────┬──────────────────────────────┘
|
||||
│
|
||||
┌───────────────────▼──────────────────────────────┐
|
||||
│ 调用量记录层 │
|
||||
│ 每次调用 → UsageService.log_usage() │
|
||||
│ 记录: tenant_id / user_id / feature / tokens │
|
||||
└───────────────────┬──────────────────────────────┘
|
||||
│
|
||||
┌───────────────────▼──────────────────────────────┐
|
||||
│ 功能开关检查层 │
|
||||
│ FeatureFlagService.is_enabled(tenant, feature) │
|
||||
│ 禁用时返回友好提示而非错误 │
|
||||
└───────────────────┬──────────────────────────────┘
|
||||
│
|
||||
┌───────────────────▼──────────────────────────────┐
|
||||
│ 配额检查层 │
|
||||
│ QuotaService.check_quota(tenant_id, patient_id) │
|
||||
│ 超限时返回降级提示 │
|
||||
└───────────────────┬──────────────────────────────┘
|
||||
│
|
||||
┌───────────────────▼──────────────────────────────┐
|
||||
│ AI 能力层 │
|
||||
│ AnalysisService / AgentOrchestrator / Copilot │
|
||||
└──────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3.4 前端组件设计
|
||||
|
||||
**AiAnalysisCard 组件**(Web 端通用):
|
||||
|
||||
```tsx
|
||||
interface AiAnalysisCardProps {
|
||||
analysisType: 'lab_report' | 'trend' | 'health_summary';
|
||||
sourceRef: string; // 化验报告 ID / 患者 ID
|
||||
patientId?: string;
|
||||
triggerLabel?: string; // 按钮文字
|
||||
collapsible?: boolean; // 是否可折叠
|
||||
}
|
||||
```
|
||||
|
||||
- 加载态:骨架屏 + "AI 正在分析..."
|
||||
- 成功态:Markdown 渲染 + 异常指标高亮
|
||||
- 错误态:友好提示 + 重试按钮
|
||||
- 配额耗尽:提示联系管理员
|
||||
- 功能关闭:提示"该功能暂未开放"
|
||||
|
||||
---
|
||||
|
||||
## 4. AI 管理看板
|
||||
|
||||
### 4.1 页面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ AI 管理中心 [AiConfigPage] │
|
||||
├─────────┬───────────────────────────────────────────────┤
|
||||
│ 侧边栏 │ 主内容区 │
|
||||
│ │ │
|
||||
│ 📊 总览 │ ┌─────────────────────────────────────────┐ │
|
||||
│ 💰 成本 │ │ 用量总览 │ │
|
||||
│ 📈 效果 │ │ ┌───────┐ ┌───────┐ ┌───────┐ ┌──────┐│ │
|
||||
│ ⚙️ 开关 │ │ │ 今日 │ │ 本月 │ │ 峰值 │ │ 预算 ││ │
|
||||
│ 🔧 配置 │ │ │ 1,234 │ │45,678 │ │ 3,200 │ │ 78% ││ │
|
||||
│ │ │ └───────┘ └───────┘ └───────┘ └──────┘│ │
|
||||
│ │ │ [调用量趋势图 — 近 30 天折线] │ │
|
||||
│ │ │ [按功能分布饼图] │ │
|
||||
│ │ └─────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ │ ┌─────────────────────────────────────────┐ │
|
||||
│ │ │ 成本分析 │ │
|
||||
│ │ │ Token 消耗趋势 / Provider 占比 │ │
|
||||
│ │ │ 月度预算进度条 / 预警阈值 │ │
|
||||
│ │ └─────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ │ ┌─────────────────────────────────────────┐ │
|
||||
│ │ │ 效果追踪 │ │
|
||||
│ │ │ 分析完成率 / 建议采纳率 │ │
|
||||
│ │ │ 异常检出率 / 人工干预率 │ │
|
||||
│ │ └─────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ │ ┌─────────────────────────────────────────┐ │
|
||||
│ │ │ 功能开关 │ │
|
||||
│ │ │ AI 分析 [ON] AI 聊天 [ON] 预警 [OFF] │ │
|
||||
│ │ │ RAG 检索 [ON] 语音 [OFF] Copilot [ON] │ │
|
||||
│ │ └─────────────────────────────────────────┘ │
|
||||
└─────────┴───────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 4.2 用量总览模块
|
||||
|
||||
**数据源:** `ai_usage` 表(现有)+ `ai_usage_daily` 聚合表(新增)
|
||||
|
||||
**API 端点:**
|
||||
|
||||
| 端点 | 说明 | 权限码 |
|
||||
|------|------|--------|
|
||||
| `GET /ai/admin/usage/overview` | 今日/本月/峰值/预算使用率 | `ai.admin.dashboard` |
|
||||
| `GET /ai/admin/usage/trend?days=30` | 近 N 天调用量趋势 | `ai.admin.dashboard` |
|
||||
| `GET /ai/admin/usage/by-feature` | 按功能分布 | `ai.admin.dashboard` |
|
||||
| `GET /ai/admin/usage/by-role` | 按角色分布 | `ai.admin.dashboard` |
|
||||
|
||||
**用量概览响应:**
|
||||
|
||||
```typescript
|
||||
interface UsageOverview {
|
||||
today: {
|
||||
totalCalls: number;
|
||||
totalTokens: number;
|
||||
inputTokens: number;
|
||||
outputTokens: number;
|
||||
};
|
||||
thisMonth: {
|
||||
totalCalls: number;
|
||||
totalTokens: number;
|
||||
budgetUsed: number; // 百分比
|
||||
budgetRemaining: number;
|
||||
};
|
||||
peak: {
|
||||
dailyCalls: number;
|
||||
peakDate: string;
|
||||
};
|
||||
trend: Array<{
|
||||
date: string;
|
||||
calls: number;
|
||||
tokens: number;
|
||||
}>;
|
||||
byFeature: Array<{
|
||||
feature: string;
|
||||
calls: number;
|
||||
tokens: number;
|
||||
}>;
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 成本分析模块
|
||||
|
||||
**数据源:** `ai_usage.cost_cents` 字段(现有)+ 按月聚合
|
||||
|
||||
**API 端点:**
|
||||
|
||||
| 端点 | 说明 |
|
||||
|------|------|
|
||||
| `GET /ai/admin/cost/summary` | 本月成本/日均/按 Provider 分布 |
|
||||
| `GET /ai/admin/cost/trend?months=6` | 近 N 个月成本趋势 |
|
||||
| `GET /ai/admin/cost/by-provider` | 按 Provider 成本分布 |
|
||||
|
||||
**成本聚合逻辑:**
|
||||
|
||||
`ai_usage` 表已有 `cost_cents` 字段。新增 `ai_usage_daily` 聚合表,每日凌晨定时任务聚合前一天的用量:
|
||||
|
||||
```sql
|
||||
-- 每日聚合
|
||||
INSERT INTO ai_usage_daily (tenant_id, date, feature, provider, model,
|
||||
total_calls, total_input_tokens, total_output_tokens, total_cost_cents)
|
||||
SELECT tenant_id, DATE(created_at), analysis_type, provider, model,
|
||||
COUNT(*), SUM(input_tokens), SUM(output_tokens), SUM(cost_cents)
|
||||
FROM ai_usage
|
||||
WHERE created_at >= CURRENT_DATE - INTERVAL '1 day'
|
||||
AND created_at < CURRENT_DATE
|
||||
GROUP BY tenant_id, DATE(created_at), analysis_type, provider, model
|
||||
ON CONFLICT (tenant_id, date, feature, provider, model)
|
||||
DO UPDATE SET
|
||||
total_calls = EXCLUDED.total_calls,
|
||||
total_input_tokens = EXCLUDED.total_input_tokens,
|
||||
total_output_tokens = EXCLUDED.total_output_tokens,
|
||||
total_cost_cents = EXCLUDED.total_cost_cents;
|
||||
```
|
||||
|
||||
**预算预警:** 当月度用量达到预算的 80%/90%/100% 时,通过消息中心推送预警。
|
||||
|
||||
### 4.4 效果追踪模块
|
||||
|
||||
**数据源:** `ai_analysis` 表 + `ai_suggestion` 表
|
||||
|
||||
**指标定义:**
|
||||
|
||||
| 指标 | 计算方式 | 说明 |
|
||||
|------|----------|------|
|
||||
| 分析完成率 | `completed / (completed + failed)` × 100% | AI 分析任务成功率 |
|
||||
| 建议采纳率 | `adopted / (adopted + dismissed)` × 100% | 用户采纳 AI 建议的比例 |
|
||||
| 异常检出率 | `有异常发现的分析 / 总分析` × 100% | AI 发现异常的能力 |
|
||||
| 人工干预率 | `人工覆盖次数 / 总建议` × 100% | 医护对 AI 建议的修正频率 |
|
||||
|
||||
**API 端点:**
|
||||
|
||||
| 端点 | 说明 |
|
||||
|------|------|
|
||||
| `GET /ai/admin/effectiveness/summary` | 效果指标汇总 |
|
||||
| `GET /ai/admin/effectiveness/trend?months=6` | 效果趋势 |
|
||||
| `GET /ai/admin/effectiveness/by-feature` | 按功能的效果 |
|
||||
|
||||
### 4.5 功能开关系统
|
||||
|
||||
#### 数据模型
|
||||
|
||||
新增 `ai_feature_flags` 表(每个租户每个功能一条记录):
|
||||
|
||||
```sql
|
||||
CREATE TABLE ai_feature_flags (
|
||||
id UUID PRIMARY KEY,
|
||||
tenant_id UUID NOT NULL,
|
||||
feature VARCHAR(100) NOT NULL, -- 功能标识
|
||||
is_enabled BOOLEAN NOT NULL DEFAULT true,
|
||||
config JSONB, -- 功能级配置(如限制条件)
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_by UUID,
|
||||
UNIQUE(tenant_id, feature)
|
||||
);
|
||||
```
|
||||
|
||||
#### 功能标识定义
|
||||
|
||||
| feature | 说明 | 默认 | 影响范围 |
|
||||
|---------|------|------|----------|
|
||||
| `ai.analysis.lab_report` | 化验报告 AI 解读 | ON | Web 触点 1 |
|
||||
| `ai.analysis.trend` | 趋势分析 | ON | Web 触点 2 |
|
||||
| `ai.analysis.report_summary` | 报告摘要 | ON | SSE 端点 |
|
||||
| `ai.analysis.checkup_plan` | 体检方案 | ON | SSE 端点 |
|
||||
| `ai.chat` | AI 聊天(小华) | ON | 全平台聊天 |
|
||||
| `ai.chat.patient` | 患者端聊天 | ON | 小程序聊天 |
|
||||
| `ai.chat.staff` | 医护端聊天 | ON | Web 聊天 |
|
||||
| `ai.alert.push` | AI 主动预警推送 | OFF | 消息中心 |
|
||||
| `ai.rag` | RAG 知识检索 | OFF | Agent Tool |
|
||||
| `ai.voice` | 语音交互 | OFF | 小程序 |
|
||||
| `ai.copilot.risk` | Copilot 风险评分 | ON | 后台辅助 |
|
||||
| `ai.copilot.insight` | Copilot 洞察服务 | ON | 后台辅助 |
|
||||
|
||||
#### 功能开关检查逻辑
|
||||
|
||||
```rust
|
||||
impl FeatureFlagService {
|
||||
/// 检查功能是否启用(缓存 5 分钟)
|
||||
pub async fn is_enabled(&self, tenant_id: Uuid, feature: &str) -> bool {
|
||||
// 1. 查缓存
|
||||
// 2. 缓存未命中 → 查 ai_feature_flags 表
|
||||
// 3. 记录不存在 → 默认 true(功能默认启用)
|
||||
// 4. 记录存在 → 返回 is_enabled
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**开关与触点的集成:** 每个 AI→UI 触点在调用前先检查功能开关:
|
||||
|
||||
```rust
|
||||
// 触点层伪代码
|
||||
if !feature_flag_service.is_enabled(ctx.tenant_id, "ai.analysis.lab_report").await {
|
||||
return Err(AppError::FeatureDisabled("AI 化验解读功能暂未开放".into()));
|
||||
}
|
||||
```
|
||||
|
||||
前端也做一次检查(隐藏按钮/灰显),但后端为权威判断。
|
||||
|
||||
#### API 端点
|
||||
|
||||
| 端点 | 说明 | 权限码 |
|
||||
|------|------|--------|
|
||||
| `GET /ai/admin/flags` | 获取所有功能开关状态 | `ai.admin.flags` |
|
||||
| `PUT /ai/admin/flags/{feature}` | 更新功能开关 | `ai.admin.flags` |
|
||||
| `GET /ai/admin/flags/{feature}/public` | 前端查询(无敏感信息) | `ai.chat.send` |
|
||||
|
||||
### 4.6 管理看板权限
|
||||
|
||||
新增权限码:
|
||||
|
||||
| 权限码 | 说明 |
|
||||
|--------|------|
|
||||
| `ai.admin.dashboard` | 查看管理看板(用量/成本/效果) |
|
||||
| `ai.admin.flags` | 管理功能开关 |
|
||||
| `ai.admin.config` | 管理 AI 配置(已有,扩展) |
|
||||
|
||||
权限码分配:`tenant_admin` 角色默认拥有全部管理权限。
|
||||
|
||||
### 4.7 前端路由与组件
|
||||
|
||||
```
|
||||
/apps/web/src/pages/ai/
|
||||
├── AiAdminPage.tsx # 管理看板主页
|
||||
├── components/
|
||||
│ ├── UsageOverview.tsx # 用量总览
|
||||
│ ├── CostAnalysis.tsx # 成本分析
|
||||
│ ├── EffectivenessTracker.tsx # 效果追踪
|
||||
│ ├── FeatureFlags.tsx # 功能开关
|
||||
│ └── UsageTrendChart.tsx # 趋势图组件
|
||||
```
|
||||
|
||||
路由注册:
|
||||
|
||||
```typescript
|
||||
{
|
||||
path: '/ai/admin',
|
||||
component: AiAdminPage,
|
||||
permissions: ['ai.admin.dashboard'],
|
||||
}
|
||||
```
|
||||
|
||||
菜单配置:在"AI 管理"菜单下新增"管理看板"子菜单。
|
||||
|
||||
---
|
||||
|
||||
## 5. 计费数据模型
|
||||
|
||||
### 5.1 计费模式
|
||||
|
||||
**按机构(租户)月度用量阶梯计价:**
|
||||
|
||||
- 每个 `tenant_id` 每月独立统计 Token 消耗
|
||||
- 不同 AI 功能统一折算为 Token 消耗
|
||||
- 基础 AI(Copilot 规则引擎、本地风险评分)不消耗 Token
|
||||
- 高级 AI(LLM 对话、化验解读、趋势分析、报告摘要)消耗 Token
|
||||
- 机构管理员可在看板中查看用量和预算进度
|
||||
|
||||
### 5.2 计费数据流
|
||||
|
||||
```
|
||||
用户触发 AI 功能 → AI 执行 → UsageService.log_usage() → ai_usage 表
|
||||
│
|
||||
每日凌晨聚合 ↓
|
||||
ai_usage_daily 表
|
||||
│
|
||||
管理看板查询 ↓
|
||||
用量/成本/趋势
|
||||
```
|
||||
|
||||
### 5.3 Token 成本计算
|
||||
|
||||
沿用现有 `ai_usage.cost_cents` 字段。成本计算公式:
|
||||
|
||||
```
|
||||
cost_cents = (input_tokens × input_price + output_tokens × output_price) / 1000
|
||||
```
|
||||
|
||||
价格表(每 1000 tokens,单位:分):
|
||||
|
||||
| Provider | 模型 | input_price | output_price |
|
||||
|----------|------|-------------|--------------|
|
||||
| Claude | claude-sonnet-4-6 | 0.3 | 1.5 |
|
||||
| Claude | claude-opus-4-7 | 1.5 | 7.5 |
|
||||
| OpenAI | gpt-4o | 0.25 | 1.0 |
|
||||
| OpenAI | gpt-4o-mini | 0.015 | 0.06 |
|
||||
|
||||
价格可通过 `settings` 表配置(`ai.billing.{provider}.{model}.input_price`)。
|
||||
|
||||
### 5.4 与现有 quota 系统的关系
|
||||
|
||||
`QuotaService` 已有月度 Token 预算检查(`monthly_token_budget`)。本次扩展:
|
||||
|
||||
- 现有 `ai_tenant_configs` 表增加 `billing_enabled` 字段(是否启用计费追踪)
|
||||
- 现有 `QuotaService.check_quota()` 逻辑不变
|
||||
- 新增 `BillingService` 负责成本计算和聚合,不替换 `QuotaService`
|
||||
|
||||
```rust
|
||||
pub struct BillingService {
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl BillingService {
|
||||
/// 获取租户本月账单摘要
|
||||
pub async fn get_monthly_summary(&self, tenant_id: Uuid) -> BillingSummary {
|
||||
// 从 ai_usage_daily 聚合本月数据
|
||||
}
|
||||
|
||||
/// 获取租户历史月度账单
|
||||
pub async fn get_billing_history(
|
||||
&self,
|
||||
tenant_id: Uuid,
|
||||
months: u32,
|
||||
) -> Vec<MonthlyBill> {
|
||||
// 从 ai_usage_daily 按月聚合
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 数据模型变更
|
||||
|
||||
### 6.1 新增表
|
||||
|
||||
#### ai_feature_flags — AI 功能开关
|
||||
|
||||
```sql
|
||||
CREATE TABLE ai_feature_flags (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
feature VARCHAR(100) NOT NULL,
|
||||
is_enabled BOOLEAN NOT NULL DEFAULT true,
|
||||
config JSONB,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_by UUID,
|
||||
CONSTRAINT uq_feature_flags_tenant_feature UNIQUE(tenant_id, feature)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_feature_flags_tenant ON ai_feature_flags(tenant_id);
|
||||
```
|
||||
|
||||
Entity: `crates/erp-ai/src/entity/ai_feature_flags.rs`
|
||||
|
||||
#### ai_usage_daily — 用量日聚合
|
||||
|
||||
```sql
|
||||
CREATE TABLE ai_usage_daily (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
date DATE NOT NULL,
|
||||
feature VARCHAR(100) NOT NULL, -- analysis_type / chat / copilot
|
||||
provider VARCHAR(50) NOT NULL,
|
||||
model VARCHAR(100) NOT NULL,
|
||||
total_calls INT NOT NULL DEFAULT 0,
|
||||
total_input_tokens BIGINT NOT NULL DEFAULT 0,
|
||||
total_output_tokens BIGINT NOT NULL DEFAULT 0,
|
||||
total_cost_cents BIGINT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT uq_usage_daily UNIQUE(tenant_id, date, feature, provider, model)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_usage_daily_tenant_date ON ai_usage_daily(tenant_id, date DESC);
|
||||
CREATE INDEX idx_usage_daily_tenant_month ON ai_usage_daily(tenant_id, (date_trunc('month', date)));
|
||||
```
|
||||
|
||||
Entity: `crates/erp-ai/src/entity/ai_usage_daily.rs`
|
||||
|
||||
#### ai_suggestion_feedback — AI 建议反馈(效果追踪用)
|
||||
|
||||
```sql
|
||||
CREATE TABLE ai_suggestion_feedback (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
suggestion_id UUID NOT NULL, -- 关联 ai_suggestion.id
|
||||
user_id UUID NOT NULL,
|
||||
action VARCHAR(20) NOT NULL, -- adopted / dismissed / modified
|
||||
feedback_text TEXT, -- 用户反馈备注
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_suggestion_feedback_tenant ON ai_suggestion_feedback(tenant_id);
|
||||
CREATE INDEX idx_suggestion_feedback_suggestion ON ai_suggestion_feedback(suggestion_id);
|
||||
```
|
||||
|
||||
Entity: `crates/erp-ai/src/entity/ai_suggestion_feedback.rs`
|
||||
|
||||
### 6.2 现有表扩展
|
||||
|
||||
#### ai_tenant_configs 增加 billing_enabled 字段
|
||||
|
||||
```sql
|
||||
ALTER TABLE ai_tenant_configs ADD COLUMN billing_enabled BOOLEAN NOT NULL DEFAULT false;
|
||||
```
|
||||
|
||||
Entity: `ai_tenant_config.rs` 增加 `billing_enabled: bool` 字段。
|
||||
|
||||
### 6.3 迁移文件
|
||||
|
||||
单个迁移文件 `m20260518_000149_ai_health_butler_v2.rs`,包含:
|
||||
|
||||
1. 创建 `ai_feature_flags` 表
|
||||
2. 创建 `ai_usage_daily` 表
|
||||
3. 创建 `ai_suggestion_feedback` 表
|
||||
4. `ai_tenant_configs` 增加 `billing_enabled` 列
|
||||
5. Seed 12 个功能开关的默认值(全部 ON,`ai.alert.push` 和 `ai.voice` 除外)
|
||||
6. Seed 3 个新权限码(`ai.admin.dashboard` / `ai.admin.flags` / `ai.admin.config` 扩展)
|
||||
|
||||
### 6.4 新增 Rust 文件清单
|
||||
|
||||
| 文件路径 | 说明 |
|
||||
|----------|------|
|
||||
| `crates/erp-ai/src/entity/ai_feature_flags.rs` | 功能开关 Entity |
|
||||
| `crates/erp-ai/src/entity/ai_usage_daily.rs` | 用量日聚合 Entity |
|
||||
| `crates/erp-ai/src/entity/ai_suggestion_feedback.rs` | 建议反馈 Entity |
|
||||
| `crates/erp-ai/src/service/feature_flag_service.rs` | 功能开关服务 |
|
||||
| `crates/erp-ai/src/service/billing_service.rs` | 计费服务 |
|
||||
| `crates/erp-ai/src/service/daily_aggregation.rs` | 日聚合定时任务 |
|
||||
| `crates/erp-ai/src/agent/sandbox.rs` | 沙箱配置 |
|
||||
| `crates/erp-ai/src/agent/session_router.rs` | 会话路由 |
|
||||
| `crates/erp-ai/src/handler/admin_handler.rs` | 管理端点 |
|
||||
| `apps/web/src/api/ai/admin.ts` | 管理端 API 模块 |
|
||||
| `apps/web/src/pages/ai/AiAdminPage.tsx` | 管理看板页面 |
|
||||
| `apps/web/src/pages/ai/components/UsageOverview.tsx` | 用量总览组件 |
|
||||
| `apps/web/src/pages/ai/components/CostAnalysis.tsx` | 成本分析组件 |
|
||||
| `apps/web/src/pages/ai/components/EffectivenessTracker.tsx` | 效果追踪组件 |
|
||||
| `apps/web/src/pages/ai/components/FeatureFlags.tsx` | 功能开关组件 |
|
||||
| `apps/web/src/components/ai/AiAnalysisCard.tsx` | AI 分析卡片组件(通用) |
|
||||
|
||||
---
|
||||
|
||||
## 7. 实施计划
|
||||
|
||||
### 7.1 Phase 1:基础设施 + 首批触点(3-4 周)
|
||||
|
||||
Phase 1 的三个子阶段可并行推进:
|
||||
|
||||
#### Phase 1A:AI→UI 触点打通(1-2 周)
|
||||
|
||||
| # | 任务 | 类型 | 文件 |
|
||||
|---|------|------|------|
|
||||
| 1A-1 | Web 化验报告页添加"AI 解读"按钮 | 前端 | `LabReportDetail.tsx` + `AiAnalysisCard.tsx` |
|
||||
| 1A-2 | Web 患者体征页添加"AI 趋势分析"按钮 | 前端 | `PatientVitals.tsx` |
|
||||
| 1A-3 | 小程序体征页"AI 健康摘要"卡片 | 前端 | MP 体征页 + 新增 `health-summary` 端点 |
|
||||
| 1A-4 | 功能开关检查中间件集成 | 后端 | 各 AI handler 添加 `FeatureFlagService` 检查 |
|
||||
| 1A-5 | 调用量统一记录(所有触点 → `UsageService`) | 后端 | 各 AI handler 添加 `log_usage()` |
|
||||
|
||||
**验证标准:**
|
||||
- Web 化验报告页点击"AI 解读"可触发 SSE 流式分析
|
||||
- Web 体征页点击"AI 趋势分析"可获取趋势报告
|
||||
- 所有 AI 调用记录到 `ai_usage` 表
|
||||
- 功能开关关闭时按钮灰显/隐藏
|
||||
|
||||
#### Phase 1B:角色沙箱(2-3 周)
|
||||
|
||||
| # | 任务 | 类型 | 文件 |
|
||||
|---|------|------|------|
|
||||
| 1B-1 | `SandboxConfig` / `SessionRouter` 实现 | 后端 | `agent/sandbox.rs` + `agent/session_router.rs` |
|
||||
| 1B-2 | `ToolRegistry::filter_by_role()` 方法 | 后端 | `agent/registry.rs` |
|
||||
| 1B-3 | 三套角色 Prompt 模板 | 后端 | `config_resolver.rs` 扩展 |
|
||||
| 1B-4 | `chat_handler` 改造(全局 Registry + 沙箱过滤) | 后端 | `handler/chat_handler.rs` |
|
||||
| 1B-5 | `AiState` 增加 `global_tool_registry` + `session_router` | 后端 | `state.rs` + `main.rs` |
|
||||
| 1B-6 | 输出过滤器(患者角色免责声明 + 诊断术语移除) | 后端 | `agent/output_filter.rs`(新文件) |
|
||||
| 1B-7 | 沙箱集成测试(3 角色 × Tool 权限 × 数据范围) | 测试 | `tests/agent_sandbox.rs` |
|
||||
|
||||
**验证标准:**
|
||||
- 患者角色只能调用 `query_patient_vitals` / `query_lab_reports` / `query_patient_profile` / `search_medical_knowledge`
|
||||
- 医护角色额外可调用 `analyze_lab_report` / `analyze_health_trends` / `get_health_insights`
|
||||
- 管理角色只能调用统计类 Tool
|
||||
- 患者角色输出自动追加免责声明
|
||||
- 所有角色数据范围受 `tenant_id` + 角色约束
|
||||
|
||||
#### Phase 1C:管理看板 + 功能开关(2-3 周)
|
||||
|
||||
| # | 任务 | 类型 | 文件 |
|
||||
|---|------|------|------|
|
||||
| 1C-1 | 数据库迁移(3 新表 + 1 扩展 + seed) | 迁移 | `m20260518_000149_ai_health_butler_v2.rs` |
|
||||
| 1C-2 | `FeatureFlagService` 实现(含缓存) | 后端 | `service/feature_flag_service.rs` |
|
||||
| 1C-3 | `BillingService` 实现(月度汇总/历史) | 后端 | `service/billing_service.rs` |
|
||||
| 1C-4 | `DailyAggregationTask` 定时任务 | 后端 | `service/daily_aggregation.rs` |
|
||||
| 1C-5 | 管理 API 端点(用量/成本/效果/开关) | 后端 | `handler/admin_handler.rs` |
|
||||
| 1C-6 | 权限码 seed(`ai.admin.dashboard` / `ai.admin.flags`) | 迁移 | 同 1C-1 |
|
||||
| 1C-7 | Web 管理看板页面(4 个子模块) | 前端 | `AiAdminPage.tsx` + 4 个子组件 |
|
||||
| 1C-8 | 前端 API 模块 | 前端 | `api/ai/admin.ts` |
|
||||
| 1C-9 | 菜单注册("AI 管理" → "管理看板") | 前端 | 路由配置 |
|
||||
|
||||
**验证标准:**
|
||||
- 管理看板展示今日/本月调用量、Token 消耗、预算进度
|
||||
- 功能开关可在看板中开启/关闭,实时生效
|
||||
- 日聚合任务正确运行,`ai_usage_daily` 数据正确
|
||||
- `ai.admin.dashboard` / `ai.admin.flags` 权限码生效
|
||||
|
||||
### 7.2 Phase 2:医护助手 + 闭环推送(4-6 周)
|
||||
|
||||
> 依赖 Phase 1 完成。
|
||||
|
||||
| # | 任务 | 说明 |
|
||||
|---|------|------|
|
||||
| 2A-1 | 医护端 AI 侧边栏组件 | Web 后台右侧常驻,查看患者时自动总结 |
|
||||
| 2A-2 | 上下文感知智能摘要 | 读取当前页面患者数据,调用 Agent 生成摘要 |
|
||||
| 2A-3 | 随访记录 AI 辅助生成 | 随访页面,AI 辅助生成随访小结 |
|
||||
| 2B-1 | Copilot 每日扫描定时任务 | 定时扫描高风险患者 |
|
||||
| 2B-2 | 洞察→消息中心推送 | 生成洞察后推送到医护/患者 |
|
||||
| 2B-3 | 建议反馈机制 | 患者"采纳/忽略/咨询医生"UI + 数据记录 |
|
||||
| 2B-4 | 效果追踪指标计算 | 从 `ai_suggestion_feedback` 计算采纳率等指标 |
|
||||
|
||||
### 7.3 Phase 3:RAG + 语音(4-6 周)
|
||||
|
||||
> 依赖 Phase 1 完成,与 Phase 2 可部分并行。
|
||||
|
||||
| # | 任务 | 说明 |
|
||||
|---|------|------|
|
||||
| 3A-1 | pgvector 扩展安装 | PostgreSQL 扩展 |
|
||||
| 3A-2 | Embedding API 集成 | 调用在线 Embedding 模型 |
|
||||
| 3A-3 | 知识库管理 API | 上传/编辑/删除/向量化知识条目 |
|
||||
| 3A-4 | `search_medical_knowledge` Tool 升级 | 从规则匹配升级为语义检索 |
|
||||
| 3A-5 | 知识库管理 UI | 管理看板中的知识库 tab |
|
||||
| 3B-1 | 语音识别集成 | Whisper API / 讯飞 |
|
||||
| 3B-2 | 语音合成集成 | OpenAI TTS / edge-tts |
|
||||
| 3B-3 | 小程序语音输入/输出 | 语音按钮 + 播放 |
|
||||
|
||||
### 7.4 总体时间线
|
||||
|
||||
```
|
||||
Week 1-2 ████████ Phase 1A (AI→UI 触点)
|
||||
Week 1-3 ██████████ Phase 1B (角色沙箱)
|
||||
Week 2-4 ████████████ Phase 1C (管理看板)
|
||||
Week 5-8 ████████████████ Phase 2 (医护助手 + 闭环)
|
||||
Week 5-10 ████████████████████████ Phase 3 (RAG + 语音)
|
||||
```
|
||||
|
||||
Phase 1 总工期 3-4 周,Phase 2-3 可部分并行,整体 8-12 周完成。
|
||||
|
||||
---
|
||||
|
||||
## 8. 待定事项
|
||||
|
||||
| # | 待定项 | 决策时机 | 影响 |
|
||||
|---|--------|----------|------|
|
||||
| 1 | Embedding API 选型(OpenAI vs 智谱 vs 阿里) | Phase 3 启动前 | RAG 知识库成本和质量 |
|
||||
| 2 | 语音服务商选型(讯飞 vs 阿里 Paraformer vs Whisper) | Phase 3 启动前 | 语音质量和成本 |
|
||||
| 3 | 管理看板独立页面 vs 嵌入现有设置中心 | Phase 1C 启动前 | 前端路由结构 |
|
||||
| 4 | 阶梯定价具体方案 | Phase 1C 启动前 | 计费逻辑 |
|
||||
| 5 | `ai_usage_daily` 聚合用 cron 任务 vs应用内定时器 | Phase 1C 实现时 | 运维复杂度 |
|
||||
| 6 | 诊断术语移除的关键词列表 | Phase 1B 实现时 | 输出过滤精度 |
|
||||
| 7 | 医护端 AI 侧边栏与现有页面布局的冲突 | Phase 2 启动前 | UI 布局方案 |
|
||||
| 8 | Copilot 每日扫描的频率和范围 | Phase 2B 实现时 | 推送频率控制 |
|
||||
Reference in New Issue
Block a user