学习笔记 · Obsidian

文本切分策略与多语言边界

LangChainTypeScript

结论

  • 通用文本优先 RecursiveCharacterTextSplitter;字符切分适合结构简单的文本,token 切分用于严格控制模型上下文,代码切分应使用语言感知 separators。
  • chunkSize、chunkOverlap、分隔符、tokenizer 和预处理规则共同构成索引契约。任一项改变都可能需要重建索引和重新评估召回。
  • /splitters 与 /splitters/index 是同正文别名;本组保留两条 source,共覆盖 6 条路由。

四类策略

策略衡量单位优势风险
Recursive character字符,按分隔符层级递归尽量保留段落、句子、词字符数不等于 token 数
Character指定字符序列,默认双换行简单、可预测结构弱时容易产生语义断裂
Token目标 tokenizer更贴近模型 context limittokenizer 不匹配会估算错误;切片可能破坏自然边界
Language-aware code语言预置 separators尽量保留类、函数与语法结构不是 AST parser,超长函数仍会被切开

RecursiveCharacterTextSplitter

默认分隔符顺序为 ['\n\n', '\n', ' ', ''],从段落逐步退化到句/词/字符,直到满足 chunk size。chunkOverlap 用重复上下文缓冲边界信息,但过大会增加索引量、embedding 成本和重复召回。

  • .splitText() 返回字符串。
  • .createDocuments() 生成 Document 并保留传入 metadata。
  • chunkSize 的实际含义由 lengthFunction 决定,不要在字符配置和 token 配置之间直接复用数值。

中文、日文、泰文

默认空格分隔会切断没有显式词边界的语言。官方建议把这些符号加入 separators:

  • ASCII/全角/表意句号:.、.、。;
  • ASCII/全角/表意逗号:,、,、、;
  • 泰语、缅甸语、高棉语和部分日文内容中的 zero-width space。

中文生产语料应额外验证标题、列表、表格、代码块和中英混排;只加入标点仍不等于真正的语义分句。

TokenTextSplitter

Token 分割必须选择与目标模型一致的 tokenizer。文档以 js-tiktoken 与 cl100k_base 为例,并提醒最终 split 仍可能大于期望 token chunk size。实际系统需留出 prompt、引用、工具 schema 和回答的预算,而不是把模型最大上下文全部给检索片段。

推荐预算:

可用于检索的 token = context limit - system/history - tool schema - output reserve - safety margin

代码切分

RecursiveCharacterTextSplitter.fromLanguage() 内置 Python、JS、TS、Markdown、LaTeX、HTML、Solidity、C#、Haskell、PHP、PowerShell、VB6 等 separators。它基于文本规则,不理解符号引用和 AST:

  • 对代码检索同时保存 repo、path、language、symbol、line range、commit;
  • 对生成代码、minified bundle、notebook 和超长函数建立单独策略;
  • 若需要准确类/函数边界,先用 parser/AST 提取,再用 splitter 处理超长节点。

评估与版本化

  1. 建立真实查询集,比较 recall@k、MRR/nDCG、重复率、无答案率和最终回答正确率。
  2. 观察 chunk 长度分布与极端值,而不只看平均值。
  3. metadata 中保存 parent document id 与 chunk ordinal,支持邻接扩展和引用回原文。
  4. splitter 配置生成版本哈希;改变配置时写入新索引,验证后切流量。
  5. embedding batch 失败可从 chunk checkpoint 恢复,避免重新加载源文档。