在 Haystack 中处理大型文档需要将其分解成易于管理的片段,并使用高效的检索策略。核心挑战在于大多数语言模型都有输入限制(通常为 512 token),并且难以处理长文本。首先使用 Haystack 的预处理工具将文档分割成更小的块。DocumentSplitter
或 PreProcessor
类可以使用诸如 split_length
(例如,每个块 200 个词)和 split_overlap
(例如,20 个词)等选项来分割文档,以保留片段之间的上下文。例如,一个 10,000 词的文档可以被分割成 50 个块,每个块 200 词,相邻块共享 20 个词,以避免在边界处丢失关键信息。这确保了每个块都符合模型限制,同时保持了语义的连续性。
分割后,使用 Haystack 的文档存储和检索管道高效地管理块。像 ElasticsearchDocumentStore
或 FAISSDocumentStore
这样的存储可以对块进行索引以便快速搜索。查询时,使用检索器(例如,BM25Retriever
或 EmbeddingRetriever
)查找相关块,然后将其传递给像 FARMReader
这样的阅读器模型进行答案提取。例如,关于大型合同中特定段落的问题,会首先检索包含该段落的相关块。为了避免冗余或碎片化的答案,可以考虑后处理步骤,例如聚合来自多个块的结果,或在管道中使用 JoinDocuments
节点合并重叠的答案。元数据(例如,document_id
)有助于将块追溯到其原始文档。
通过平衡块大小和检索精度来优化性能。较小的块减少了计算负载,但可能错过更广泛的上下文。尝试不同的块长度(例如,128 vs. 512 token)和重叠值,为您的用例找到合适的权衡点。对于非常大的数据集,使用可扩展的文档存储,如 Elasticsearch,它可以有效地处理高吞吐量搜索。此外,利用 Haystack 的缓存机制(例如,带有 update_existing_documents=True
的 SQLDocumentStore
)来避免重新处理未更改的文档。如果运行时性能至关重要,可以在管道中结合使用稀疏检索器(快速但不精确)和密集检索器(较慢但更精确),以在不牺牲相关性的情况下优先考虑速度。例如,使用 BM25Retriever
进行初步过滤,并使用 EmbeddingRetriever
细化结果。