想象你经营一家私房菜馆,客人点单后,你从菜市场买回一整条三文鱼、一整颗南瓜、一整扇排骨。你当然不会把整条三文鱼直接端上桌让客人自己撕着吃——那样既无从下筷,也找不到最美味的部位。你需要“备菜”:先按纹理和部位切成合适大小的块,既保证每块都完整入味,又不至于切得太碎让客人不过瘾。 大语言模型的应用系统(如 RAG,检索增强生成)也面临同样的“备菜”难题。它的“冰箱”——知识库——里存放着大量长文档。当用户提问时,系统要去冰箱里翻找相关资料,再把找到的食材(片段)交给大模型“厨师”烹饪成答案。如果整篇文档直接入库存取,就像把整头牛塞进冰箱,检索时既拖沓又找不到重点。所以,所有文档入库存放前,都要经过一道关键工序:分块(Chunking)。本文就用“备菜刀法”作比喻,带你一口气看懂语义分块、滑动窗口等主流分块策略,以及它们背后的取舍智慧。

岗位关联

对于 AI 从业者而言,分块策略直接决定 RAG 系统的检索质量、成本与可维护性。掌握它,你就能在知识库项目里做出让工程师和业务方都满意的技术决策。

目录
  1. 可视化演示
  2. 1. 为什么需要分块
  3. 2. 语义分块原理:看纹理下刀
  4. 3. 固定窗口法:尺子切菜
  5. 4. 滑动窗口法:切蛋糕的重叠刀法
  6. 5. 递归分块法:冰箱分层收纳
  7. 6. Agentic 分块:看单下刀的主厨
  8. 7. 粒度权衡调参:厚薄之间找平衡
  9. 8. 实践评估应用:用指标检验刀法
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示滑动窗口固定分块、语义分块嵌入相似度切分及四种策略性能对比,揭示分块粒度与检索质量的权衡关系。

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

滑动窗口分块 固定大小窗口以stride步长滑动,重叠区保证上下文连续 stride=chunk_size-overlap 重叠区域减少语义断裂但增加存储开销

1. 为什么需要分块

你雇的帮厨从菜市场回来,把一整头牛放在案板上,问:“老板,直接下锅吗?”你当然会摇头。客人点的是“青椒牛柳”,不是“整牛火锅”。于是帮厨把牛按部位拆解:牛里脊切条、牛腩切块、牛骨熬汤,每一份恰好服务一道菜。

RAG 系统的“厨房”也遵循同样的逻辑。知识库接收文档时,如果整篇存进去,检索时每一轮都要把整篇文档与用户问题做比对。这不仅慢,而且返回的“答案食材”里掺杂了大量无关部位——客人想要牛柳,你端上来一头牛。所以,系统先把文档切成语义相对独立的片段,这些片段被称为块(chunk),每个块才是后续检索的最小单元。

块的大小直接影响两道工序:一是检索(query 与块的匹配),二是生成(把检索到的块喂给大模型)。块太小,一个完整观点被切成碎片,检索到的内容只有“半个证据”;块太大,噪音淹没重点。工程上通常用一个简单公式估算分块数量:

回到厨房场景:分块就像备菜的分寸拿捏。切得太粗,客人找不到想要的部位;切得太细,一炒就碎。理解了这个道理,我们才能继续看不同“刀法”——不同的分块策略,如何各显神通。

N=⌈LK⌉N = \left\lceil \frac{L}{K} \right\rceil
其中 L 是文档总长度,K 是每块的目标长度,N 是最少需要切的块数。这个公式告诉我们:块越大,块数越少。
  1. L文档总长度:把整篇文档的字符数(或 token 数)加总,就像一头牛的总重量,是备菜前的原始量。
    L=文档的字符总数L = \text{文档的字符总数}
  2. K目标块长度:每块计划包含多少字符,由任务精度决定,相当于一盘菜想装多少食材。
    K=每块的目标字符数K = \text{每块的目标字符数}
  3. N最少分块数:总长除以块长并向上取整,保证每一块不会超过目标大小。
    N≥LKN \geq \frac{L}{K}

2. 语义分块原理:看纹理下刀

