Menu Docs
Página inicial do Docs
/ /

Adicione memória e cache semântica aos seus aplicativos RAG com LangChain e MongoDB

Este tutorial demonstra como aprimorar seus aplicativos RAG adicionando memória de conversação e cache semântico usando a integração LangChain com MongoDB.

  • A memória permite manter o contexto da conversa em várias interações com o usuário.

  • O cache semântica reduz a latência da resposta ao armazenar em cache queries semanticamente semelhantes.

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

Antes de começar, certifique-se de ter o seguinte:

  • Um dos seguintes tipos de cluster MongoDB :

    • Um cluster do Atlas executando 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 da Voyage AI. Para criar uma conta e uma chave de API, consulte o site 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.

  • Um ambiente para executar blocos de anotações interativos do Python, como o CoLab.

Dica

Recomendamos concluir o tutorial de Introdução para aprender como criar uma implementação de RAG ingênua antes de concluir este tutorial.

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 langchain-community langchain-core langchain-mongodb langchain-voyageai langchain-openai pypdf
  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

Cole e execute o seguinte código no seu bloco de anotações para criar uma instância do armazenamento de vetor denominada vector_store utilizando o namespace langchain_db.rag_with_memory 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.rag_with_memory"
)
3

Cole e execute o código a seguir em seu bloco de anotações para inserir um PDF de amostra que contém um relatório de rendimentos recente do MongoDB no armazenamento de vetores.

Este código utiliza um divisor de texto para dividir os dados do PDF em documentos pai menores. Ele especifica o tamanho da parte (número de caracteres) e a sobreposição da parte (número de caracteres sobrepostos entre partes consecutivas) para cada documento.

from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter 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)

Dica

Depois de executar esse código, se estiver usando o Atlas, poderá verificar suas incorporações vetoriais navegando até o namespace langchain_db.rag_with_memory na interface do usuário do Atlas.

4

Execute o código a seguir para criar o índice do MongoDB Vector Search para o armazenamento de vetores e ativar a pesquisa vetorial 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
)

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.

Esta seção demonstra como implementar o RAG com memória de conversação utilizando a integração do LangChain com o MongoDB.

1

Para manter o histórico de conversas em várias interações, use a classe MongoDBChatMessageHistory. Ela permite armazenar mensagens de chat em um banco de dados MongoDB e integrá-las à sua cadeia RAG para gerenciar o contexto da conversa.

Cole e execute o código a seguir no seu notebook para criar uma função chamada get_session_history que retorna uma instância MongoDBChatMessageHistory. Essa instância recupera o histórico de bate-papo para uma sessão 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"
)
2

Cole e execute os seguintes trechos de código para criar a cadeia RAG:

  1. Especificar o LLM a ser usado.

    from langchain_openai import ChatOpenAI
    # Define the model to use for chat completion
    llm = ChatOpenAI(model = "gpt-4o")
  2. Defina um prompt que resuma o histórico do chat para o recuperador.

    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
  3. Construa uma cadeia de recuperação que processe o histórico do chat e 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])))
  4. Defina um prompt para gerar uma resposta com base no histórico de conversas e no 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}"),
    ]
    )
  5. Implemente o RAG com memória.

    Combine os componentes que você definiu em uma cadeia 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",
    )
3

Invoque a cadeia para responder a perguntas. Essa cadeia mantém o contexto da conversa e retorna respostas relevantes que consideram as interações anteriores. Suas respostas podem 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.

Esta seção adiciona cache semântico sobre a sua cadeia RAG. O cache semântico é uma forma de cache que recupera prompts armazenados em cache com base na similaridade semântica entre as queries.

Observação

Você pode usar o cache semântico independentemente da memória de conversação, mas para este tutorial, você usará os dois recursos juntos.

Para assistir a um tutorial em vídeo sobre esse recurso, consulte Aprenda assistindo.

1

Execute o seguinte código para configurar o cache semântico utilizando a classe 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
))
2

O cache semântico armazena automaticamente seus prompts. Execute as consultas de exemplo a seguir, onde você deverá observar uma redução significativa no tempo de resposta para a segunda query. As respostas e os tempos de resposta podem variar.

Dica

Você pode visualizar suas solicitações em cache na coleção semantic_cache. O cache semântica armazena em cache apenas a entrada no LLM. Ao usá-lo em cadeias de recuperação, observe que os documentos recuperados podem ser alterados entre as execuções, resultando em falhas de cache para queries semanticamente semelhantes.

%%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.'

Siga este tutorial em vídeo para aprender mais sobre cache semântico com LangChain e MongoDB.

Duração: 30 minutos

Voltar

Começar

Nesta página