Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Junte-se a nós no Amazon Web Services re:Invent 2024! Saiba como usar o MongoDB para casos de uso de AI .
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Produtoschevron-right
Atlaschevron-right

Adicionando cache semântico e memória ao seu aplicativo RAG usando MongoDB e LangChain

Richmond Alake, Apoorva Joshi15 min read • Published Aug 13, 2024 • Updated Aug 13, 2024
IAPandasPythonAtlas
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty

Introdução

A geração aumentada de recuperação (RAG) é um padrão de projeto de arquitetura predominante em aplicativos modernos de IA que fornece funcionalidades de IA generativa. O RAG foi aceito em aplicativos generativos devido ao seu benefício adicional de basear as respostas e saídas de modelos de linguagem grandes (LLMs) em informações relevantes, reais e atualizadas. A principal contribuição do RAG é a junção do conhecimento não paramétrico com o conhecimento paramétrico do LLM para gerar respostas adequadas às consultas dos usuários.
Aplicativos de AI modernos que usam LLMs e IA generativa exigem mais do que capacidades de resposta eficazes. Os engenheiros e desenvolvedores de IA devem considerar duas outras funcionalidades antes de mover as aplicações RAG para produção. Cache e memória semântica são duas capacidades importantes para aplicativos de IA generativa que ampliam a utilidade das aplicativos de AI modernos ao reduzir os custos de infraestrutura, a latência de resposta e o armazenamento de conversas.
O cache semântico é um processo que usa um armazenamento de dados para manter um registro das queries e seus resultados com base na semântica ou no contexto dentro das próprias queries.
Isso significa que, ao contrário de um cache tradicional que armazena dados com base em correspondências exatas de solicitações de dados ou identificadores específicos, um cache semântico entende e aproveita o significado e os relacionamentos inerentes aos dados. Em um aplicativo LLM ou RAG, isso significa que as queries do usuário que forem correspondências exatas e contextualmente semelhantes a quaisquer queries que tenham sido armazenadas anteriormente se beneficiarão de um processo eficiente de recuperação de informações.
Veja, por exemplo, o chatbot de suporte ao cliente de uma plataforma de e-commerce; a integração do cache semântica permite que o sistema responda às dúvidas por meio da compreensão do contexto por trás das queries do usuário. Portanto, se um cliente perguntar sobre o "melhor smartphone para fotografia noturna" ou "um telefone para fotos noturnas", o chatbot pode aproveitar seu cache semântico para obter respostas relevantes previamente armazenadas, melhorando a eficiência e a relevância de suas respostas.
As interfaces de chatbot com LLM agora prevalecem em aplicativos de IA generativa. Ainda assim, as conversas mantidas entre o LLM e os usuários do aplicativo devem ser armazenadas e recuperadas para criar um histórico de interação coerente e contextualmente relevante. Os benefícios de ter uma referência do histórico de interação estão em fornecer contexto adicional aos LLMs, entender as conversas realizadas anteriormente, melhorar a personalização dos aplicativos de GenAI e permitir que o chatbot forneça respostas mais precisas às queries.
Os recursos de pesquisa vetorial do MongoDB Atlas permitem a criação de um cache semântico, e a nova integração LangChain-MongoDB facilita a integração desse cache em aplicativos RAG. A integração LangChain-MongoDB também facilita a implementação de um armazenamento de conversas para interações com aplicativos RAG.
Aqui está o que é abordado neste tutorial:
  • Como implementar a memória e o armazenamento do histórico de conversas usando LangChain e MongoDB
  • Como implementar cache semântica usando LangChain e MongoDB
  • Visão geral do cache semântico e utilização da memória em aplicativos de RAG
O seguinte repositório do GitHub contém todas as implementações apresentadas neste tutorial, juntamente com outros casos de uso e exemplos de implementações de RAG.

Etapa 1: instalação das bibliotecas necessárias

