StoryWeaver Benchmark

六套中文文本切分算法
在叙事语料上的对比评测

同一篇原文,两套切法并排交给裁判,只问一句——哪一套下刀的位置更好。 逐维度二选一,每对位置互换各问一遍,汇总为胜率与 Bradley-Terry 实力分。

结论

第一名
LumberChunker
胜率 87%
线上现役
ClusterSemanticChunker
第 2 名 · 胜率 74%
「语义切分不比固定切分好」——这个流行结论在本场景不成立。 四套语义方法占据第 1–4 名,两套非语义基线落在第 5–6 名。 公开研究里语义切分吃亏的结论多出自 in-corpus 检索(跨文档找答案); 而小说创作是 in-document 检索(在同一部书的正文里召回场景),两者结论相反。

总榜

胜率是所有维度、所有对手、所有语料上的总票数占比。BT 实力分由 Bradley-Terry 迭代求解、归一到均值 1.0, 衡量「两两对战中赢的倾向」——它是比值尺度,两方实力分之比即预测胜率 (第一名 3.31 对末名 0.11,预测胜率 97%)。 接近全胜时 BT 会发散,所以主榜按胜率排布,实力分作辅助列。

方法胜率BT 实力分块数中位块长块长范围额外成本
1LumberChunker 第一
lumber
87%3.313257481–798每 700 字一次 LLM 调用
2ClusterSemanticChunker 线上现役
cluster
74%1.4852319204–597零额外调用
3Semantic Double-Pass Merging
sdpm
56%0.6463252202–481零额外调用
4Max-Min 自适应
maxmin
44%0.3670214200–1500零额外调用
5固定字符滑窗
fixed_800
19%0.1128800132–800零额外调用
6递归字符切分
recursive_350
19%0.117229870–391零额外调用
块数与块长一并列出,是因为块大小会系统性影响裁判判断: 块越大越不容易切断场景,也越容易混进无关内容。 若某方法块长与其余差一个量级,它的名次就该被怀疑成块大小的假象而非切分质量。

两两胜率

行对列的胜率。每对在 12 篇语料上各比多遍,正反序各投一票。

lumberclustersdpmmaxminfixedrecursive
lumber72%85%88%95%97%
cluster28%74%82%95%90%
sdpm15%26%64%89%87%
maxmin12%18%36%78%76%
fixed5%5%11%22%54%
recursive3%10%13%24%46%

分维度

各方法在单个维度上的胜率,口径与总榜一致。

lumberclustersdpmmaxminfixedrecursive
场景完整95%74%52%39%21%18%
片段自足95%73%54%41%19%18%
块内混杂73%73%62%52%18%22%

维度含义

六套方案:机制与失效场景

LumberChunker

lumber · 第 1 名 · 胜率 87% · 每 700 字一次 LLM 调用 最弱语料 对时 72%

LLM 逐组读段落,回答「内容从哪一段开始明显转向」,以该段为界滚动推进。唯一只在段落边界下刀的方法,因此从不破句。原论文面向叙事文本,配套数据集取自古腾堡小说。

失效场景切分粒度受段落长度支配。当一个段落内部本身横跨语义边界时无法在段中下刀——闪回嵌套结构中,回忆与当下同处一段则必然并入同一块。此外每 700 字一次 LLM 调用,写入延迟与费用随语料量线性增长,与其余五套不在同一成本量级。

ClusterSemanticChunker 线上现役

cluster · 第 2 名 · 胜率 74% · 零额外调用 最弱语料 夜班 38%

动态规划求全局最优连续分组,目标函数是「块内所有句对相似度之和」最大,受块长上限约束。与断点法的根本差别:断点法只看相邻句距离(局部贪心),它评估块内全部句对(全局最优)。

