记录一下那天晚上的排查过程。知识库里有 60 份对账说明,表格用 markdown 写成 12 列,RecursiveCharacterTextSplitter 按 800 字切完,第一块带表头,后面几块只剩数据行,模型回答时把“应缴金额”读成了“已缴金额”。
刚开始盯着「只对文本递归切分,没有识别表格结构」,折腾了半个多小时,排掉了。
真正麻烦的地方在于,几个原因的现象几乎一样。表格整体超过 chunk_size,被按字符硬切成多段。少数情况下是分隔符把 markdown 的竖线行切断,单行数据被拆成两半。
少数情况下是chunk_overlap 只重复尾部文字,不会重复表头。
先看切分后每块是否含表头行
python -c "print(open('chunk_3.txt').read().splitlines()[:3])"
随后改用按标题层级切分的分割器,保留表格区块
python -c "from langchain_text_splitters import MarkdownHeaderTextSplitter;s=MarkdownHeaderTextSplitter([('#','h1'),('##','h2')]);print(len(s.split_text(open('doc.md').read())))"
给每个数据块补齐表头再入向量库
python -c "h='| 科目 | 应缴 | 已缴 |';print(h+'\n'+open('chunk_3.txt').read())"
剩下的就是重建索引并抽查三块的列数是否一致
python -c "print([l.count('|') for l in open('chunk_3.txt').read().splitlines()][:5])"
别只看报错消失,验证要多做一步。每个分块的列数与表头一致,问“应缴金额是多少”时回答引用的是应缴那一列,数值与原文对得上。
容易忽略的是,表格是结构化数据,用纯文本切分器处理必然丢结构,比较稳的做法是整表保留,超长时按行切但每块都复制表头。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。