Esta seção orienta você pelo processo de instalação das bibliotecas essenciais necessárias para implementar o aplicação RAG, completo com recursos de memória e histórico, dentro do seu ambiente de desenvolvimento atual. Aqui está a lista de bibliotecas necessárias:
  • datasets: biblioteca Python para obter acesso a conjuntos de dados disponíveis no Hugging Face Hub
  • langchain: kit de ferramentas Python para LangChain
  • langchain-mongodb: pacote Python para usar o MongoDB como armazenamento de vetores, cache semântico, armazenamento de histórico de chat etc. em LangChain
  • langchain-openai: pacote Python para usar modelos OpenAI com LangChain
  • pymongo: conjunto de ferramentas Python para MongoDB
  • pandas: biblioteca Python para análise, exploração e manipulação de dados
1! pip install -qU datasets langchain langchain-mongodb langchain-openai pymongo pandas
Observe que este tutorial utiliza modelos básicos e de incorporação OpenAI. Para acessar os modelos, verifique se você tem uma  chave de API OpenAI.
Em seu ambiente de desenvolvimento, crie uma referência para a chave de API OpenAI.
1import getpass
2OPENAI_API_KEY = getpass.getpass("Enter your OpenAI API key:")

Etapa 2: configuração do banco de dados

Para lidar com os requisitos de equipar o aplicativo RAG com os recursos de armazenar o histórico de interações ou conversas e um cache semântico, duas novas coleções devem ser criadas junto com a coleção que conterá os dados principais do aplicativo.
A criação de um banco de dados e de uma coleção no MongoDB é simplificada com o MongoDB Atlas.
  1. Registre uma conta Atlas gratuita ou entre na sua conta Atlas existente.
  2. Siga as instruções (selecione Atlas UI como procedimento) para implantar seu primeiro cluster. 
  3. Crie o banco de dados: "langchain_chatbot".
  4. No banco de dados "langchain_chatbot", crie as seguintes coleções: 
    • data : contém todos os dados que funcionam como fonte de conhecimento para o chatbot.
    • history : contém todas as conversas realizadas entre o chatbot e o usuário do aplicativo.
    • semantic_cache : mantém todas as queries feitas ao chatbot junto com suas respostas LLM.
  5. Crie um índice de pesquisa vetorial chamado vector_index para a coleçãodata . Esse índice permite que a aplicação RAG recupere registros como contexto adicional para complementar as consultas do usuário por meio da pesquisa vetorial. Abaixo está a definição JSON do índice de pesquisa vetorial da coleção data
1 {
2   "fields": [
3     {
4       "numDimensions": 1536,
5       "path": "embedding",
6       "similarity": "cosine",
7       "type": "vector"
8     }
9   ]
10 }
6. Crie um índice de pesquisa vetorial com um filtro de texto chamado vector_index para a coleção semantic_cache. Esse índice permite que o aplicativo RAG recupere respostas a queries semanticamente semelhantes a uma query atual solicitada pelo usuário do aplicativo. Confira abaixo a definição JSON do índice de busca vetorial da coleçãosemantic_cache.
1 {
2   "fields": [
3     {
4       "numDimensions": 1536,
5       "path": "embedding",
6       "similarity": "cosine",
7       "type": "vector"
8     },
9     {
10       "path": "llm_string",
11       "type": "filter"
12     }
13   ]
14 }
Ao final desta etapa, você deverá ter um banco de dados com três coleções e dois índices de pesquisa vetorial definidos. A etapa final desta seção é obter a string de conexão com o cluster do Atlas criado para estabelecer uma conexão entre os bancos de dados e o ambiente de desenvolvimento atual. Siga as etapas para obter a string de conexão a partir da IU do Atlas. 
Em seu ambiente de desenvolvimento, crie uma referência para a string URI MongoDB.
1MONGODB_URI = getpass.getpass("Enter your MongoDB connection string:")

Etapa 3: baixe e prepare o conjunto de dados

