docs: 模型切换至 mimo-v2.5 + 文档全面更新

- config.py: INTENT_MODEL 从 deepseek-v4-flash 切换至 mimo-v2.5
- config.py: get_intent_client() 从百炼 API 切换至 mimo API
- RAG系统完整指南.md: v4.0→v4.1,新增图片检索子系统、P0安全网、
  救援管线、五层缓存架构文档;替换所有旧模型名和API地址
- RAG数据流程.md: 完全重写,匹配实际代码逻辑
- curl测试手册.md: 更新模型名和Reranker配置
- MinerU模型部署指南.md: VLM_MODEL 更新为 mimo-v2.5
- 开发与系统模块说明.md: API地址和模型名更新
- 测试指南.md: API地址和模型名更新
This commit is contained in:
lacerate551
2026-06-21 23:11:46 +08:00
parent 4753a53487
commit 8268071fdc
7 changed files with 466 additions and 297 deletions

View File

@@ -1,10 +1,10 @@
# RAG 系统完整指南
> **版本**: v4.0统一编排 + 四层缓存修复)
> **版本**: v4.1模型切换 + 图片检索修复)
> **生产入口**: `api/chat_routes.py::rag()` → `generate()` → `core/engine.py`
> **最后更新**: 2026-06-05
> **最后更新**: 2026-06-21
>
> 本次更新:删除未使用的 AgenticRAG 备用编排路径10 个文件 ~2050 行),修复 Query Cache 键不匹配与阈值问题,将语义缓存集成至生产 `/rag` 端点
> 本次更新:LLM/意图/VLM 模型统一切换至 mimo-v2.5xiaomimimo.com APIReranker 切换至 xop3qwen8breranker讯飞云 API新增 chart_contexts 降门槛、P0 安全网、答案后过滤等图片检索修复逻辑
## 一、功能概述
@@ -14,12 +14,13 @@
|------|------|----------|
| **意图分析** | LLM 驱动的双层判断(是否需要检索)+ 查询改写 | `core/intent_analyzer.py` |
| **混合检索** | 向量检索 + BM25 + RRF 融合 + Rerank 重排 | `core/engine.py` |
| **层缓存** | Query + Embedding + RerankLRU+ 语义缓存FAISS | `core/cache.py` + `core/semantic_cache.py` |
| **层缓存** | Query + Embedding + RerankLRU+ 语义缓存FAISS+ ChromaDB 元数据缓存 | `core/cache.py` + `core/semantic_cache.py` |
| **流式生成** | SSE 流式答案输出,逐 token 推送 | `core/engine.py::generate_answer_stream()` |
| **引用标注** | 自动标注信息来源和引用编号 | `api/chat_routes.py::_attach_citations()` |
| **富媒体** | 图片/表格的智能提取与展示 | `api/chat_routes.py` |
| **富媒体** | 图片/表格的智能提取与展示 + P0 安全网 + 答案后过滤 | `api/chat_routes.py` |
| **查询理解** | 查询分解、扩展、MMR 去重、自适应 TopK | `core/` 各独立模块 |
| **安全护栏** | 敏感信息过滤、Prompt 安全守卫 | `api/response_utils.py``core/prompt_guard.py` |
| **救援管线** | BM25 散度救援、词法匹配救援、章节聚类救援、表格救援 | `core/engine.py` |
---
@@ -78,9 +79,12 @@
│ │ FAQ 加权 │→ │ 黑名单过滤 │→ │ 时间衰减 │ │
│ └───────────┘ └──────────────┘ └──────┬───────┘ │
│ ↓ │
│ ┌───────────────┐ ┌──────────────┐
│ │ 上下文扩展 │→ │ 自适应 TopK │
│ └───────────────┘ └──────────────┘
│ ┌───────────────┐ ┌──────────────┐ ┌──────────────┐
│ │ 上下文扩展 │→ │ 自适应 TopK │→ │ 救援管线 │
│ └───────────────┘ └──────────────┘ │ (BM25散度/ │
│ │ 词法/章节/ │ │
│ │ 表格救援) │ │
│ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
@@ -105,7 +109,7 @@
---
## 三、层缓存架构
## 三、层缓存架构
### 3.1 缓存层次概览
@@ -115,6 +119,7 @@
| L2 | Embedding Cache | LRU (OrderedDict) | 2000 条 | 24 小时 | 缓存向量化结果,避免重复调用 embedding 模型 |
| L3 | Rerank Cache | LRU (OrderedDict) | 1000 条 | 1 小时 | 缓存 Rerank 分数,避免重复调用 Reranker |
| L4 | Semantic Cache | FAISS IndexFlatIP | 10000 条 | 无过期 | 语义级缓存,相似查询也能命中 |
| L5 | ChromaDB 元数据缓存 | 进程内 dict | 无限制 | 无过期 | 缓存 ChromaDB Collection 元数据kb_version 等),避免频繁查询 ChromaDB |
### 3.2 Query Cache
@@ -288,9 +293,9 @@ search_knowledge(query, top_k=30)
├─ 7. 章节过滤(查询提到章节时优先匹配)
├─ 8. ★ Rerank 重排 ★(云端 DashScope qwen3-rerank 或本地 BGE
│ └─ rerank_results(query, results, top_k)
│ └─ 由 RERANK_BACKEND 控制local/cloud/fallback
├─ 8. ★ Rerank 重排 ★(云端讯飞 xop3qwen8breranker 或本地 BGE
│ └─ rerank_results(query, results, top_k)
│ └─ 由 RERANK_BACKEND 控制local/cloud/fallback
├─ 9. MMR 去重
│ ├─ 语义向量版MMR_USE_EMBEDDING=True
@@ -306,7 +311,9 @@ search_knowledge(query, top_k=30)
├─ 14. 自适应 TopK根据置信度调整返回数量
─ 15. 缓存写入 → 返回结果
─ 15. 救援管线BM25散度/词法匹配/章节聚类/表格救援)
└─ 16. 缓存写入 → 返回结果
```
### 5.2 混合检索代码示例
@@ -330,7 +337,7 @@ image_results = collection.query(
# RRF 融合(动态权重)
fused = reciprocal_rank_fusion([vector_results, bm25_results], weights=[vector_w, bm25_w])
# Rerank 重排(云端 DashScope qwen3-rerank 或本地 BGE
# Rerank 重排(云端讯飞 xop3qwen8breranker 或本地 BGE
reranked = rerank_results(query, fused, top_k=15)
# MMR 去重
@@ -359,7 +366,7 @@ RRF分数 = Σ (权重 / (k + 排名位置))
| RERANK_BACKEND | 说明 |
|----------------|------|
| `"cloud"` | 仅使用云端 DashScope `qwen3-rerank` API |
| `"cloud"` | 仅使用云端讯飞 `xop3qwen8breranker` API |
| `"local"` | 仅使用本地 `BAAI/bge-reranker-base`CrossEncoder / ONNX |
| `"fallback"` | 优先云端,失败时自动回退本地(推荐生产环境) |
@@ -368,13 +375,13 @@ RRF分数 = Σ (权重 / (k + 排名位置))
```python
# config.py
RERANK_BACKEND = os.getenv("RERANK_BACKEND", "local")
RERANK_CLOUD_MODEL = "qwen3-rerank"
RERANK_CLOUD_MODEL = "xop3qwen8breranker"
RERANK_CLOUD_API_KEY = os.getenv("RERANK_CLOUD_API_KEY", DASHSCOPE_API_KEY)
RERANK_CLOUD_BASE_URL = "https://dashscope.aliyuncs.com/compatible-api/v1/reranks"
RERANK_CLOUD_BASE_URL = "https://maas-api.cn-huabei-1.xf-yun.com/v1/rerank"
RERANK_CLOUD_TIMEOUT = 15
```
`CloudReranker` 类(`core/engine.py`)封装 DashScope 的 `/compatible-api/v1/reranks` 接口,提供与本地 `CrossEncoder.predict()` / `ONNXReranker.predict()` 一致的调用接口。
`CloudReranker` 类(`core/engine.py`)封装讯飞云的 `/v1/rerank` 接口,提供与本地 `CrossEncoder.predict()` / `ONNXReranker.predict()` 一致的调用接口。
**本地 Reranker备选**
@@ -424,12 +431,16 @@ POST /rag (SSE 流式)
├─ 5. 图片补充检索 + 图片打分选择 (select_images)
│ └─[DEV] 发 SSE: images_selected
├─ 6. 构建上下文 (_order_texts_for_prompt)
│ └─ chart_contexts 使用 min_score * 0.5 降门槛
│ └─[DEV] 发 SSE: context_built
├─ 6.5. P0 安全网 — 确保 selected_images 描述完整进入 LLM 上下文
├─ 7. 流式答案生成 engine.generate_answer_stream()
│ └─ 逐 token 发 SSE: chunk
├─ 8. 答案图号对齐过滤
├─ 8.5. 答案后过滤 (_filter_images_by_answer) — 根据 LLM 答案过滤不相关图片
├─ 9. 引用标注 _attach_citations()
├─ 10. 敏感信息过滤 filter_response()
├─ 11. 语义缓存写入 SemanticCache.set() # 写入缓存供后续命中
@@ -454,6 +465,76 @@ POST /rag (SSE 流式)
> 标注 [DEV] 的事件仅在 `IS_DEV=True` 时发送。
### 6.1 图片检索子系统
图片检索是独立于文本上下文管线的子系统,存在特有的"两管线断裂"问题,已通过多重修复保障完整性。
**图片检索流程**
```
search_knowledge() 返回混合检索结果
┌──────────────────────────────────────────────────────────────┐
│ _order_text_contexts_for_prompt() — 上下文提取与构建 │
│ │
│ 1. 分离 text_contexts 和 chart_contexts │
│ 2. chart_contexts 使用 min_score * 0.5 降门槛过滤 │
CrossEncoder 对图片打分系统性偏低0.002-0.08
│ 3. chart_contexts 的描述注入 context_text 【相关图片信息】 │
│ 4. text_contexts 正常注入 context_text │
└──────────────────────────────────────────────────────────────┘
↓ ↓
┌──────────────────┐ ┌──────────────────────────────────────┐
│ select_images() │ │ context_text 送入 LLM │
│ 独立图片选择 │ │ (可能不包含所有选中图片的描述) │
│ P1: BM25/向量 │ └──────────────────────────────────────┘
│ P2: VLM 检查 │
│ P3: CE 排名 │
│ P4: 多样性去重 │
└────────┬─────────┘
┌──────────────────────────────────────────────────────────────┐
│ P0 安全网 — 保证 selected_images 描述完整进入 LLM 上下文│
│ │
│ 检查 context_text 中的 【相关图片信息】 部分, │
│ 若 selected_images 的描述不在 context_text 中, │
│ 强制追加缺失的描述。 │
│ (解决两管线断裂:图片被选中但描述被 min_score 过滤掉) │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ _filter_images_by_answer() — 答案后过滤 │
│ │
│ LLM 生成答案后,根据答案内容过滤不相关图片。 │
│ ⚠️ 鸡生蛋问题:若 LLM 因上下文缺失而回答"未找到"
│ 会导致正确图片被误过滤。P0 安全网可缓解此问题。 │
└──────────────────────────────────────────────────────────────┘
```
**select_images 四阶段选择**
| 阶段 | 方法 | 说明 |
|------|------|------|
| P1 | BM25/向量召回 | 从检索结果中筛选 chunk_type 为 image/chart 的候选 |
| P2 | VLM 相关性检查 | `_check_vlm_relevance()` 判断图片与查询的相关性,不相关者 -3.0 惩罚 |
| P3 | CrossEncoder 排名 | CE<0 移除CE 0~2 保留无加成CE>2 加分 |
| P4 | 多样性去重 | 同文档多图片按分数保留 TopN避免单一文档图片垄断 |
**CrossEncoder 图片评分特征**CrossEncoder 对图片/图表的打分系统性低于文本0.002-0.08 vs 0.3-0.9),因此 `chart_contexts` 使用 `min_score * 0.5` 的降门槛策略。
**VLM 相关性检查**`_check_vlm_relevance()` 使用 VLM 模型判断图片内容与查询的相关性,阈值 0.3,不相关图片会被施加 -3.0 的分数惩罚。
### 6.2 救援管线
当常规检索召回不足时,以下救援机制依次尝试补充结果:
| 救援类型 | 触发条件 | 策略 |
|----------|----------|------|
| BM25 散度救援 | 向量与 BM25 结果差异大 | 补充 BM25 独有但向量遗漏的高分结果 |
| 词法匹配救援 | 专有名词/术语精确匹配 | 对查询中的关键术语做精确匹配补充 |
| 章节聚类救援 | 同章节切片被部分召回 | 补充同章节内相邻切片rerank 后、扩展前) |
| 表格救援 | 表格数据被碎片化 | 对 table 类型切片做整表补充 |
---
## 七、API 调用方式
@@ -530,14 +611,24 @@ curl http://localhost:5001/cache/stats \
```python
# config.py
DASHSCOPE_API_KEY = "your-api-key" # 通义千问 API
DASHSCOPE_BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1"
DASHSCOPE_MODEL = "qwen3.6-flash" # 文本生成模型(主力 LLM
INTENT_MODEL = "qwen-turbo" # 意图分析模型(轻量快速)
VLM_MODEL = "qwen-vl-plus" # 视觉语言模型(图片描述)
RAG_CHAT_MODEL = "qwen3.6-flash" # RAG 对话模型
DASHSCOPE_API_KEY = "your-api-key" # mimo API 密钥
DASHSCOPE_BASE_URL = "https://token-plan-cn.xiaomimimo.com/v1"
DASHSCOPE_MODEL = "mimo-v2.5" # 文本生成模型(主力 LLM
INTENT_MODEL = "mimo-v2.5" # 意图分析模型(轻量快速)
VLM_MODEL = "mimo-v2.5" # 视觉语言模型(图片描述)
RAG_CHAT_MODEL = "mimo-v2.5" # RAG 对话模型
# Embedding 模型(本地)
EMBEDDING_MODEL_PATH = "models/bge-base-zh-v1.5"
# Reranker 模型
RERANK_MODEL_PATH = "models/bge-reranker-base" # 本地备选
RERANK_CLOUD_MODEL = "xop3qwen8breranker" # 云端(讯飞云)
RERANK_CLOUD_BASE_URL = "https://maas-api.cn-huabei-1.xf-yun.com/v1/rerank"
```
> **注意**:百炼 APIDashScope额度用尽后所有 LLM 调用已统一切换至 mimo APIxiaomimimo.com。`get_intent_client()` 也使用 `DASHSCOPE_API_KEY` / `DASHSCOPE_BASE_URL`(即 mimo API不再使用百炼 API。
### 8.2 检索参数
```python
@@ -553,7 +644,7 @@ RECALL_MULTIPLIER = 3 # 候选池最小倍数
# 重排序
USE_RERANK = True # 启用重排序
RERANK_BACKEND = "local" # "local"=本地模型, "cloud"=云端API, "fallback"=优先云端失败回退本地
RERANK_CLOUD_MODEL = "qwen3-rerank"
RERANK_CLOUD_MODEL = "xop3qwen8breranker"
RERANK_CANDIDATES = 20 # 送入重排序的候选数
RERANK_TOP_K = 15 # 重排序后保留数
RERANK_USE_ONNX = True # ONNX 加速(仅本地模式,环境变量控制)
@@ -701,10 +792,10 @@ config/ # 运行时配置
| 检索方式 | 单一向量检索 | 向量 + BM25 + FAQ + 图片独立召回 |
| 融合算法 | 无 | RRF 动态权重融合 |
| 去重 | 无 | MMR 语义去重 |
| 重排序 | 无 | 云端 qwen3-rerank API支持本地 BGE 回退) |
| 重排序 | 无 | 云端 xop3qwen8breranker API讯飞云,支持本地 BGE 回退) |
| 问题分解 | 无 | 自动拆分对比/推理类查询 |
| 闲聊处理 | 无 | 意图分析自动判断 |
| 缓存体系 | 无 | 层缓存Query + Embedding + Rerank + 语义缓存) |
| 缓存体系 | 无 | 层缓存Query + Embedding + Rerank + 语义缓存 + 元数据缓存 |
| 语义缓存 | 无 | FAISS 向量索引相似查询复用92x 加速) |
| 自适应 TopK | 固定 top_k | 根据置信度动态调整 |
| 上下文理解 | 无 | 多轮对话 + 历史上下文 |
@@ -736,9 +827,9 @@ Rerank 在生产流程中有 **一个调用路径**
|--------|--------|------|
| `USE_RERANK` | `True` | 总开关 |
| `RERANK_BACKEND` | `"local"` | 后端选择 |
| `RERANK_CLOUD_MODEL` | `"qwen3-rerank"` | 云端模型名称 |
| `RERANK_CLOUD_MODEL` | `"xop3qwen8breranker"` | 云端模型名称 |
| `RERANK_CLOUD_API_KEY` | 同 `DASHSCOPE_API_KEY` | 云端 API 密钥 |
| `RERANK_CLOUD_BASE_URL` | `https://dashscope.aliyuncs.com/compatible-api/v1/reranks` | 云端 API 地址 |
| `RERANK_CLOUD_BASE_URL` | `https://maas-api.cn-huabei-1.xf-yun.com/v1/rerank` | 云端 API 地址(讯飞云) |
| `RERANK_CLOUD_TIMEOUT` | `15` | 云端请求超时(秒) |
| `RERANK_MODEL_PATH` | `models/bge-reranker-base` | 本地模型路径 |
| `RERANK_CANDIDATES` | `20` | 送入 Rerank 的候选数 |
@@ -807,6 +898,26 @@ print({"hits": sc.hits, "misses": sc.misses, "total": sc.total_entries})
## 十三、演进记录
### v4.12026-06-21— 模型切换 + 图片检索修复
**模型统一切换**:百炼 APIDashScope额度用尽后所有 LLM 调用统一切换至 mimo APIxiaomimimo.com
- `DASHSCOPE_MODEL` / `RAG_CHAT_MODEL` / `INTENT_MODEL` / `VLM_MODEL``qwen3.6-flash` / `qwen-turbo` / `qwen-vl-plus``mimo-v2.5`
- `DASHSCOPE_BASE_URL``dashscope.aliyuncs.com``token-plan-cn.xiaomimimo.com/v1`
- `get_intent_client()`:从百炼 API 切换至 mimo API
**Reranker 切换**
- `RERANK_CLOUD_MODEL``qwen3-rerank``xop3qwen8breranker`(讯飞云)
- `RERANK_CLOUD_BASE_URL``dashscope.aliyuncs.com``maas-api.cn-huabei-1.xf-yun.com/v1/rerank`
**图片检索修复**P0 级):
1. **chart_contexts 降门槛**CrossEncoder 对图片/图表打分系统性偏低0.002-0.08 vs 文本 0.3-0.9),原 `min_score=0.05` 过滤掉几乎所有图表。修复为 `min_score * 0.5 = 0.025`
2. **P0 安全网**`select_images` 独立于文本上下文管线选择图片,但图片描述可能因 min_score 过滤未进入 LLM 上下文。新增安全网检查:若 `selected_images` 的描述未出现在 `context_text` 中,强制注入。
3. **答案后过滤**`_filter_images_by_answer`LLM 生成答案后,根据答案内容过滤不相关图片。注意:若 LLM 因上下文缺失而回答"未找到",会导致正确图片被误过滤(鸡生蛋问题)。
**救援管线**:新增 BM25 散度救援、词法匹配救援、章节聚类救援、表格救援等机制,确保低召回场景下的结果覆盖。
**缓存层扩展**:从四层缓存扩展为五层,新增 ChromaDB 元数据缓存L5避免频繁查询 ChromaDB 获取 kb_version 等元数据。
### v4.02026-06-05— 统一编排 + 四层缓存修复
**删除未使用的备用编排路径**:移除了 `core/agentic.py` 及 8 个 Mixin 文件(共 10 个文件 ~2050 行)。这些文件实现了完整的决策循环编排(含置信度门控、质量评估、推理反思等),但从未接入任何 HTTP 路由。
@@ -820,7 +931,7 @@ print({"hits": sc.hits, "misses": sc.misses, "total": sc.total_entries})
### v3.2 — 模型/Reranker/管线更新
引入云端 qwen3-rerank、ONNX 加速、动态 RRF 权重等。
引入云端 Reranker现 xop3qwen8breranker/讯飞云,原 qwen3-rerank/DashScope、ONNX 加速、动态 RRF 权重等。
---
@@ -828,7 +939,7 @@ print({"hits": sc.hits, "misses": sc.misses, "total": sc.total_entries})
### Redis 缓存外部化
当前层缓存均为进程内内存存储,在多 Worker / 多实例部署时无法共享。已规划 Redis 迁移方案(详见 `reports/redis_migration_plan.md`),核心设计:
当前层缓存均为进程内内存存储L5 ChromaDB 元数据缓存除外),在多 Worker / 多实例部署时无法共享。已规划 Redis 迁移方案(详见 `reports/redis_migration_plan.md`),核心设计:
- `RedisCacheManager` 提供与 `RAGCacheManager` 相同的接口
- 通过 `REDIS_CACHE_URL` 环境变量启用,向后兼容