首页 > 教程攻略 > ai资讯 >通过句子切分实现高精度的检索问答

通过句子切分实现高精度的检索问答

来源:互联网 时间:2026-08-03 14:28:28

《Lost in the Middle: How Language Models Use Long Contexts》这篇论文,几乎是所有搞长上下文的人必读的。它揭示了一个相当反直觉的现象:在同时处理多文档问答和键值检索两类任务时,模型对信息的敏感度,表现出一种典型的“U型”曲线——出现在开头和结尾的信息被利用得最好,而一旦目标信息被埋在了长上下文的中间部分,哪怕对于专门做了长上下文优化的模型来讲,性能也会出现断崖式下跌。

https://arxiv.org/abs/2307.03172

这个问题,直接引出了今天要聊的技术方案。

LlamaIndex 里的 SentenceWindowNodeParser,思路非常简单但实用。它先把文档拆成一个个独立的句子,每个节点里只装一句。但关键在元数据里——它还保留了这句话周围的几句,这个“周围上下文”就叫窗口。

这么做的好处很直接。当我们生成嵌入向量时,我们希望句子本身的语义范围非常聚焦,非常精确。但真正把检索结果送给大模型时,我们又希望大模型能看到这句话周围的完整信息,而不是断章取义。所以,配合 MetadataReplacementNodePostProcessor,就能在检索到某个节点后,用元数据中的窗口上下文,替换掉原来那句孤零零的句子,再送进大模型。

举个例子:如果你问“中国什么时候掌握了交会对接技术”,模型检索到的可能只是“至此,载人航天的三项基本技术均已被中国掌握”这一句。但如果给它加上上下文窗口,它就能看到前面那句“11月3日凌晨,神舟八号与天宫一号以自动模式成功实现中国首次空间交会与对接”,整个信息链条就完整了。

在具体实现上,第一步就是解决中文分句的问题。LlamaIndex 默认依赖的 NLTK 库,对中文文档的句子切分效果并不理想。这里给出一个网上能找到的替代方案:

完成LLM和嵌入模型的初始化后,我们设置窗口大小为3:

然后加载数据集并建立索引:

接下来,直接提问:

返回的结果是这样的:

根据提供的信息,中国在2011年11月3日凌晨掌握了载人航天的三项基本技术,即天地往返、出舱活动和交会对接。具体来说,神舟八号与天宫一号成功实现了中国首次空间交会与对接,标志着中国已经掌握了这三项载人航天的关键技术。

把结果跟原文对照一下:

答案完全正确。

最后,可以对比一下窗口内容与原始句子的区别——红色是最终输出了窗口上下文的片段,蓝色则是原始句子本身:

window: 11月3日凌晨,神舟八号与天宫一号以自动模式成功实现中国首次空间交会与对接。 至此,载人航天的三项基本技术(天地往返、出舱活动、交会对接)均已被中国掌握。2012年6月16日,神舟九号飞船搭载航天员景海鹏、刘旺和刘洋发射升空后与天宫一号对接,三名航天员进入天宫一号,随后进行了约十天的短期驻留并完成了首次手控交会对接试验,其中刘洋凭借这次任务成为中国首位进入太空的女航天员。------------------original text: 至此,载人航天的三项基本技术(天地往返、出舱活动、交会对接)均已被中国掌握。

可以清楚地看到,原始检索到的句子虽然包含了核心结论,但缺少了关键的事件背景。加上窗口后,大模型获得的上下文不仅完整,而且直接命中答案。这个方案,在对抗“lost in the middle”的问题上,确实是一个轻量但高效的选择。

完整代码可以在这里找到:https://github.com/realyinchen/LlamaIndex/blob/main/Document_Node/MetadataReplacement%2BNodeSentenceWindow.ipynb