经验丰富的帮厨绝不闭着眼睛乱切。他拿刀前先观察纹理:牛肉的纹路顺着纤维走,南瓜的质地从皮到瓤渐变。纹理相近的地方一切到底,纹理突然断裂的地方才落刀——这样切出来的每块食材,都自带完整“身份”。

语义分块(Semantic Chunking)就是这种“看纹理下刀”的工程实现。它先把文档按句子拆开,再让每个句子通过一个嵌入模型变成一组数字,这组数字就是句子的“纹理坐标”,也叫向量。随后计算相邻两个句子向量的相似度:相似度高,说明两句话还在聊同一个话题;相似度突然跌到低谷,说明话题切换了——这里就是切分点。

实际操作时,相似度通常用余弦相似度计算:

语义分块的产出是“话题完整”的块:边界和自然语义对齐,检索时容易精准命中。缺点是每个句子都要做一次向量计算,成本比“尺子切法”高得多。帮厨看纹理下刀虽然慢,但端出来的每道菜都完整——这就是语义分块的独特价值。

sim(A,B)=A⋅B∥A∥∥B∥\text{sim}(\mathbf{A}, \mathbf{B}) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|}
这个公式把两个句子的向量夹角转成 -1 到 1 之间的分数,越接近 1 表示两句话的方向越一致,语义越接近。
  1. 分子向量点积:两个句子向量对应位置相乘再相加,衡量它们朝同一方向“走”了多远。
    A⋅B=∑i=1nAiBi\mathbf{A} \cdot \mathbf{B} = \sum_{i=1}^{n} A_i B_i
  2. 分母模长乘积:各自先算“长度”再相乘,作用是消除句子长短带来的干扰。
    ∥A∥∥B∥=∑Ai2×∑Bi2\|\mathbf{A}\| \|\mathbf{B}\| = \sqrt{\sum A_i^2} \times \sqrt{\sum B_i^2}
  3. 比值余弦相似度:结果落在 -1 到 1 之间,值越大,两个句子在语义空间里越“同向”。
    cos⁡(θ)=A⋅B∥A∥∥B∥∈[−1,1]\cos(\theta) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} \in [-1, 1]

3. 固定窗口法:尺子切菜

如果今天你请的帮厨是位临时工,他不想观察纹理,也不想算相似度。他直接拿出一把尺子,在长条案板上每隔10厘米“咔”一刀。整根胡萝卜、整条茄子全切成等长的小段,快速利落。

固定窗口分块(Fixed-size Chunking)就是这把“尺子”。它设定一个固定长度 K(比如 512 个 token 或 200 个字符),从文档开头每 K 个长度切一刀,不考虑句子、段落或语义。优点是极简单:不需要任何模型,速度最快,代码只有几行。对日志、结构化表格、代码仓库这类天然等长的文本,它完全够用。

但它有显而易见的短板:可能把一句话拦腰斩断,把一段完整的论证拆成两半。此时可用窗口遍历公式估算块数:

尺子切菜确实省事,但代价是切坏纹理:一句话可能被切成两半,就像把三文鱼腹部的花纹拦腰切断。所以它只适合“标准化食材”,遇到讲究语义的文档就要换更聪明的刀法。

Nw=⌊L−KS⌋+1N_w = \left\lfloor \frac{L - K}{S} \right\rfloor + 1
其中 S 是窗口每次移动的步长。固定窗口下步长等于 K,即每次移动一格完整窗口。
  1. L - K可滑动范围:最后一个窗口的起点最多能到文档末尾之前的 K 个字符处。
    L−KL - K
  2. 除以 S可放几个步长:把可滑动范围除以步长,得到中间还能移动几步。
    L−KS\frac{L - K}{S}
  3. 向下取整加一向下取整得到中间步数,再加首窗口 1 个,就是总窗口数。
    ⌊L−KS⌋+1\left\lfloor \frac{L - K}{S} \right\rfloor + 1

4. 滑动窗口法:切蛋糕的重叠刀法

过生日切蛋糕时,你会让每一刀都和上一刀稍微重叠一点吗?其实不用。但如果你不是一次性切完,而是“边切边分给客人”,重叠刀法就有用了:每一刀都从上一刀边缘往后挪一段,让每一块蛋糕都带上一点上一块的花边——这样无论奶油花纹在哪里,每块都能分到完整的一层。

