逐日AI
第 1 周 · D4约 5 小时

切块策略:固定、递归、按结构、父子与语义五种切法,以及用评估而不是直觉来选

切块是整条链路里最容易凭感觉决定、又最影响结果的一步。这一天把五种主流切法逐个实现并说明各自的适用面,讲清楚重叠区与上下文块头的作用,最后用一组固定问题把五种切法拉到同一把尺子下比较。

今日目标 0/3

登录后可以勾选并保存进度。

今日目标

  1. 能说清固定长度、递归、按文档结构、父子、语义五种切法各自的假设与失效场景
  2. 能解释重叠区和上下文块头分别在补救什么问题,并说明它们各自的代价
  3. 能设计一组问题把不同切法的检索命中率量化对比,用数据而不是直觉做决定

昨天你把 PDF、HTML、Markdown 三类来源统一成了一串带标题路径的节点,解析这一关过了。今天要回答的是紧接着的那个问题:这串东西该按多大的粒度切开、切在哪里,才能被检索到。读完回到页面顶部把三条目标勾掉。

小白版讲解

一、切菜:块太大调料进不去,块太小尝不出是什么菜

我家做红烧肉有一条铁律:肉块要切成两厘米见方。切成五厘米,外面咸了里面还是白的,酱汁根本进不去;切成半厘米,倒是入味了,可炖完之后满锅都是碎渣,你夹起一块来分不清这到底是五花还是里脊。

切块(chunking)面对的是同一个矛盾,只是两头的代价换了名字。

块太大,调料进不去。 检索是拿问题去和块比对。一个两千字的块里可能只有一句话跟问题有关,剩下一千九百多字全是噪声,把这句话的信号稀释掉了。就算它被检索到了,塞进模型上下文的也是这两千字——你为一句话付了一整块的钱,还占掉了别的块本来可以进来的位置。

块太小,尝不出是什么菜。 一个三十字的块写着「保留期是 30 天,到期自动彻底删除」。这句话本身很精确,但它说的是谁的保留期?回收站?日志?备份?块被切下来的那一刻,它就和上下文失去了联系,变成一句谁也认不出的孤立陈述。检索能捞到它,模型却答不出所以然。

所以切块从来不是「选一个数」,而是在信噪比完整度这两个互相拉扯的量之间找一个位置。这也是为什么网上那些「就用 512 token、重叠 50」的建议看起来都对,用起来又都不太对——它们省略了前提:什么样的文档、什么样的问题、给检索留了多少上下文预算。

今天要做的事情很具体:把五种主流切法实现在同一个接口下,用同一份语料各切一遍,再用同一批问题量出它们的命中率。这一天之后,「块该切多大」在你这里就不是一个观点问题,而是一条命令的输出。

二、固定长度与递归:最简单的两种,以及分隔符优先级值多少钱

固定长度是最直白的做法:不看任何结构,数够 400 个字就切一刀。它的假设是「文本各处的重要性均匀分布」,所以在哪切都无所谓。这个假设在小说和聊天记录上大致成立,在技术文档上完全不成立。

它的问题在我们的实验里量得很清楚:30 篇语料切出 60 块,48.3% 的块结尾停在一句话中间。也就是说,将近一半的块是从半句话开始、到半句话结束的。

唯一的补救手段是重叠区(overlap):让相邻两块共享一段尾巴,被切开的那句话至少在其中一块里是完整的。

fixed.js
// 固定长度切块:步长 = 块长 - 重叠,于是相邻两块共享 overlap 个字符
export function chunkFixed(text, size = 400, overlap = 80) {
  const chunks = []
  const step = Math.max(1, size - overlap)
  for (let start = 0; start < text.length; start += step) {
    const piece = text.slice(start, start + size).trim()
    if (piece) chunks.push(piece)
    if (start + size >= text.length) break // 最后一块已经覆盖到结尾,别再多切一个尾巴
  }
  return chunks
}