Este tutorial usa o conjunto de dados embedded_movies do MongoDB. Um ponto de dados dentro do conjunto de dados do filme contém informações correspondentes a um filme específico; lote, gênero, elenco, tempo de execução e muito mais são capturados para cada ponto de dados. Depois de carregar o conjunto de dados no ambiente de desenvolvimento, ele é convertido em um objeto do Pandas DataFrame, que permite a manipulação e análise da estrutura de dados com relativa facilidade.
1from datasets import load_dataset
2import pandas as pd
3
4data = load_dataset("MongoDB/embedded_movies")
5df = pd.DataFrame(data["train"])
6
7# Only keep records where the fullplot field is not null
8df = df[df["fullplot"].notna()]
9
10# Renaming the embedding field to "embedding" -- required by LangChain
11df.rename(columns={"plot_embedding": "embedding"}, inplace=True)
O código acima executa as seguintes operações:
  • Importe o módulo load_dataset da biblioteca datasets, que permite que o conjunto de dados apropriado seja carregado para este tutorial, especificando o caminho. O conjunto de dados completo é carregado no ambiente e referenciado pela variável data.
  • Apenas a partição de treinamento do conjunto de dados precisa ser utilizada; a variável df contém uma referência à partição de treinamento do conjunto de dados como um DataFrame do Pandas.
  • O DataFrame é filtrado para manter apenas registros onde o campo fullplot não é nulo. Esta etapa garante que quaisquer operações ou análises subsequentes que dependam do campo fullplot, como o processo de incorporação, não sejam prejudicadas pela falta de dados. O processo de filtragem usa o método notna() do Pandas para verificar entradas não nulas na coluna fullplot.
  • A coluna plot_embedding no DataFrame foi renomeada para embedding. Essa etapa é necessária para compatibilidade com o LangChain, que requer um campo de entrada chamado incorporação.
Ao final das operações nesta seção, temos um conjunto de dados completo que atua como uma fonte de conhecimento para o chatbot e está pronto para ser ingerido na coleção data no banco de dados langchain_chatbot.

Etapa 4: crie uma cadeia RAG naive com o armazenamento vetorial do MongoDB 

