6阶段管线:从用户提问到精准回答的完整RAG流程
RAG(Retrieval-Augmented Generation,检索增强生成)是一种让LLM"查阅资料再回答"的技术:
类比:传统LLM像"闭卷考试",RAG像"开卷考试"——可以翻书找答案。
RAG 6阶段管线
══════════════
用户提问: "公司的年假政策是什么?"
│
▼
┌─────────────────────────────────────────────────────────┐
│ Stage 1: 查询改写 (QueryRewrite) │
│ │
│ 原始: "年假多少天?" │
│ 上下文: 用户之前问了"关于假期" │
│ 改写: "公司的年假天数政策规定" (消解代词/补充上下文) │
└──────────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ Stage 2: 检索缓存 (RetrievalCache) │
│ │
│ Caffeine本地缓存, 相同查询直接返回 │
│ 命中 → 跳到Stage 5 │
│ 未命中 → 继续 │
└──────────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ Stage 3: 多查询扩展 + RRF融合 │
│ │
│ LLM生成N个查询变体: │
│ Q1: "年假政策" │
│ Q2: "年假天数规定" │
│ Q3: "假期管理制度 年假" │
│ │
│ 并行搜索: Q1→结果集1, Q2→结果集2, Q3→结果集3 │
│ RRF融合: 合并三个结果集, 按RRF公式重排序 │
└──────────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ Stage 4: 重排序 (Reranker) │
│ │
│ LLM对每个结果打分(1-10): │
│ Doc1: 9分 (高度相关) │
│ Doc2: 7分 (相关) │
│ Doc3: 4分 (弱相关) │
│ 按Token预算截断 (保留高分文档) │
└──────────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ Stage 5: 上下文组装 (ContextAssembler) │
│ │
│ 编号引用格式: │
│ [1] 年假政策规定... (来源: 员工手册.pdf) │
│ [2] 假期管理... (来源: 公司制度.docx) │
│ │
│ + 引用指令: "请根据以上内容回答,标注来源编号" │
└──────────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ Stage 6: 间接注入扫描 + LLM流式生成 │
│ │
│ 扫描上下文 → 安全后传给LLM │
│ 系统提示词: "只使用检索到的内容回答,不要编造" │
│ → 流式生成最终回答 + 来源引用 │
└─────────────────────────────────────────────────────────┘
这是本项目的核心创新之一:
RRF (Reciprocal Rank Fusion) 算法:
问题: 不同查询变体返回不同的结果集,如何合并?
查询1结果: [DocA(1), DocB(2), DocC(3)] ← 排名1,2,3
查询2结果: [DocB(1), DocD(2), DocA(3)] ← 排名1,2,3
查询3结果: [DocC(1), DocA(2), DocE(3)] ← 排名1,2,3
RRF公式: score(doc) = Σ 1/(k + rank_i)
k = 60 (平滑常数)
DocA: 1/(60+1) + 1/(60+3) + 1/(60+2) = 0.0484
DocB: 1/(60+2) + 1/(60+1) = 0.0323
DocC: 1/(60+3) + 1/(60+1) = 0.0318
最终排序: DocA > DocB > DocC
优势:
· 不依赖绝对分数,只用排名
· 对异常值鲁棒
· 多个查询的"投票"效应提高召回质量
项目使用向量语义搜索 + MySQL全文索引的混合搜索:
HybridSearchService:
用户查询
│
├──→ 向量语义搜索 (Milvus)
│ │ "年假政策" → embedding → 余弦相似度匹配
│ │ 优势: 理解语义,"年假" ≈ "带薪休假"
│ │
│ └──→ 关键词搜索 (MySQL FULLTEXT)
│ "年假政策" → 分词 → 精确匹配
│ 优势: 精确匹配专有名词、编号
│
└──→ 合并去重 (content hash)
│
└──→ 返回统一结果集
去重策略:
SHA-256(content) 相同 → 保留评分更高的