递归切分(recursive splitting)换了个思路:既然一定要切,那就挑代价最小的地方切。它准备一张按「语义边界从强到弱」排好序的分隔符表——空行、换行、句号、分号、逗号、最后才是硬切——先用最强的切,切完还超长的那一段再用次一级的切,一级级退下去。

这张表的顺序就是它的全部智慧。在同一份语料、同样 400 字上限下,递归切出 61 块,块数跟固定长度几乎一样,切碎率却从 48.3% 掉到 1.6%。同样的块数、同样的成本,只是换了个切法。

三、按文档结构切:标题层级就是作者划好的语义边界

前面两种都在猜边界在哪儿。但对于一份有标题层级的文档,边界根本不用猜——作者写下每一个二级标题的时候,已经替你划好了。

按结构切就是直接拿标题当块边界:一个小节一块,标题路径顺手记进块的元数据里。在我们的语料上,它切出 153 块,平均每块 102 字,切碎率 2.0%。块数比前两种多一倍半,因为小节本来就比 400 字短。

structure.js
// 按标题层级切:维护一个标题栈,遇到 N 级标题就把栈截到 N-1 层再压进去
export function splitSections(markdown) {
  const sections = []
  const stack = []
  let buffer = []
  let path = []
 
  const flush = () => {
    const text = buffer.join('\n').trim()
    if (text) sections.push({ headingPath: [...path], text })
    buffer = []
  }
 
  for (const line of markdown.split('\n')) {
    const heading = /^(#{1,6})\s+(.*)$/.exec(line)
    if (heading) {
      flush() // 上一节到此为止
      stack.length = Math.min(stack.length, heading[1].length - 1)
      stack[heading[1].length - 1] = heading[2].trim()
      path = stack.filter(Boolean)
      continue
    }
    buffer.push(line)
  }
  flush()
  return sections
}

这是五种里最划算的一种:几乎零成本,效果却接近语义切分。但它有一个硬前提——昨天的解析没有把结构丢掉。解析器一旦把标题压成普通段落,这条路当场就断了。这就是第三天为什么要花那么大力气把标题路径保下来:结构是解析阶段唯一一次能免费拿到的东西,丢了就再也补不回来。

另外要防一个退化:结构切法会切出长度极不均匀的块。我们语料里最长的一节 415 字,最短的十几个字。所以实现里要给一个上限,超过就退回递归切分,否则一个超长小节会重新把你带回「块太大」那个坑。

四、父子切块:小块用来检索、大块用来喂给模型

前三种切法都默认了一件事:被检索的那个单位,和被塞进上下文的那个单位,是同一个东西。 父子切块(parent-child chunking)第一次把这两件事拆开。

道理不复杂。检索喜欢小块,因为信噪比高;模型喜欢大块,因为语境完整。那就切两套:小块进索引负责被找到,找到之后不把小块给模型,而是顺着 parentId 把它所在的整个小节回填进去。检索用两百字的精度,生成拿八百字的完整度。

代价也很直接。索引里多了一层映射要维护;文档更新时父子两套都要重算;更要命的是上下文的账——同样 600 token 的预算,父子切法平均装 4.8 块,但每装一个新子块可能就要拖进来一整个父节,预算消耗得比看上去快。它在我们这份语料上和按结构切打平(都是 7/8),因为语料本身的小节就不长,父子的优势还没到发挥的时候。

父子索引怎么建、回填怎么做、成本怎么算,是第十一天的完整内容。 今天你只要记住这一句概念:小块检索、大块回填,检索单位和上下文单位可以不是同一个东西。

五、语义切分与命题切分:贵在哪、值不值

前面四种都是在用规则猜「话题在哪里变了」。语义切分(semantic chunking)不猜——它逐句算 embedding,相邻两句的向量相似度掉下去的地方,就是话题变了的地方。

命题切分(proposition chunking)走得更远:让模型把每段话改写成一条条独立成立的陈述句,每条当一个块。它能把「它的保留期是 30 天」这种带指代的句子还原成「回收站的保留期是 30 天」,检索效果最好,也最贵——每一段正文都要过一次模型,而且改写本身可能引入事实错误。

semantic.js
// 断点阈值取分位数,不要写死一个绝对值
export function findBreakpoints(vectors, percentile = 0.25) {
  const sims = vectors.slice(1).map((v, i) => cosine(vectors[i], v))
  const sorted = [...sims].sort((a, b) => a - b)
  // 只在本篇「最不像」的那 25% 处断开:阈值随文档自适应
  const threshold = sorted[Math.floor(sorted.length * percentile)] ?? -1
  return sims.map((sim, i) => (sim <= threshold ? i + 1 : -1)).filter((i) => i > 0)
}

注意上面这段代码里最重要的一行是 threshold 的算法。不要把相似度阈值写死成一个绝对值。 不同 embedding 模型的相似度分布完全不同,有的模型任意两句中文都在 0.8 以上,有的模型同一段话的相邻句只有 0.4。写死 0.55,换个模型就变成「全断」或者「全不断」。取分位数则是自适应的:不管分布长什么样,我永远只在本篇最不像的那 25% 处断开。

至于值不值,我们的实验给的答案是在这份语料上不值:语义切分切出 90 块,命中率 7/8,和零成本的按结构切完全一样,却多花了一次全量 embedding 的钱。这不是说语义切分没用,而是说——当你的文档本来就有清晰的标题层级时,作者已经免费替你做完了语义切分。 它真正的用武之地是没有结构的长文本:会议逐字稿、客服通话记录、扫描出来的连续段落。

六、上下文块头:给孤立的块补一句它是谁

回到第一节那个例子:「保留期是 30 天」这个块,谁也不知道说的是什么的保留期。

上下文块头(contextual chunk header)的做法是给每一块前面拼一句定位说明,再拿拼完的文本去建索引。便宜的做法是用第三天保下来的标题路径直接拼:「《网盘与文件管理》回收站:保留期是 30 天……」。贵的做法是让模型读完全文再为每一块写一句话——这就是 Anthropic 那篇上下文检索博文的思路,具体实现和它的完整评估在第十一天,今天只需要知道有这么个手法。

但今天必须先说清楚它的代价,而且这个代价是我们真跑出来的:给固定长度那一档加上标题路径块头之后,命中率一点没变,索引 token 涨了 10.4%,答案文档的平均名次反而从 2.88 退到了 3.25。

先把前提说清楚:这是纯关键词检索(BM25)下的结果,向量侧的结论很可能相反。 为什么在这一侧会退步?因为块头对关键词检索是有稀释作用的。同一篇文档的每一块都被拼上了同样的标题,这个标题里的词就从「只出现在少数几块里的强信号」变成了「到处都是的弱信号」,逆文档频率被自己拉低了。块头真正的收益在向量检索那一侧——它让孤立的块在语义空间里有了定位。所以这个手法的正确用法是配着混合检索一起上,单独加在纯关键词检索上是负收益。

这件事本身就是今天最值得记住的一课:一个在别人博客里效果显著的手法,放进你的链路里可能是负的。 唯一能分辨的办法是跑数字。

七、重叠区不是越大越好

最后收一个最容易被无脑放大的参数。

重叠区确实在补救问题——它让被切开的句子至少在一处是完整的。但它的三笔账都是实打实的:

第一笔是存储与 token。 我们把重叠从 0 调到 80(块长 400 的两成),索引总 token 从 15641 涨到 18002,涨了 15%。这笔钱在向量库里是存储费,在每次检索时是比对量,在生成时还可能变成上下文费。

第二笔是检索结果的冗余。 重叠越大,相邻块的内容越像,检索前几名越有可能是同一段话的三个版本。你以为自己给了模型三条证据,其实只有一条,说了三遍。这个问题在重排(rerank)之前基本无解。

第三笔是引用定位变糊。 同一句话出现在两个块里,模型标出处时标哪一个?第六天做引用校验的时候,这会直接变成一个要处理的边界情况。

经验区间是块长的 10% 到 20%,但这个区间的意义是「先从这儿起步」,不是「就用这个」。 真正的做法永远是:调一档、跑一遍评估、看三笔账,然后决定留不留。

源码导读

动手实验

🧪 D4 实验:五种切块策略的并排实现与同一批问题下的命中率对照表

代码位置:labs/rag-14days/day-04-chunking-strategies

验收标准:

  1. MOCK=1 pnpm start 打印出三张表:块级统计、命中率对照、加块头前后对比,并写出 chunking-report.json
  2. 第一张表里,固定长度的切碎率接近一半(48.3%),递归只有 1.6%——两者块数几乎一样,差别全在切在哪。
  3. 第二张表里,固定长度与递归是 6/8,按结构、父子、语义是 7/8;同样 600 token 的预算,前两者平均只装得下 1.2 块,后三者能装 2.5 到 4.8 块。
  4. q06(主备切换谁审批、叫什么名字)五种切法全部未中——切块解决不了多跳问题。
  5. 第三张表里,加块头之后命中率没变,索引 token 涨 10.4%,答案文档平均名次从 2.88 退到 3.25。

动手之前先确认一件事:eval/questions-10.json 里那十个问题是全课的标准答案集,第八天会把它扩到 20 题并原样复用这十题。所以现在别改它们,先照着跑,把「同一批问题」这把尺子握稳。卡住了先看 README 里的「评估口径」三条,八成的疑问在那儿。

  1. 把五个切块器的空缺补完(练习 1 到 4),跑一遍看第一张表:递归的切碎率应该从 48.3% 掉到 1.6%,按结构的块数应该从 30 变成 153。
  2. 看第二张表的「平均装入块数」这一列,理解为什么对照的尺子必须是 token 预算而不是「取前几块」。
  3. 补完练习 5 的上下文块头,对比第三张表的两行:命中率、名次、token 三个数字各变了多少。
  4. FIXED_OVERLAP 从 80 改成 0 和 160 各跑一遍,记录索引 token 与命中率的变化,验证「重叠不是越大越好」。
  5. 写下你的选型结论,并在结论后面补一句它成立的前提:什么样的文档、什么样的问题、多大的上下文预算。

面试题

今天 4 道题在下方题库区,侧重切块粒度与召回精度的权衡、父子结构的收益、评估驱动的参数选择。展开后先看分析过程再看要点——照着推导练,比背要点管用。标注国内高频与海外高频方便按目标市场取舍。

检查清单与明日预告

  • 能说清固定长度、递归、按文档结构、父子、语义五种切法各自的假设与失效场景
  • 能解释重叠区和上下文块头分别在补救什么问题,并说明它们各自的代价
  • 能设计一组问题把不同切法的检索命中率量化对比,用数据而不是直觉做决定
  • 能说出为什么切法对照必须在同一个 token 预算下做,而不是「同样取前五块」
  • 实验的 5 条验收标准全部通过,chunking-report.json 里的数字和正文对得上
  • 4 道面试题不看要点也能答出至少 3 道

明天(D5)我们把注意力从「切成什么样」转到「切完了存哪儿、怎么查得快」:分层可导航小世界图和倒排文件两种索引的结构与调参、用量化把内存砍下来、以及最容易踩坑的带过滤查询。顺序是有意的——今天你把块的数量从 30 篇变成了上百上千条,索引的规模问题才真正开始,这时候再谈索引选型才有具体的数字可以谈。

面试题库

  • 你怎么决定切块大小?说出你会看的两个指标和一个反例。How do you decide on chunk size? Name two metrics you would look at, and one counterexample.
    国内高频海外高频进阶#chunking#evaluation

    分析过程 · 先想清楚再作答

    1. 这题的题眼是「怎么决定」,不是「多大合适」。答一个具体数字(512 token、1000 字符)就已经输了——面试官想看的是你有没有一套定法,而不是你记得住哪个默认值。
    2. 先把矛盾摆出来:块大则信噪比低、上下文贵,块小则单块缺语境、模型答不出所以然。切块大小就是在这两头之间找位置,所以两个指标必须分别对应这两头。
    3. 第一个指标是检索侧的命中率——答案文档有没有进上下文。第二个是生成侧的可用性,最省事的代理指标是切碎率,也就是有多少块结尾停在半句话上;再往前一步就是忠实度和引用是否可定位。
    4. 关键补一句:两个指标必须在**同一个 token 预算**下比,不能按「取前 k 块」比。k 固定时块越大塞进去的字越多,大块切法会赢在买得多而不是切得准上。这一句往往是这道题的区分点。
    5. 反例要具体。最好用的一个是:把块从 400 字调到 1200 字,命中率不降反升——但那是因为一整篇短文档被当成一块塞了进去,检索其实什么都没做,等于退化成了全文投喂。指标涨了,系统更差了。
    6. 可预期的追问是「那你第一次上手时从哪个数字起步」。答:先按文档类型选切法(有标题层级就按结构切),块长从 300 到 500 字起步、重叠取一到两成,然后立刻建一组标准问题跑评估,用两三轮迭代把它调到位。起步值是起步值,不是结论。

    How to reason about it · think before answering

    1. The question is about method, not about a number. Answering with a specific default (512 tokens, 1000 characters) already loses it — the interviewer wants to hear that you have a procedure.
    2. State the tension first: large chunks dilute the signal and cost context; small chunks lose the surrounding meaning so the model cannot use them. The two metrics you name should map onto those two failure modes.
    3. Metric one is retrieval-side hit rate: did a document that actually answers the question make it into the context. Metric two is generation-side usability, cheaply proxied by the fraction of chunks that end mid-sentence, and more seriously by faithfulness and whether citations resolve.
    4. Add the point that separates candidates: both metrics must be compared under the same token budget, never under a fixed top-k. With fixed k, bigger chunks simply buy more text and win for the wrong reason.
    5. Make the counterexample concrete: raising chunk size from 400 to 1200 characters can lift hit rate purely because whole short documents now fit in one chunk, which means retrieval stopped doing anything and you are back to stuffing full documents. The metric improved while the system got worse.
    6. Expect the follow-up: where do you start on day one. Pick the strategy from the document type first (structural splitting whenever headings exist), start around 300 to 500 characters with 10 to 20 percent overlap, then build a golden set immediately and iterate. A starting point is not a conclusion.

    答题要点

    • 先按文档类型选切法,再调长度:有标题层级就按结构切,没有结构才谈固定长度或语义。
    • 看两个指标:检索侧的命中率,生成侧的切碎率(进一步是忠实度与引用可定位性)。
    • 两个指标必须在同一个 token 预算下比,不能按「取前 k 块」比,否则大块只是买得更多。
    • 反例:块调大后命中率上升,但那是因为整篇被当成一块,检索退化成全文投喂。
    • 起步值 300 到 500 字、重叠一到两成,然后靠一组固定问题迭代,不靠直觉定稿。

    Key points

    • Choose the strategy from the document type first, then tune length: split on headings whenever the structure survives parsing.
    • Watch two metrics: retrieval hit rate on one side, mid-sentence break rate (then faithfulness and citation resolvability) on the other.
    • Compare under an equal token budget, never a fixed top-k, or larger chunks win by buying more text.
    • Counterexample: hit rate rises after enlarging chunks because whole documents now fit in one chunk and retrieval has effectively stopped working.
    • Start near 300 to 500 characters with 10 to 20 percent overlap, then iterate against a fixed question set instead of guessing.
  • 父子切块的收益是什么?它在什么情况下反而会拖慢系统?What does parent-child chunking buy you, and when does it slow the system down instead?
    国内高频海外高频进阶#chunking#parent-child

    分析过程 · 先想清楚再作答

    1. 这题考的是你有没有意识到「检索单位」和「上下文单位」可以是两个东西。答不出这句话,后面说什么都是复述。
    2. 收益一句话说清:小块进索引,信噪比高、容易被找到;命中之后顺着父指针把整节回填给模型,语境完整。精度和完整度这次不用二选一。
    3. 拖慢的场景要从代价一条条推。第一条是上下文预算:每命中一个新子块可能拖进来一整个父节,同样的 token 预算装不下几条,检索结果的多样性反而变差。
    4. 第二条是写入侧:父子两套都要维护,文档更新时两边都要重算,块 id 的稳定性也更难保证,增量同步的复杂度明显上升。
    5. 第三条是收益消失的条件:当文档本身的小节就不长时,父块和子块差不多大,你付了两套索引的钱,什么也没多买到。所以父子切块适合长节、深层级的文档,不适合结构本来就细碎的知识库。
    6. 可预期的追问是「那和直接把块切大有什么区别」。答:切大是把噪声一起放进索引,父子是只把噪声放进上下文、不放进索引——被检索的那一段始终是干净的短文本,这是本质区别。

    How to reason about it · think before answering

    1. This question checks whether you know that the retrieval unit and the context unit can be two different things. Without that sentence, everything else is recitation.
    2. State the benefit compactly: small chunks go into the index so they are easy to match, and once a child is hit you follow the parent pointer and hand the model the whole section. You stop trading precision against completeness.
    3. Derive the slowdown from the costs. First, the context budget: every new child may drag in an entire parent, so an equal budget holds fewer distinct pieces and result diversity drops.
    4. Second, the write path: two levels to maintain, both recomputed on every document update, and chunk ids become harder to keep stable, which makes incremental sync noticeably more complex.
    5. Third, the condition under which the benefit disappears: when sections are already short, the parent and the child are nearly the same text, so you paid for two indexes and bought nothing. Parent-child suits long sections and deep hierarchies, not already fine-grained knowledge bases.
    6. Expect the follow-up: how is this different from simply using bigger chunks. Bigger chunks put the noise into the index; parent-child puts the noise only into the context. What gets matched stays short and clean.

    答题要点

    • 核心是把检索单位和上下文单位拆开:小块负责被找到,大块负责被读懂。
    • 收益是精度与完整度同时拿到,不用在信噪比和语境之间二选一。
    • 代价一:一次命中可能拖进整个父节,同样的上下文预算装得下的条数变少,结果多样性下降。
    • 代价二:父子两套索引都要维护与重算,文档更新时增量同步的复杂度明显上升。
    • 失效场景:文档小节本来就短时父子块差不多大,多付一套成本却没多买到东西。

    Key points

    • The core idea is decoupling the retrieval unit from the context unit: small chunks get found, large chunks get understood.
    • The payoff is precision and completeness at the same time instead of trading one for the other.
    • Cost one: a single hit can drag in a whole parent, so an equal context budget holds fewer distinct results and diversity suffers.
    • Cost two: two index levels to maintain and recompute, which makes incremental sync on document updates considerably harder.
    • It stops paying off when sections are already short, because parent and child are nearly identical and you bought nothing for the extra cost.
  • 重叠区设成块长的百分之多少合适?重叠过大会带来什么具体问题?What overlap ratio would you use, and what concretely goes wrong when the overlap is too large?
    国内高频海外高频基础#chunking#overlap

    分析过程 · 先想清楚再作答

    1. 这是一道送分题,但送分点不在那个百分比上,而在后半句。只答「一般一到两成」就停住的人,面试官会认为他没跑过。
    2. 先说清重叠在补救什么:固定长度切法会把句子从中间切开,重叠让被切开的那句话至少在相邻两块之一里是完整的。它是给「乱切」打的补丁,不是一个独立的优化。
    3. 由此推出第一个结论:如果你用的是按结构切或递归切,边界本来就落在语义位置上,重叠的必要性会大幅下降,甚至可以是零。**重叠比例这个问题的前提是切法**,脱开切法谈比例就是背数字。
    4. 过大的代价要说三笔,越具体越好。存储与 token:块长 400、重叠从 0 加到 80,索引 token 会涨一成半左右,这笔钱在向量库是存储费、在检索时是比对量。
    5. 检索冗余:相邻块越像,前几名越可能是同一段话的三个版本,你以为给了模型三条证据,其实是一条说了三遍。这一条在重排之前基本无解。
    6. 引用定位:同一句话出现在两个块里,模型标出处该标哪一个,这会直接变成引用校验环节要处理的边界情况。可预期的追问就是「那你怎么去重」,答按内容指纹或最长公共子串在结果层合并,而不是在切块层想办法。

    How to reason about it · think before answering

    1. This is a giveaway question, but the marks are in the second half, not the percentage. Stopping at 'usually ten to twenty percent' reads like someone who has never run it.
    2. Say what overlap is patching: fixed-length splitting cuts sentences in half, and overlap guarantees the broken sentence survives intact in at least one of the two neighbours. It is a patch for careless splitting, not an optimisation of its own.
    3. That yields the first conclusion: with structural or recursive splitting the boundaries already land on semantic positions, so the need for overlap drops sharply and can legitimately be zero. The ratio question is meaningless without naming the strategy.
    4. Give three concrete costs. Storage and tokens: at 400-character chunks, moving overlap from 0 to 80 grows total index tokens by roughly fifteen percent, which is storage cost in the vector store and comparison work at query time.
    5. Retrieval redundancy: the more neighbours overlap, the more likely the top results are three versions of the same passage. You think you handed the model three pieces of evidence; you handed it one, three times. Nothing fixes this before reranking.
    6. Citation resolution: when a sentence lives in two chunks, which one does the model cite. Expect the follow-up on deduplication: merge at the result layer using a content fingerprint or longest common substring, not by tweaking the chunker.

    答题要点

    • 经验区间是块长的一到两成,但这个数字的前提是你用的是固定长度切法。
    • 按结构或递归切时边界本来就在语义位置上,重叠可以很小甚至为零。
    • 过大代价一:索引 token 与存储明显上涨,块长 400 时重叠加到 80 大约涨一成半。
    • 过大代价二:相邻块高度相似,检索前几名变成同一段话的多个版本,证据多样性是假的。
    • 过大代价三:同一句话跨块出现,引用标注和去重都要额外处理。

    Key points

    • Ten to twenty percent of chunk length is the working range, but that number assumes fixed-length splitting.
    • With structural or recursive splitting the boundaries are already semantic, so overlap can be small or zero.
    • Cost one: index tokens and storage grow noticeably; at 400-character chunks, an 80-character overlap adds roughly fifteen percent.
    • Cost two: neighbouring chunks become near-duplicates, so the top results are several versions of one passage and the evidence diversity is illusory.
    • Cost three: a sentence spanning two chunks complicates citation attribution and forces result-level deduplication.
  • 语义切分比递归切分贵不少,你怎么向团队证明这笔钱值得花?Semantic chunking costs considerably more than recursive splitting. How would you prove to your team that the money is well spent?
    国内高频海外高频深入#chunking#evaluation#cost

    分析过程 · 先想清楚再作答

    1. 这题表面问技术,实际考的是你会不会做一次带对照组的技术论证。上来就讲语义切分原理的人,答的是另一道题。
    2. 第一步是先承认它可能不值。语义切分的收益来自「文档没有可用的结构」;如果知识库是结构良好的文档,作者的标题层级已经免费替你做完了语义切分,这时候花的钱大概率打水漂。**先说清适用前提,再谈证明,这一步就把大多数候选人区分开了。**
    3. 第二步是把「值不值」翻译成可测的三笔账:指标涨了多少(同一批标准问题、同一个 token 预算下的命中率)、延迟涨了多少(切块是离线的,但更新链路的端到端时间会变)、钱涨了多少(首次全量 embedding 的费用,加上按更新频率折算的重算费用)。只报第一笔的论证不成立。
    4. 第三步是设计对照。递归切分是基线,语义切分是实验组,两组必须用同一份语料、同一批问题、同一个上下文预算、同一个检索器,只改切法这一个变量。改两个变量的实验,结论一文不值。
    5. 第四步是给决策一个门槛,而不是给一个感想。比如:命中率相对基线提升低于三个百分点就不上;提升超过五个百分点且重算成本在月度预算内就上;中间地带先在一类文档上灰度。**门槛要在跑数字之前定好**,否则你会不自觉地去迁就已经跑出来的结果。
    6. 可预期的追问是「有没有更便宜的办法拿到同样的收益」。答有:先试按结构切,它零成本且效果常常接近;结构确实不可用时,再考虑只对高价值的那一部分文档做语义切分,而不是全量上。

    How to reason about it · think before answering

    1. This looks like a technical question but it tests whether you can run a controlled technical argument. Launching into how semantic chunking works answers a different question.
    2. Step one is to concede that it may well not be worth it. The gain comes from documents that have no usable structure; if your knowledge base is well-formed documents, the authors' heading hierarchy already did the semantic split for free and the money is likely wasted.
    3. Step two is translating 'worth it' into three measurable numbers: how much the metric moved (hit rate on the same golden set under the same token budget), how much latency moved (chunking is offline, but the end-to-end update path changes), and how much it costs (the initial full embedding pass plus recomputation amortised over update frequency).
    4. Step three is the control. Recursive splitting is the baseline, semantic chunking the treatment, and they must share the corpus, the questions, the context budget and the retriever. Change one variable only; a two-variable experiment proves nothing.
    5. Step four is a decision threshold rather than an impression. For example: below three points of hit-rate gain, no; above five points with recomputation inside the monthly budget, yes; in between, roll it out on one document class first. Fix the threshold before you run the numbers, or you will quietly bend it to fit them.
    6. Expect the follow-up: is there a cheaper way to the same gain. Yes — try structural splitting first, since it is free and often nearly as good, and if the structure really is unusable, apply semantic chunking only to the high-value subset rather than the whole corpus.

    答题要点

    • 先讲适用前提:语义切分的收益来自文档没有可用结构,结构良好的文档上它大概率不值。
    • 把「值不值」翻译成三笔账:命中率涨多少、延迟涨多少、钱涨多少,只报第一笔不算论证。
    • 做对照实验:同语料、同问题集、同上下文预算、同检索器,只改切法一个变量。
    • 决策门槛必须在跑数字之前定好,避免事后迁就结果。
    • 先试零成本的按结构切;确需语义切分时也优先只覆盖高价值文档,而不是全量上。

    Key points

    • Start with the precondition: the gain comes from documents without usable structure, so on well-formed documents it usually is not worth it.
    • Translate 'worth it' into three numbers — hit rate, latency, and cost. Reporting only the first is not an argument.
    • Run a controlled comparison: same corpus, same golden set, same context budget, same retriever, with the splitting strategy as the only variable.
    • Fix the decision threshold before running the numbers so you cannot bend it to fit the result afterwards.
    • Try free structural splitting first, and if semantic chunking is genuinely needed, apply it to the high-value subset rather than the entire corpus.

评论

登录后即可参与讨论

还没有评论,来说第一句。