Menu Docs
Página inicial do Docs
/
Atlas
/ / /

Realize recuperação autoconsulta com MongoDB e LangChain

Você pode integrar o MongoDB Vector Search ao LangChain para realizar a recuperação auto-consulta. Este tutorial demonstra como usar o retriever autoquery para executar queries do MongoDB Vector Search em linguagem natural com filtragem de metadados.

A recuperação autoconsulta usa um LLM para processar sua query de pesquisa para identificar possíveis filtros de metadados, forma uma query de pesquisa vetorial estruturada com os filtros e, em seguida, executa a consulta para recuperar os documentos mais relevantes.

Exemplo

Com uma consulta como "O que são filmes de ação depois de 2010 com classificações acima de 8?", O recuperador pode identificar filtros nos campos genre, year e rating e usar esses filtros para recuperar documentos que correspondam à query.

Trabalhe com uma versão executável deste tutorial como um bloco de anotações Python.

Para concluir este tutorial, você deve ter o seguinte:

  • Um dos seguintes tipos de cluster MongoDB :

    • Um Atlas cluster executando o MongoDB versão 6.0.11, 7.0.2 ou posterior. Garanta que seu endereço IP esteja incluído na lista de acessodo seu projeto Atlas.

    • Um sistema local do Atlas criado utilizando o Atlas CLI. Para saber mais, consulte Criar uma implantação de Atlas local.

    • Um cluster MongoDB Community ou Enterprise com Search e Vector Search instalados.

  • Uma chave de API do Voyage AI. Para saber mais, consulte Documentação da Voyage AI.

  • Uma chave de API da OpenAI. Você deve ter uma conta da OpenAI com créditos disponíveis para solicitações de API. Para aprender mais sobre como registrar uma conta OpenAI, consulte o website de API OpenAI.

Nesta seção, você cria uma instância de armazenamento de vetor usando seu cluster MongoDB como um banco de dados de vetor.

1

Configure o ambiente para este tutorial. Crie um bloco de anotações Python interativo salvando um arquivo com a extensão .ipynb. Este bloco de anotações permite que você execute trechos de código Python individualmente, e você o usará para executar o código neste tutorial.

Para configurar seu ambiente de bloco de anotações:

  1. Execute o seguinte comando no seu notebook:

    pip install --quiet --upgrade langchain-mongodb langchain-voyageai langchain-openai langchain langchain-core lark
  2. Defina variáveis de ambiente.

    Execute o seguinte código para definir as variáveis de ambiente para este tutorial. Forneça sua chave de API Voyage, chave de API OpenAI e a string de conexão SRV do cluster MongoDB.

    import os
    os.environ["OPENAI_API_KEY"] = "<openai-key>"
    os.environ["VOYAGE_API_KEY"] = "<voyage-key>"
    MONGODB_URI = "<connection-string>"

    Observação

    Substitua <connection-string> pela string de conexão do seu cluster do Atlas ou da implantação local do Atlas.

    Sua string de conexão deve usar o seguinte formato:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net

    Para saber mais, consulte Conectar a um cluster via drivers.

    Sua string de conexão deve usar o seguinte formato:

    mongodb://localhost:<port-number>/?directConnection=true

    Para saber mais, consulte Connection strings.

2

Execute o seguinte código em seu bloco de anotações para criar uma instância de armazenamento de vetor denominada vector_store utilizando o namespace langchain_db.self_query no MongoDB:

from langchain_mongodb import MongoDBAtlasVectorSearch
from langchain_voyageai import VoyageAIEmbeddings
# Use the voyage-3-large embedding model
embedding_model = VoyageAIEmbeddings(model="voyage-3-large")
# Create the vector store
vector_store = MongoDBAtlasVectorSearch.from_connection_string(
connection_string = MONGODB_URI,
embedding = embedding_model,
namespace = "langchain_db.self_query",
text_key = "page_content"
)
3

Cole e execute o código a seguir em seu bloco de anotações para alimentar alguns documentos de exemplo com metadados em sua coleção no MongoDB.

