想象你要把一本 300 页的厚小说交给一个读书小组传阅,但每位组员一次只能读 30 页。为了让大家都能接上剧情,你决定把书拆成一叠叠小册子:第 1 叠是第 1~30 页,第 2 叠从第 26 页开始,一直读到第 55 页——每叠末尾都多夹了前一位读者看过的 5 页,当作“剧情便签”,保证下一位读者不至于一头雾水。这个“拆书装订”的过程,就是 RAG(检索增强生成)里最基础也最关键的一步:分块(Chunking)。“每叠 30 页”就是 chunk_size,“重复的 5 页剧情便签”就是 overlap。拆得好,每一位“读者”(AI 模型)都能顺畅理解;拆得不好,不是剧情断在中间,就是整本书被复制得又厚又贵。这篇内容,就是教你怎么把这本书拆得既省纸、又不断戏。

岗位关联

分块参数的调优是 RAG 从“能跑”到“好用”的分水岭。掌握 chunk_size 与 overlap 的调优方法,是每一位 RAG 应用工程师的必修课。

目录
  1. 可视化演示
  2. 分块基础概念
  3. 核心参数解析
  4. 固定大小分块
  5. 递归字符分块
  6. 语义分块
  7. 调优方法论
  8. 实战落地建议
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

通过Chunk大小、重叠窗口和分块方法对比三个视角,展示RAG文档处理中分块参数对检索质量的影响与调优策略。

本节配有交互动效(进入视口后自动加载,约 3KB)。

分块基础概念

想象你要把一本 300 页的厚小说交给读书小组传阅,但每位组员一次只能读 30 页。你能做的,就是把书拆成一叠叠小册子:第 1 叠是 1~30 页,第 2 叠是 26~55 页……每叠之间有 5 页“重复交接区”,确保下一位读者不必从头猜剧情。这个“拆书”的动作,就是 RAG 中最关键的第一步——分块(Chunking)。

在 RAG 系统里,长的原始文档不能直接喂给大模型,因为大模型的“阅读上限”(上下文窗口)是有限的。于是我们把文档切成小片段,对每个片段做向量化(Embedding),存入向量数据库;用户提问时,系统先检索最相关的几个片段,再交给大模型组织答案。分块后的每个片段,就是检索时的最小单位——相当于递给读者的那一叠小册子。

分块决定了检索的粒度:块太大,向量里混入太多无关信息,检索出的片段重点模糊;块太小,单个片段信息量不足,语义被拦腰截断。分块质量直接影响“能否找回正确答案”和“找回的内容是否干净”。它是整条 RAG 流水线的第一刀,这一刀切歪了,后面所有环节都会跟着将就。

所以,拆书之前先算清楚“一本书会被拆成多少叠”。这份基础账目一旦建立,后面的参数调优就有了共同的“语言”——无论换哪种切法,你都知道自己手里的书页总数是守恒的。

L=n×s−(n−1)×oL = n \times s - (n - 1) \times o
一整本书记作总长 L;切成 n 叠,每叠 s 页;相邻两叠共享 o 页,所以总页数等于各叠之和减去所有重叠部分的重复页数。
  1. n 块数文档总共被切成多少份,直接决定向量库的规模。
    n:分块数量n: \text{分块数量}
  2. s 块大小每个分块包含多少字符或 token,也就是 chunk_size 参数。
    s=chunk_sizes = chunk\_size
  3. o 重叠量相邻分块之间共享的尾部内容长度,也就是 overlap 参数。
    o=overlapo = overlap
  4. 总长平衡式总长度等于 n 个块的长度之和,再减去 n−1 次重叠重复。
    L=n×s−(n−1)×oL = n \times s - (n-1) \times o

核心参数解析

读书小组有两条铁规矩:一是“每叠多少页”,二是“交接区重复几页”。页数太多,一叠小册子沉甸甸,读者读不完还抓不住重点;页数太少,每叠都在重翻旧内容,成本翻倍。交接区的页数也有讲究:太少了,下一位读者接不上剧情;太多了,整本书等于被复制了一小半。这两条规矩,就是分块参数里最核心的两个旋钮:chunk_size 和 overlap。

