docs(wiki): 更新 erp-ai 模块 — Ollama 对接 + bug 修复记录
- index.md: 迁移 123 个, 提交 577 次, 新增 AI 分析症状导航 4 条 - erp-ai.md: 新增 §4 Ollama 本地模型对接、已知限制、已修复 bug - erp-ai.md: 更新 SSE 流程图(预校验 + 缓存回放修复) - erp-ai.md: 3 个管理前端页面已实现
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
---
|
||||
title: erp-ai AI 分析模块
|
||||
updated: 2026-05-03
|
||||
updated: 2026-05-05
|
||||
status: in-development
|
||||
tags: [ai, llm, sse, health-analysis, claude]
|
||||
tags: [ai, llm, sse, health-analysis, ollama]
|
||||
---
|
||||
|
||||
# erp-ai AI 分析模块
|
||||
@@ -22,8 +22,10 @@ tags: [ai, llm, sse, health-analysis, claude]
|
||||
- **原生 Rust crate** — 与 erp-health 同级,直接调用数据库和事件总线
|
||||
- **ErpModule trait 实现** — `AiModule` 在 erp-server 注册,路由挂载到 `/api/v1/ai`
|
||||
- **SSE 流式响应** — 所有分析端点使用 Server-Sent Events 实时推送
|
||||
- **多提供商支持** — AiProvider trait 抽象,当前实现 Claude (Anthropic)
|
||||
- **多提供商支持** — AiProvider trait 抽象,已实现 Claude (Anthropic)、Ollama (本地)、OpenAI
|
||||
- **数据脱敏** — 发送前自动移除患者 PII(姓名、身份证、手机号)
|
||||
- **分析预校验** — 触发分析前校验数据完整性,items/sections 为空时直接返回 400
|
||||
- **非对话化 Prompt** — 迁移 000123 更新所有 prompt 为结构化输出格式
|
||||
|
||||
## 2. 关键文件 + 数据流
|
||||
|
||||
@@ -99,13 +101,15 @@ crates/erp-ai/
|
||||
|
||||
```
|
||||
客户端 POST → handler::stream_*()
|
||||
→ 预校验: items/sections 为空 → 400 直接拒绝
|
||||
→ sanitization: 移除 PII (姓名→患者, 身份证→***)
|
||||
→ PromptService: 加载激活模板 + 渲染变量
|
||||
→ AnalysisService: 编排分析流程
|
||||
→ AiProvider::stream(): 调用 LLM API
|
||||
→ 检查缓存: 相同输入 + prompt 版本 → 复用已有结果(直接回放纯文本)
|
||||
→ AiProvider::stream(): 调用 LLM API(Ollama/Claude/OpenAI)
|
||||
→ 逐 chunk SSE 推送: data: { "content": "..." }
|
||||
→ AnalysisService: 保存结果到 ai_analysis
|
||||
→ UsageService: 记录 token 用量
|
||||
→ AnalysisService: 保存结果到 ai_analysis(已完成的跳过)
|
||||
→ 后处理: 解析建议、发布事件
|
||||
→ SSE done
|
||||
```
|
||||
|
||||
@@ -124,23 +128,60 @@ crates/erp-ai/
|
||||
⚡ **不变量**: SSE 连接超时必须设置,避免挂起
|
||||
⚡ **不变量**: 用量追踪必须记录,用于计费和审计
|
||||
|
||||
## 4. 活跃问题 + 陷阱
|
||||
## 4. Ollama 本地模型对接
|
||||
|
||||
### 配置方式
|
||||
|
||||
`crates/erp-server/config/default.toml`:
|
||||
|
||||
```toml
|
||||
[ai]
|
||||
default_provider = "ollama"
|
||||
model = "qwen3:4b"
|
||||
|
||||
[ai.providers.ollama]
|
||||
provider_type = "ollama"
|
||||
base_url = "http://localhost:11434"
|
||||
default_model = "qwen3:4b"
|
||||
max_tokens = 2048
|
||||
temperature = 0.3
|
||||
is_enabled = true
|
||||
```
|
||||
|
||||
### 已知限制
|
||||
|
||||
| 问题 | 说明 |
|
||||
|------|------|
|
||||
| qwen3-vl:4b 无法运行 | Ollama 已知 bug(#13101),VL 模型内存估算异常(3.3GB 模型要求 38.3 GiB) |
|
||||
| qwen3:4b 思考模式 | 模型内置 `<think/>` 标签,首次响应可能延迟 |
|
||||
| 无图像识别能力 | 当前所有分析使用结构化数据库数据,不需要 VL 模型 |
|
||||
| Prompt 模板 model_config | DB 中 `ai_prompt.model_config.model` 优先级高于全局配置,需同步更新 |
|
||||
|
||||
### 已修复的 bug
|
||||
|
||||
| Bug | 修复 |
|
||||
|-----|------|
|
||||
| 缓存回放 JSON 嵌套 | `replay_cached` 直接回放纯文本;`complete_analysis` 跳过已完成记录 |
|
||||
| 分析返回对话式回复 | 迁移 000123 更新 prompt 为非对话、结构化输出 |
|
||||
| 空数据触发无效分析 | handler 层预校验 items/sections 非空 |
|
||||
|
||||
## 5. 活跃问题 + 陷阱
|
||||
|
||||
### 当前状态: 🔧 开发中
|
||||
|
||||
6 个 API 端点已实现,SSE 流式分析可用。当前为 Phase 1 MVP。
|
||||
6 个 API 端点已实现,SSE 流式分析可用,已对接本地 Ollama。前端 3 个管理页面已实现(Prompt 管理、分析历史、用量统计)。当前为 Phase 1 MVP。
|
||||
|
||||
### 待完善
|
||||
|
||||
| 问题 | 级别 | 说明 |
|
||||
|------|------|------|
|
||||
| 管理端前端页面 | P1 | Prompt 管理、分析历史、用量统计页面 |
|
||||
| 小程序端集成 | P2 | 患者端查看 AI 分析结果 |
|
||||
| 更多提供商 | P2 | 接入 OpenAI、本地模型等 |
|
||||
| 用量配额限制 | P1 | 按租户设置用量上限 |
|
||||
| 化验报告必填项 | P1 | 后端校验已加,前端录入表单也应对应设置必填 |
|
||||
|
||||
## 5. 变更记录
|
||||
## 6. 变更记录
|
||||
|
||||
| 日期 | 变更 |
|
||||
|------|------|
|
||||
| 2026-05-05 | 对接本地 Ollama qwen3:4b;修复缓存回放 JSON 嵌套 bug;预校验 + prompt 非对话化 |
|
||||
| 2026-04-25 | 创建 erp-ai wiki 页面 |
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|------|-----|
|
||||
| Rust crate | 18 个(erp-core + 5 基础业务 + erp-health + erp-ai + erp-dialysis + erp-plugin + 5 插件 + erp-plugin-prototype) |
|
||||
| 数据库表 | 30 基础表 + 44 健康业务表 + 3 AI 表(已实现) |
|
||||
| 数据库迁移 | 103 个 |
|
||||
| 数据库迁移 | 123 个 |
|
||||
| 后端路由 | 328 个(8 公开 + 320 受保护) |
|
||||
| 核心模块 | 5 基础 (auth/config/workflow/message/plugin) + 3 业务 (health + ai + dialysis) |
|
||||
| erp-health 实体 | 46 个 Entity(~27k 行 Rust) |
|
||||
@@ -22,7 +22,7 @@
|
||||
| DTO | 105+ 个结构体(23 文件) |
|
||||
| 权限码 | 50 声明(health 39 + ai 6 + dialysis 5)+ 56 基础模块手动注册 |
|
||||
| API 文档 | `http://localhost:3000/api/docs/openapi.json` |
|
||||
| Git 提交 | 574 次 |
|
||||
| Git 提交 | 577 次 |
|
||||
| 审计状态 | 2026-04-30 全系统审计完成(83% 总体完成度) |
|
||||
| UI/UX 重构 | Phase 1-5 完成(6 共享组件 + 4 角色仪表盘 + 个人统计数据 + 表单抽屉 + 小程序优化) |
|
||||
|
||||
@@ -53,6 +53,9 @@
|
||||
| 告警管理按钮不显示 | [[frontend]] 权限码拼写 | AlertList.tsx | `health.alert.manage` → `health.alerts.manage`(缺 s) |
|
||||
| 小程序晚间血压丢失 | [[miniprogram]] 体征录入 | indicator_type 映射 | **已修复:** 新增 `blood_pressure_evening` 类型,录入页+日常监测页+后端+测试全覆盖 |
|
||||
| AI 分析 SSE 无 UI 入口 | [[erp-health]] AI 分析 | 前端未调用 | 4 个 SSE 端点无管理界面触发 |
|
||||
| AI 分析返回对话式回复 | [[erp-ai]] prompt 模板 | 迁移 000123 | system_prompt 未加非对话指令 / 数据为空 |
|
||||
| AI 分析结果显示原始 JSON | [[erp-ai]] 缓存回放 | `replay_cached` | 迁移 000123 前的嵌套 JSON bug,前端 `extractPlainText` 兼容 |
|
||||
| AI 分析 400 缺少数据 | 后端预校验 | handler 层 | 化验报告 items 为空 / 趋势数据 metrics 为空 |
|
||||
|
||||
## 模块导航
|
||||
|
||||
@@ -69,7 +72,7 @@
|
||||
|
||||
### 核心业务层(HMS 专属)
|
||||
- [[erp-health]] — **患者管理 · 健康数据 · 预约排班 · 随访管理 · 咨询管理 · 内容管理 · 积分商城 · 透析管理 · 线下活动 · 日常监测 · 告警系统**(原生 Rust 模块,46 实体,已实现)
|
||||
- [[erp-ai]] — **AI 智能分析 · 化验单解读 · 趋势分析 · 报告摘要**(原生 Rust 模块,6 实体,Phase 1 MVP)
|
||||
- [[erp-ai]] — **AI 智能分析 · 化验单解读 · 趋势分析 · 报告摘要**(原生 Rust 模块,6 实体,Phase 1 MVP,已对接本地 Ollama qwen3:4b)
|
||||
|
||||
### 组装层
|
||||
- [[erp-server]] — Axum 入口 · AppState · 7+ 模块注册 · 后台任务 · 优雅关闭
|
||||
|
||||
Reference in New Issue
Block a user