核心内容摘要
KittyxKum:猫咪的软萌诱惑,与你共享的治愈时光
作者来自 Elastic Kathleen DeRusso探索用于 LLMs 的 chunking 和 snippet 提取重点介绍用于识别并发送给 rerankers 和 LLMs 等模型的最相关 chunks 和 snippets 的增强功能。
Elasticsearch 内置了大量新功能帮助你为自己的使用场景构建最佳搜索解决方案。
欢迎参加我们关于构建现代 Search AI 体验的动手式网络研讨会学习如何将这些功能付诸实践。
你也可以开始免费的 cloud trial或立即在本地机器上试用 Elastic。
如今如果你做过语义搜索或上下文工程可能已经大量接触过 chunks。
如果你不熟悉 chunkschunk 是从较大文档中提取的一小段有意义的内容。
这篇博客提供了关于 chunking 的扎实基础概览解释了它为什么重要以及不同的 chunking 策略。
在这篇博客中我们想聚焦于 chunking 主题中的一个具体问题即定义发送给大语言模型 LLM 或其他模型的最佳上下文。
模型能够接收的上下文 token 数量是有限的但即使在这个限制之内发送大量内容也可能导致相关性下降原因包括上下文衰减context rot或 “丢失在中间” 等问题即重要信息被隐藏在大段文本中而被忽略。
这引出了一个问题我们如何把这件事做得更好检索器中的重排序我们首先从检索器入手具体是 text_similarity_reranker 检索器。
我们知道许多 cross-encoder 重排序模型在处理长文档时表现不佳。
这是因为这些重排序模型会将较长内容截断到模型的 token 窗口内丢弃其余内容。
如果文档中最相关的部分在发送给重排序器之前被截断这实际上会导致搜索相关性下降。
为了解决这个问题我们为 text_similarity_reranker 检索器引入了 chunk_rescorer。
当指定该参数时我们不会将整个文档发送给重排序器而是先对文档进行 chunking并根据重排序推理文本对每个 chunk 进行评估。
我们通过将每个 chunk 索引到一个临时的内存 Lucene 索引中并对这些 chunks 执行 BM25 文本搜索来实现这一点。
然后返回最优的 chunks 供重排序器进一步评估。
chunk rescorer 的使用非常简单只需对 API 调用做一个小改动即可GET books/_search { retriever: { text_similarity_reranker: { retriever: { standard: { query: { match: { author: Tolkien } } } }, rank_window_size: 10, field: semantic_text, inference_text: are all who wander lost?, chunk_rescorer: { size: 1 } } } }在评估 chunk rescorer 时我们发现对于许多会发生截断的模型都有显著提升包括 Elastic Reranker 和 Cohere 的 rerank-english-v
0 模型。
然而当我们对 jina-reranker-v2-base-multilingual 进行评估时效果并不那么显著因为 Jina 已在内部解决了长文档问题。
我们使用 Multilingual Long-Document Retrieval MLDR 英文数据集进行了评估。
这是一个包含非常长文章内容的数据集许多重排序模型在该数据集上都会触发文档截断问题。
下表展示了在使用 BM25 文本搜索且 rank_window_size 为 32 时的评估结果Reranker modelNDCG10NDCG10 NDCG10 with chunk rescoringjina-reranker-v2-base-multilingual
0.
7
764488Cohere rerank-english-v
3.
00.
5925880.
rerank-v1-elasticsearch
0.
4
751994值得注意的是在不进行重排序的情况下原始 BM25 结果的 Normalized Discounted Cumulative Gain NDCG 得分即相关性得分接近
64。
更多背景可参考这篇论文。
这意味着对于会发生截断的 rerankers在处理长文档时重排序后的结果实际上比不进行重排序还要差。
需要注意的是这一问题仅适用于长文档能够完全放入 token 窗口的较短文档不会受到该问题影响。
在我们评估的 rerankers 中Jina 是唯一一个开箱即用就能很好处理长文档的 reranker这得益于其滑动窗口方法。
在使用 Elastic Learned Sparse EncodeR ELSER 的 semantic_text 字段时我们看到了更好的基线性能但整体结果差异与之前相似。
我们认为对于会发生截断的模型这些结果足够有前景因此将 chunk rescorer 作为一个可选特性发布以便为相关模型带来额外的相关性提升。
但我们建议在将其用于生产之前先针对具体的 rerankers 进行评估。
ES|QL然而chunk 提取的真正威力在于 Elasticsearch Query Language ES|QL 。
我们希望让 chunks 和 snippets 成为 ES|QL 中的一等公民这样就可以轻松地将它们提取出来并重新用于 reranking、发送到 LLM 上下文或其他用途。
我们首先在 Elasticsearch
2 版本中引入了 CHUNK 函数FROM books | EVAL chunks CHUNK(description)CHUNK 是一个极简原语它接收一些字符串内容文本字段、semantic text 字段或任何其他字符串类型的行内容并将其进行 chunk。
你可以查看并与这些 chunks 交互还可以尝试使用不同的 chunking 设置FROM books | EVAL chunks CHUNK(description, {strategy: sentence, max_chunk_size: 25, sentence_overlap: 0})然后你可以将 chunk 与现有原语结合使用例如 MV_SLICE 和 MV_EXPAND以格式化 chunks 在行输出中的表示方式FROM books | WHERE MATCH(author, Tolkien) | EVAL chunks CHUNK(semantic_description, {strategy: sentence, max_chunk_size: 25, sentence_overlap: 0}) | EVAL truncated MV_SLICE(chunks, 0,
| MV_EXPAND truncated | KEEP title, truncated这很好但我们真正想要的是获取查询的最匹配 snippets因此我们在 Elasticsearch
3 版本中引入了 TOP_SNIPPETSFROM books | EVAL snippets TOP_SNIPPETS(description, ring)我们增加了对返回 snippet 数量和单词长度的控制使用基于句子的 chunking 策略FROM books | EVAL snippets TOP_SNIPPETS(description, ring, { num_snippets: 3, num_words: 25 }) | MV_EXPAND snippets | KEEP title, snippets当你加入 COMPLETION 时这就融入了 LLMs 的更大框架。
以下是我们设想 TOP_SNIPPETS 与 LLM 集成的示例FROM books METADATA _score | WHERE semantic_description:what are hobbits? | SORT _score DESC | LIMIT 10 | FORK ( EVAL snippets TOP_SNIPPETS(semantic_description, what are hobbits?, {num_snippets: 3}) | COMPLETION CONCAT(Answer what are hobbits, snippets) WITH {inference_id: my-completion-endpoint})在这个示例中我们执行语义搜索但对于每个文档我们识别该文档中的最优 snippets。
我们将高度相关的 snippets 发送到 completion 命令而不是整个文档。
这是一个简单文档的示例但你也可以在此使用 reranking并且未来当有多个分支可用时同样格式将支持混合搜索 hybrid search 。
我们还可以在最新版的 RERANK 中利用 snippetsFROM books | WHERE MATCH(title, ring) | EVAL snippets TOP_SNIPPETS(semantic_description, what are hobbits?, { num_snippets: 3, num_words: 25 }) | RERANK what are hobbits? ON snippets WITH { inference_id : my-reranker }我们的下一步思考关于 chunking 和 snippet 提取的故事还没有结束实际上才刚刚开始。
我们正在研究如何将现有的 semantic_text chunks 开箱即用地整合到 chunking 和 snippet 提取策略中。
同时我们也在探索还需要哪些功能才能让 snippet 提取成为在 Elastic Agent Builder 等产品中值得使用的功能。
总体而言我们很高兴分享这些工具并期待在我们不断优化获取 LLM 最佳上下文策略的过程中收到你的反馈原文https://www.elastic.co/search-labs/blog/llm-chunking-snippet-extraction