# RAG 检索改进方案 **作者:** 小小叶 **日期:** 2026-03-18 **适用项目:** hr-assistant --- ## 📊 问题分析 ### 当前问题 - ❌ top3 检索准确率不足,需要 top7 才能答对 - ❌ 纯向量检索,关键词匹配能力弱 - ❌ 没有重排序机制 ### 根本原因 1. **向量检索局限**:语义相近但关键词不匹配的内容会排前面 2. **chunk_size 太小**:500 字符容易切断完整概念 3. **单一检索策略**:没有融合多种检索方式 --- ## 🛠️ 改进方案 ### 核心思路:混合检索 + 重排序 ``` 查询 → 向量检索 (20 个) →┐ ├→ RRF 融合 (15 个) → LLM 重排序 → 最终结果 (7 个) 查询 → 关键词检索 (20 个) →┘ ``` ### 技术细节 #### 1️⃣ 向量检索 - 使用原有的 SQLite-Vec + 余弦相似度 - 召回 20 个候选(不是最终结果) #### 2️⃣ 关键词检索 - jieba 分词 + Jaccard 相似度 - 术语加权:精确匹配查询词额外加分 - 公式:`score = Jaccard + 0.1 × 匹配词数` #### 3️⃣ RRF 融合(Reciprocal Rank Fusion) - 公式:`RRF_score = 1/(60+vector_rank) + 1/(60+keyword_rank)` - 平衡两个检索系统的权重 - 融合后取 top 15 #### 4️⃣ LLM 重排序 - 用 LLM 对 15 个候选文档进行相关性打分(0-10 分) - 按分数重新排序,返回 top 7 - 最准确但最慢(可选) --- ## 📁 文件说明 ### `rag_retrieval_improved.py` 改进的检索器实现,包含: - `ImprovedRAGRetriever` 类 - 支持向量 + 关键词混合检索 - 支持 RRF 融合和 LLM 重排序 ### 主要方法 ```python # 初始化 retriever = ImprovedRAGRetriever( vec_db_path="../sqlight/vec_3.db", llm_model_path='' ) # 简单检索(返回内容列表) results = retriever.retrieve_for_query(query, top_k=7) # 详细检索(返回带分数的字典列表) results = retriever.retrieve(query, top_k=7, use_rerank=True) # 调试模式(打印详细过程) retriever.debug_retrieval(query, top_k=5) ``` --- ## 🚀 集成到你的项目 ### 方法 1:替换原有检索逻辑 在 `RAG/rag.py` 中修改 `retrieve_for_query` 方法: ```python from .rag_retrieval_improved import ImprovedRAGRetriever class RAG: def __init__(self, vec_db_path): # ... 原有代码 ... self.retriever = ImprovedRAGRetriever(vec_db_path) def retrieve_for_query(self, query: str, top_k: int = 7): # 使用改进的检索器 results = self.retriever.retrieve_for_query(query, top_k=top_k) return results ``` ### 方法 2:单独使用检索器 ```python from rag_retrieval_improved import ImprovedRAGRetriever retriever = ImprovedRAGRetriever(vec_db_path='../sqlight/vec_3.db') results = retriever.retrieve_for_query("第二课堂包含哪些课程类别?", top_k=7) for i, content in enumerate(results): print(f"[{i+1}] {content}") ``` --- ## 📈 预期效果 | 改进项 | 当前 | 改进后 | 提升 | |--------|------|--------|------| | top3 准确率 | ~40% | ~65% | +25% | | top7 准确率 | ~60% | ~85% | +25% | | 关键词匹配 | 弱 | 强 | 显著 | | 语义理解 | 中 | 强 | 明显 | --- ## ⚙️ 参数调优 ### 可调参数 ```python # RRF 融合常数(默认 60) k = 60 # 增大 → 更平衡两个检索系统 # 检索候选数量 vector_top_k = 20 # 向量检索召回数 keyword_top_k = 20 # 关键词检索召回数 fuse_top_k = 15 # 融合后数量 final_top_k = 7 # 最终返回数量 # 重排序开关 use_rerank = True # 是否使用 LLM 重排序 ``` ### 性能优化 如果重排序太慢,可以: 1. 关闭重排序:`use_rerank=False` 2. 减少候选数量:`fuse_top_k=10` 3. 限制文档长度:`content[:500]` --- ## 🧪 测试建议 ### 测试查询示例 ```python test_queries = [ "第二课堂包含哪些课程类别?", "学分如何计算?", "毕业论文要求是什么?", "奖学金评定标准", ] for query in test_queries: print(f"\n查询:{query}") results = retriever.retrieve_for_query(query, top_k=7) for i, content in enumerate(results[:3]): print(f" [{i+1}] {content[:100]}...") ``` ### 调试模式 ```python # 查看检索过程 retriever.debug_retrieval("第二课堂包含哪些课程类别?", top_k=5) ``` --- ## 📝 下一步优化建议 ### 短期(1-2 天) 1. ✅ 调大 chunk_size 到 1000-1500 2. ✅ 增加 overlap 到 150-200 3. ✅ 实现混合检索 ### 中期(1 周) 1. 父子分块(Parent-Child Chunking) 2. 元数据过滤(按文档类型、日期筛选) 3. 查询改写(Query Rewriting) ### 长期(1 月+) 1. 微调 Embedding 模型(领域适配) 2. 端到端 RAG 优化(RAGAS 评估) 3. 多路召回 + 复杂重排序 --- **加油!有问题随时找我~** 🌱