滑动窗口分块(Sliding Window Chunking)借鉴了这种重叠智慧。它仍使用固定窗口大小 K,但每次滑动距离 S 小于 K。于是相邻两个块之间有一段重复内容,称为重叠区。这段重叠让跨块上下文得以保留:上一块的结尾结论,会在下一块的开头再次出现,检索时无论命中哪一块,上下文都相对完整。

重叠的程度用重叠率 r 表示,步长与重叠率的关系是:

滑动窗口是“上下文连续性”与“存储效率”的折中。重叠太多,知识库膨胀、检索返回重复;重叠太少,连续性问题依旧。就像切蛋糕:刀刀重叠才能保住花纹,但每刀都切在同一个地方,那就永远切不出蛋糕了。

S=K×(1−r)S = K \times (1 - r)
重叠率 r 在 0 到 1 之间。r = 0 时退化为固定窗口;r = 0.5 表示下一块会重复上一块一半的内容。
  1. K × (1 - r)有效新内容:每次滑动只往前带出 (1 - r) 比例的新内容,其余是重叠。
    K×(1−r)K \times (1 - r)
  2. S实际步长:窗口每步移动的距离,等于新内容长度。
    S=K×(1−r)S = K \times (1-r)
  3. 重叠区长度K 减去 S,就是两块之间共享的字符数。
    K−S=K×rK - S = K \times r

5. 递归分块法:冰箱分层收纳

整理冰箱时,最高效的思路是分层收纳:冷藏区放蔬菜、冷冻区放肉类;每个区里再用保鲜盒把牛肉、猪肉分开;如果牛肉还要细分,就再贴上标签“牛里脊”“牛腩”。这种“先分大类、再分小类”的结构化方法,就是递归分块(Recursive Chunking)的灵魂。

递归分块先按照文档的原生结构——章节、小节、段落、句子——构建一棵“文本树”。树的根是整篇文档,向下逐层展开到段落甚至句子。切分时“自顶向下”:先把文档按章切开,再把每章按节切开,直到达到目标粒度。每一层都提供不同粒度的块:上层适合概括型检索,下层适合精确型定位。

如果每层固定分成 b 个孩子,树的深度为 d,那么最终叶子块的数量是:

冰箱分层让你从“找肉”变成“先开冷冻区、再拿左边盒子”,检索也可以“先走上层再下钻”:用上层块判断方向,再顺着树往下找具体内容,效率和精确兼得。

N=bdN = b^d
深度每增加一层,块数按倍数增长。这提醒我们:递归分块要控制层数和分支数,避免块数量爆炸。
  1. b每层分支数:每一层把文本平均分成 b 个子块,相当于每层往冰箱里放 b 个保鲜盒。
    b=分支因子b = \text{分支因子}
  2. d树的深度:从根到叶子的层级数,代表“章→节→段”的嵌套层数。
    d=层级深度d = \text{层级深度}
  3. N叶子块总数:分支数连乘 d 次,就是最终分出来的叶子块数量。
    N=bdN = b^d

6. Agentic 分块:看单下刀的主厨

前几种刀法都遵循固定的规则,有经验的主厨却会“看单下刀”:客人点了寿喜锅,三文鱼切厚片;客人点了刺身,三文鱼切薄片;客人对鱼过敏,他直接换菜。Agentic 分块就是把这种“临场判断力”交给 AI 的技术。

Agentic 分块的核心是让大语言模型(LLM)充当帮厨。它先阅读文档的标题、章节名、段落大意和当前任务描述(比如“做一个政策条款问答系统”),然后自主决定:这篇文章要不要分层?哪些地方按语义切?哪一段值得整块保留?它甚至可以混合多种策略——前半篇用递归分块,中间某段用语义分块。

从数学视角看,LLM 是在候选策略集合中做选择,目标是最大化最终的检索质量:

看单下刀的主厨让每道菜都恰到好处,但主厨很贵、也慢。Agentic 分块同样如此:它能实现最灵活的分块方案,但每次决策都要调用 LLM,适合对检索质量要求高、知识库规模可控的场景。

