做饭的人都知道,备菜比下锅更花心思。一整只羊不能直接扔进锅里——锅装不下,火候不均,端上桌也没法分。主厨会把它拆成羊排、腿肉、里脊,再按菜谱切成块、片、丝,各归其位。大语言模型的 RAG(检索增强生成)知识库问答,也卡在同样一道“备菜”环节上:文本分块。 用户把文档交给 AI 前,系统得先把长文切成许多小块存起来;用户提问时,再挑最相关的几块喂给模型。块切大了,AI 的“嘴”(上下文窗口)装不下;切小了,一句完整的话被腰斩,语义碎一地;切的位置不对,再聪明的模型也拼不回原意。 这篇文章带你看懂四种主流“刀法”:固定窗口用尺子量着切,滑动窗口带着重叠切,递归字符顺着文本纹理切,语义分块则按“意思”归堆。你会明白它们各有什么脾气、适合什么样的“食材”,以及如何用实验数据找到最佳参数。

岗位关联

文本分块是 RAG 工程的第一道工序,直接决定检索命中率与回答质量。掌握四种策略的原理与选型方法,是 AI 应用工程师的必备基本功,能帮你从“能跑通”进阶到“效果好”。

目录
  1. 可视化演示
  2. 分块的初心——为什么不能把整本书喂给 AI
  3. 固定窗口分块——用尺子量着切
  4. 滑动窗口分块——刀锋带着重叠切
  5. 递归字符分块——顺着纹理切
  6. 语义分块——按菜品备料
  7. 参数调优——火候与刀工的平衡
  8. 选型指南——什么菜配什么刀
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

对比展示RAG四种分块策略:固定窗口(等长切分)、滑动窗口(重叠区域)、递归字符(分隔符优先级)、语义分块(Embedding相似度跳变检测)。

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

'+captions.fixed+'

分块的初心——为什么不能把整本书喂给 AI

假如你要在家里办一场 20 人的聚会,冰箱里躺着一整只羊。你会怎么做?老练的主厨不会把整只羊塞进烤箱——烤不熟,也分不均。他会先拆解:羊排拿来烤,腿肉拿来炖,剩下的剁成肉馅做丸子。每道菜用到的那部分,恰好是它该有的分量。这个“拆解备菜”的动作,就是今天的主角——文本分块。

大语言模型虽然博学,但它的“工作记忆”(上下文窗口)有字数上限,不可能一次读完你上传的几百页 PDF。RAG(检索增强生成)的思路是:先把文档切成许多小块存入向量数据库,用户提问时,系统只检索最相关的几块拼给模型看。分块的好坏,直接决定“检索”这一步是百发百中还是大海捞针。

为什么不能随便切?第二个动机是检索粒度:块太粗,一块里混了五六个话题,检索时“相关”和“跑题”的内容粘在一起,稀释了相关性;块太细,一个完整观点被劈成碎片,检索永远只能捞到半句话。第三个动机是成本:大模型按 token 计费,块越大,每次问答塞进去的 token 越多,账单越贵。于是有了一个最基本的公式——文档总长 L 除以块大小 S,得到块数 N。

备菜的核心不是“切得整齐”,而是“切得合适”。理解了分块的初心,接下来我们看看市面上四种主流“刀法”,以及它们各自的脾气和适用场景。

N=⌈LS⌉N = \left\lceil \frac{L}{S} \right\rceil
这个公式告诉你:文档总长度除以每块的目标大小,向上取整就是总块数。块数越多,存储与检索的开销越大。
  1. L——文档总长度通常用字符数或 token 数衡量,相当于整只羊的“肉量”。
    L=文档的字符数或 token 数L = \text{文档的字符数或 token 数}
  2. S——块大小(chunk size)每块的目标长度,决定“刀口间距”。
    S=每块包含的字符数或 token 数S = \text{每块包含的字符数或 token 数}
  3. ⌈·⌉——向上取整最后一块可能凑不满,但也要单独成块,就像最后几片肉也要装盘。
    ⌈LS⌉=不小于 L/S 的最小整数\left\lceil \frac{L}{S} \right\rceil = \text{不小于 } L/S \text{ 的最小整数}
  4. N——总块数块数直接影响检索开销和存储成本,是后续所有成本估算的起点。
    N=最终需要生成的块数量N = \text{最终需要生成的块数量}

