ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

混合检索:向量 + BM25 + RRF + Rerank

混合检索:向量 + BM25 + RRF + Rerank 【摘要】 向量检索的不足, 精确检索, BM25, RRF, Rerank, 混合检索一、向量检索的不足之前我们学习的 RAG检索层只有向量(文档切片, 向量化后存到数据库, 提问检索时把问题向量化, 通过计算相似度来召回topK), 文本被压缩成语义坐标意思接近的就挨在一起。向量强在语义但压缩时只剩下语义了, 如果问题涉及精确字符, 这类问题就没办法检索了, 比如要检索 订单号 ORD-2026-0087 和 ORD-2026-0176 , 在向量空间两个订单号几乎重合但是却是两个完全不同订单, 使用向量检索就没办法检索了。所以要增加精确词的检索办法, 两者混合使用: 语义用向量检索精确的用精确检索。二、精确检索RAG 中常用的精确检索方式精确检索也叫稀疏/关键词检索, 目前常用的有TF-IDF最经典的词袋统计。每个词权重 词频TF× 逆文档频率IDF越独有的词越高。纯数学统计不训练任何模型。缺点是词频无上限、不区分长短文档。BM25TF-IDF 的工业升级版。在 TF 上加饱和度TF有上限、加文档长度归一化长文词多要扣分、短文精准命中要加分。BM25 得分 词 IDF × 饱和 TF (考虑文档长度)再把查询每个词分数累加。(需要分词)Elasticsearch / OpenSearch自带分词、高亮、聚合、集群扩展。本质还是 BM25 打分多的是工程能力代价是要单独部署维护一个服务。SPLADE神经稀疏检索用模型把文档映射成稀疏向量大多维度为 0少数维度有权重相当于模型替你挑出重要词并赋权。需要模型推理速度和成本都上涨。ColBERT延迟交互把查询和文档都切成 token 向量检索时做 token 级细粒度匹配“延迟交互”。精度高但索引大、查询慢、吃内存通常只在语料大、精度要求极高时用。对比分析方法原理需要模型速度部署成本适合场景TF-IDF词频 × 逆文档频否极快零教学、极小语料BM25TF-IDF 饱和 长度归一否极快零订单号、专有名词、精确数字ElasticsearchBM25 引擎化否快中部署服务大规模生产环境SPLADE模型生成稀疏向量是中推理中想要 BM25 速度又想沾点语义ColBERTtoken 级延迟交互是慢高内存大高精度、大语料对于我们本地部署学习, 使用BM25非常适合。三、混合检索结合向量检索和精确检索一起使用, 再增加检索结果融合以及重排序, 就是混合检索, 我们在RAG中使用向量检索BM25。混合检索流程(以一次提问为例)向量路召回查询向量化从向量数据库召回语义最像的 topMBM25 路召回查询分词从语料召回关键词命中的 topNRRF 融合两路结果按排名合并去重得到 topP 候选Rerank 精排候选送交叉编码器按深度相关度重排取 topK拼上下文把 topK 原文拼进 prompt 然后给 LLM, LLM根据topK输出。RRF 排名融合两路分数不能直接相加, 向量检索的余弦相似度范围 0~1BM25 能到十几两种的分数含义和取值范围都不同, 量纲不同。可以使用 RRF算法计算Reciprocal Rank Fusion倒数排名融合score Σ 每一路贡献的 1/(k rank) k: 平滑常数(也叫衰减因子)常见开源默认值60但不是数学推导出来的固定常数是经验超参数, 作用是控制名次之间分数衰减有多快。 k小(如10)靠前名次优势巨大往后掉得很快。第一名权重非常强势稍微往后几名收益快速缩水。 k大(如100)前后名次差距被抹平。第一名优势被削弱中后段名次也能拿到可观分数。但是RRF有缺点: 由于RRF只看排名不看原始分数高低。 想象 BM25只要分数 0 就保留文档。中文里面虚词 “的” 之类一堆文档沾一点点边就得分大于 0。于是一大堆几乎无关的文档全部进入 RRF 融合流程, 都能算出RRF分数。解决办法: 每一路自己先做过滤, 取该路最高分的30% 作为阈值低于这个阈值就不要了不参与后面 RRF 计算。Rerank 重排序向量和 BM25 都是各看各的, 查询和文档分别编码再比对。Rerank 是交叉编码把查询和每篇候选拼一起精读能判断是否深层相关。交叉编码成本高128 条要算 128 次深度匹配所以最后使用重排序, 所以RRF保留少一点再 Rerank 精排。可以使用智谱的Rerank APIhttps://open.bigmodel.cn/api/paas/v4/rerank, 返回相关性得分与排序。# hybrid_search.py import jieba from rank_bm25 import BM25Okapi # ---------- 语料示例 ---------- docs { d1: LangChain 框架入门介绍了5大核心概念和DeepSeek接入方法, d2: RAG完整八步流程Chroma.from_documents持久化分块时 chunk_size800TopK默认 k3, d3: 用智谱 embedding-3 替换 ChromaDB 默认模型中文向量效果明显提升, d4: numpy 数组运算、tiktoken 统计 token 数量、tenacity 网络请求重试, d5: RAG 优化实验分块大小 500/1000/2000 对比相似度阈值 0.4 过滤噪声, d6: 智能体的记忆系统短期记忆存上下文窗口长期记忆存向量数据库, d7: python-dotenv 管理环境变量API KEY 不能写死在代码里, d8: MCP 协议把工具标准化Agent 像插 USB-C 一样连接外部系统, } # ---------- BM25 关键词检索 ---------- def tokenize(text: str) - list: return [t for t in jieba.lcut(text) if t.strip()] tokenized_corpus [tokenize(t) for t in docs.values()] bm25 BM25Okapi(tokenized_corpus) def bm25_search(query: str, top_n: int 10) - list[str]: scores bm25.get_scores(tokenize(query)) best scores.max() ranked sorted(zip(docs, scores), keylambda x: -x[1]) return [doc_id for doc_id, s in ranked[:top_n] if s float(best) * 0.3] # ---------- 向量检索 ---------- def vector_search(query: str, k: int 10) - list[str]: # 模拟d6/d3/d8 是语义最近的结果 return [d6, d3, d8] # ---------- 融合RRF ---------- def rrf_fuse(result_lists: list[list[str]], k: int 60, top_n: int 5) - list[str]: 多路结果按排名融合每路第 r 名贡献 1/(kr)k60 经验平滑值 scores: dict[str, float] {} for results in result_lists: for rank, doc_id in enumerate(results, start1): scores[doc_id] scores.get(doc_id, 0.0) 1.0 / (k rank) return [d for d, _ in sorted(scores.items(), keylambda x: -x[1])[:top_n]] # ---------- Rerank 用智谱的API ---------- def rerank(query: str, doc_ids: list[str], top_n: int 3) - list[str]: import os, requests key os.getenv(ZHIPU_API_KEY) if not key: return doc_ids[:top_n] r requests.post( https://open.bigmodel.cn/api/paas/v4/rerank, headers{Authorization: fBearer {key}}, json{model: rerank, query: query, documents: [docs[d] for d in doc_ids], top_n: top_n, return_documents: False}, timeout10) r.raise_for_status() return [doc_ids[item[index]] for item in r.json()[results]] # ---------- 混合检索 ---------- def hybrid_search(query: str, k: int 3) - list[str]: candidates rrf_fuse([vector_search(query), bm25_search(query)], top_n5) return rerank(query, candidates, top_nk) if __name__ __main__: for q in [RAG流程的chunk_size 是多少, 智能体的记忆是怎么存的, 怎么管理 API KEY]: hits hybrid_search(q) print(f\nQ: {q}\n → {[f{i}: {docs[i][:20]}… for i in hits]})实际应用时把之前学的wiki替换到docs命中后顺着 [[互链]] 把相关条目也放到上下文。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
返回列表