在LangChain中使用自查询检索器

概要

在处理大量文档时,仅依靠简单的关键词匹配往往无法满足复杂的查询需求。自查询检索器(Self-Query Retriever)允许我们构建更加智能的检索机制,它能够根据自然语言查询自动构造结构化的查询语句,并应用于底层的向量存储(VectorStore)。本文将详细介绍如何在LangChain中实现自查询检索器,并通过具体示例展示其工作原理。

技术名词解释

自查询检索器简介
自查询检索器(Self-Query Retriever)是一种特殊的检索器,它不仅可以基于内容进行语义相似性检索,还能根据查询条件从文档的元数据中提取过滤条件并执行这些过滤条件。这意味着,自查询检索器能够理解自然语言查询,并将其转换为结构化的查询,从而实现更精准的文档检索。

技术细节

构建文档集
首先,我们需要准备一组文档,这里我们以几部电影的简介为例。

from langchain_community.vectorstores import Chroma
from langchain_core.documents import Document

docs = [
    Document(
        page_content="一群科学家带回恐龙爆发了混乱",
        metadata={"year": 1993, "rating": 7.7, "genre": "科幻小说"},
    ),
    Document(
        page_content="故事发生在1920年北洋年间中国南方,马邦德花钱买官,购得“萨南康省”的县长一职,坐“马拉的火车”赴任途中遭马匪张麻子一行人伏击",
        metadata={"year": 2010, "director": "姜文", "rating": 8.2},
    ),
    Document(
        page_content="话说孙悟空护送唐三藏前往西天取经,半路却和牛魔王合谋要杀害唐三藏,并偷走了紫霞仙子持有的月光宝盒。观音闻讯赶到,欲除掉孙悟空以免危害苍生。唐三藏慈悲为怀,愿意一命赔一命,感化劣徒,观音遂令孙悟空五百年后投胎做人,赎其罪孽。",
        metadata={"year": 1994, "director": "刘镇伟", "rating": 8.6},
    ),
    Document(
        page_content="故事背景设定在2075年,讲述了太阳即将毁灭,毁灭之后的太阳系已经不适合人类生存,而面对绝境,人类将开启“流浪地球”计划,试图带着地球一起逃离太阳系,寻找人类新家园的故事。",
        metadata={"year": 2019, "director": "郭帆", "rating": 8.3},
    ),
    Document(
        page_content="该片讲述了耿浩和好哥们郝义一场荒诞而有趣的“寻爱之旅”。该片采用双线叙事的手法,以耿浩和康小雨婚姻破裂为叙事的起点,在郝义携耿浩前往剧组送道具途中“寻爱”的故事中,穿插着昔日康小雨孤身前往大理并与耿浩相遇的前尘往事,讲述着在现代生活中不同人群对婚姻、生活与理想的不同追求。",
        metadata={"year": 2014, "genre": "喜剧"},
    ),
]

创建向量存储
接下来,我们需要创建一个向量存储来保存这些文档。

from langchain_community.embeddings.huggingface import HuggingFaceEmbeddings

embeddings_path = "D:\\ai\\download\\bge-large-zh-v1.5"
embeddings = HuggingFaceEmbeddings(model_name=embeddings_path)

vectorstore = Chroma.from_documents(docs, embeddings)

实例化自查询检索器
为了实例化自查询检索器,我们需要提供一些关于文档支持的元数据字段的信息以及文档内容的简短描述。

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

metadata_field_info = [
    AttributeInfo(
        name="genre",
        description='电影的类型。 ["科幻小说","喜剧","剧情片","惊悚片","爱情片","动作片","动画片"]之一',
        type="string",
    ),
    AttributeInfo(
        name="year",
        description="电影上映年份",
        type="integer",
    ),
    AttributeInfo(
        name="director",
        description="电影导演的名字",
        type="string",
    ),
    AttributeInfo(
        name="rating", description="电影评分为 1-10", type="float"
    ),
]

document_content_description = "电影的简要概述"

from langchain_openai import ChatOpenAI, OpenAI

openai_api_key = "EMPTY"
openai_api_base = "http://127.0.0.1:1234/v1"
model = ChatOpenAI(
    openai_api_key=openai_api_key,
    openai_api_base=openai_api_base,
    temperature=0.3,
)

retriever = SelfQueryRetriever.from_llm(
    model,
    vectorstore,
    document_content_description,
    metadata_field_info,
    enable_limit=True,
    search_kwargs={"k": 2}
)

查询示例
现在我们可以使用自查询检索器来执行一些示例查询。

查询高评分电影

# 只指定过滤条件
retriever.invoke("给我推荐一部评分8.5以上的电影")

查询特定主题的电影

retriever.invoke("帮我推荐1个关于寻爱之旅的电影")

小结

通过本文,我们学习了如何在LangChain中使用自查询检索器来提升文档检索的能力。自查询检索器不仅能理解自然语言查询,还能从文档的元数据中提取过滤条件,从而实现更精准的检索。希望这篇博客能为你的项目提供有用的参考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值