π∗=arg⁡max⁡π∈ΠQ(π,D,T)\pi^* = \arg\max_{\pi \in \Pi} Q(\pi, D, T)
其中 D 是文档,T 是任务,Q 是质量评估函数,π* 是选出的最优策略。
  1. Π候选策略集合:所有可能的分块策略(固定、滑动、语义、递归等)构成一个集合。
    Π={π1,π2,…,πm}\Pi = \{\pi_1, \pi_2, \dots, \pi_m\}
  2. Q(π, D, T)质量函数:给定文档和任务,评估策略 π 能带来多好的检索效果。
    Q:Π×D×T→RQ: \Pi \times \mathcal{D} \times \mathcal{T} \to \mathbb{R}
  3. argmax挑选最优:在所有策略中找出让 Q 最大的那个 π。
    π∗=arg⁡max⁡Q(π,D,T)\pi^* = \arg\max Q(\pi, D, T)

7. 粒度权衡调参:厚薄之间找平衡

涮火锅的羊肉片要薄,红烧肉的块要厚,回锅肉要切得厚薄适中。没人会说“肉切得越薄越好”或“越厚越好”,一切要看菜式。分块粒度(chunk size)也是同一个道理:没有绝对最优,只有任务匹配。

粒度影响最核心的两个指标是召回率(Recalled relevant chunks / total relevant chunks)和准确率(Relevant retrieved chunks / total retrieved chunks)。细粒度块小、主题单一,检索时容易精确命中目标内容,所以召回率高;但块太短,上下文信息不足,生成阶段可能答得“没头没尾”。

粗粒度块上下文丰富,大模型能充分理解语境,但块内噪声多,可能把不相关的内容一起带给大模型,拉低准确率。两者常被合成一个综合指标 F1:

厚薄合适才好吃。分块大小没有标准答案,但有调参法则:先跑基线、再看指标、再微调。你的任务是决定这盘“菜”要什么口感,而不是执着于最流行的那把刀。

F1=2×P×RP+RF1 = \frac{2 \times P \times R}{P + R}
P 是准确率,R 是召回率。F1 在两者之间取调和平均,值越高,表示粒度设置越均衡。
  1. P准确率:检索到的块中,真正相关的那部分占比。
    P=命中且相关命中总数P = \frac{\text{命中且相关}}{\text{命中总数}}
  2. R召回率:所有相关块中,被检索出来的那部分占比。
    R=命中且相关相关总数R = \frac{\text{命中且相关}}{\text{相关总数}}
  3. F1调和平均:把 P 和 R 揉成一个数,对两者一视同仁,防止只偏科。
    F1=2PRP+RF1 = \frac{2PR}{P + R}

8. 实践评估应用:用指标检验刀法

再好的刀法都要拿到真实宴席上验证。客人觉得好吃,菜才算成立;分块策略同样要在真实检索任务中接受检验。评估标准不是“切得整齐”,而是“检索质量好不好”。

实践一般分三步。第一步,选择基线:先跑固定窗口与滑动窗口,得到最基本的召回与准确率。第二步,对比升级:换成语义分块或递归分块,看是否带来显著提升。第三步,任务适配:政策评估类项目需要去查“某一具体条款”,就用细粒度语义分块;医学研究要跨段落阅读完整证据链,就用滑动窗口+重叠;商业情报要同时回答宏观和微观问题,就上 Agentic 混合策略。

评估时可把多个指标加权成一个综合分:

一场宴席检验刀法,一次评估检验策略。分块不是为了切得好看,而是为了让大模型“厨师”最终端出的答案让用户满意。掌握了这套评估方法,你就能在真实项目中从容地选择、比较、迭代你的分块策略。

S=αR+βP,α+β=1S = \alpha R + \beta P, \quad \alpha + \beta = 1
α 和 β 表示你更看重召回还是准确。偏检索全面性时调大 α,偏结果纯净时调大 β。
  1. R召回率:是否把相关块都捞回来了,对应“该上的菜都上了”。
    R=TPTP+FNR = \frac{TP}{TP + FN}
  2. P准确率:捞上来的块是否干净,对应“上来的菜都不是客人拒绝的”。
    P=TPTP+FPP = \frac{TP}{TP + FP}
  3. 综合分 Sα、β 分别给召回和准确打分,再求和,得到这个策略的最终得分。
    α+β=1\alpha + \beta = 1

AI 应用场景

政策文件检索:语义分块让条款“找得准”

阶段:知识库构建与数据预处理