固定窗口分块——用尺子量着切

有些食堂大厨切豆腐,先拿尺子比好,一刀一刀,每块整整齐齐 5 厘米。固定窗口分块就是这个思路:不管文本内容是什么,一律按固定长度下刀。文档从左到右,数够 S 个字符就切一刀,然后接着数,再切一刀,像一台没有感情的切菜机。

技术上它是最朴素的实现:设块大小为 S,第 i 块就是文本区间 [i·S, (i+1)·S)。优点是极简单——一个循环就能写完;速度快,不用理解文本;结果可预测,块数固定,成本好估算。很多团队把它当作 RAG 工程的基线(Baseline),先跑通全链路再说。

最大缺点是切断语义。一句话可能从中间被劈开,前半句在上一块、后半句在下一块;检索时只找到后半句,模型读到的是一个没头没尾的残句。这就像一刀切在了豆腐花纹的正中间——花纹断了,卖相和口感都打了折扣。

适用场景:日志、固定格式的流水记录,或者对检索质量要求不高、只想快速验证的 Demo。它简单可靠,但别指望它“懂”文本。用尺子切豆腐方便省事,但你没法保证花纹完整——碰到花纹,只能叹气。

blocki=text[ i⋅S, (i+1)⋅S )\text{block}_i = \text{text}[\,i \cdot S,\ (i+1) \cdot S\,)
意思是:第 i 块从文本的第 i×S 个字符开始,取到第 (i+1)×S 个字符为止,块与块之间没有任何重叠。
  1. block_i——第 i 块编号从 0 开始,第一块是 block_0。
    第 i 个文本块\text{第 } i \text{ 个文本块}
  2. i·S——块起点从第 i×S 个字符开始取,上一块的终点就是下一块的起点。
    i⋅S=第 i 块的首字符位置i \cdot S = \text{第 } i \text{ 块的首字符位置}
  3. (i+1)·S——块终点到第 (i+1)×S 个字符为止,但终点本身不包含在内。
    (i+1)⋅S=第 i 块的末端字符位置(i+1) \cdot S = \text{第 } i \text{ 块的末端字符位置}
  4. [ )——左闭右开区间包含起点,不包含终点,避免边界字符被重复取到。
    [a,b)={x∣a≤x<b}[a, b) = \{ x \mid a \le x < b \}

滑动窗口分块——刀锋带着重叠切

老练的肉贩切五花肉时,不会每次把刀完全挪开再下刀,而是让刀锋与上一刀保持一点重叠——确保肉皮上的纹理不会被接缝切断。滑动窗口分块的灵感正来源于此:固定块大小 S,但每刀只向前推进 stride 个字符,让相邻两块共享一段重叠区 O。

这样做的收益很明显:一个恰好被“骑”在边界上的知识点,会在下一块中以完整形态再出现一次,检索时无论命中哪一块,都能拿到完整信息。代价同样肉眼可见——冗余。同样的内容被存了两遍,向量库体积变大,Embedding 和存储成本上升;检索时还可能同时返回两块“看起来几乎一样”的结果。overlap 设得越大,冗余越严重。

适用场景:对话流、新闻正文等上下文高度连贯、没有自然章节边界的文本。合理的 overlap 一般取块大小的 10%~20%,既能防断裂,又不至于太浪费。刀锋重叠虽然会多切几刀,但保证了关键花纹不会断在两刀之间。

stride=S−O\text{stride} = S - O
步长等于块大小减去重叠大小。重叠越多,步长越小,块数越多,成本越高。
  1. S——块大小每个窗口要截取的长度,是“刀锋宽度”。
    S=窗口宽度(块内字符数)S = \text{窗口宽度(块内字符数)}
  2. O——重叠大小(overlap)前后两个窗口重复的字符数。
    O=相邻窗口共享的字符数O = \text{相邻窗口共享的字符数}
  3. stride——步长每切一刀,起点向后移动的距离。它等于 S 减 O,是滑动窗口最核心的旋钮。
    stride=S−O\text{stride} = S - O