Antes de adicionar histórico de chat e cache, vejamos primeiro como criar uma cadeia RAG simples usando o LangChain, com o MongoDB como armazenamento vetorial. Veja como é o fluxo de trabalho:
Fluxo de trabalho do Naive RAG
A pergunta do usuário é incorporada e os documentos relevantes são recuperados do armazenamento vetorial do MongoDB. Os documentos recuperados, juntamente com a query do usuário, são passados como um prompt para o LLM, que gera uma resposta para a pergunta.
Vamos primeiro ingerir dados em uma coleção do MongoDB. Usaremos esta coleção como o armazenamento vetorial para nossa cadeia RAG.
1from pymongo import MongoClient
2
3# Initialize MongoDB python client
4client = MongoClient(MONGODB_URI)
5
6DB_NAME = "langchain_chatbot"
7COLLECTION_NAME = "data"
8ATLAS_VECTOR_SEARCH_INDEX_NAME = "vector_index"
9collection = client[DB_NAME][COLLECTION_NAME]
O código acima cria um cliente MongoDB e define o banco de dados langchain_chatbot e a coleção data onde armazenaremos nossos dados. Lembre-se de que você também precisará criar um índice de pesquisa vetorial para recuperar dados com eficiência do armazenamento de vetores MongoDB, conforme documentado na Etapa 2 deste tutorial. Para fazer isso, consulte nosso guia oficial de criação de índice de pesquisa vetorial.
Ao criar o índice de pesquisa vetorial para a coleção data, certifique-se de que ele seja nomeado vector_index e que a definição do índice tenha a seguinte aparência:
1 {
2   "fields": [
3     {
4       "numDimensions": 1536,
5       "path": "embedding",
6       "similarity": "cosine",
7       "type": "vector"
8     }
9   ]
10 }
OBSERVAÇÃO: definimos numDimensions  como 1536  porque usamos o modelo text-embedding-ada-002 da OpenAI para criar incorporações.
Em seguida, excluímos qualquer documento existente da coleção "data" e ingerimos nossos dados nela:
1# Delete any existing records in the collection
2collection.delete_many({})
3
4# Data Ingestion
5records = df.to_dict('records')
6collection.insert_many(records)
7
8print("Data ingestion into MongoDB completed")
A ingestão de dados em uma coleção MongoDB a partir de um DataFrame do pandas é um processo simples. Primeiro convertemos o DataFrame em uma lista de dicionários e depois utilizamos o método insert_many para ingerir documentos em massa na coleção.
Com nossos dados no MongoDB, vamos usá-los para construir um armazenamento vetorial para nossa cadeia RAG:
1from langchain_openai import OpenAIEmbeddings
2from langchain_mongodb import MongoDBAtlasVectorSearch
3
4# Using the text-embedding-ada-002 since that's what was used to create embeddings in the movies dataset
5embeddings = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY, model="text-embedding-ada-002")
6
7# Vector Store Creation
8vector_store = MongoDBAtlasVectorSearch.from_connection_string(
9 connection_string=MONGODB_URI,
10 namespace=DB_NAME + "." + COLLECTION_NAME,
11 embedding= embeddings,
12 index_name=ATLAS_VECTOR_SEARCH_INDEX_NAME,
13 text_key="fullplot"
14)
Usamos o método from_connection_string da classe MongoDBAtlasVectorSearch da integração langchain_mongodb para criar um armazenamento vetorial do MongoDB a partir de um URI de conexão do MongoDB. O método get_connection_string recebe os seguintes argumentos:
  • connection_string: URI de conexão do MongoDB
  • namespace: um namespace MongoDB válido (banco de dados e coleção)
  • incorporação: modelo de incorporação a ser usado para gerar incorporações para uma pesquisa vetorial
  • index_name: nome do índice de pesquisa vetorial do MongoDB Atlas
  • text_key: campo nos documentos ingeridos que contêm o texto
A próxima etapa é usar o armazenamento vetorial do MongoDB como um recuperador em nossa cadeia RAG. Em LangChain, um recuperador é uma interface que retorna documentos a partir de uma query. Você pode usar um armazenamento vetorial como um recuperador usando o método as_retriever:
1retriever = vector_store.as_retriever(search_type="similarity", search_kwargs={"k": 5})
as_retriever pode receber argumentos como search_type , ou seja, qual métrica usar para recuperar documentos. Aqui, escolhemos similarity , pois queremos recuperar os documentos mais semelhantes a uma determinada query. Também podemos especificar argumentos de pesquisa adicionais, como  k - ou seja, o número de documentos a serem recuperados. Em nosso exemplo, definimos 5, o que significa que os 5 documentos mais semelhantes serão recuperados para uma determinada query.
A etapa final é colocar todas essas peças juntas para criar uma cadeia RAG. 
OBSERVAÇÃO: as cadeias no LangChain são uma sequência de chamadas para um LLM, uma ferramenta ou uma etapa de processamento de dados. A maneira recomendada de compor cadeias no LangChain é usando a Linguagem de expressão do LangChain (LCEL). Cada componente em uma cadeia é denominado Runnable e pode ser invocado, transmitido etc., independentemente de outros componentes na cadeia.
1from langchain_openai import ChatOpenAI
2from langchain_core.prompts import ChatPromptTemplate
3from langchain_core.runnables import RunnablePassthrough
4from langchain_core.output_parsers import StrOutputParser
5
6# Generate context using the retriever, and pass the user question through
7retrieve = {"context": retriever | (lambda docs: "\n\n".join([d.page_content for d in docs])), "question": RunnablePassthrough()}
8template = """Answer the question based only on the following context: \
9{context}
10
11Question: {question}
12"""
13# Defining the chat prompt
14prompt = ChatPromptTemplate.from_template(template)
15# Defining the model to be used for chat completion
16model = ChatOpenAI(temperature=0, openai_api_key=OPENAI_API_KEY)
17# Parse output as a string
18parse_output = StrOutputParser()
19
20# Naive RAG chain
21naive_rag_chain = (
22 retrieve
23 | prompt
24 | model
25 | parse_output
26)
O trecho de código acima faz o seguinte:
  • Define o componente retrieve : ele recebe a entrada do usuário (uma pergunta) e a envia para retriever para obter documentos semelhantes. Ele também formata a saída para corresponder ao formato de entrada esperado pelo próximo Runnable, que, nesse caso, é um dicionário com context e question como chaves. A chamada RunnablePassthrough() para a chave question indica que a entrada do usuário é simplesmente passada para o próximo estágio na chave question.
  • Define o componente prompt: cria um prompt preenchendo um modelo de prompt com o context e question do estágioretrieve.
  • Define o componente model: especifica o modelo de chat a ser usado. Usamos o OpenAI — a menos que especificado de outra forma, o modelo gpt-3.5-turbo é usado por padrão.
  • Define o componente parse_output: um analisador de saída simples analisa o resultado do LLM em uma string.
  • Define um naive_rag_chain: usa a notação de pipe ( | ) do LCEL para encadear os componentes acima.