chunk_size 决定每个分块的长度上限,overlap 决定相邻分块首尾共享多少内容。两者共同决定“滑动步长”(step = chunk_size − overlap),也就是每个新块比前一块多出的新内容长度。overlap 的初衷是给边界处的语义打补丁——当一句话恰好在块尾被切断,它的开头还能在下一块里再出现一次,避免彻底丢失上下文。但补丁不是万能药:它增加存储与嵌入成本,也无法真正让被切断的句子变完整。

理解这两个旋钮,关键是看它们如何联动决定分块总数。块数越多,向量库越大,检索和存储成本越高;块数越少,每块越“臃肿”,检索精度越差。这个数量关系可以用下面这个公式精确表达。

调参从来不是“把页数调大一点”这么简单。chunk_size 与 overlap 像一对联动齿轮,转动任何一个,块数、成本、检索效果全都跟着变。先记住这张“账本”,后面无论采用哪种切法,你都能立刻算出它的开销。

N=⌈L−os−o⌉N = \left\lceil \frac{L - o}{s - o} \right\rceil
通俗地说:分块总数 = 向上取整(总长度减掉第一个块的尾部,再除以每次前进的步长)。这就是评估任何参数组合的第一张“账本”。
  1. N 分块总数文档最终被切成的块数,决定向量库规模与检索延迟。
    N:分块总数N: \text{分块总数}
  2. L 文档总长原始文本的总长度,以字符数或 token 数计。
    L:文档总长度L: \text{文档总长度}
  3. o 重叠量相邻块共享的尾部长度,即 overlap。
    o:重叠量o: \text{重叠量}
  4. s−o 滑动步长每个新块相对于前一块引入的新内容长度。
    s−o:滑动步长s - o: \text{滑动步长}
  5. 向上取整最后一块哪怕只剩 1 页,也要单独算作一叠。
    ⌈⋅⌉\lceil \cdot \rceil

固定大小分块

最省事的拆书办法是什么?拿一把尺子,量好 30 页就切一刀,不管这一刀是不是正好落在剧情高潮那句话的中间。“反正 30 页一叠,规矩统一”——这就是传说中的“一刀切”。

对应到代码里,就是固定大小分块(Fixed-size Chunking):给定一个 chunk_size,按字符数或 token 数从头到尾机械地切;overlap 则机械地把前一块尾部的若干字符复制到下一块开头。它的优点极其直白:实现简单、速度最快、分块数量完全可预测,非常适合处理日志、商品信息这类“每条记录独立自洽”的文本。

缺点是结构性的:文本的语义单元(段落、句子)长度参差不齐,固定长度硬切,大概率把一句话甚至一个词劈成两半,产生大量“残句块”。检索时即使命中了残句块,大模型也很难理解。overlap 只能让切点附近的文字在下一块再出现一次,相当于给伤口贴创可贴——句子本身依然是断的。重叠多少合适,可以用重叠率来衡量。

对一本书来说,用尺子量着切等于无视纸张的褶皱和墨水的标点——虽然快,但拆出来的册子满纸都是被裁掉的半句话。固定大小分块的归宿,是那些“每一页本来就能独立阅读”的资料,比如错峰出行的通知、分条列目的价目表。给小说用这种切法,纯属暴殄天物。

r=os×100%r = \frac{o}{s} \times 100\%
重叠率 = 重叠量 ÷ 块大小。工程经验上一般取 10%~20%,超过这个范围,冗余成本会明显上升,而语义收益趋于饱和。
  1. r 重叠率衡量“重复阅读”占每块的比例,是判断冗余程度的核心指标。
    r:重叠率r: \text{重叠率}
  2. o 重叠量相邻分块共享的尾部字符数或 token 数。
    o:重叠量o: \text{重叠量}
  3. s 块大小chunk_size 的字符数或 token 数。
    s:块大小s: \text{块大小}
  4. 百分比换算把比值乘以 100%,方便与 10%~20% 的经验区间对照。
    ×100%\times 100\%

递归字符分块

聪明的拆书匠不会死量页数,而是顺着书的“自然折痕”拆:先按大章节拆,一章太长就按小节拆,小节还长就按段落拆,段落再长就按句子拆……一层一层往里剥,直到每一叠都装得下为止。

