记录一下那天晚上的排查过程。用小块检索命中很准,但送给模型的小块缺少前后文,回答经常断章取义,改成大块又检索不准。

刚开始盯着「父块过大,超出上下文预算」,折腾了半个多小时,排掉了。

真正麻烦的地方在于,几个原因的现象几乎一样。只用小块做检索,送进模型的也是小块。还有一种是父子关系没有写进元数据,无法回溯。

少数情况下是多个子块命中同一父块,重复送给模型。

第一件事是检索用小片段,返回时换成父块

docs = [parent_map[d.metadata['parent_id']] for d in hits]

随后写入时为每个子块记录父块 id

meta = {'parent_id': pid, 'source': path}

再往下对同一父块的多次命中去重

docs = list({d['id']: d for d in docs}.values())

控制父块长度不超过预算

python -c "print(max(len(d['text']) for d in docs))")

怎么算真的好了,看的是同一批现象。回答能引用完整的上下文段落,重复引用消失,输入 token 控制在预算内。

父块过大时截断等于白做,父块大小要按模型上下文和问题类型调,通常控制在子块的四到六倍比较合适。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189