Usando SelfQueryRetriever com LangChain para consultar um banco de dados vetorial
LangChain é bem conhecido por orquestrar interações com modelos de linguagem grandes (LLMs). Recentemente, o LangChain introduziu uma forma de realizar auto-consulta, permitindo que eles consultem a “chain” ou os próprios módulos usando uma consulta de entrada do usuário. Este post mostrará como fazer auto-consulta no Milvus, o banco de dados vetorial mais popular do mundo. Ao interpretar uma consulta do usuário, o sistema pode refinar buscas dentro de armazenamentos vetoriais, melhorando os resultados de recuperação. Você pode encontrar o código deste exemplo no CoLab aqui.
Vamos configurar a auto-consulta no Milvus com o LangChain. Este processo consiste em quatro etapas lógicas.
Configure os fundamentos do LangChain e do Milvus.
Obtenha ou crie os dados necessários.
Informe o modelo sobre o formato de dados esperado.
Demonstre a auto-consulta e explique como ela funciona.
Introdução à Auto-Consulta
A auto-consulta é uma técnica poderosa usada em processamento de linguagem natural (NLP) e recuperação de informações. Ela permite que um sistema consulte a si mesmo usando uma consulta de entrada do usuário, possibilitando resultados mais precisos e relevantes. No contexto do LangChain, a auto-consulta é usada para recuperar informações de um armazenamento vetorial, que é um banco de dados que armazena vetores que representam documentos ou pontos de dados. O recuperador de auto-consulta é um componente-chave do framework LangChain, permitindo a criação de consultas e recuperações complexas usando linguagem natural.
Ao aproveitar a auto-consulta, o LangChain pode decompor a consulta de um usuário em um formato estruturado que o armazenamento vetorial possa entender. Esse processo garante que os documentos recuperados sejam altamente relevantes para a consulta do usuário, facilitando encontrar as informações de que precisa. Seja criando um modelo de IA conversacional ou um mecanismo de busca, a auto-consulta pode aumentar significativamente a precisão e a relevância dos seus resultados.
Configurando o LangChain e o Milvus
A primeira etapa é configurar as bibliotecas necessárias. Você pode instalar as bibliotecas necessárias usando pip install openai langchain milvus python-dotenv. Se você seguiu meus tutoriais anteriores, já está familiarizado com python-dotenv, minha biblioteca preferida para lidar com variáveis de ambiente. Usamos a biblioteca OpenAI com o LangChain para acessar o GPT e utilizar o Milvus como nosso armazenamento vetorial.
Depois de se conectar à chave da API da OpenAI, importe os módulos necessários do LangChain. Precisamos dos seis módulos a seguir:
Document: Um tipo de dado do LangChain para armazenamento de dados.OpenAIeOpenAIEmbeddings: Duas funcionalidades para acessar a OpenAI e seus embeddings.Milvus: Um módulo para acessar o Milvus a partir do LangChain.SelfQueryRetriever: Um módulo recuperador.AttributeInfo: Um módulo que define nossa estrutura de dados para o LangChain.
Após importar os módulos, definimos a variável embeddings como a função padrão do OpenAI Embeddings. A etapa final no processo de configuração é usar a biblioteca milvus para iniciar uma instância do Milvus Lite em nosso notebook.
Agora, vamos dar uma olhada nos dados.
import os
from dotenv import load_dotenv
load_dotenv()
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")
from langchain.schema import Document
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Milvus
from langchain.llms import OpenAI
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain.chains.query_constructor.base import AttributeInfo
embeddings = OpenAIEmbeddings()
from milvus import default_server
default_server.start()
Vamos reunir alguns dados. Você pode fazer scraping dos seus dados, usar os dados fornecidos como estão ou usá-los como um modelo para criar seus dados. Preparei uma lista de documentos sobre filmes para este exemplo, incluindo Jurassic Park, Toy Story, Finding Nemo, The Unbearable Weight of Massive Talent, Lord of War e Ghost Rider. Embora eu não inclua os títulos em nossos dados, quero que você saiba a quais filmes eles se referem.
Eu armazeno cada um desses filmes como um objeto LangChain Document. Ele contém uma chave page_content correspondente a uma string, neste caso, a descrição do filme. Ele também inclui metadados, como o ano, a avaliação e o gênero do filme.
docs = [
# jurassic park
Document(page_content="A bunch of scientists bring back dinosaurs and mayhem breaks loose",
metadata={"year": 1993, "rating": 7.7, "genre": "action"}),
# toy story
Document(page_content="Toys come alive and have a blast doing so",
metadata={"year": 1995, "genre": "animated", "rating": 9.3 }),
# finding nemo
Document(page_content="A dad teams up with a mentally disabled partner to break into a dentist\'s office to save his son.",
metadata={"year": 2003, "genre": "animated", "rating": 8.2 }),
# unbearable weight of massive talent
Document(page_content="Nicholas Cage plays Nicholas Cage in this movie about Nicholas Cage.",
metadata={"year": 2022, "genre": "comedy", "rating": 7.0 }),
# lord of war
Document(page_content="Nicholas Cage sells guns until he has enough money to marry his favorite model. Then he sells more guns.",
metadata={"year": 2005, "genre": "comedy", "rating": 7.6 }),
# ghost rider
Document(page_content="Nicholas Cage loses his skin and sets his skull on fire. Then he rides a motorcycle.",
metadata={"year": 2007, "genre": "action", "rating": 5.3 }),
]
Definindo metadados de self-query e self query retriever para LangChain e Milvus
Concluímos as duas primeiras etapas do quebra-cabeça, e agora é hora da terceira.
Primeiro, vamos configurar nosso banco de dados vetorial para ingestão. Podemos usar a implementação Milvus do LangChain para ingerir nossos documentos e criar um banco de dados vetorial com base em nossos documentos existentes. Esta etapa também é onde a função de embeddings entra em ação, usando a variável embeddings que criamos anteriormente. A instrução de comparação leva em consideração os formatos e diretrizes específicos necessários para criar condições de filtro que orientam os processos de recuperação de dados.
O parâmetro connection_args é o único parâmetro obrigatório para se conectar ao Milvus. Neste tutorial, também uso o parâmetro collection_name para atribuir um nome à coleção onde armazenamos nossos dados. Cada coleção no Milvus deve ter um nome. Por padrão, o LangChain usa LangChainCollection.
vector_store = Milvus.from_documents(
docs,
embedding=embeddings,
connection_args={"host": "localhost", "port": default_server.listen_port},
collection_name="movies"
)
Em seguida, vamos definir as informações de metadados usando a funcionalidade AttributeInfo para que o LangChain saiba o que esperar. Esta seção criará uma lista de informações de atributos para os dados. Especificaremos o nome, a descrição e o tipo de dados de cada atributo. É aqui que uma instrução de condição lógica se torna essencial para formular comparações e operações lógicas dentro do processo de construção da consulta.
metadata_field_info = [
AttributeInfo(
name="genre",
description="The genre of the movie",
type="string",
),
AttributeInfo(
name="year",
description="The year the movie was released",
type="integer",
),
AttributeInfo(
name="rating",
description="A 1-10 rating for the movie",
type="float"
),
]
As últimas duas partes descrevem o documento, inicializam o LLM e definem o Self-Query Retriever. Definimos o recuperador de auto-consulta chamando seu método ‘from_llm’. Devemos usar esse método para conectar o LLM, o armazenamento vetorial, a descrição do conteúdo do documento e as informações dos campos de metadados. Neste exemplo, também definimos ‘verbose = True’ para habilitar a saída detalhada para esse recuperador de auto-consulta. A string de consulta deve incluir apenas texto relevante que corresponda ao conteúdo do documento, garantindo que quaisquer condições nos filtros sejam separadas de forma distinta e não incluídas na própria string de consulta.
document_content_description = "Brief summary of a movie"
llm = OpenAI(temperature=0)
retriever = SelfQueryRetriever.from_llm(
llm, vector_store, document_content_description, metadata_field_info, verbose=True
)
Resultados de auto-consulta
Concluímos a configuração do recuperador de auto-consulta. Agora, vamos ver como ele funciona na prática. Neste exemplo, usei três descrições de filmes relacionadas a Nicholas Cage. Portanto, a pergunta que fazemos é: quais são alguns filmes sobre Nicholas Cage?
# This example only specifies a relevant query
retriever.get_relevant_documents("What are some movies about Nicholas Cage?")
Devemos obter uma saída como a abaixo.
langchain-query-vector-database.png
Ao definir verbose=True, podemos visualizar a consulta, o filtro e o limite. O LLM converte nossa consulta de “Quais são alguns filmes sobre Nicholas Cage?” para “Nicholas Cage.” Observando os resultados, podemos notar que os três principais resultados são todos filmes com Nicholas Cage. No entanto, o quarto resultado, Procurando Nemo, é irrelevante por causa do parâmetro definido para recuperar quatro resultados.
Esperamos que o passo a passo do código tenha esclarecido o conceito de auto-consulta em um banco de dados vetorial. No site da LangChain, a LangChain descreve a auto-consulta como um método para um LLM consultar a si mesmo usando o armazenamento vetorial subjacente. Em outras palavras, a LangChain está desenvolvendo um app simples de geração aumentada por recuperação (RAG) no framework CVP que inclui uma função de auto-consulta.
Neste tutorial, exploramos o recurso de auto-consulta da LangChain usando Milvus como o armazenamento vetorial subjacente. A auto-consulta permite criar um app RAG simples combinando um LLM e um banco de dados vetorial. O LLM divide a consulta em linguagem natural em uma string, que então é vetorizada para consulta.
Em nosso exemplo, geramos alguns dados de amostra relacionados a filmes. Uma maneira de expandir este exemplo é coletar seus dados. Ao definir o recuperador de auto-consulta, lembre-se de fornecer as descrições tanto para o armazenamento vetorial quanto para os metadados.
Para começar e experimentar o recurso de auto-consulta da LangChain, consulte o notebook colab.
Consultando o Armazenamento Vetorial com Instruções de Operação Lógica
Ao consultar o armazenamento vetorial, instruções de operação lógica são usadas para especificar condições para filtrar documentos. Uma instrução de operação lógica assume a forma de op(statement1, statement2, …), em que op é um operador lógico como AND, OR ou NOT. Cada instrução pode ser uma instrução de comparação, que assume a forma de comp(attr, val), em que comp é um comparador como EQ, LT ou GT, e attr e val são o atributo e o valor sendo comparados, respectivamente.
Por exemplo, uma instrução de operação lógica pode se parecer com isto: AND(EQ(language, “English”), GT(rating, 4)). Essa instrução filtraria documentos que têm um atributo de idioma igual a “English” e um atributo de classificação maior que 4. Ao usar instruções de operação lógica, você pode criar consultas complexas que combinam múltiplas condições, permitindo uma filtragem mais precisa de documentos no armazenamento vetorial.
Lidando com a Consulta do Usuário
Quando um usuário insere uma consulta, o recuperador de autoconsulta usa um construtor de consultas para gerar uma consulta estruturada. A consulta estruturada é então traduzida em consultas ao armazenamento vetorial, que são executadas no armazenamento vetorial para recuperar documentos relevantes. O construtor de consultas usa um prompt e um analisador de saída para gerar a consulta estruturada, que captura os filtros especificados pelo usuário.
Por exemplo, se um usuário inserir a consulta “Find movies with a rating greater than 4 and a runtime less than 2 hours”, o construtor de consultas pode gerar uma consulta estruturada como esta: AND(GT(rating, 4), LT(runtime, 120)). Essa consulta estruturada seria então traduzida em consultas ao armazenamento vetorial e executada no armazenamento vetorial para recuperar documentos relevantes. Ao lidar com a consulta do usuário dessa forma, o recuperador de autoconsulta garante que os resultados sejam adaptados aos requisitos específicos do usuário.
Melhores práticas e conclusão
Ao usar o recuperador de autoconsulta, é importante seguir as melhores práticas para garantir resultados precisos e relevantes. Aqui estão algumas dicas:
Use uma linguagem específica e concisa ao inserir consultas.
Use instruções de operação lógica para especificar condições para filtrar documentos.
Use instruções de comparação para comparar atributos e valores.
Use o comparador EQ para especificar correspondências exatas.
Use os comparadores LT e GT para especificar consultas de intervalo.
Use os operadores lógicos AND e OR para combinar condições.
Em conclusão, o recuperador de autoconsulta é uma ferramenta poderosa para criar modelos de IA conversacional que podem recuperar e processar informações de várias fontes. Ao usar instruções de operação lógica e instruções de comparação, os usuários podem especificar consultas complexas e recuperar documentos relevantes de um armazenamento vetorial. Ao seguir as melhores práticas e usar o recuperador de autoconsulta de forma eficaz, os desenvolvedores podem criar modelos de IA mais precisos e relevantes que conseguem lidar com uma ampla variedade de consultas de usuários.
Continue lendo

Zilliz Cloud Now Available in Azure North Europe: Bringing AI-Powered Vector Search Closer to European Customers
The addition of the Azure North Europe (Ireland) region further expands our global footprint to better serve our European customers.

Vector Databases vs. Hierarchical Databases
Use a vector database for AI-powered similarity search; use a hierarchical database for organizing data in parent-child relationships with efficient top-down access patterns.

Zilliz Cloud BYOC Upgrades: Bring Enterprise-Grade Security, Networking Isolation, and More
Discover how Zilliz Cloud BYOC brings enterprise-grade security, networking isolation, and infrastructure automation to vector database deployments in AWS



