现场是这样的。用 llama-index-core 0.10 建索引,chunk_size 设 512,中文合同被切在句子中间,检索回来的片段常常只有半句,回答因此断章取义。

中间走过弯路,把「没给 secondary_chunking_regex,回退成按字符硬切」当成主因,改完现象没变。

把日志和配置对完,能解释这个现象的基本就这几处。0.10 的默认分隔符集来自英文标点,中文句号不在里面;chunk_size 按 token 计,中文一个字约一个 token,512 太短;文档解析后没分段,整篇被当成一个节点再切,段落边界丢失。

第一件事是打印当前切分器的分隔符与块长

python -c "from llama_index.core.node_parser import SentenceSplitter;s=SentenceSplitter();print(s.paragraph_separator,s.chunk_size)"

显式指定中文标点并加大块长

python -c "from llama_index.core.node_parser import SentenceSplitter;s=SentenceSplitter(chunk_size=900,secondary_chunking_regex='[^。!?]+[。!?]');print(s.chunk_size)"

接着用真实文档跑一遍看块首尾

python -c "from llama_index.core import SimpleDirectoryReader;d=SimpleDirectoryReader('docs').load_data();print(d[0].text[:120])"

等前面都确认过,再把切好的节点落盘抽查前两块

python -c "from llama_index.core import SimpleDirectoryReader;from llama_index.core.node_parser import SentenceSplitter;print([n.text[-20:] for n in SentenceSplitter(chunk_size=900).get_nodes_from_documents(SimpleDirectoryReader('docs').load_data())[:2]])"

别只看报错消失,验证要多做一步。抽查的节点全部以句号或问号结尾,长度落在 600 到 900 字之间,同一问题的召回片段能读成完整句子。

块长不是越大越好,900 字已接近多数 embedding 模型的有效区间,再长首尾信息会被稀释。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189