Docs Menu
Docs Home
/ /

Realice recuperaciones mediante autoconsulta con MongoDB y LangChain

Puede integrar MongoDB Vector Search con LangChain para realizar Recuperación con autoconsulta. Este tutorial muestra cómo usar el recuperador con autoconsulta para ejecutar consultas de búsqueda vectorial de MongoDB en lenguaje natural con filtrado de metadatos.

La recuperación mediante autoconsulta utiliza un LLM para procesar su consulta de búsqueda para identificar posibles filtros de metadatos, forma una consulta de búsqueda vectorial estructurada con los filtros y luego ejecuta la consulta para recuperar los documentos más relevantes.

Ejemplo

Con una consulta como "¿Qué películas de suspenso posteriores a 2010 tienen calificaciones superiores a 8?", el recuperador puede identificar filtros en el genre, year y rating, y utilice esos filtros para recuperar documentos que coincidan con la consulta.

Trabaje con una versión ejecutable de este tutorial como Cuaderno de Python.

Para completar este tutorial, debes tener lo siguiente:

  • Uno de los siguientes tipos de clúster de MongoDB:

    • Un clúster Atlas que ejecute MongoDB 6.0.11 versión, 7.0.2 o posterior. Asegúrese de que su Ladirección IP está incluida en la lista de acceso de su proyecto Atlas.

    • Una implementación local de Atlas creada usando Atlas CLI. Para obtener más información, consulta Crear una Implementación local de Atlas.

    • Un clúster de MongoDB Community o Enterprise con Search y Vector Search instalados.

  • Una clave API de Voyage AI. Para obtener más información, consulte la documentación de Voyage AI.

  • Una llave de API de OpenAI. Debes tener una cuenta de OpenAI con créditos disponibles para las solicitudes de API. Para obtener más información sobre cómo registrar una cuenta de OpenAI, consulta el sitio web de la API de OpenAI.

En esta sección, creará una instancia de tienda de vectores utilizando su clúster MongoDB como base de datos de vectores.

1

Configura el entorno para este tutorial. Cree un cuaderno interactivo de Python guardando un archivo con la extensión .ipynb. Este cuaderno te permite ejecutar snippets de código Python de forma individual y lo utilizarás para ejecutar el código en este tutorial.

Para configurar el entorno de su portátil:

  1. Ejecute el siguiente comando en su cuaderno:

    pip install --quiet --upgrade langchain-mongodb langchain-voyageai langchain-openai langchain langchain-core lark
  2. Establecer variables de entorno.

    Ejecute el siguiente código para establecer las variables de entorno para este tutorial. Proporcione su clave de API de Voyage, la clave de API de OpenAI y la SRV cadena de conexión.del clúster de MongoDB

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

    Nota

    Se debe sustituir <connection-string> por la cadena de conexión del clúster Atlas o de la implementación local de Atlas.

    Su cadena de conexión debe usar el siguiente formato:

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

    Para obtener más información,consulte Conectarse a un clúster a través de bibliotecas de cliente.

    Su cadena de conexión debe usar el siguiente formato:

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

    Para obtener más información, consulta Cadenas de conexión.

2

Ejecute el siguiente código en su cuaderno para crear una instancia de almacén de vectores denominada vector_store utilizando el espacio de nombres langchain_db.self_query en 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

Pegue y ejecute el siguiente código en su cuaderno para ingerir algunos documentos de muestra con metadatos en su colección en 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)

Si se utiliza Atlas, se pueden verificar las incrustaciones vectoriales navegando hasta el namespace langchain_db.self_query en la Interfaz de usuario de Atlas.

4

Ejecute el siguiente código para crear el índice de búsqueda vectorial de MongoDB con filtros para el almacén de vectores para habilitar la búsqueda vectorial y el filtrado de metadatos en sus datos:

# 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)
)

Tip

El índice debería tardar aproximadamente un minuto en crearse. Mientras se crea, el índice está en un estado de sincronización inicial. Cuando termine de crearse, se pueden empezar a realizar los query en los datos de la colección.

En esta sección, inicializa el recuperador de autoconsulta para consultar datos de tu almacén de vectores.

1

Para usar el recuperador de autoconsultas, debe describir los documentos de su colección y los campos de metadatos que desea filtrar. Esta información ayuda al LLM a comprender la estructura de sus datos y a filtrar los resultados según las consultas de los usuarios.

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

Ejecute el siguiente código para crear un recuperador de autoconsulta utilizando el 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
)

Ejecute las siguientes consultas para ver cómo el recuperador de autoconsultas ejecuta diferentes tipos de consultas:

# 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")]

Puedes usar el recuperador de autoconsultas en tu pipeline de RAG. Pega y ejecuta el siguiente código en tu notebook para implementar un ejemplo de pipeline de RAG que realice la recuperación de autoconsultas.

Este código también configura el recuperador para usar el parámetro enable_limit, lo que permite al LLM limitar el número de documentos que devuelve si es necesario. La respuesta generada puede 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")]

Volver

Parent Document Retrieval

En esta página