失效场景受块长上限约束,无法输出「整篇即一块」;该上限与 min_chars 冲突时优先保下限,故遇到超长单句会略微越界。同一场景内话题自然漂移时,目标函数会顺着相似度下降切开,把本应完整的场景拆散。它只能做连续分组,双线交替结构中同一条线的内容被另一条线隔开,无法聚合。DP 是 O(n²),长文档按 1000 句分窗口以免内存与数值精度失控。

Semantic Double-Pass Merging

sdpm · 第 3 名 · 胜率 56% · 零额外调用 最弱语料 对时 33%

第一遍按相邻句相似度分组;第二遍跳窗比较,若第 k 组与第 k+2 组相似,则把夹在中间的那组一并缝合。针对「场景 A → 插叙 → 回到 A」这类被打断的结构。

失效场景阈值取本篇相似度分布的分位数,这意味着必然产生切点——无论文本多连贯,总有固定比例的相邻位置落在阈值之下。因此在单一连续场景与对话密集文本上会切出无意义的边界。跳窗距离固定为 2,被更长插叙打断的场景缝不回来。

Max-Min 自适应

maxmin · 第 4 名 · 胜率 44% · 零额外调用 最弱语料 借条 23%

以块内句对的最低相似度作为该块的「内聚下限」,新句对块内任一句的最高相似度不低于该下限即并入,否则另起一块。设计意图是块越紧凑要求越严,无需全局分位数或绝对阈值。

失效场景块内只有一句时算不出内聚下限,只能退回配置的绝对阈值 initial_threshold = 0.6。而实测中文相邻句余弦相似度中位为 0.466(12 篇全部落在 0.44–0.53 区间),阈值高于分布,导致每句都触发「另起一块」、块始终凑不满句对、自适应机制从未启动:全语料 709 句被切成 553 块,平均每块 1.28 句。这些碎块最终由 min_chars 兜底粘合,边界实际由长度而非语义决定。长描写文本上损伤最大——长段落被等距截断,与内容结构无关。

固定字符滑窗

fixed_800 · 第 5 名 · 胜率 19% · 零额外调用 最弱语料 量体 8%

每 800 字一刀,相邻块重叠 120 字,完全不读取语义。多份公开评测中它被视为难以打败的朴素基线,本榜用它检验语义切分是否值得。

失效场景按字符位置下刀,切点落在句中乃至词中;块间 120 字 overlap 造成内容重复。裁判判词中可直接看到断裂痕迹(块尾停在「顺手把玻璃上的雾」、块首以「,说咸」起始)。语义连续推进、缺乏显式结构信号的文本上损伤最重。

递归字符切分

recursive_350 · 第 6 名 · 胜率 19% · 零额外调用 最弱语料 缝纫机 2%

LangChain RecursiveCharacterTextSplitter 的等价实现:按 段落→换行→句号→逗号 的分隔符优先级递归切碎,再贪心填回目标长度。RAG 中最常见的默认选择。

失效场景按分隔符优先级找边界的努力,被「填满目标长度」这一步抵消:先按段落切好,再为凑满 350 字把不相干的段落粘合、或把长段落拆开。闪回结构与对话密集文本上跌至全场最低,正是粘合把语义无关的内容并进了同一块。

评测方法

相对判断,不打绝对分

给裁判的上下文是:原文全篇 + 甲的切法 + 乙的切法,块与块之间用横线隔开。 逐维度二选一,不允许打平——绝对分在跨篇比较时没有可比性,相对胜负才有。

位置互换以消除位置偏见

同一对方法正反各问一遍(甲乙对调)。只认位置不认内容的裁判,两序各得一票自相抵消; 真有偏好的才能拉开差距。这是判分可信的前提,不是可选项。

难判率用于语料体检,不参与排名

若某篇语料上各方法两两都判不出高下,说明这篇没有区分度。它是语料的体检指标

语料字数难判率
修船141427%
打烊131727%
面馆152724%
对时131118%
铜哨132416%
旁听125813%
借条18789%
夜班16649%
白事14717%
缝纫机13337%
量体14924%
雨脚12632%

结论的适用边界