|
|
@@ -413,158 +413,110 @@ $ cd backend-java && mvn compile
|
|
|
|
|
|
---
|
|
|
|
|
|
-## 七、后续建议
|
|
|
+## 七、提交代码(本地操作)
|
|
|
|
|
|
-1. **【紧急】启动数据库并导入全部数据**: 按 5.6 节步骤执行,这是搜索功能可用的前提
|
|
|
-2. **Phase 2 待实现**: 平均响应时间追踪、Redis 限流、AI 出题功能、LLM 联网搜索增强
|
|
|
-3. **Phase 2 待实现**: Exam 模块从 stub 升级为真实 DB 查询(题库数据入库后)
|
|
|
-4. **已验证无差距**: Java ↔ Python 后端功能完全对齐
|
|
|
+```bash
|
|
|
+cd D:\project\AIyaodianzhushou
|
|
|
+git add -A
|
|
|
+git commit -m "feat: Java补齐Python + RAG质量 + 2020药典 + 前端真实API"
|
|
|
+git push origin main
|
|
|
+```
|
|
|
|
|
|
---
|
|
|
|
|
|
-## 八、第二轮变更:提高 RAG 回答质量(2026-07-20)
|
|
|
-
|
|
|
-### 8.1 背景
|
|
|
-
|
|
|
-导入完成后回答质量仍不理想,经代码审查发现 3 个瓶颈。
|
|
|
-
|
|
|
-### 8.2 变更明细
|
|
|
+## 八、线上部署操作(复制粘贴执行)
|
|
|
|
|
|
-#### 变更 1: `docx_ingest.py` — 引入 DrugChunker 切分长 section
|
|
|
+> 以下所有命令在服务器上按顺序执行,每个 Step 标注了预期结果。
|
|
|
|
|
|
-**问题**: 原代码每个 section 全文 = 1 个 chunk。甲硝唑"概述"2000+ 字 → 1 个巨型向量 → Embedding 语义信号稀释。
|
|
|
+### Step 8.1: 拉代码 + 编译 + 重启 Java
|
|
|
|
|
|
-**修改**: 在 `ingest_docx_entries()` 中引入已有的 `DrugChunker` 类。超过 1500 字的 section 自动切分为多个 chunk(含 200 字 overlap)。
|
|
|
-
|
|
|
-```python
|
|
|
-# 短 section: 直接作为 1 个 chunk(不变)
|
|
|
-if len(section_text) <= 1500:
|
|
|
- content = f"【{drug_name} - {section_key}】\n{section_text}\n\n来源:{source}"
|
|
|
-# 长 section: 用 DrugChunker 切分(新增)
|
|
|
-else:
|
|
|
- sub_chunks = chunker._split_long_section(section_text, drug_name, section_key, source_dict)
|
|
|
+```bash
|
|
|
+cd /opt/pharmacopoeia-ai
|
|
|
+git pull origin main
|
|
|
+bash tools/java-deploy.sh deploy
|
|
|
```
|
|
|
+**预期**: 看到 `✅ 启动成功!` 和健康检查返回 `{"status":"UP"}`。
|
|
|
|
|
|
-**影响**: 需重新运行 `docx_ingest.py` 重导数据。
|
|
|
-
|
|
|
-#### 变更 2: `RetrieverService.java` — 药名匹配增强
|
|
|
-
|
|
|
-**问题**: 搜"布洛芬缓释胶囊"→ 查不到精确药名 → 降级为全库向量搜索 → 可能返回其他药的相似段落。
|
|
|
+### Step 8.2: 清空旧数据 + 重导(新版切片逻辑)
|
|
|
|
|
|
-**修改**:
|
|
|
-- 新增 `FORMULATION_SUFFIXES`(缓释胶囊/片/注射液等 20 种剂型后缀)
|
|
|
-- `extractDrugName()` 改为 4 步递进匹配:
|
|
|
- 1. 精确匹配(如"布洛芬缓释胶囊")
|
|
|
- 2. 剥剂型后缀匹配(→"布洛芬")
|
|
|
- 3. ILIKE 模糊匹配兜底
|
|
|
- 4. 完全未命中则不限定检索范围
|
|
|
-- 匹配到的药名用于限定向量搜索范围(`WHERE d.name = '布洛芬'`)
|
|
|
-
|
|
|
-#### 变更 3: `PromptService.java` — Prompt 微调
|
|
|
-
|
|
|
-**修改**:
|
|
|
-- COMPLIANCE 新增两条最高优先级规则:"参考资料无信息不得编造""不同剂型信息不可混用"
|
|
|
-- NO_DOCS prompt 新增第 7 条:"建议用户尝试更具体的关键词"
|
|
|
-
|
|
|
-### 8.3 改动文件清单
|
|
|
-
|
|
|
-| 文件 | 改动 | 需重导数据 |
|
|
|
-|------|------|-----------|
|
|
|
-| `data-pipeline/docx_ingest.py` | 引入 DrugChunker 切分长 section | ✅ 是 |
|
|
|
-| `backend-java/.../RetrieverService.java` | 剂型后缀剥离 + ILIKE 模糊匹配 | ❌ 否 |
|
|
|
-| `backend-java/.../PromptService.java` | Prompt 加强版 | ❌ 否 |
|
|
|
+```bash
|
|
|
+cd /opt/pharmacopoeia-ai/data-pipeline
|
|
|
+source venv/bin/activate
|
|
|
|
|
|
-### 8.4 RAG 回答完整链路(优化后)
|
|
|
+# 清空旧 chunks
|
|
|
+docker exec -i pharmacopoeia-pg psql -U postgres -d pharmacopoeia -c "TRUNCATE drug_chunks;"
|
|
|
|
|
|
+# 导入 Wiki 数据(~2 分钟)
|
|
|
+python import_all.py
|
|
|
```
|
|
|
-用户输入 "布洛芬缓释胶囊的用法用量"
|
|
|
- │
|
|
|
- ▼
|
|
|
-① 意图分类 classifyIntent()
|
|
|
- 本地关键词 → "usage_guide"
|
|
|
- │
|
|
|
- ▼
|
|
|
-② 药名提取 extractDrugName()
|
|
|
- "布洛芬缓释胶囊" → 剥"缓释胶囊" → 基药名"布洛芬"
|
|
|
- DB 精确匹配 → 命中 "布洛芬"
|
|
|
- │
|
|
|
- ▼
|
|
|
-③ 限定范围向量检索 search()
|
|
|
- embed("布洛芬缓释胶囊的用法用量") → 1024维向量
|
|
|
- SELECT ... WHERE d.name = '布洛芬' ORDER BY vec <=> query_vec
|
|
|
- → Top-20(仅布洛芬相关 chunks)
|
|
|
- │
|
|
|
- ▼
|
|
|
-④ 重排序 RerankerService.rerank()
|
|
|
- 阈值过滤 + n-gram 加权 + Jaccard 去重 + section 加权
|
|
|
- Top-20 → Top-5
|
|
|
- │
|
|
|
- ▼
|
|
|
-⑤ 拼 Prompt → Qwen 生成 → 返回
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
+**预期**: `🎉 全部导入完成!共处理 3 个文件`
|
|
|
|
|
|
-## 九、第三轮变更:2020 药典补充 + 前端接真实 API + 线上部署(2026-07-20)
|
|
|
+### Step 8.3: 导入 2025 药典 DOCX(~2-4 小时)
|
|
|
|
|
|
-### 9.1 变更明细
|
|
|
-
|
|
|
-#### 变更 4: `docx_ingest.py` — 2025/2020 版本共存
|
|
|
-
|
|
|
-**问题**: 原 `dedup_old_versions()` 逻辑将非 2025 版药品标记为 `is_active=FALSE`,导致 2020 数据被隐藏。
|
|
|
-
|
|
|
-**修改**: 去重函数改为空操作,2025 和 2020 版数据均保持 `active`。检索层通过 `RerankerService` 的版本优先级(2025 +0.05)自然将 2025 排在前面。
|
|
|
-
|
|
|
-#### 变更 5: `RetrieverService.java` — 2025 优先 / 2020 降级检索
|
|
|
-
|
|
|
-**修改**: `search()` 方法改为两轮策略:
|
|
|
-1. 第一轮:限定 `d.source_version = '2025年版'`
|
|
|
-2. 若结果 < 3 条或最高相似度 < 0.4,降级到全部版本(含 2020)
|
|
|
-3. 合并结果:2025 在前,2020 在后,去重
|
|
|
+```bash
|
|
|
+screen -S ingest
|
|
|
+python docx_ingest.py
|
|
|
+# Ctrl+A D 分离,可断开 SSH
|
|
|
+```
|
|
|
+**预期**: `🎉 全部完成!新增药品 6316 个, chunks 49483 条`
|
|
|
|
|
|
-新增 `embedWithCache()`:Embedding 向量缓存到 Redis(7 天 TTL),大幅降低 DashScope API 调用量。
|
|
|
+### Step 8.4: 导入 2020 药典 PDF(~30 分钟)
|
|
|
|
|
|
-#### 变更 6: `pdf2020_ingest.py` — 新建 2020 药典 PDF 导入脚本
|
|
|
+```bash
|
|
|
+python pdf2020_ingest.py
|
|
|
+```
|
|
|
+**预期**: 提取几百到几千条中药条目并入库。
|
|
|
|
|
|
-**功能**: 解析 `pharmacopoeia_2020_volume1_toc.pdf`(463 页,一部 2711 种中药),提取药品条目并向量化入库。
|
|
|
+### Step 8.5: 修复 + 验证
|
|
|
|
|
|
-#### 变更 7: `static/index.html` — 前端从 Mock 切换为真实 API
|
|
|
+```bash
|
|
|
+# 修复 vec 列
|
|
|
+docker exec -i pharmacopoeia-pg psql -U postgres -d pharmacopoeia -c "
|
|
|
+UPDATE drug_chunks SET vec = (embedding::text)::vector WHERE vec IS NULL AND embedding IS NOT NULL;
|
|
|
+UPDATE drugs SET is_active = TRUE;
|
|
|
+"
|
|
|
|
|
|
-**问题**: 前端使用 `mockResponse()` 硬编码假数据,从未调用后端 API。
|
|
|
+# 完整性验证
|
|
|
+python verify_import.py
|
|
|
+```
|
|
|
+**预期**: `✅ 导入完整,无漏读漏写`
|
|
|
|
|
|
-**修改**: 完全重写 JavaScript:
|
|
|
-- 通过 `/api/v1/auth/guest` 获取 Token
|
|
|
-- 调用 `/api/v1/chat/stream`(SSE 流式)实时显示 AI 回答
|
|
|
-- 支持图片/视频上传(`/api/v1/chat/stream-image` 和 `stream-multimodal`)
|
|
|
-- 药品库调用 `/api/v1/drug/search` + `/api/v1/drug/{id}` 加载真实数据
|
|
|
-- 自动检测同主机 9000 端口
|
|
|
+### Step 8.6: 前端生效
|
|
|
|
|
|
-#### 变更 8: `verify_import.py` — 新建导入完整性验证脚本
|
|
|
+```bash
|
|
|
+nginx -s reload
|
|
|
+```
|
|
|
+浏览器访问页面,强刷新(Ctrl+Shift+R)。搜索"布洛芬"应返回药典原文。
|
|
|
|
|
|
-逐项检查:DOCX 文件数 vs DB 药品数、漏读药品、孤儿 chunks、无 chunk 药品、向量维度、抽查特定药品 sections。
|
|
|
+### Step 8.7: 最终验证
|
|
|
|
|
|
-#### 变更 9: `database/reset_schema.sql` — 新建数据库重置脚本
|
|
|
+```bash
|
|
|
+curl -s -X POST http://localhost:9000/api/v1/chat/ask \
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
+ -d '{"message":"布洛芬"}' | python3 -m json.tool | head -10
|
|
|
+```
|
|
|
+**预期**: `answer` 包含药典原文(性状/鉴别/检查等),`sources` 不为空。
|
|
|
|
|
|
-一键清空所有表和数据,重建最新 schema。配合 `schema.sql` 使用。
|
|
|
+---
|
|
|
|
|
|
-### 9.2 最终文件清单(本次提交)
|
|
|
+## 九、变更文件清单
|
|
|
|
|
|
| 文件 | 操作 | 说明 |
|
|
|
|------|------|------|
|
|
|
-| `RerankerService.java` | **新建** | 重排序服务(阈值+n-gram+去重+版本优先级) |
|
|
|
-| `ChatController.java` | 修改 | +上传端点 +conversation_id +注入RerankerService |
|
|
|
-| `ChatPersistenceService.java` | 修改 | title回退 + 分页优化 |
|
|
|
-| `PromptService.java` | 修改 | 禁止编造 + 剂型不混用 + 建议换关键词 |
|
|
|
-| `RetrieverService.java` | 修改 | 剂型后缀 + ILIKE + 2025优先降级 + Embedding缓存 |
|
|
|
-| `DrugService.java` | 修改 | 分类树层次化 |
|
|
|
-| `DrugRepository.java` | 修改 | 新增子分类查询 |
|
|
|
-| `DrugController.java` | 修改 | 响应键名 tree |
|
|
|
-| `AdminController.java` | 修改 | +top_drugs +daily_queries |
|
|
|
-| `application.yml` | 修改 | multipart 50MB |
|
|
|
-| `docx_ingest.py` | 修改 | DrugChunker切片 + 2025/2020共存 |
|
|
|
-| `pdf2020_ingest.py` | **新建** | 2020药典PDF导入 |
|
|
|
-| `verify_import.py` | **新建** | 导入完整性验证 |
|
|
|
-| `reset_schema.sql` | **新建** | 数据库重置脚本 |
|
|
|
-| `static/index.html` | **重写** | Mock→真实API |
|
|
|
-| `OPERATIONS_GUIDE.md` | **新建** | 线上部署完整方案 |
|
|
|
-| `CHANGELOG_JAVA_PYTHON_PARITY.md` | **新建** | 本变更文档 |
|
|
|
+| `backend-java/.../RerankerService.java` | **新建** | 阈值+n-gram+去重+版本优先级 |
|
|
|
+| `backend-java/.../ChatController.java` | 修改 | +上传端点 +cid +注入RerankerService |
|
|
|
+| `backend-java/.../ChatPersistenceService.java` | 修改 | title回退+分页优化 |
|
|
|
+| `backend-java/.../PromptService.java` | 修改 | 禁编造+剂型不混用 |
|
|
|
+| `backend-java/.../RetrieverService.java` | 修改 | 剂型后缀+2025优先降级+缓存 |
|
|
|
+| `backend-java/.../DrugService.java` | 修改 | 分类树层次化 |
|
|
|
+| `backend-java/.../DrugRepository.java` | 修改 | 子分类查询 |
|
|
|
+| `backend-java/.../DrugController.java` | 修改 | tree键名 |
|
|
|
+| `backend-java/.../AdminController.java` | 修改 | +top_drugs+daily_queries |
|
|
|
+| `backend-java/.../application.yml` | 修改 | multipart 50MB |
|
|
|
+| `data-pipeline/docx_ingest.py` | 修改 | DrugChunker+2025/2020共存 |
|
|
|
+| `data-pipeline/pdf2020_ingest.py` | **新建** | 2020药典PDF导入 |
|
|
|
+| `data-pipeline/verify_import.py` | **新建** | 导入验证 |
|
|
|
+| `database/reset_schema.sql` | **新建** | DB重置脚本 |
|
|
|
+| `static/index.html` | **重写** | Mock→真实SSE API |
|
|
|
+| `docs/OPERATIONS_GUIDE.md` | **新建** | 部署方案 |
|
|
|
+| `docs/CHANGELOG_JAVA_PYTHON_PARITY.md` | **新建** | 本文档 |
|