这一策略在工程上的典型实现,就是递归字符分块(Recursive Character Text Splitting),LangChain 的 RecursiveCharacterTextSplitter 是最常用的代表。它维护一个由粗到细的分隔符列表,比如:段落空行 “\n\n“ → 换行 ”\n“ → 句号 ”。” → 问号/感叹号 → 逗号 → 空格 → 单字符。算法从最粗的分隔符开始切分,若某段仍超过 chunk_size,就换下一级更细的分隔符继续递归切分;切完后,再把相邻的小块合并,使每块尽量长但不超过上限。

这样“顺着折痕切”,句子和段落被劈开的概率大幅下降,同时块的利用率保持在高位。实际编码时有一个常见的坑:chunk_size 参数通常以 token 计,而文档长度我们习惯按字符看,两者需要换算。换算系数因语言而异,下面的公式给出了通用关系。

“顺着折痕拆书”听起来很聪明,但千万别迷信:折痕找得准,句子是完整了;可如果某一段话本身就有 2000 字,递归分块最后也会退化到按字符硬切。折痕是工具,不是魔法——它只是把“切在哪儿”的选择权从距离交给了结构。

schar≈α×stokens_{\text{char}} \approx \alpha \times s_{\text{token}}
字符数 ≈ 每 token 覆盖字符数 × token 数。中文每 token 大约覆盖 0.8~1 个汉字,英文每 token 约覆盖 3.5~4 个字符。这决定了你在代码里填 chunk_size=500 时,实际对应多少“字”。
  1. s_char 分块字符数我们直观感知的文本长度,以字符为单位。
    schar:分块字符数s_{\text{char}}: \text{分块字符数}
  2. s_token 分块 token 数模型真正计费和处理的粒度。
    stoken:分块 token 数s_{\text{token}}: \text{分块 token 数}
  3. α 语言密度系数每个 token 平均覆盖的字符数,中文与英文差异明显。
    α:语言密度系数\alpha: \text{语言密度系数}
  4. 近似换算关系字符数与 token 数通过语言密度系数互相换算。
    ≈α×\approx \alpha \times

语义分块

最讲究的读书会,会请一位“懂书的人”来拆:一场戏必须完整地交给同一位读者,哪怕这场戏只有 5 页,而下一场戏有 40 页。按剧情单元拆,而不是按页数或折痕拆——这就是语义分块的理想状态。

机器不会读剧情,但它有一个替代品:嵌入模型(Embedding Model)。具体流程是:先把文本切成句子,用嵌入模型把每个句子编码成一个向量;再计算相邻两个句子的余弦相似度——相似度高说明话题连续,相似度突然跌到阈值以下,说明“剧情转折”了,那里就是切点。切出的每一块,恰好是一段完整论述。

语义分块的最大优势是语义完整性极高,检索到的块往往就是用户想要的“那一段话”;代价也很明显:每个句子都要调用嵌入模型,计算成本高、延迟大,相似度阈值还得根据文档风格单独调,否则不是切得太碎就是切不动。相似度的计算方式正是这个方法的数学内核。

请“懂书的人”拆书最贵,也最贴心。如果你的业务是合同、论文这类“一句话都不能断”的场景,这份贵是值得的;但如果只是海量商品描述,语义分块就是杀鸡用牛刀。

sim(vi,vi+1)=vi⋅vi+1∥vi∥×∥vi+1∥\text{sim}(v_i, v_{i+1}) = \frac{v_i \cdot v_{i+1}}{\lVert v_i \rVert \times \lVert v_{i+1} \rVert}
两个句子的向量越“同向”,余弦相似度越接近 1,说明话题越连贯;跌破阈值就是分块信号的“剧情转折点”。
  1. v_i 句子向量第 i 个句子的嵌入向量,把一段文字映射成数字坐标。
    vi:句子嵌入向量v_i: \text{句子嵌入向量}
  2. 点积运算两个向量逐位相乘再求和,衡量它们的同向程度。
    vi⋅vi+1v_i \cdot v_{i+1}
  3. 模长乘积把点积结果归一化,消除句子长度带来的偏差。
    ∥vi∥×∥vi+1∥\lVert v_i \rVert \times \lVert v_{i+1} \rVert
  4. 余弦相似度结果落在 [−1, 1],越接近 1 表示语义越连贯。
    sim∈[−1,1]\text{sim} \in [-1, 1]

调优方法论