Vamos testar nossa cadeia fazendo uma pergunta. Fazemos isso usando o método `invoke()`, que é usado para chamar uma cadeia em uma entrada:
1naive_rag_chain.invoke("What is the best movie to watch when sad?")
2Output: Once a Thief
OBSERVAÇÃO: com cadeias complexas, pode ser difícil saber se as informações estão fluindo por elas como esperado ou não. Recomendamos usar o LangSmith para depuração e monitoramento nesses casos. Basta pegar uma chave de API e adicionar as seguintes linhas ao seu código para ver os rastreamentos na IU do LangSmith:
1 export LANGCHAIN_TRACING_V2=true
2 export LANGCHAIN_API_KEY=<your-api-key>

Etapa 5: crie uma cadeia RAG com histórico de chat

Agora que vimos como criar uma cadeia RAG simples, vejamos como adicionar um histórico de mensagens de chat a ela e persisti-la no MongoDB. O fluxo de trabalho para essa cadeia é mais ou menos assim:
insira a descrição da imagem aqui
A pergunta do usuário e o histórico de mensagens de bate-papo (se disponível) são usados primeiro para criar uma pergunta independente para recuperar documentos do armazenamento de vetores. A pergunta do usuário, juntamente com os documentos recuperados e o histórico de chat, são então passados como entradas para um LLM para gerar uma resposta.
Vamos primeiro definir uma função para obter o histórico de mensagens de chat de uma sessão específica do MongoDB:
1from langchain_mongodb.chat_message_histories import MongoDBChatMessageHistory
2from langchain_core.runnables.history import RunnableWithMessageHistory
3from langchain_core.prompts import MessagesPlaceholder
4
5def get_session_history(session_id: str) -> MongoDBChatMessageHistory:
6 return MongoDBChatMessageHistory(MONGODB_URI, session_id, database_name=DB_NAME, collection_name="history")
A função get_session_history recebe um session_id e retorna uma instância de MongoDBChatMessageHistory, que contém o histórico de bate-papo dessa sessão, recuperado da coleção history do banco de dados langchain_chatbot definido anteriormente.
Em seguida, vamos definir um Runnable question_chain, que usa o histórico de mensagens de chat e uma pergunta de acompanhamento como entrada e cria uma pergunta autônoma que pode ser passada como entrada para o recuperador.
1standalone_system_prompt = """
2Given a chat history and a follow-up question, rephrase the follow-up question to be a standalone question. \
3Do NOT answer the question, just reformulate it if needed, otherwise return it as is. \
4Only return the final standalone question. \
5"""
6standalone_question_prompt = ChatPromptTemplate.from_messages(
7 [
8 ("system", standalone_system_prompt),
9 MessagesPlaceholder(variable_name="history"),
10 ("human", "{question}"),
11 ]
12)
13
14question_chain = standalone_question_prompt | model | parse_output
A cadeia do recuperador aqui parece um pouco diferente da Etapa 5:
1retriever_chain = RunnablePassthrough.assign(context=question_chain | retriever | (lambda docs: "\n\n".join([d.page_content for d in docs])))
Observe que a cadeia do recuperador aqui usa RunnablePassthrough.assign(...). Isso adiciona os argumentos adicionais passados para a função de atribuição à entrada do usuário antes de passá-la para o próximo componente. Este exemplo adicionará o context obtido do recuperador à entrada do usuário antes de passá-lo para o prompt.
O prompt, nesse caso, consiste na pergunta do usuário, no contexto recuperado e no histórico de chat da sessão:
1rag_system_prompt = """Answer the question based only on the following context: \
2{context}
3"""
4rag_prompt = ChatPromptTemplate.from_messages(
5 [
6 ("system", rag_system_prompt),
7 MessagesPlaceholder(variable_name="history"),
8 ("human", "{question}"),
9 ]
10)
Por fim, criamos um RAG e o envolvemos em RunnableWithMessageHistory, que é um executável que gerencia o histórico de mensagens de chat para outro executável, incluindo atualizações.
1# RAG chain
2rag_chain = (
3 retriever_chain
4 | rag_prompt
5 | model
6 | parse_output
7)
8
9# RAG chain with history
10with_message_history = RunnableWithMessageHistory(
11 rag_chain,
12 get_session_history,
13 input_messages_key="question",
14 history_messages_key="history",
15)
Os parâmetros para o executável RunnableWithMessageHistory acima são os seguintes:
  • rag_chain: base executável para encapsular
  • get_session_history: a função para obter o histórico de mensagens do chat 
  • input_messages_key: Chave para mensagens de entrada se a base executável aceitar um dicionário
  • history_messages_key: chave para mensagens históricas se o executável base espera um histórico de mensagens