from langchain_core.documents import Document
docs = [
Document(
page_content="A bunch of scientists bring back dinosaurs and mayhem breaks loose",
metadata={"year": 1993, "rating": 7.7, "genre": "action"},
),
Document(
page_content="A fight club that is not a fight club, but is a fight club",
metadata={"year": 1994, "rating": 8.7, "genre": "action"},
),
Document(
page_content="Leo DiCaprio gets lost in a dream within a dream within a dream within a ...",
metadata={"year": 2010, "genre": "thriller", "rating": 8.2},
),
Document(
page_content="A bunch of normal-sized women are supremely wholesome and some men pine after them",
metadata={"year": 2019, "rating": 8.3, "genre": "drama"},
),
Document(
page_content="Three men walk into the Zone, three men walk out of the Zone",
metadata={"year": 1979, "rating": 9.9, "genre": "science fiction"},
),
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, "genre": "thriller", "rating": 9.0},
),
Document(
page_content="Toys come alive and have a blast doing so",
metadata={"year": 1995, "genre": "animated", "rating": 9.3},
),
Document(
page_content="The toys come together to save their friend from a kid who doesn't know how to play with them",
metadata={"year": 1997, "genre": "animated", "rating": 9.1},
),
]
# Add data to the vector store, which automaticaly embeds the documents
vector_store.add_documents(docs)

Se você estiver usando o Atlas, verifique suas incorporações vetoriais navegando até o namespace langchain_db.self_query na UI do Atlas.

4

Execute o código a seguir para criar o índice do MongoDB Vector Search com filtros para o armazenamento de vetores para ativar a pesquisa vetorial e a filtragem de metadados em seus dados:

# Use LangChain helper method to create the vector search index
vector_store.create_vector_search_index(
dimensions = 1024, # The dimensions of the vector embeddings to be indexed
filters = [ "genre", "rating", "year" ], # The metadata fields to be indexed for filtering
wait_until_complete = 60 # Number of seconds to wait for the index to build (can take around a minute)
)

Dica

O índice deve levar cerca de um minuto para ser criado. Enquanto ele é compilado, o índice está em um estado de sincronização inicial. Quando a construção estiver concluída, você poderá começar a fazer query nos dados em sua coleção.

Nesta seção, você inicializa o recuperador de consulta automática para consultar dados de seu armazenamento de vetor.

1

Para usar o recuperador de consulta automática, você deve descrever os documentos em sua coleção e os campos de metadados que deseja filtrar. Essas informações ajudam o LLM a entender a estrutura de seus dados e como filtrar os resultados com base nas queries do usuário.

from langchain.chains.query_constructor.schema import AttributeInfo
# Define the document content description
document_content_description = "Brief summary of a movie"
# Define the metadata fields to filter on
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"
),
]
2

Execute o código a seguir para criar um recuperador de consulta automática usando o método MongoDBAtlasSelfQueryRetriever.from_llm.

from langchain_mongodb.retrievers import MongoDBAtlasSelfQueryRetriever
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o")
retriever = MongoDBAtlasSelfQueryRetriever.from_llm(
llm=llm,
vectorstore=vector_store,
metadata_field_info=metadata_field_info,
document_contents=document_content_description
)

Execute as seguintes queries para ver como o retriever com auto-query executa diferentes tipos de query:

