☰
RAG 召回差?先改切片和重排
2026/10/26 2:02:02 网站建设 项目流程

做好切片和重排

我第一次给内部文档搭 RAG,召回回来的块总差一口气。问怎么降大模型调用成本,它回了一段讲向量库存储贵的。排查下来,症结在切片和重排这两道工序,模型本身没问题。这篇把 RAG 检索的原理拆开讲,代码能直接跑。

一、切片定召回上限

1、按照字符长度硬切(按照模型限制且)
2、按照语句段落切(保留完整句子)

切片直接决定召回的上限。固定长度切块图省事,却常把一句完整的话从中间劈开,模型拿到的块结尾是断的,语义被切断,召回自然掉。

我把同一段 226 字文档喂给两种切法。固定长度切出 2 块,其中 1 块在句子中间断开。递归字符切块同样 2 块,没有一处断句。差距就在句子完不完整。

递归切块先按段落、再按句子、最后按长度,能保住大多数句子完整,是工程上的默认选择。块大小我一般控制在两百到五百字,再留百分之十到二十的重叠给边界句,让相邻块共享上下文。

def recursive_chunk(text, size=200, overlap=40): """先按段落、再按句子、最后按长度切。 为什么这么写:保证句子不被切断,召回的块语义才完整。""" chunks = [] for para in re.split(r"\n+", text): para = para.strip() if not para: continue # 按句切,单句超过 size 才硬切,正常句子整段保留 sents = re.split(r"(?<=[。!?])", para) cur = "" for s in sents: if len(cur) + len(s) <= size: cur += s else: if cur: chunks.append(cur) while len(s) > size: chunks.append(s[:size]) s = s[size - overlap:] cur = s if cur: chunks.append(cur) return chunks

二、混合检索补语义

混合检索流程

词法检索(BM25)擅长精确词匹配,可查询词和文档用词不一致时就抓不到。我问每月开销怎么缩减,语料里没有开销、缩减这两个词,纯词法前 3 名里根本没有讲成本的块。

语义通道补上这一块。生产环境用 bge-m3、gte 这类嵌入模型把文本编码成向量再比余弦,查询写缩减开销也能命中讲降低成本的块。我这个 demo 用同义词扩展离线近似,机制一致,两路打分后按排名融合。

融合用 Reciprocal Rank Fusion,不依赖两路分数量纲一致,实现成本低。上面那个口语查询,语义通道把讲成本的块从第 3 名外拉进前 3,重排再抬到第 2。

import math, redef expand_query(query): """把口语词换回语料里的标准词,模拟语义检索跨词形匹配的能力。""" q = re.sub(r"\s+", "", query) for std, cols in {"成本": ["开销", "花费", "账单"], "切块": ["切分", "分块"]}.items(): for c in cols: if c in q: q = q.replace(c, std) return qdef rrf(ranks, k=60): """Reciprocal Rank Fusion:按排名融合,不挑两路分数量纲。""" fused = {} for rank in ranks: for pos, (idx, _) in enumerate(rank): fused[idx] = fused.get(idx, 0) + 1 / (k + pos + 1) return [i for i, _ in sorted(fused.items(), key=lambda x: -x[1])]

真实跑出来的前几名,口语查询每月开销怎么缩减的结果如下。

纯词法前 3:c_embed、c_trap、c_distract(无讲成本的块)语义通道前 3:c_embed、c_trap、c_cost(c_cost 被拉进前 3)重排后前 5:c_embed、c_cost、c_trap、c_distract、c_hybrid

三、重排定答案准度

重排定答案准度

召回只要不漏,重排才决定答案准不准。融合阶段只看排名,谁词频高谁靠前,偏题块容易混进来。

我放了个陷阱块,满篇都是成本和大模型调用成本,词法分很高,排在融合第 1。但它只讲涨价和担心账单,没讲怎么降。重排阶段我加了融合没有的两个信号,块里有没有查询的意图动作词(省钱、压),以及有没有精确短语。带省钱、压的块被抬上去,陷阱块被压到第 2,讲怎么降成本的块回到第 1。

重排只挑召回前 N 条做,因为交叉编码器逐对打分很慢,全量做不现实。

def rerank(query, idxs, bm25, topk=5): """对融合后的候选做特征重排。 加的两个信号融合阶段没有:精确短语、意图动作词。""" q = re.sub(r"\s+", "", query) scored = [] for idx in idxs: doc = CORPUS[list(CORPUS)[idx]] bm = bm25.score(query, idx) phrase = 1.0 if any(q[i:i+4] in doc for i in range(len(q)-3)) else 0.0 intent = 1.0 if any(t in doc for t in ["省钱", "压", "降低"]) else 0.0 length_penalty = 1.0 if len(doc) <= 200 else 0.6 scored.append((idx, 0.3*bm + 0.8*phrase + 1.2*intent + length_penalty)) scored.sort(key=lambda x: -x[1]) return [i for i, _ in scored[:topk]]

四、常见坑

坑 1 用字符数估算成本。表现是用 len(text) 估 token,中文场景账单比预期高两三倍。改用分词器的 encode 实测字符对应的 token 数。

坑 2 切块太大或太小。块超过五百字噪声多,小于两百字上下文不够。按二百到五百字切,留百分之十到二十的重叠。

坑 3 只跑词法不跑语义。查询和文档用词不一致时召回漏掉正确答案。加一路嵌入检索再融合。

坑 4 把召回当排序。召回阶段只管不漏,排序交给重排。别让词频高的偏题块直接进答案。

学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%免费】

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询