Vamos testar nossa cadeia RAG com histórico fazendo uma pergunta:
1with_message_history.invoke({"question": "What is the best movie to watch when sad?"}, {"configurable": {"session_id": "1"}})
2
3Output: The best movie to watch when feeling down could be "Last Action Hero." It\'s a fun and action-packed film that blends reality and fantasy, offering an escape from the real world and providing an entertaining distraction.
4
5with_message_history.invoke({"question": "How about something more light?"}, {"configurable": {"session_id": "1"}})
6
7Output: For a lighter movie option, you might enjoy "Cousins." It\'s a comedy film set in Barcelona with action and humor, offering a fun and entertaining escape from reality. The storyline is engaging and filled with comedic moments that could help lift your spirits.
Observe os argumentos passados para as chamadas invoke acima. O primeiro argumento é um dicionário com uma chave question que contém a entrada do usuário. Essa chave deve corresponder ao valor do argumento input_messages_key passado para o executável RunnableWithMessageHistory. O segundo argumento é usado para criar um novo histórico de mensagens de chat ou pesquisar um existente que corresponda ao session_id especificado.

Etapa 6: obtenha respostas mais rápidas usando cache semântico

Cadeia RAG com integração de cache semântico
Adicionar um cache semântico ao aplicativo RAG atual é fácil com a integração Langchain-MongoDB. Esta seção aborda o processo de adição de cache semântico ao aplicativo RAG, reduzindo efetivamente os custos operacionais ao armazenar os resultados das perguntas dos usuários e as próprias perguntas.
Isso permite que o aplicativo faça referência aos resultados quando o usuário fizer uma pergunta semanticamente semelhante no futuro, reduzindo assim o número de chamadas de API feitas ao provedor de LLM. A vantagem do cache semântico é que ele reduz a latência e o custo do aplicativo RAG geral.
1from langchain_mongodb.cache import MongoDBAtlasSemanticCache
2from langchain_core.globals import set_llm_cache
3
4set_llm_cache(MongoDBAtlasSemanticCache(
5 connection_string=MONGODB_URI,
6 embedding=embeddings,
7 collection_name="semantic_cache",
8 database_name=DB_NAME,
9 index_name=ATLAS_VECTOR_SEARCH_INDEX_NAME,
10 wait_until_ready=True # Optional, waits until the cache is ready to be used
11))
No código acima, as seguintes operações são executadas:
  • Importe o módulo MongoDBAtlasSemanticCache, que fornece a interface de conexão com o MongoDB e a criação do armazenamento em cache semântico. O MongoDBAtlasSemanticCache fornece métodos para inicializar o cache, procurar respostas em cache com base em prompts de query e strings de LLM, atualizar o cache com novas respostas e limpar entradas em cache totalmente ou com base em critérios específicos. 
  • Importe o módulo set_llm_cache, que define o cache do LLM para o ambiente atual do aplicativo. 
  • Configure o cache semântico passando uma instância do MongoDBAtlasSemanticCache com o argumento apropriado como um parâmetro para a função set_llm_cache.