没有哪本书自带“标准拆法”。技术手册、菜谱、小说、合同,它们的“剧情单元”长度天差地别。所以拆书前要试装几个版本,拿给真正的读者反馈,而不是拍脑袋定页数。

RAG 的调优同样是实验驱动的:先定一组候选的 chunk_size 和 overlap,跑检索,看指标,再迭代。没人能一次报出最优参数,但方法论有章可循。工程实践中的推荐起点是:chunk_size = 250~500 token,overlap = chunk_size 的 10%~20%。然后根据文档类型微调:代码、表格这类结构强文本适合递归分块配小 overlap;散文、论文适合大块加适当重叠;条款型文本优先语义分块。

更系统的做法是网格搜索(Grid Search):把多个候选 chunk_size 与 overlap 组合成一张参数网格,逐一在小评估集上测试,用检索召回率(Recall)与答案相关性等指标选出最优组合。所谓“最优”,本质上就是在候选集合里求一个最大值。

试装几版给读者看,读者说哪版读得最顺,就按哪版装订——只不过这里的“读者”是一个带标准答案的评估集,“读得顺”是召回率和答案相关性。用数据投票,比任何经验都靠谱。

(s∗,o∗)=arg⁡max⁡(s,o)∈PRecall(s,o)(s^*, o^*) = \arg\max_{(s, o) \in \mathcal{P}} \text{Recall}(s, o)
在候选参数集合 P 中,找出让检索召回率最高的“块大小 + 重叠”组合。调参的全部目标,就是让指标说话,而不是让感觉说话。
  1. 候选集 P由经验起始值扩展出的所有参数组合网格。
    P:候选参数集合\mathcal{P}: \text{候选参数集合}
  2. Recall 召回率在特定参数下,相关文档被成功检索出的比例。
    Recall(s,o):检索召回率\text{Recall}(s, o): \text{检索召回率}
  3. argmax 求最大遍历候选集,挑出使召回率最大的那组参数。
    arg⁡max⁡\arg\max
  4. 最优参数组合调参的最终产出,即 s* 与 o*。
    (s∗,o∗)(s^*, o^*)

实战落地建议

真到开读书会那天,你还会发现一个隐藏成本:如果交接区重复的页数太多,整套书会“变厚”——本来 300 页的书,拆完可能变成 350 页。多出来的 50 页就是重叠的代价,对应到系统里就是存储空间和嵌入算力的浪费。

分块参数的实战选择,从来不是“质量单指标”问题,而是质量与成本的双指标权衡。落地时建议走四步:第一,先统计文档分布——平均段落长度、句子数、token 密度,据此确定初始参数区间;第二,构建小规模评估集,几百条带标准答案的问答即可;第三,在评估集上跑网格搜索,用“召回率 + 答案相关性 − 成本惩罚”综合评分;第四,上线后持续监控嵌入量、检索延迟与冗余率,用真实用户反馈迭代。

其中,冗余率是最容易被忽略的成本指标。它量化了“为了补边界而额外嵌入的内容”占有效新内容的比例,是计算账单的直接依据。

读书会开到最后,你会发现最好的拆法不是“越厚越好”,也不是“重叠越多越安全”,而是在“每叠装得下、剧情接得上、全书不虚胖”之间找到平衡。分块参数调优的终点,也正是这个平衡点。

R=os−oR = \frac{o}{s - o}
冗余率 = 重叠量 ÷ 滑动步长。R = 0 表示零重叠;R = 1 表示有一半的嵌入内容是重复的。这个数字可以直接换算成存储和成本。
  1. R 冗余率重叠带来的额外嵌入内容占有效新内容的比例。
    R:冗余率R: \text{冗余率}
  2. o 重叠量每个新块开头重复的上一块尾部内容。
    o:重叠量o: \text{重叠量}
  3. s−o 滑动步长每个新块真正引入的新内容长度。
    s−o:滑动步长s - o: \text{滑动步长}
  4. 比率含义比值越大,说明为了衔接付出的存储代价越高。
    R=os−oR = \frac{o}{s - o}

AI 应用场景

企业知识库智能问答机器人

阶段:文档加载与处理(分块与向量化索引)

解决的问题:产品手册通常有数千页,直接整体喂给大模型既超出上下文窗口,检索命中率也很低。传统做法是人工整理 FAQ,费时费力且难以覆盖长尾问题。采用递归字符分块,将 chunk_size 设为 300 token、overlap 设为 50 token 后,检索能从“大海捞针”变成“精准定位”。

