检索
这里回顾的一些概念利用模型来生成查询(例如,用于SQL或图形数据库)。 这样做存在固有的风险。 确保您的数据库连接权限尽可能根据应用程序的需求进行限制。 这将减轻(尽管不能消除)构建能够查询数据库的模型驱动系统的风险。 有关一般安全最佳实践的更多信息,请参阅我们的安全指南。
概述
检索系统是许多人工智能应用的基础,能够有效地从大数据集中识别相关信息。 这些系统适应各种数据格式:
- 非结构化文本(例如,文档)通常存储在向量存储或词汇搜索索引中。
- 结构化数据通常存储在具有定义模式的关系或图数据库中。
尽管数据格式的多样性不断增加,现代人工智能应用程序越来越致力于通过自然语言界面使所有类型的数据可访问。 模型在这一过程中扮演着关键角色,通过将自然语言查询翻译成与底层搜索索引或数据库兼容的格式。 这种翻译使得与复杂数据结构的交互更加直观和灵活。
关键概念
(1) 查询分析: 一个模型转换或构建搜索查询以优化检索的过程。
(2) 信息检索: 搜索查询用于从各种检索系统中获取信息。
查询分析
虽然用户通常更喜欢使用自然语言与检索系统交互,但这些系统可能需要特定的查询语法或从某些关键词中受益。 查询分析充当原始用户输入和优化搜索查询之间的桥梁。查询分析的一些常见应用包括:
- 查询重写: 查询可以被重写或扩展,以提高语义或词汇搜索的效果。
- 查询构建: 搜索索引可能需要结构化查询(例如,数据库的SQL)。
查询分析使用模型从原始用户输入中转换或构建优化的搜索查询。
查询重写
检索系统理想情况下应该能够处理广泛的用户输入,从简单且措辞不佳的查询到复杂、多方面的问题。 为了实现这种多功能性,一种流行的方法是使用模型将原始用户查询转换为更有效的搜索查询。 这种转换可以从简单的关键词提取到复杂的查询扩展和重构。 以下是在非结构化数据检索中使用模型进行查询分析的一些关键好处:
- 查询澄清:模型可以重新表述模糊或措辞不当的查询以提高清晰度。
- 语义理解: 它们能够捕捉查询背后的意图,超越字面关键词匹配。
- 查询扩展: 模型可以生成相关术语或概念以扩大搜索范围。
- 复杂查询处理:它们可以将多部分问题分解为更简单的子查询。
已经开发了各种技术来利用模型进行查询重写,包括:
名称 | 何时使用 | 描述 |
---|---|---|
Multi-query | 当您希望通过提供问题的多种表述来确保检索的高召回率时。 | 使用多种表述重写用户问题,为每个重写的问题检索文档,返回所有查询的唯一文档。 |
Decomposition | 当一个问题可以分解为较小的子问题时。 | 将一个问题分解为一组子问题/问题,这些问题可以顺序解决(使用第一个问题的答案+检索来回答第二个问题)或并行解决(将每个答案整合到最终答案中)。 |
Step-back | 当需要更高层次的概念理解时。 | 首先提示LLM提出一个关于更高层次概念或原则的通用问题,并检索相关事实。使用这些基础来帮助回答用户问题。论文。 |
HyDE | 如果您在使用原始用户输入检索相关文档时遇到挑战。 | 使用LLM将问题转换为回答问题的假设文档。使用嵌入的假设文档来检索真实文档,前提是文档-文档相似性搜索可以产生更相关的匹配。论文。 |
例如,查询分解可以通过使用提示和强制生成子问题列表的结构化输出来简单地完成。 然后可以在下游检索系统上顺序或并行运行这些子问题。
from pydantic import BaseModel, Field
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage
# Define a pydantic model to enforce the output structure
class Questions(BaseModel):
questions: List[str] = Field(
description="A list of sub-questions related to the input query."
)
# Create an instance of the model and enforce the output structure
model = ChatOpenAI(model="gpt-4o", temperature=0)
structured_model = model.with_structured_output(Questions)
# Define the system prompt
system = """You are a helpful assistant that generates multiple sub-questions related to an input question. \n
The goal is to break down the input into a set of sub-problems / sub-questions that can be answers in isolation. \n"""
# Pass the question to the model
question = """What are the main components of an LLM-powered autonomous agent system?"""
questions = structured_model.invoke([SystemMessage(content=system)]+[HumanMessage(content=question)])
查询构建
查询分析还可以专注于将自然语言查询翻译成专门的查询语言或过滤器。 这种翻译对于有效地与存储结构化或半结构化数据的各种数据库进行交互至关重要。
-
结构化数据示例:对于关系型和图数据库,使用领域特定语言(DSLs)来查询数据。
- 文本到SQL:将自然语言转换为SQL用于关系型数据库。
- 文本到Cypher:将自然语言转换为Cypher用于图数据库。
-
半结构化数据示例: 对于向量存储,查询可以结合语义搜索和元数据过滤。
- 自然语言到元数据过滤器: 将用户查询转换为适当的元数据过滤器。
这些方法利用模型来弥合用户意图与不同数据存储系统的特定查询需求之间的差距。以下是一些流行的技术:
名称 | 使用时机 | 描述 |
---|---|---|
Self Query | 如果用户提出的问题更适合通过基于元数据而不是文本相似性来获取文档来回答。 | 这使用LLM将用户输入转换为两件事:(1)用于语义查找的字符串,(2)与之配套的元数据过滤器。这很有用,因为通常问题涉及文档的元数据(而不是内容本身)。 |
Text to SQL | 如果用户提出的问题需要从关系型数据库中获取信息,且该数据库可通过SQL访问。 | 这使用LLM将用户输入转换为SQL查询。 |
Text-to-Cypher | 如果用户提出的问题需要存储在图形数据库中的信息,可以通过Cypher访问。 | 这使用LLM将用户输入转换为Cypher查询。 |
作为一个例子,这里展示了如何使用SelfQueryRetriever
将自然语言查询转换为元数据过滤器。
metadata_field_info = schema_for_metadata
document_content_description = "Brief summary of a movie"
llm = ChatOpenAI(temperature=0)
retriever = SelfQueryRetriever.from_llm(
llm,
vectorstore,
document_content_description,
metadata_field_info,
)
- 查看我们的教程:text-to-SQL、text-to-Cypher,以及元数据过滤器的查询分析。
- 查看我们的博客文章概述。
- 观看我们关于查询构建的RAG从零开始视频。
信息检索
常见的检索系统
词汇搜索索引
许多搜索引擎基于将查询中的单词与每个文档中的单词进行匹配。 这种方法称为词汇检索,使用通常基于词频的搜索算法。 直觉很简单:如果一个单词在用户的查询和特定文档中频繁出现,那么这个文档可能是一个很好的匹配。
用于实现这一点的特定数据结构通常是倒排索引。 这种类型的索引包含一个单词列表以及每个单词到其在各种文档中出现位置的映射。 使用这种数据结构,可以有效地将搜索查询中的单词与它们出现的文档进行匹配。 BM25 和 TF-IDF 是 两种流行的词汇搜索算法。
- 查看 BM25 检索器集成。
- 查看Elasticsearch检索器集成。
向量索引
向量索引是索引和存储非结构化数据的另一种方式。
有关详细概述,请参阅我们的概念指南向量存储。
简而言之,向量存储不是使用词频,而是使用嵌入模型将文档压缩为高维向量表示。
这使得可以使用简单的数学运算(如余弦相似度)在嵌入向量上进行高效的相似性搜索。
关系型数据库
关系数据库是许多应用程序中使用的一种基本的结构化数据存储类型。 它们将数据组织成具有预定义模式的表,其中每个表代表一个实体或关系。 数据存储在行(记录)和列(属性)中,允许通过SQL(结构化查询语言)进行高效的查询和操作。 关系数据库在维护数据完整性、支持复杂查询以及处理不同数据实体之间的关系方面表现出色。
- 查看我们的教程以了解如何使用SQL数据库。
- 查看我们的 SQL 数据库工具包。
图数据库
图数据库是一种专门设计用于存储和管理高度互连数据的数据库类型。 与传统的关系数据库不同,图数据库使用由节点(实体)、边(关系)和属性组成的灵活结构。 这种结构允许高效地表示和查询复杂的互连数据。 图数据库以图结构存储数据,包括节点、边和属性。 它们特别适用于存储和查询数据点之间的复杂关系,例如社交网络、供应链管理、欺诈检测和推荐服务。
- 查看我们的教程以了解如何使用图数据库。
- 查看我们的图形数据库集成列表。
- 查看Neo4j的LangChain入门套件。
检索器
LangChain 通过 retriever 概念提供了一个统一的接口,用于与各种检索系统进行交互。该接口非常简单:
- 输入:一个查询(字符串)
- 输出:文档列表(标准化的LangChain Document 对象)
你可以使用前面提到的任何检索系统来创建一个检索器。我们讨论的查询分析技术在这里特别有用,因为它们为通常需要结构化查询语言的数据库提供了自然语言接口。
例如,你可以使用文本到SQL转换来为SQL数据库构建一个检索器。这使得自然语言查询(字符串)可以在后台转换为SQL查询。
无论底层的检索系统是什么,LangChain中的所有检索器都共享一个通用接口。你可以使用简单的invoke
方法来使用它们:
docs = retriever.invoke(query)