Com o cache semântico agora configurado para nosso aplicativo RAG, é possível monitorar os tempos de execução da query. Essa observação destaca os ganhos de eficiência e benefícios gerados pela implementação do cache semântico.
1%%time
2naive_rag_chain.invoke("What is the best movie to watch when sad?")
O código acima invoca a RAG com a query, "What is the best movie to watch when sad?" O comando %%time permite que a medição da duração de uma operação específica seja computada em um bloco de anotações Jupyter ou em um ambiente IPython.
Como mostrado acima, a primeira invocação da cadeia com a query é executada em 1,24 segundos. O bloco de resposta abaixo mostra isso.
1CPU times: user 87.8 ms, sys: 670 µs, total: 88.5 ms
2Wall time: 1.24 s
3'Once a Thief'
A cadeia RAG invocada com a query deve mostrar um tempo de resposta reduzido para garantir que o cache semântico esteja funcionando conforme o esperado.
1%%time
2naive_rag_chain.invoke("Which movie do I watch when sad?")
A saída abaixo mostra que a mesma query tem um tempo de resposta significativamente reduzido.
1CPU times: user 43.5 ms, sys: 4.16 ms, total: 47.7 ms
2Wall time: 255 ms
3'Once a Thief'
OBSERVAÇÃO: o cache semântico armazena em cache apenas a entrada para o LLM. Ao usá-lo em cadeias de recuperação, lembre-se de que os documento recuperados podem mudar entre as execuções, resultando em perda de cache para queries semanticamente semelhantes.

Conclusão

Foi demonstrado que o padrão de projeto de arquitetura RAG em IA generativa e aplicativos modernos oferece alguns benefícios ao fazer com que os aplicativos RAG forneçam respostas mais relevantes e atualizadas às queries dos usuários.
No entanto, um aplicativo moderno e robusto requer mais do que apenas uma implementação de RAG naive. Para melhorar a interação dos aplicativos com os usuários, fatores como personalização, histórico e tempos de resposta eficientes são considerações que os engenheiros e construtores de IA devem considerar já na fase de POC ou demonstração de desenvolvimento.
Este tutorial demonstra como é simples integrar cache semântico e memória aos aplicativos RAG quando facilitados pelo MongoDB e LangChain. Instruções passo a passo foram fornecidas para orientar a implementação de um aplicativo RAG; a criação de bancos de dados, coleções e índices; e a utilização do LangChain para desenvolver uma cadeia e um aplicativo RAG.
Seguindo as etapas descritas neste tutorial, os desenvolvedores podem aproveitar os recursos do Atlas Vector Search e a integração perfeita entre Langchain e MongoDB para criar aplicativos RAG mais responsivos, eficientes e inteligentes. A combinação de cache semântico e histórico de conversação reduz os custos operacionais e aumenta significativamente a precisão e a personalização das respostas geradas pelos LLMs.
Todo o código de implementação apresentado no tutorial pode ser acessado no repositório.

