Este tutorial demuestra cómo mejorar tu aplicaciones RAG añadiendo memoria conversacional y almacenamiento en caché semántico usando la integración de LangChain MongoDB.
Memoria permite mantener el contexto de la conversación a lo largo de múltiples interacciones de los usuarios.
La caché semántica reduce la latencia de respuesta almacenando en caché consultas semánticamente similares.
Trabaja con una versión ejecutable de este tutorial como Cuaderno de Python.
Requisitos previos
Antes de comenzar, asegúrate de tener lo siguiente:
Uno de los siguientes tipos de clúster de MongoDB:
An Clúster Atlas con MongoDB 6.0.11 versión, 7.0.2 o posterior. Asegúrese de que su direcció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 de la API de Voyage IA. Para crear una clave de API, consulta Claves de API del modelo.
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.
Un entorno para ejecutar cuadernos interactivos de Python como Colab.
Tip
Recomendamos completar el tutorial Get Started para aprender cómo crear una implementación ingenua de RAG antes de completar este tutorial.
Usa MongoDB como Vector Store
En esta sección, crearás una instancia de almacenamiento vectorial usando tu clúster de MongoDB como base de datos vectorial.
Configura el entorno.
Configura el entorno para este tutorial. Crea un cuaderno interactivo de Python guardando un archivo con el .ipynb Extensión. Este cuaderno te permite ejecutar fragmentos de código Python individualmente y lo usarás para ejecutar el código en este tutorial.
Para configurar el entorno de su portátil:
Ejecuta el siguiente comando en tu notebook:
pip install --quiet --upgrade langchain langchain-community langchain-core langchain-mongodb langchain-voyageai langchain-openai pypdf 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, consulta Conectar a un clúster a través de bibliotecas de clientes.
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.
Instanciar la tienda de vectores.
Pega y ejecuta el siguiente código en su cuaderno para crear una instancia de vector store llamada vector_store utilizando el namespace langchain_db.rag_with_memory 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.rag_with_memory" )
Añade datos al almacén vectorial.
Pega y ejecuta el siguiente código en tu notebook para ingerir un PDF de muestra que contiene un informe de ganancias reciente de MongoDB en la base de datos vectorial.
Este código utiliza un divisor de texto para fragmentar los datos del PDF en documentos padre más pequeños. Especifica el tamaño del fragmento (número de caracteres) y la superposición de fragmentos (número de caracteres superpuestos entre fragmentos consecutivos) para cada documento.
from langchain_community.document_loaders import PyPDFLoader from langchain_text_splitters import RecursiveCharacterTextSplitter # Load the PDF loader = PyPDFLoader("https://investors.mongodb.com/node/13176/pdf") data = loader.load() # Split PDF into documents text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=20) docs = text_splitter.split_documents(data) # Add data to the vector store vector_store.add_documents(docs)
Tip
Después de ejecutar este código, si estás usando Atlas, puedes verificar tus incrustaciones vectoriales navegando al langchain_db.rag_with_memory namespace en la Interfaz de Usuario de Atlas.
Crea el índice de búsqueda vectorial de MongoDB.
Ejecute el siguiente código para crear el índice MongoDB Vector Search para la tienda de vectores y permitir búsquedas vectoriales 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 )
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.
Implementar RAG con Memoria
Esta sección demuestra cómo implementar RAG con memoria conversacional utilizando la integración de LangChain MongoDB.
Define una función para obtener el historial de mensajes del chat.
Para mantener un historial de conversación a través de varias interacciones, utiliza la clase MongoDBChatMessageHistory. Permite almacenar mensajes de chat en una base de datos MongoDB y extenderlos a la cadena RAG para gestionar el contexto de la conversación.
Pega y ejecuta el siguiente código en tu notebook para crear una función llamada get_session_history que devuelve una instancia de MongoDBChatMessageHistory. Esta instancia recupera el historial de chat de una sesión específica.
from langchain_mongodb.chat_message_histories import MongoDBChatMessageHistory from langchain_core.runnables.history import RunnableWithMessageHistory from langchain_core.prompts import MessagesPlaceholder def get_session_history(session_id: str) -> MongoDBChatMessageHistory: return MongoDBChatMessageHistory( connection_string=MONGODB_URI, session_id=session_id, database_name="langchain_db", collection_name="rag_with_memory" )
Crea una cadena RAG que gestione el historial de mensajes de chat.
Pega y ejecuta los siguientes fragmentos de código para crear la cadena RAG:
Especifique el LLM a utilizar.
from langchain_openai import ChatOpenAI # Define the model to use for chat completion llm = ChatOpenAI(model = "gpt-4o") Define un mensaje que resuma el historial de chat del retriever.
from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser # Create a prompt to generate standalone questions from follow-up questions standalone_system_prompt = """ Given a chat history and a follow-up question, rephrase the follow-up question to be a standalone question. Do NOT answer the question, just reformulate it if needed, otherwise return it as is. Only return the final standalone question. """ standalone_question_prompt = ChatPromptTemplate.from_messages( [ ("system", standalone_system_prompt), MessagesPlaceholder(variable_name="history"), ("human", "{question}"), ] ) # Parse output as a string parse_output = StrOutputParser() question_chain = standalone_question_prompt | llm | parse_output Compila una cadena de recuperadores que procese el historial de chat y recupere documentos.
from langchain_core.runnables import RunnablePassthrough # Create a retriever retriever = vector_store.as_retriever(search_type="similarity", search_kwargs={ "k": 5 }) # Create a retriever chain that processes the question with history and retrieves documents retriever_chain = RunnablePassthrough.assign(context=question_chain | retriever | (lambda docs: "\n\n".join([d.page_content for d in docs]))) Define una solicitud para generar una respuesta basada en el historial de chat y el contexto recuperado.
# Create a prompt template that includes the retrieved context and chat history rag_system_prompt = """Answer the question based only on the following context: {context} """ rag_prompt = ChatPromptTemplate.from_messages( [ ("system", rag_system_prompt), MessagesPlaceholder(variable_name="history"), ("human", "{question}"), ] ) Implementar RAG con memoria.
Combina los componentes que has definido en una cadena RAG completa:
# Build the RAG chain rag_chain = ( retriever_chain | rag_prompt | llm | parse_output ) # Wrap the chain with message history rag_with_memory = RunnableWithMessageHistory( rag_chain, get_session_history, input_messages_key="question", history_messages_key="history", )
Prueba tu implementación de RAG.
Invoque la cadena para responder preguntas. Esta cadena mantiene el contexto de la conversación y devuelve respuestas relevantes que consideran las interacciones previas. Sus respuestas pueden variar.
# First question response_1 = rag_with_memory.invoke( {"question": "What was MongoDB's latest acquisition?"}, {"configurable": {"session_id": "user_1"}} ) print(response_1)
MongoDB's latest acquisition was Voyage AI, a pioneer in state-of-the-art embedding and reranking models for next-generation AI applications.
# Follow-up question that references the previous question response_2 = rag_with_memory.invoke( {"question": "Why did they do it?"}, {"configurable": {"session_id": "user_1"}} ) print(response_2)
MongoDB acquired Voyage AI to enable organizations to easily build trustworthy AI applications by integrating advanced embedding and reranking models into their technology. This acquisition aligns with MongoDB's goal of helping businesses innovate at "AI speed" using its flexible document model and seamless scalability.
Agregar Caché Semántica
Esta sección añade almacenamiento semántico en caché por encima de la cadena RAG. El almacenamiento en caché semántico es una forma de almacenamiento en caché que recupera los prompts almacenados en caché en función de la similitud semántica entre las consultas.
Nota
Puede utilizar el almacenamiento en caché semántico independientemente de la memoria de conversación, pero para este tutorial utilice ambas funciones juntas.
Para ver un video tutorial de esta función, consulte Aprender mirando.
Configura la caché semántica.
Ejecute el siguiente código para configurar la caché semántica usando la clase MongoDBAtlasSemanticCache:
from langchain_mongodb.cache import MongoDBAtlasSemanticCache from langchain_core.globals import set_llm_cache # Configure the semantic cache set_llm_cache(MongoDBAtlasSemanticCache( connection_string = MONGODB_URI, database_name = "langchain_db", collection_name = "semantic_cache", embedding = embedding_model, index_name = "vector_index", similarity_threshold = 0.5 # Adjust based on your requirements ))
Prueba el caché semántico con tu cadena RAG.
La caché semántica almacena automáticamente tus avisos. Ejecute las siguientes consultas de muestra, donde debería ver una reducción significativa en el tiempo de respuesta para la segunda consulta. Tus respuestas y tiempos de respuesta podrían variar.
Tip
Puedes ver tus avisos en caché en la colección semantic_cache. La caché semántica almacena solo la entrada para el LLM. Al utilizarlo en cadenas de recuperación, ten en cuenta que los documentos recuperados pueden variar entre ejecuciones, lo que lleva a errores de caché para consultas semánticamente similares.
%%time # First query (not cached) rag_with_memory.invoke( {"question": "What was MongoDB's latest acquisition?"}, {"configurable": {"session_id": "user_2"}} )
CPU times: user 54.7 ms, sys: 34.2 ms, total: 88.9 ms Wall time: 7.42 s "MongoDB's latest acquisition was Voyage AI, a pioneer in state-of-the-art embedding and reranking models that power next-generation AI applications."
%%time # Second query (cached) rag_with_memory.invoke( {"question": "What company did MongoDB acquire recently?"}, {"configurable": {"session_id": "user_2"}} )
CPU times: user 79.7 ms, sys: 24 ms, total: 104 ms Wall time: 3.87 s 'MongoDB recently acquired Voyage AI.'
Aprende observando
Sigue este video tutorial para aprender más sobre el almacenamiento en caché semántico con LangChain y MongoDB.
Duración: 30 minutos