# This example specifies a filter (rating > 9)
retriever.invoke("What are some highly rated movies (above 9)?")
[Document(id='686e84de13668e4048bf9ff3', metadata={'_id': '686e84de13668e4048bf9ff3', 'year': 1979, 'rating': 9.9, 'genre': 'science fiction'}, page_content='Three men walk into the Zone, three men walk out of the Zone'),
Document(id='686e84de13668e4048bf9ff5', metadata={'_id': '686e84de13668e4048bf9ff5', 'year': 1995, 'genre': 'animated', 'rating': 9.3}, page_content='Toys come alive and have a blast doing so'),
Document(id='686e84de13668e4048bf9ff6', metadata={'_id': '686e84de13668e4048bf9ff6', 'year': 1997, 'genre': 'animated', 'rating': 9.1}, page_content="The toys come together to save their friend from a kid who doesn't know how to play with them")]
# This example specifies a semantic search and a filter (rating > 9)
retriever.invoke("I want to watch a movie about toys rated higher than 9")
[Document(id='686e84de13668e4048bf9ff5', metadata={'_id': '686e84de13668e4048bf9ff5', 'year': 1995, 'genre': 'animated', 'rating': 9.3}, page_content='Toys come alive and have a blast doing so'),
Document(id='686e84de13668e4048bf9ff6', metadata={'_id': '686e84de13668e4048bf9ff6', 'year': 1997, 'genre': 'animated', 'rating': 9.1}, page_content="The toys come together to save their friend from a kid who doesn't know how to play with them"),
Document(id='686e84de13668e4048bf9ff3', metadata={'_id': '686e84de13668e4048bf9ff3', 'year': 1979, 'rating': 9.9, 'genre': 'science fiction'}, page_content='Three men walk into the Zone, three men walk out of the Zone')]
# This example specifies a composite filter (rating >= 9 and genre = thriller)
retriever.invoke("What's a highly rated (above or equal 9) thriller film?")
[Document(id='686e84de13668e4048bf9ff4', metadata={'_id': '686e84de13668e4048bf9ff4', 'year': 2006, 'genre': 'thriller', 'rating': 9.0}, page_content='A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea')]
# This example specifies a query and composite filter (year > 1990 and year < 2005 and genre = action)
retriever.invoke(
"What's a movie after 1990 but before 2005 that's all about dinosaurs, " +
"and preferably has the action genre"
)
[Document(id='686e84de13668e4048bf9fef', metadata={'_id': '686e84de13668e4048bf9fef', 'year': 1993, 'rating': 7.7, 'genre': 'action'}, page_content='A bunch of scientists bring back dinosaurs and mayhem breaks loose'),
Document(id='686e84de13668e4048bf9ff0', metadata={'_id': '686e84de13668e4048bf9ff0', 'year': 1994, 'rating': 8.7, 'genre': 'action'}, page_content='A fight club that is not a fight club, but is a fight club')]
# This example only specifies a semantic search query
retriever.invoke("What are some movies about dinosaurs")
[Document(id='686e84de13668e4048bf9fef', metadata={'_id': '686e84de13668e4048bf9fef', 'year': 1993, 'rating': 7.7, 'genre': 'action'}, page_content='A bunch of scientists bring back dinosaurs and mayhem breaks loose'),
Document(id='686e84de13668e4048bf9ff5', metadata={'_id': '686e84de13668e4048bf9ff5', 'year': 1995, 'genre': 'animated', 'rating': 9.3}, page_content='Toys come alive and have a blast doing so'),
Document(id='686e84de13668e4048bf9ff1', metadata={'_id': '686e84de13668e4048bf9ff1', 'year': 2010, 'genre': 'thriller', 'rating': 8.2}, page_content='Leo DiCaprio gets lost in a dream within a dream within a dream within a ...'),
Document(id='686e84de13668e4048bf9ff6', metadata={'_id': '686e84de13668e4048bf9ff6', 'year': 1997, 'genre': 'animated', 'rating': 9.1}, page_content="The toys come together to save their friend from a kid who doesn't know how to play with them")]

Você pode usar o retriever autoquery em seu pipeline RAG. Cole e execute o seguinte código em seu bloco de anotações para implementar um exemplo de pipeline RAG que executa a recuperação por meio de autoconsulta.

Este código também configura o recuperador para usar o parâmetro enable_limit, que permite ao LLM limitar o número de documentos retornados pelo recuperador, se necessário. A resposta gerada pode variar.

import pprint
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o")
# Configure self-query retriever with a document limit
retriever = MongoDBAtlasSelfQueryRetriever.from_llm(
llm,
vector_store,
document_content_description,
metadata_field_info,
enable_limit=True
)
# Define a prompt template
template = """
Use the following pieces of context to answer the question at the end.
{context}
Question: {question}
"""
prompt = PromptTemplate.from_template(template)
# Construct a chain to answer questions on your data
chain = (
{ "context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
# Prompt the chain
question = "What are two movies about toys after 1990?" # year > 1990 and document limit of 2
answer = chain.invoke(question)
print("Question: " + question)
print("Answer: " + answer)
# Return source documents
documents = retriever.invoke(question)
print("\nSource documents:")
pprint.pprint(documents)
Question: What are two movies about toys after 1990?
Answer: The two movies about toys after 1990 are:
1. The 1995 animated movie (rated 9.3) where toys come alive and have fun.
2. The 1997 animated movie (rated 9.1) where toys work together to save their friend from a kid who doesn’t know how to play with them.
Source documents:
[Document(id='686e84de13668e4048bf9ff5', metadata={'_id': '686e84de13668e4048bf9ff5', 'year': 1995, 'genre': 'animated', 'rating': 9.3}, page_content='Toys come alive and have a blast doing so'),
Document(id='686e84de13668e4048bf9ff6', metadata={'_id': '686e84de13668e4048bf9ff6', 'year': 1997, 'genre': 'animated', 'rating': 9.1}, page_content="The toys come together to save their friend from a kid who doesn't know how to play with them")]

Voltar

Parent Document Retrieval

Nesta página