解决的问题:政策文件动辄几十页,条款交错。传统整篇入库时,用户问“新能源补贴的申领条件”,检索结果杂糅了大量背景内容;固定窗口又会把一条完整的申领条款拦腰截断,生成阶段答不到点子上。

具体案例:某政策评估团队用语义分块处理《“十四五”现代能源体系规划》。先把文件按章节拆成段落,再对每个句子做向量编码,计算相邻句相似度,在低谷处切分。提问“充电桩建设的用地审批流程”,系统能返回包含完整条款语义的块,评估人员复核工作量下降约 60%。

医学文献综述:滑动窗口保住证据链

阶段:知识检索与上下文组装

解决的问题:医学文献的结论常在前一段、统计分析在后一段。固定窗口把“结论与证据”拆到两个块里,检索只命中结论块时,大模型拿到“幸存者偏差”却看不到统计口径。

具体案例:肿瘤研究团队用滑动窗口处理 PubMed 摘要,窗口 256 token、重叠率 20%。生成综述时,“5 年生存率提升”这个结论块天然带有上一窗口的入组标准和统计方法,引用时证据链完整。团队将检索命中率从 52% 提升到 78%。

商业决策情报:Agentic 分块应对多变需求

阶段:动态知识管理与智能问答

解决的问题:高管的问题跨度极大:“公司去年整体营收多少”需要粗粒度上下文,而“华东区 Q3 单品销量”需要精确定位。固定一种粒度的分块策略无法两头兼顾。

具体案例:某商业情报系统让 LLM 根据 query 自动选择分块策略:宏观问题读取文档树的粗粒度根节点,细节问题下钻到细粒度叶子节点;系统还会缓存不同粒度的块,降低重复计算。最终知识库检索响应时间保持稳定,而答案引用的“可溯源性”显著提升。

Python 演示

python109 行
# -*- coding: utf-8 -*-"""演示三种常见分块策略:固定窗口、滑动窗口、语义分块。使用词袋重合度近似语义相似度,避免依赖外部库。"""import re  def split_sentences(text):    """按中英文句号、感叹号、问号拆分句子。"""    parts = re.split(r'[。!?!?]', text)    return [p.strip() for p in parts if p.strip()]  def tokenize(text):    """简易分词:保留中文字符和英文单词。"""    return re.findall(r'[\u4e00-\u9fa5]|[a-zA-Z]+', text.lower())  def jaccard_sim(sent_a, sent_b):    """用 Jaccard 相似度近似句子语义相似度。"""    set_a, set_b = set(tokenize(sent_a)), set(tokenize(sent_b))    if not set_a or not set_b:        return 0.0    return len(set_a & set_b) / len(set_a | set_b)  class FixedWindowChunker:    """固定窗口分块:每 chunk 固定字符长度。"""     def __init__(self, chunk_size=100):        self.chunk_size = chunk_size     def chunk(self, text):        return [text[i:i + self.chunk_size]                for i in range(0, len(text), self.chunk_size)]  class SlidingWindowChunker:    """滑动窗口分块:固定长度 + 前向重叠。"""     def __init__(self, chunk_size=100, overlap_ratio=0.2):        self.chunk_size = chunk_size        self.step = max(1, int(chunk_size * (1 - overlap_ratio)))     def chunk(self, text):        chunks = []        start = 0        while start < len(text):            chunks.append(text[start:start + self.chunk_size])            start += self.step        return chunks  class SemanticChunker:    """语义分块:句子嵌入相似度低处切分。"""     def __init__(self, threshold=0.25):        self.threshold = threshold     def chunk(self, text):        sents = split_sentences(text)        if len(sents) <= 1:            return [text]        merged = [sents[0]]        for i in range(1, len(sents)):            sim = jaccard_sim(sents[i - 1], sents[i])            if sim < self.threshold:                merged.append('\n--- 语义分块 ---\n')            merged.append(sents[i])        chunks = []        cur_chunk = []        for part in merged:            if part == '\n--- 语义分块 ---\n':                if cur_chunk:                    chunks.append('。'.join(cur_chunk))                    cur_chunk = []            else:                cur_chunk.append(part)        if cur_chunk:            chunks.append('。'.join(cur_chunk))        return chunks  def main():    text = (        '语义分块与滑动窗口是RAG系统的关键策略。'        '它们决定知识库如何被检索。'        '语义分块依赖句子向量之间的相似度。'        '相似度突然下降的地方就是切分点。'        '滑动窗口则关注上下文连续性。'        '每一刀都与上一刀有部分重叠。'        '固定窗口实现最简单。'        '但可能会切断重要的语义信息。'    )    print('原始文档长度:', len(text))    print('\n=== 固定窗口(60字) ===')    for i, c in enumerate(FixedWindowChunker(60).chunk(text)):        print(f'[{i}] {c}')    print('\n=== 滑动窗口(60字, 20%重叠) ===')    for i, c in enumerate(SlidingWindowChunker(60, 0.2).chunk(text)):        print(f'[{i}] {c}')    print('\n=== 语义分块(阈值0.25) ===')    for i, c in enumerate(SemanticChunker(0.25).chunk(text)):        print(f'[{i}] {c}')  if __name__ == '__main__':    main()
目的:用纯标准库实现三种分块策略,直观对比固定窗口、滑动窗口和语义分块的输出差异。
  1. self.step = max(1, int(chunk_size * (1 - overlap_ratio)))用重叠率算步长,重叠越多,步长越小,切出的相邻块共享内容越多。
  2. chunks.append(text[start:start + self.chunk_size])每次都从 start 处切一个固定长度的窗口,模拟“蛋糕刀法”。
  3. sim = jaccard_sim(sents[i - 1], sents[i])用 Jaccard 相似度近似句子语义距离,不需要外部向量模型。
  4. if sim < self.threshold:相似度低于阈值,说明话题断裂,插入分块标记。
  5. for i, c in enumerate(FixedWindowChunker(60).chunk(text)):逐个打印每个块的编号和内容,方便肉眼对比三种策略的差异。