递归字符分块——顺着纹理切

有经验的大厨分解一只鸡,绝不会抡起砍刀硬剁骨头,而是先找到关节,轻轻一拧就拆开了。递归字符分块就是文本世界的“关节大师”:它不按固定长度硬切,而是顺着文本的天然结构逐层拆解——先按段落分,段落太大再按句子分,句子还太大就按子句、按词分。

具体做法是准备一组按优先级排列的分隔符:段落符(两个换行)、换行符、句号、空格。切分函数 f(t) 这样工作:如果 t 的长度还没超过阈值 S,就直接收下;否则用当前最高优先级的分隔符把 t 劈开,然后对每一片子串递归调用 f。LangChain 的 RecursiveCharacterTextSplitter 就是这一思路的著名实现。

优势是尊重结构:段落、句子通常不会被人为切断,每个块内部的语义相对完整。缺陷是它依赖分隔符的“成色”:如果文档本身没有清晰分隔符——比如一行行滚动的服务器日志——它就退化成固定窗口,甚至因递归开销而更慢。

适用场景:Markdown 文档、技术博客、合同条款这类“天生有结构”的文本。顺着纹理下刀,肉不碎、语义也不散。

f(t)={{t},∣t∣≤S⋃ti∈t.split(s0)f(ti),∣t∣>Sf(t) = \begin{cases} \{t\}, & |t| \le S \\ \bigcup_{t_i \in t.\text{split}(s_0)} f(t_i), & |t| > S \end{cases}
这是一个递归定义:文本够短就直接作为一块;太长就用当前最高优先级的分隔符切碎,再对每一片递归执行同样操作。
  1. f(t)——递归分块函数输入一段文本,输出一个块集合。
    f:文本↦块集合f: \text{文本} \mapsto \text{块集合}
  2. |t| ≤ S——终止条件文本足够短,不再下刀,原样作为一块。
    ∣t∣≤S⇒{t}|t| \le S \Rightarrow \{t\}
  3. t.split(s_0)——用最高优先级分隔符切分s_0 是当前可用的最高级分隔符,比如段落符。
    t.split(s0)={t1,t2,…,tk}t.\text{split}(s_0) = \{t_1, t_2, \ldots, t_k\}
  4. ⋃ f(t_i)——递归并集对每个子串再调用 f,最后把所有子块合并起来,形成最终结果。
    ⋃tif(ti)=所有子块的并集\bigcup_{t_i} f(t_i) = \text{所有子块的并集}

语义分块——按菜品备料

顶级私房菜的主厨备菜,从来不是按重量称好就完事,而是按“这道菜要做什么”来归堆:做鱼的放一盆,做肉的放一盆,炖汤的药材放一袋。这种“按意思归类”的分块方式,就是基于 Embedding 的语义分块。

它的大致流程是:先把文本按句切碎,用 Embedding 模型把每个句子编码成一个向量(一串代表语义的数字);然后计算相邻两句向量的余弦相似度——相似度高,说明话题在延续;相似度低,说明话题发生转折,就在这个“低谷”处下刀。于是每一块内部的句子都围绕同一主题,而块与块之间井水不犯河水。

有了相似度序列后,设定一个阈值 θ,凡是相邻相似度低于 θ 的位置就是候选切分点。这种方法产出的块,内部语义高度内聚,检索质量通常是四种策略中最高的。代价也最贵:需要额外调用 Embedding 模型为每个句子推理一次,长文档处理速度慢、成本高,阈值还需要反复调。

适用场景:FAQ、论文、产品文档等“话题边界清晰”的高质量文本,以及检索质量直接决定业务体验的场景。慢工出细活,说的就是它。

cos⁡(va,vb)=va⋅vb∥va∥∥vb∥\cos(\mathbf{v}_a, \mathbf{v}_b) = \frac{\mathbf{v}_a \cdot \mathbf{v}_b}{\|\mathbf{v}_a\| \|\mathbf{v}_b\|}
余弦相似度衡量两个句子“想表达的意思”有多接近:越接近 1 越相似,越低越可能该切分了。
  1. v_a、v_b——两个句子的 Embedding 向量把句子压缩成一串数字,数字分布代表语义。
    v=embedding(句子)\mathbf{v} = \text{embedding}(\text{句子})
  2. v_a·v_b——点积衡量两个向量在方向上的一致性,对应“话题走向是否相同”。
    va⋅vb=∑jvajvbj\mathbf{v}_a \cdot \mathbf{v}_b = \sum_j v_{aj} v_{bj}
  3. ‖v_a‖‖v_b‖——模长的乘积把相似度归一化到 [-1,1],消除句子长度带来的偏差。
    ∥v∥=∑jvj2\|\mathbf{v}\| = \sqrt{\sum_j v_j^2}
  4. cos 值——余弦相似度越接近 1 越相似,越接近 0 或负值越不相关。
    cos⁡(va,vb)≈1⇒语义相近\cos(\mathbf{v}_a, \mathbf{v}_b) \approx 1 \Rightarrow \text{语义相近}

参数调优——火候与刀工的平衡

刀工再好,火候不对菜也废。分块策略选得再好,参数设得离谱,效果照样翻车。参数调优是分块工程从“能用”到“好用”的那段路。

三个核心旋钮:chunk_size(块大小)决定单刀宽度,越大单块信息越全但噪声越多,越小纯度越高但上下文越容易碎;chunk_overlap(重叠大小)决定块与块的衔接,越大上下文越连贯但冗余越重;分隔符选择则决定递归和语义方法的边界质量。三者互相牵制,改一个往往要重新评估全局。

这个公式最直观的提醒是:overlap 从 10% 涨到 30%,块数会明显增加,存储与 Embedding 成本跟着上升。因此参数调优不能拍脑袋,要用真实的检索评测集反复实验,对比 Recall@k 等指标——好厨师靠试菜,好的分块参数靠实验数据说话。

经验上,多数知识库文档的块大小在 300~800 token 之间,overlap 在 10%~20%。但记住:一切以你的数据实测为准。好厨师从不迷信菜谱,而是反复试菜。

N=⌈L−SS−O⌉+1N = \left\lceil \frac{L - S}{S - O} \right\rceil + 1
这是滑动窗口的总块数公式。它揭示了:重叠 O 变大或块 S 变小时,块数会加速上涨,成本也跟着水涨船高。
  1. L——文档总长还是那锅菜的“总量”。
    L=文档总字符数L = \text{文档总字符数}
  2. S——块大小、O——重叠大小两个最核心的旋钮。
    S=块大小,O=重叠大小S = \text{块大小},\quad O = \text{重叠大小}
  3. S - O——实际步长每块重复 O 个字符后,真正向前走 S-O 个字符。
    S−O=strideS - O = \text{stride}
  4. ⌈(L-S)/(S-O)⌉ + 1——总块数第一块从 0 开始,之后每走一个步长就多一块,最后不满一块也要兜底。
    N=⌈L−SS−O⌉+1N = \left\lceil \frac{L - S}{S - O} \right\rceil + 1

选型指南——什么菜配什么刀

中式厨房里,切肉的、切鱼的、切水果的刀通常是分开的——没有哪把刀能包打天下,分块策略也一样。关键在于看“食材”和“菜谱”。

三个决策维度。文档类型:结构化的 Markdown、合同、论文,优先递归字符分块,因为它们的天然边界明显;对话、新闻这类流式文本,用滑动窗口保持上下文;话题庞杂的 FAQ 或百科,语义分块的收益最大。业务需求:实时性要求高(比如在线文档实时问答),要避开慢速的语义分块;准确率要求高,则预算允许时优先语义分块。链路协同:下游 Embedding 模型的窗口长度、检索器的类型、大模型的上下文大小,都会反过来约束块大小。

实践上最稳健的路径是“先简单后复杂”:先用固定窗口跑通基线、把链路装好,再针对检索质量瓶颈,换成递归字符或语义分块,用 A/B 数据证明收益。不要一上来就上最贵的方案——你不知道钱花在了哪里。

备菜没有标准答案,但懂了每种刀法的脾气,你就能在灶台前从容不迫。

Score=w1Q+w2V−w3C\text{Score} = w_1 Q + w_2 V - w_3 C
综合得分 = 质量分 × 质量权重 + 速度分 × 速度权重 − 成本分 × 成本权重。权重由业务目标决定。
  1. Q——质量分该策略在评测集上的检索或问答质量。
    Q=质量评估得分Q = \text{质量评估得分}
  2. V——速度分处理单位文本的耗时倒数,越快得分越高。
    V=速度评估得分V = \text{速度评估得分}
  3. C——成本分Embedding、存储、API 调用带来的单位成本。
    C=成本评估得分C = \text{成本评估得分}
  4. w_1, w_2, w_3——权重按业务目标设置,比如“质量优先”时 w_1 取大。
    w1Q+w2V−w3C=综合得分w_1 Q + w_2 V - w_3 C = \text{综合得分}

AI 应用场景

智能客服知识库——语义分块提升问答精准度

阶段:数据准备与索引构建

解决的问题:传统固定窗口会把“退货政策”和“退款流程”混在同一个块里,用户问退款时效时,检索结果夹杂大量无关介绍,回答差之千里。语义分块按话题边界切分,让每个块聚焦单一主题。

具体案例:某电商平台把上千篇客服文档用语义分块重新切分,每块只包含一个知识点;用户问“退货多久到账”时,检索到的块直接命中退款时效的那一段,回答准确率提升约 20%,人工转接率明显下降。

代码库文档问答——递归字符分块保住结构

阶段:离线索引构建

解决的问题:Markdown 技术文档包含标题、代码块、列表等多层结构,固定窗口常切断函数说明与其示例代码,导致问答时“有代码没解释”。递归字符分块按标题与段落边界切分,结构完整性大幅提升。

具体案例:一个开发者工具团队用递归字符分块处理 GitHub Wiki 和 API 文档,优先按标题和段落边界切分,函数说明与示例代码始终在同一块内,开发者提问时检索命中率显著提升,文档问答机器人被更多团队采用。

客服工单流式问答——滑动窗口保持对话连续

阶段:流式数据接入与处理

解决的问题:客服聊天记录是连续文本,话题边界模糊,固定窗口会割裂同一用户诉求的上下文。滑动窗口的重叠机制确保一个完整诉求至少完整出现在一个块中。

具体案例:某 SaaS 公司对历史工单对话做滑动窗口分块,overlap 设为块大小的 20%;后续做工单聚类分析时,同一诉求的片段能同时被召回,聚类准确率提升,客服运营团队能更快发现高频问题。

Python 演示

python59 行
# 文本分块策略演示import re  def fixed_window(text, size=50):    """按固定长度切分"""    return [text[i:i + size] for i in range(0, len(text), size)]  def sliding_window(text, size=50, overlap=10):    """滑动窗口, 相邻块有重叠"""    stride = size - overlap    return [text[i:i + size] for i in range(0, len(text), stride)]  def recursive_split(text, separators=("\n\n", "\n", "。", " "), max_size=50):    """递归字符分块: 按优先级从段落切到词"""    chunks = []    _recursive(text, separators, max_size, chunks)    return chunks  def _recursive(text, seps, max_size, chunks):    """递归辅助函数"""    if len(text) <= max_size:        chunks.append(text)        return    for sep in seps:        parts = text.split(sep)        if len(parts) > 1:            for p in parts:                _recursive(p, seps, max_size, chunks)            return    chunks.append(text)  def semantic_split(text, max_size=40):    """简化版语义分块: 按句子聚合到接近块大小"""    sentences = re.split(r"(?<=[。!?])", text)    chunks, cur = [], ""    for s in sentences:        if len(cur) + len(s) <= max_size:            cur += s        else:            if cur:                chunks.append(cur)            cur = s    if cur:        chunks.append(cur)    return chunks  if __name__ == "__main__":    sample = ("今天天气很好。我们一起去公园。公园里有很多花。"              "下午回家。我开始写代码。代码跑通了。")    print("固定窗口:", fixed_window(sample, size=15))    print("滑动窗口:", sliding_window(sample, size=15, overlap=5))    print("递归字符:", recursive_split(sample, max_size=15))    print("语义分块:", semantic_split(sample, max_size=15))
目的:用 Python 实现四种文本分块策略,直观对比同一段文本在不同“切法”下的输出差异。
  1. def fixed_window(text, size=50):定义固定窗口分块函数,默认块大小 50 字符
  2. return [text[i:i + size] for i in range(0, len(text), size)]按固定步长 size 切片,一块接一块,毫无重叠
  3. stride = size - overlap滑动窗口的步长:块大小减去重叠量,重叠越大步长越小
  4. for sep in seps:递归字符分块的入口:从最高优先级的分隔符开始尝试
  5. parts = text.split(sep)用当前分隔符把文本劈成若干子串
  6. if len(cur) + len(s) <= max_size:句子还能塞进当前块就继续塞,塞不下就另起一块
  7. chunks.append(cur)一个块攒满后,把它收进结果列表

常见误区

误区“文本分块嘛,随便切切就行——反正 Embedding 模型能理解意思,检索靠向量相似度就够了吧?”

正解分块决定检索粒度和语义完整性。切碎了,Embedding 再强也难找回完整观点;切粗了,一块里全是噪声,Top-k 检索结果中真正相关的比例直线下降。就像把一盘红烧肉剁成肉泥,再好的舌头也尝不出原来的味道。

为何常见:刚接触 RAG 时,注意力都放在模型和向量库上,低估了“前处理”对链条的放大作用。

误区“块越大,喂给大模型的信息越全,回答自然越准。512 不够就 1024,1024 不够就 2048。”

正解块过大会引入大量无关话题,检索时相似度被噪声稀释,真正相关的信息反而“沉”在块里;同时 token 成本上升,响应变慢。块大小应匹配任务复杂度,通过实验调优而不是盲目加大。

为何常见:直觉上“信息多 = 好”,忽略了检索机制是“相关性排序”而非“全都要”。

误区“滑动窗口的重叠不就是防止信息断裂吗?那把 overlap 设成块大小的一半,肯定更保险。”

正解重叠会带来存储和成本成倍增长——overlap 越大,stride 越小,块数越多;检索时还可能返回多个几乎重复的块,浪费上下文窗口。一般 overlap 取块大小的 10%~20% 就足够。

为何常见:看到了滑动窗口解决“切断语义”问题的好处,却没算冗余的账。成本是块数的函数,而块数是重叠的增函数。

误区“语义分块检索质量最高,那所有文档都用它就好了,贵有贵的道理。”

正解语义分块需要额外调用 Embedding 模型为每个句子推理,处理速度慢、成本高。对实时性要求高的流水线(如在线问答、流式接入)和超长文本,可能不划算。它适合离线处理的高质量文档库。

为何常见:对比实验里语义分块常表现最好,让人误以为“越贵越高级越有效”,忽略了工程上的时效和成本约束。

误区“递归字符分块顺着段落和句子切,语义一定完整,不会切断观点。”

正解它只是“尽量”尊重文本结构,本质上仍然在靠字符模式(分隔符)切分,而非理解语义。如果文档没有清晰分隔符(如服务器日志、聊天记录),或者分隔符质量不高,效果可能和固定窗口差不多,甚至因为递归开销更慢。

为何常见:把“结构优先”误当成“语义优先”,忽略它依然是一个基于规则的方法。

面试题

Q1. 在 RAG 系统中,对文档做分块的最主要原因是?

单选题 · easy

  • A.减少存储空间的占用
  • B.适配上下文并提升检索精度← 正确答案
  • C.加快模型训练的收敛
  • D.提高生成文字的多样性

答案:B。RAG 的核心是先把文档切成小块存起来,检索时按相关度召回再喂给模型。分块的核心目的是让每个块既能在模型上下文窗口内,又能被精准检索到。减少存储(A)不是主因,加快训练(C)与 RAG 无关,多样性(D)也答非所问。

Q2. 固定窗口分块最大的缺点是?

单选题 · easy

  • A.实现起来过于复杂
  • B.计算成本消耗太高
  • C.可能切断语义的边界← 正确答案
  • D.完全不需要 embedding

答案:C。固定窗口像用尺子切豆腐——整齐但会切断花纹。它不管句子和段落边界,可能把一个完整观点劈成两半,检索时只找到半句话。它实现简单、成本低(A、B 是反的),不需要 embedding 是特点而非缺点(D)。

Q3. 滑动窗口分块中,stride(步长)的计算方式是?

单选题 · mid

  • A.stride 等于块大小加重叠值
  • B.stride 等于块大小减重叠值← 正确答案
  • C.stride 等于重叠值减块大小
  • D.stride 等于块大小乘重叠值

答案:B。滑动窗口让相邻块有重叠,重叠值 O 是重复保留的部分,所以真正向前移动的步长 = 块大小 − 重叠。如果 stride = S + O(A),块之间会出现缝隙;其他两个式子更是无意义的变形。

Q4. 递归字符分块在选择分隔符时的基本策略是?

单选题 · mid

  • A.段落优先于句子和词← 正确答案
  • B.句子优先于段落和词
  • C.随机挑选任一标点符号
  • D.只用换行符做单一切分

答案:A。递归字符分块像顺着筋膜切肉,优先用最自然的分隔符。段落(空行)是最强的边界,其次换行、句号、空格,按优先级从高到低逐层切分。它不会随机选(C),也不会只用一个分隔符(D),更不是句子优先(B)。

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

单选题 · mid

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

答案:C。语义分块把句子编码成向量,用相邻句向量之间的余弦相似度判断话题是否转折:相似度低的地方就是切分点。字符数(A)、标点频率(B)、关键词次数(D)都是表面的文本特征,不是语义依据。

Q6. 语义分块相比其他策略的明显劣势有哪些?

多选题 · mid

  • A.需要额外的 embedding 推理← 正确答案
  • B.计算和存储的成本较高← 正确答案
  • C.检索质量一定处于最优
  • D.完全无需任何参数调优

答案:AB。语义分块贵在“理解”,成本自然不低:需要额外调用 Embedding 模型(A),计算与存储开销大(B)。但它并不“一定最优”(C 太绝对),也需要调阈值等参数(D 错)。像顶级大厨备菜,费时费力但味道好——前提是预算够。

Q7. 以下哪种文本最适合用滑动窗口分块?

单选题 · mid

  • A.需要保持段落完整语义
  • B.对话流式的连续上下文← 正确答案
  • C.超短文本的简单切分
  • D.图片描述的自动生成

答案:B。滑动窗口的核心价值是保留块间上下文连续。对话流式文本话题连贯、没有明显的章节边界,最适合用它。保持段落完整(A)更适合递归字符或语义分块;超短文本(C)怎么切都行;图片描述(D)不是文本分块的范畴。

Q8. RAG 分块策略选型时,需要考虑的因素包括?

多选题 · hard

  • A.文档的类型与结构← 正确答案
  • B.业务的时效与预算← 正确答案
  • C.办公室座位的朝向
  • D.下游生成的性能要求← 正确答案

答案:ABD。选型要看“食材”和“菜谱”:文档类型与结构(A)决定天然边界在哪;业务时效与预算(B)决定能否接受语义分块的高成本;下游生成性能要求(D)决定块大小与检索质量目标。办公室座位(C)显然是干扰项,选型不取决于工位风水。

Q9. 设置 chunk_overlap 参数的主要目的是?

单选题 · easy

  • A.让每个块变得小一些
  • B.避免跨块信息被切断← 正确答案
  • C.减少总体的计算量
  • D.替代语义模型做分块

答案:B。overlap 是相邻块之间的重叠区域,让一个跨边界的观点能完整出现在至少一个块里,避免信息断裂。它不是让块变小(A)、更不是减少计算(C)或替代语义模型(D)。就像刀锋带着重叠切肉,是为了不遗漏纹理。

Q10. 关于文本分块参数调优说法正确的有?

多选题 · hard

  • A.大块信息全但噪声较多← 正确答案
  • B.小块信息纯但易断语义← 正确答案
  • C.块大小需实验对比评估← 正确答案
  • D.任何文档都用固定大小

答案:ABC。参数调优是权衡的艺术——块大有噪声(A)、块小易断义(B),所以要用实验对比(C)找到最佳点。“任何文档都用固定大小”(D)正是我们反对的“一刀切”。火候对了,菜才好吃;参数对了,检索才准。