具体案例:某 SaaS 公司的客服机器人需要回答关于 200 篇产品手册的提问。调优前用固定大小分块,检索召回率只有 62%;改用递归字符分块并调整 chunk_size 与 overlap 后,召回率提升到 81%,答案准确率同步上升,人工客服转接率下降约三成。

法律合同辅助审查

阶段:文档加载与处理(语义分块)

解决的问题:合同中的赔偿条款、免责条款必须完整呈现,任何“拦腰截断”都可能导致 AI 遗漏关键约束。语义分块按条款话题边界切分,确保每个块都是一个完整条款,显著降低漏答风险。

具体案例:某律所知识库用语义分块处理上千份合同,嵌入成本比固定分块高约 40%,但条款级问题的正确率从 71% 提升到 93%,客户对 AI 辅助审查的信任度大幅提升。

多语种混合文档检索

阶段:文档加载与处理(参数单位换算与适配)

解决的问题:中英混合的企业文档中,token 与字符的换算系数完全不同,直接用同一套 chunk_size 会导致中文块过短、英文块过长。利用语言密度系数 α 分别换算,再为不同语种设置独立的分块参数,可让每种语言的块长度落在同一 token 区间。

具体案例:某跨境电商平台的技术文档中英混杂,按语言分流后分别设置 chunk_size(中文 400 字符、英文 1200 字符),向量库总存储量下降 18%,检索准确率提升 12%。

Python 演示

python88 行
# -*- coding: utf-8 -*-"""演示 chunk_size 与 overlap 对分块结果的影响,并对比三种分块策略"""import reimport math  def fixed_chunk(text, chunk_size, overlap):    """固定大小分块:每块 chunk_size 字符,相邻块共享 overlap 字符"""    step = max(1, chunk_size - overlap)    chunks = []    start = 0    while start < len(text):        end = min(start + chunk_size, len(text))        chunks.append(text[start:end])        if end == len(text):            break        start += step    return chunks  def recursive_chunk(text, chunk_size, separators=("\n\n", "\n", "。", ",")):    """递归字符分块:按分隔符从粗到细逐层切分,直到每块不超过 chunk_size"""    def split_recursive(seg, seps, level):        if len(seg) <= chunk_size or level >= len(seps):            return [seg] if seg.strip() else []        parts = re.split("(" + re.escape(seps[level]) + ")", seg)        buf = ""        merged = []        for part in parts:            if len(buf) + len(part) <= chunk_size:                buf += part            else:                if buf:                    merged.append(buf)                buf = part        if buf:            merged.append(buf)        result = []        for item in merged:            if len(item) > chunk_size:                result.extend(split_recursive(item, seps, level + 1))            else:                result.append(item)        return result     return split_recursive(text, separators, 0)  def char_overlap_sim(a, b):    """用字符重合度模拟嵌入相似度(真实场景应使用嵌入模型)"""    sa, sb = set(a), set(b)    if not sa or not sb:        return 0.0    return len(sa & sb) / math.sqrt(len(sa) * len(sb))  def semantic_chunk(sentences, sim_func, threshold):    """语义分块:相邻句子相似度低于阈值时切块"""    chunks = []    current = [sentences[0]]    for i in range(1, len(sentences)):        if sim_func(sentences[i - 1], sentences[i]) < threshold:            chunks.append("".join(current))            current = [sentences[i]]        else:            current.append(sentences[i])    chunks.append("".join(current))    return chunks  if __name__ == "__main__":    doc = ("RAG系统先把长文档切成小块,\n"           "再对每个块做向量化并存入向量库。\n\n"           "查询时,系统把问题也转成向量,\n"           "检索与问题最相似的若干分块。\n\n"           "最后,大模型基于这些分块生成答案,\n"           "并附上引用来源。\n\n") * 5    print("文档总长度:", len(doc))    fixed = fixed_chunk(doc, 60, 15)    print("固定分块块数:", len(fixed), "前2块:",          [c[:10] + "..." for c in fixed[:2]])    rec = recursive_chunk(doc, 60)    print("递归分块块数:", len(rec), "平均长度:",          sum(len(c) for c in rec) // len(rec))    sents = [x for x in re.split("(?<=。)", doc.replace("\n", "")) if x]    sem = semantic_chunk(sents, char_overlap_sim, 0.45)    print("语义分块块数:", len(sem), "平均长度:",          sum(len(c) for c in sem) // len(sem))
目的:用同一份模拟文档对比固定大小分块、递归字符分块与语义分块三种策略,直观展示 chunk_size 与 overlap 如何影响块数、块长与语义完整性。
  1. step = max(1, chunk_size - overlap)滑动步长是块大小减重叠量,且必须大于 0,否则会死循环。
  2. chunks.append(text[start:end])从当前起点切出一个 chunk_size 长度的窗口作为分块。
  3. start += step窗口向前滑动一个步长,从而产生相邻块之间的重叠。
  4. parts = re.split("(" + re.escape(seps[level]) + ")", seg)用带捕获组的正则切分,保留分隔符本身不丢失。
  5. if len(buf) + len(part) <= chunk_size:贪心合并小块,让每块尽量接近上限又不超限。
  6. result.extend(split_recursive(item, seps, level + 1))超长块降级到下一级分隔符递归处理。
  7. len(sa & sb) / math.sqrt(len(sa) * len(sb))用字符重合度模拟余弦相似度,值域在 0~1 之间。
  8. if sim_func(sentences[i - 1], sentences[i]) < threshold:相邻句相似度跌破阈值,判定为语义边界并切块。
  9. doc = (...) * 5用重复段落拼接模拟一份更长的文档,方便观察分块效果。
  10. print("固定分块块数:", len(fixed), ...)输出三种策略的块数与平均长度,直接对比差异。