常见误区

误区我一开始把文档都切成 2048 token 的大块,想着上下文越完整答案越准,结果检索老是返回答非所问的段落。

正解块越大,噪声越多,检索相似度被无关信息稀释;而且超出窗口限制还会被截断。理想块应该恰好覆盖“一个完整语义单元”,就像帮厨把整条鱼切段,而不是连着水桶一起下锅。

为何常见:直观上“完整”让人觉得会更准确,忽视了检索相关性是在“片段级”计算的。

误区固定窗口分块快、代码简单,也不用训练模型,大家都这么用,我也一直用。

正解固定窗口无视语义结构,常把句子、公式、条款拦腰切断。对于叙事型和论证型文档,检索质量明显下降。“够用”只在结构化日志类文档上成立。

为何常见:因为实现成本低,容易形成路径依赖;很多教程也以固定窗口为默认示例。

误区语义分块比固定窗口聪明,肯定是所有场景的最佳方案。

正解语义分块需要额外 embedding 计算,对长句子和短文本不稳定,有时会把紧密相关的内容误判为“话题断裂”,而且边界是估计的,并非绝对正确。它更适合语义边界清晰的论述文,不适合代码或表格这类结构化文本。

为何常见:新技术看起来“智能”,容易让人忽略成本与适用条件。

误区为了不丢上下文,我把重叠率设定成 90%,结果知识库膨胀了三倍,检索速度也变慢了。

正解重叠率过高会让同一信息出现在多个块里,不仅浪费存储,还会让检索返回大量内容雷同的块,产生冗余噪声。常见经验是 10%~30%,具体要随文本长度和任务微调。

为何常见:人直觉上认为“多重复=更保险”,没意识到检索去重和存储成本也是关键指标。

误区部署时选好一个分块策略,跑通之后就一直用,从没想过换。

正解分块策略必须跟着下游任务走。任务从“全文摘要”改成“条款检索”,最佳粒度就变了;语料从政策文件换成医学论文,语义边界也变了。定期评估并用评测指标(如 recall@k)回测是必要的。

为何常见:上线后能跑就懒得动,且评估分块对检索质量的影响需要额外工具和指标。

面试题

Q1. 分块的主要目的是什么?

单选题 · easy

  • A.减小文档存储空间
  • B.生成语义连贯检索单元← 正确答案
  • C.加快模型训练速度
  • D.让文档排版更美观

