把 chunk_overlap 从 100 改成 0 想省存储,问电池保修和整机保修分别多久时只答出整机,另一半在被切断的下一块里,检索根本没召回。
一开始怀疑是「切分器按长度上限断开,不看语义边界」,查了一圈,方向不对。
原因不止一个,得分开看。重叠为 0 时跨块信息没有交集,切断处语义断裂。还有一种是两个答案分属不同块,top_k 只取回其中一块。
还有一种情况,问题本身跨两个主题,单块无法覆盖。
恢复适度重叠并看块数变化
python -c "from langchain_text_splitters import RecursiveCharacterTextSplitter;print(len(RecursiveCharacterTextSplitter(chunk_size=500,chunk_overlap=80).split_text('a。'*400)))"
随后对比重叠 0 与 80 的块数
python -c "print(400//500,400//420)"
然后把跨主题问题拆成两个查询
python -c "print(['电池保修多久','整机保修多久'])"
等前面都确认过,再用评测集看两类问题的命中率
python -c "import pandas as pd;print(pd.read_csv('eval.csv').groupby('overlap').hit.mean())"
别只看报错消失,验证要多做一步。跨主题问题的答案能同时覆盖电池与整机,多块召回后合并去重,评测集 hit@5 回到 0.85 以上。
提醒一点。重叠是拿存储换召回,80 到 120 字通常够用,再大只会让同义块互相挤占 top_k 名额。这类问题最好一次改到位,反复小改反而容易把原因搅混。