常见误区

误区chunk_size 设大一点,每个块里的信息更多,检索肯定更准。我把 chunk_size 调到 2000 token,效果应该比 500 好很多吧?

正解块太大,一个向量里混入多个话题,检索时“平均”了所有重点,反而什么都匹配不准;而且可能超过嵌入模型的最大长度被截断。实践经验中 250~500 token 通常是甜区,具体要靠评估集验证,而不是直觉。

为何常见:直觉上“内容多 = 信息多”,却忽略了向量检索需要的是“主题纯净”的块,而不是信息堆砌的块。

误区overlap 越大,边界上下文保留得越多,那我直接把 overlap 设为 chunk_size 的一半,甚至让相邻块完全一样,总该更保险吧?

正解overlap 增大意味着嵌入总量 N × s 上升,存储与算力成本同步上升,冗余率 R = o/(s−o) 也会膨胀。overlap 只是给边界语义打补丁,并不能修复被切断的句子。10%~20% 是常用区间,超过后收益递减。

为何常见:把 overlap 当成“免费保险”,只看到它能补上下文,没算它带来的存储和成本账单。

误区固定用 chunk_size=512、overlap=64,所有项目都这么配,省事又不会出大错。文档类型不一样,真有那么大区别吗?

正解代码、合同、论文、客服会话的语义单元长度差异巨大。合同的一句话可能长达 200 字,代码的一行可能只有 20 字符。必须按文档类型和数据分布调整参数,并用评估集验证,不能复制经验值到底。

为何常见:项目交付压力大,习惯复制成功案例的参数,缺少“先看数据分布再定参数”的工程意识。

误区chunk_size=2000,不就是 2000 个汉字吗?中文一个字就是一个 token,直接按字数填就行。

正解中文一个 token 大约覆盖 0.8~1 个汉字,英文一个 token 约覆盖 3.5~4 个字符。框架里的 chunk_size 默认多以 token 计,填之前必须先换算,否则实际块长与你的预期可能差一倍。

为何常见:人习惯用“字数”感知文本长度,而模型按 token 计费和处理,两种单位之间的换算关系常被忽略。

误区语义分块最智能,一定比递归分块效果好。直接上语义分块,一步到位。

正解语义分块要为每个句子调用嵌入模型,计算成本高、延迟大,阈值还敏感;对海量短文本、商品描述这类场景性价比很低。大多数场景下,递归字符分块已经足够好,语义分块只适合“一句话都不能断”的高价值文档。

为何常见:认为“更先进 = 更有效”,忽略了成本约束和场景匹配,属于技术选型上的贪心。

面试题