Perguntas frequentes

1. O que é geração aumentada de recuperação (RAG)? RAG é um padrão de design em aplicativos de IA que aprimora os recursos dos grandes modelos de linguagem (LLMs), fundamentando suas respostas com informações relevantes, factuais e atualizadas. Isso é feito complementando o conhecimento paramétrico dos LLMs com conhecimento não paramétrico, permitindo a geração de respostas mais precisas e contextualmente relevantes.
2. Como a integração da memória e do histórico de chat aprimora os aplicativos RAG? A integração da memória e do histórico de chat aos aplicativos RAG permite a retenção e a recuperação de interações anteriores entre os grandes modelos de linguagem (LLM) e os usuários. Essa funcionalidade aprimora a conscientização de contexto do modelo, permitindo que ele gere respostas relevantes para a query imediata e reflitam a continuação e as nuances das conversas em andamento. Ao manter um histórico de interação coerente e contextualmente relevante, os aplicativos RAG podem oferecer respostas mais personalizadas e precisas, melhorando significativamente a experiência do usuário e a eficácia geral do aplicativo.
3. Por que o cache semântico é importante nos aplicativos RAG? O cache semântico armazena os resultados das queries do usuário e suas respostas associadas com base na semântica da query. Essa abordagem permite a recuperação eficiente de informações quando queries semanticamente semelhantes forem feitas no futuro, reduzindo as chamadas de API para provedores de LLM e diminuindo a latência e os custos operacionais.
4. De que forma o MongoDB Atlas é compatível com aplicativos RAG? O MongoDB Atlas oferece recursos de pesquisa vetorial, facilitando a implementação de caches semânticos e armazenamentos de conversas em aplicativos RAG. Essa integração facilita a recuperação eficiente de queries semanticamente semelhantes e o armazenamento de históricos de interação, melhorando o desempenho geral do aplicativo e a experiência do usuário.
5. Como o cache semântico pode reduzir o tempo de execução de query em aplicativos RAG? Os aplicativos RAG podem recuperar rapidamente respostas em cache para queries semanticamente semelhantes sem recalculá-las, armazenando em cache respostas a queries com base em seu conteúdo semântico. Isso reduz significativamente o tempo para gerar respostas, conforme demonstrado pelos tempos de execução de query reduzidos em queries semelhantes subsequentes.
6. Quais benefícios a integração LangChain-MongoDB oferece? Essa integração simplifica o processo de adicionar recursos de cache e memória semântica aos aplicativos RAG. Ela permite o gerenciamento eficiente de históricos de conversas e a implementação de caches semânticos usando os poderosos recursos de pesquisa vetorial do MongoDB, levando ao melhor desempenho do aplicativo e à experiência do usuário.
7. Como se mede o impacto do cache semântico em um aplicativo RAG? Ao monitorar os tempos de execução da query antes e depois da implementação do cache semântico, os desenvolvedores podem observar os ganhos de eficiência que o cache oferece. Uma redução notável nos tempos de execução para queries semanticamente semelhantes indica a eficácia do cache em melhorar as velocidades de resposta e reduzir os custos operacionais.
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.
Iniciar a conversa

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Tutorial

Pesquisa semântica com Jina Embeddings v2 e MongoDB Atlas


Dec 05, 2023 | 12 min read
Artigo

Audio Find - Atlas Vector Search para áudio


Sep 09, 2024 | 11 min read
exemplo de código

Trends Analyser


Sep 11, 2024 | 1 min read
Tutorial

Resposta de LLMs em cache com MongoDB Atlas e Vector Atlas Search


Sep 02, 2024 | 8 min read
Sumário