答案:B。分块的核心目的是把长文档切成适合检索和生成的语义单元,就像备菜是为了让每道菜的食材独立完整。减少存储并非主要目的,C、D 与分块无关。

Q2. 哪种分块策略会保留相邻块之间的重叠内容?

单选题 · easy

  • A.固定窗口分块法
  • B.滑动窗口分块法← 正确答案
  • C.句子语义分块法
  • D.章节主题分块法

答案:B。滑动窗口分块让每次滑动的步长小于窗口大小,从而产生重叠区,就像切蛋糕时刀刀带一点上一块的花边。固定窗口、语义分块和主题分块都不会刻意制造重叠。

Q3. 语义分块通常在什么位置切分?

单选题 · easy

  • A.固定字符间隔处
  • B.相似度最高的位置
  • C.相似度突降的位置← 正确答案
  • D.句子数量过半处

答案:C。语义分块先算相邻句子的语义相似度,相似度从高处突然跌到谷底的位置,往往就是话题切换处,所以在这里下刀。固定间隔是固定窗口的做法,与句子数量和相似度峰值无关。

Q4. 滑动窗口分块中,窗口大小 K=200 字符、重叠率 r=50%,步长 S 是多少?

单选题 · mid

  • A.50字符
  • B.100字符← 正确答案
  • C.150字符
  • D.200字符

答案:B。步长 S = K × (1 - r) = 200 × 0.5 = 100 字符。重叠率 50% 意味着每个窗口有一半内容与上一个窗口重复,就像每刀都要带回一半上一块的奶油。

Q5. 递归分块与固定窗口的核心区别是什么?

单选题 · mid

  • A.递归按空格切分
  • B.先粗后细逐层分级← 正确答案
  • C.只用于英文文档
  • D.不考虑文档结构

答案:B。递归分块按“章→节→段落”逐层分级,像冰箱分层收纳;固定窗口是一次性按固定长度切完。递归分块并不限定语言,也恰恰依赖文档结构。

Q6. 给定 6 个相邻句子的余弦相似度序列 [0.82, 0.79, 0.31, 0.77, 0.83],语义分块最可能在哪两个句子之间切分?

单选题 · extreme

  • A.第 3 和第 4 句之间← 正确答案
  • B.第 1 和第 2 句之间
  • C.第 5 和第 6 句之间
  • D.第 2 和第 3 句之间

答案:A。切分点应选在相似度谷底,即 0.31 所在位置(第 3 与第 4 句之间)。其他位置的相似度都在 0.77 以上,说明话题连贯,不适合下刀。

Q7. 以下哪类任务最适合使用细粒度的分块?

单选题 · mid

  • A.全文观点概括
  • B.精确条款检索← 正确答案
  • C.长篇小说梗概
  • D.大型图片识别

答案:B。精确条款检索需要“一找就中”的短块,细粒度能提高召回精度。全文概括和小说梗概需要粗粒度上下文,图片识别与文本分块无关。

Q8. 下列哪些属于常见的分块策略?

多选题 · mid

  • A.固定窗口分块← 正确答案
  • B.滑动重叠分块← 正确答案
  • C.递归分级分块← 正确答案
  • D.随机抽样分块

答案:ABC。固定窗口、滑动重叠、递归分级都是工程中常用的分块策略,各有适用场景。随机抽样会破坏文档结构,不构成有效的分块策略。

Q9. 关于滑动窗口的重叠率,以下说法正确的有?

多选题 · hard

  • A.上下文更连贯← 正确答案
  • B.冗余存储更多← 正确答案
  • C.重叠率越高越好
  • D.检索噪声更大← 正确答案

答案:ABD。重叠率提高会增强上下文连贯性(A),也会让同一内容出现在多个块中,造成存储冗余(B)和检索噪声(D)。但重叠率并非越高越好,“越高越好”(C)是错误的极端化理解。

Q10. 语义分块的实现步骤包含哪些?

多选题 · mid

  • A.句子向量化编码← 正确答案
  • B.计算相邻相似度← 正确答案
  • C.在相似度谷底切分← 正确答案
  • D.按首行缩进切分

答案:ABC。语义分块的三步是:把句子编码成向量、计算相邻句子的相似度、在相似度谷底处切分。按首行缩进切分是排版规则,与语义计算无关。