探索“自查询”检索技术:让你的搜索系统更智能

57 阅读4分钟

探索“自查询”检索技术:让你的搜索系统更智能

在现代数据驱动的世界中,检索系统扮演着越来越重要的角色。尤其是当我们面对大量的数据时,如何快速、准确地获取所需信息成为一大挑战。本篇文章将介绍一种新的检索技术——“自查询”检索(Self-Querying Retrieval)。这种技术不仅能实现语义检索,还能根据用户查询提取元数据过滤器,从而提高检索精度。

引言

在本篇文章中,我们将深入探讨“自查询”检索的概念、实现方法、潜在挑战及其解决方案,并通过代码示例展示其实际应用。读完这篇文章,你将了解如何构建一个自查询检索系统,并为进一步学习提供资源。

主要内容

1. 自查询检索的概念

自查询检索指的是一种可以根据自然语言查询自动生成结构化查询的检索器。这种检索器利用一个查询构建LLM链来编写结构化查询,并将该查询应用于底层的向量存储(VectorStore)。这样不仅可以对存储文档的内容进行语义相似度比较,还能从用户查询中提取元数据过滤器并执行这些过滤器。

2. 构建自查询检索器所需的工具

为了演示,我们将使用一个叫做Chroma的向量存储,并创建一组包含电影摘要的小型演示文档。特别注意,由于某些地区的网络限制,开发者可能需要考虑使用API代理服务来提高访问稳定性。

3. 初始化向量存储

首先,我们需要安装必要的Python包:

%pip install --upgrade --quiet lark langchain-chroma

然后,初始化向量存储并添加文档:

from langchain_chroma import Chroma
from langchain_core.documents import Document
from langchain_openai import OpenAIEmbeddings

docs = [
    Document(
        page_content="A bunch of scientists bring back dinosaurs and mayhem breaks loose",
        metadata={"year": 1993, "rating": 7.7, "genre": "science fiction"},
    ),
    Document(
        page_content="Leo DiCaprio gets lost in a dream within a dream within a dream within a ...",
        metadata={"year": 2010, "director": "Christopher Nolan", "rating": 8.2},
    ),
    Document(
        page_content="A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea",
        metadata={"year": 2006, "director": "Satoshi Kon", "rating": 8.6},
    ),
    Document(
        page_content="A bunch of normal-sized women are supremely wholesome and some men pine after them",
        metadata={"year": 2019, "director": "Greta Gerwig", "rating": 8.3},
    ),
    Document(
        page_content="Toys come alive and have a blast doing so",
        metadata={"year": 1995, "genre": "animated"},
    ),
    Document(
        page_content="Three men walk into the Zone, three men walk out of the Zone",
        metadata={
            "year": 1979,
            "director": "Andrei Tarkovsky",
            "genre": "thriller",
            "rating": 9.9,
        },
    ),
]

vectorstore = Chroma.from_documents(docs, OpenAIEmbeddings())
# 使用API代理服务提高访问稳定性

4. 创建自查询检索器

接下来,我们需要提供文档元数据字段的信息以及文档内容的简短描述来实例化检索器。

from langchain.chains.query_constructor.base import AttributeInfo
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain_openai import ChatOpenAI

metadata_field_info = [
    AttributeInfo(
        name="genre",
        description="The genre of the movie. One of ['science fiction', 'comedy', 'drama', 'thriller', 'romance', 'action', 'animated']",
        type="string",
    ),
    AttributeInfo(
        name="year",
        description="The year the movie was released",
        type="integer",
    ),
    AttributeInfo(
        name="director",
        description="The name of the movie director",
        type="string",
    ),
    AttributeInfo(
        name="rating", description="A 1-10 rating for the movie", type="float"
    ),
]

document_content_description = "Brief summary of a movie"
llm = ChatOpenAI(temperature=0)
retriever = SelfQueryRetriever.from_llm(
    llm,
    vectorstore,
    document_content_description,
    metadata_field_info,
)

5. 测试检索器

我们可以通过几个示例来测试我们的检索器:

# 仅指定过滤器的示例
print(retriever.invoke("I want to watch a movie rated higher than 8.5"))

# 指定查询和过滤器的示例
print(retriever.invoke("Has Greta Gerwig directed any movies about women"))

# 指定复合过滤器的示例
print(retriever.invoke("What's a highly rated (above 8.5) science fiction film?"))

# 指定查询和复合过滤器的示例
print(retriever.invoke(
    "What's a movie after 1990 but before 2005 that's all about toys, and preferably is animated"
))

常见问题和解决方案

1. 访问限制问题

由于某些地区的网络限制,访问OpenAI等API服务可能不稳定。建议使用API代理服务提高访问稳定性。可以参考这里获取相关API代理服务。

2. 元数据字段不匹配

确保元数据字段名称和类型与实际存储的数据匹配。如果字段名称或类型不匹配,检索器可能无法正确提取和过滤数据。

总结和进一步学习资源

自查询检索技术使得检索系统不仅能够进行语义相似度比较,还能基于用户查询提取和执行元数据过滤器,从而提高检索精度。通过本文的介绍和代码示例,你可以尝试构建自己的自查询检索系统。

若想深入了解并进一步提高技能,可以参考以下资源:

参考资料

  1. LangChain 官方文档
  2. OpenAI API 参考
  3. Lark 语法解析文档

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

---END---