Q1. chunk_size 通常以什么为单位?

单选题 · easy

  • A.字符或 Token← 正确答案
  • B.段落或章节
  • C.字节或比特
  • D.文件或目录

答案:A。chunk_size 是分块的长度参数,以字符数或 token 数计量;段落、章节属于语义结构单位,文件、目录属于存储单位,都不是长度单位。

Q2. overlap 在分块中的主要作用是什么?

单选题 · easy

  • A.压缩文档体积
  • B.保留边界上下文← 正确答案
  • C.提升切分速度
  • D.减少向量数量

答案:B。overlap 让相邻分块共享尾部内容,避免切点附近的语义被割裂。它不会压缩体积,反而增加存储,也不会提升速度或减少向量数量。

Q3. 固定大小分块最主要的问题是什么?

单选题 · mid

  • A.切分速度过慢
  • B.句子被拦腰切断← 正确答案
  • C.无法预测块数量
  • D.不支持并行处理

答案:B。固定大小分块按字符数硬切,完全无视句子的自然边界,极易产生残句块。它的优势恰恰是速度快、块数可预测且支持并行,问题出在语义完整性上。

Q4. 递归字符分块优先使用哪个分隔符?

单选题 · mid

  • A.段落空行← 正确答案
  • B.单个汉字
  • C.逗号分号
  • D.句号问号

答案:A。递归分块的分隔符列表由粗到细,段落空行是最粗的层级,优先使用;句子、子句、单词是后续的降级选择,单个汉字是最后兜底。

Q5. 语义分块判断切分边界的依据是什么?

单选题 · mid

  • A.相邻句向量相似度← 正确答案
  • B.分块的字符总数
  • C.关键词出现频率
  • D.标点符号数量

答案:A。语义分块把每个句子编码成向量,比较相邻句子的余弦相似度,相似度跌破阈值就切块。字符数、词频、标点都不是判断语义转折的依据。

Q6. overlap 设置过大会带来哪些影响?

多选题 · mid

  • A.向量库冗余增加← 正确答案
  • B.嵌入成本上升← 正确答案
  • C.检索收益递减← 正确答案
  • D.准确率必然提升

答案:ABC。overlap 增大使嵌入总量 N × s 上升,冗余率 R = o/(s−o) 变大,存储和成本都增加;边界补丁的效果边际递减。D 错在“必然”——冗余还可能引入噪声,准确率不升反降。

Q7. 某文档 L=10000 字符,chunk_size=500,overlap=100,分块数约为多少?

单选题 · hard

  • A.大约 20 块
  • B.大约 25 块← 正确答案
  • C.大约 30 块
  • D.大约 40 块

答案:B。滑动步长 s−o = 400,代入公式 N = ⌈(L−o)/(s−o)⌉ = ⌈(10000−100)/400⌉ = ⌈24.75⌉ = 25。属于典型的“账本”式计算,考察对块数公式的掌握。

Q8. 语义分块有哪些不足之处?

多选题 · hard

  • A.计算开销与延迟高← 正确答案
  • B.效果依赖嵌入模型← 正确答案
  • C.无需设定阈值参数
  • D.块长度不固定波动← 正确答案

答案:ABD。语义分块要为每个句子调用嵌入模型,成本高、延迟大;嵌入模型质量直接影响边界判断;块长随语义单元变化,波动大。C 错,相似度阈值正是它必须人工调的关键参数。

Q9. 中文文档目标 chunk_size=500 token,若每 token 约覆盖 0.8 字符,对应约多少字符?

单选题 · hard

  • A.约 400 字符← 正确答案
  • B.约 500 字符
  • C.约 625 字符
  • D.约 800 字符

答案:A。由换算公式 s_char ≈ α × s_token,α = 0.8,500 × 0.8 = 400 字符。这个换算关系决定了代码里填的 token 数与实际文本长度的对应,中英差异很大。

Q10. 分块参数调优时应该关注哪些指标?

多选题 · easy

  • A.检索召回率← 正确答案
  • B.答案相关性← 正确答案
  • C.嵌入成本延迟← 正确答案
  • D.原始文件大小

答案:ABC。调优的目标是质量与成本双指标平衡:检索召回率和答案相关性衡量质量,嵌入成本和延迟衡量开销。原始文件大小是输入信息,不是评估指标。