Para agentes de IA: um índice de documentação está disponível em https://www.mongodb.com/pt-br/docs/llms.txt — as versões de marcação de todas as páginas estão disponíveis anexando .md a qualquer caminho de URL .
Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
MongoDB Branding Shape
Click here >
Menu Docs

Construa um agente de IA com LangGraph e MongoDB Atlas

Você pode integrar o MongoDB Atlas ao LangGraph para criar agentes de IA. Este tutorial demonstra como criar um agente de IA que responde a perguntas sobre dados de amostra no MongoDB.

Especificamente, o agente usa a integração para implementar o RAG agente e a memória do agente. Ela usa ferramentas de pesquisa semântica e pesquisa de texto completo para recuperar informações relevantes e responder a perguntas sobre os dados. Ele também implementa memória de curto e longo prazo usando o MongoDB , armazenando o histórico de conversas e interações importantes em coleções separadas.

O código nesta página cria um aplicação de exemplo completo . Você também pode trabalhar no código como um bloco de anotações do Python se preferir aprender passo a passo.

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

  • Um dos seguintes tipos de cluster MongoDB :

  • Uma chave de API do Voyage AI. Para aprender mais, consulte Chave de API e cliente Python.

  • 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.

Observação

Verifique os requisitos do pacote langchain-voyageai para garantir que você esteja usando uma versão compatível do Python.

Para configurar o ambiente, conclua as seguintes etapas:

1

Crie um novo diretório de projeto e, em seguida, instale as dependências necessárias:

mkdir langgraph-mongodb-ai-agent
cd langgraph-mongodb-ai-agent
pip install --quiet --upgrade python-dotenv langgraph "langgraph-checkpoint-mongodb>=0.4.0" "langgraph-store-mongodb>=0.3.0" langchain langchain-mongodb langchain-voyageai langchain-openai pymongo

Observação

Seu projeto usará a seguinte estrutura:

langgraph-mongodb-ai-agent
├── .env
├── config.py
├── search-tools.py
├── memory-tools.py
├── agent.py
├── main.py
2

Crie um arquivo .env no seu projeto e especifique as seguintes variáveis. Substitua os valores de espaço reservado por chaves de API válidas e pela string de conexão do cluster MongoDB .

VOYAGE_API_KEY = "<voyage-api-key>"
OPENAI_API_KEY = "<openai-api-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-se a um cluster por meio de bibliotecas de clientes.

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

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

Para saber mais, consulte Connection strings.

Para configurar o MongoDB como um banco de dados vetorial para armazenamento e recuperação, complete as seguintes etapas:

1

Para este tutorial, utilize um dos nossos conjuntos de dados de amostra como fonte de dados. Caso ainda não tenha feito isso, complete as etapas para carregar dados de amostra em seu Atlas cluster.

Especificamente, você usará o conjunto de dados embedded_movies, que contém documentos sobre filmes, incluindo as incorporações vetoriais de seus enredos.

Observação

Se você quiser utilizar seus próprios dados, consulte Introdução ao langchain ou Como criar vector embeddings manualmente para saber como processar vector embeddings no Atlas.

2

Crie um arquivo denominado config.py em seu projeto. Este arquivo configura o MongoDB como o armazenamento de vetores para seu agente. Ele também cria os índices para habilitar a pesquisa vetorial e a pesquisa de texto completo nos dados de amostra.

Copie e cole o seguinte código no seu arquivo config.py.

import os
from pymongo import MongoClient
from langchain_mongodb import MongoDBAtlasVectorSearch
from langchain_mongodb.index import create_fulltext_search_index
from langchain_voyageai import VoyageAIEmbeddings
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Get required environment variables
MONGODB_URI = os.getenv("MONGODB_URI")
if not MONGODB_URI:
raise ValueError("MONGODB_URI environment variable is required")
# Initialize models
embedding_model = VoyageAIEmbeddings(
model="voyage-3-large",
output_dimension=2048
)
llm = ChatOpenAI("gpt-4o")
# MongoDB setup
mongo_client = MongoClient(MONGODB_URI)
collection = mongo_client["sample_mflix"]["embedded_movies"]
# LangChain vector store setup
vector_store = MongoDBAtlasVectorSearch.from_connection_string(
connection_string=MONGODB_URI,
namespace="sample_mflix.embedded_movies",
embedding=embedding_model,
text_key="plot",
embedding_key="plot_embedding_voyage_3_large",
relevance_score_fn="dotProduct",
)
# Create indexes on startup
print("Setting up vector store and indexes...")
try:
existing_indexes = list(collection.list_search_indexes())
vector_index_exists = any(idx.get('name') == 'vector_index' for idx in existing_indexes)
if vector_index_exists:
print("Vector search index already exists, skipping creation...")
else:
print("Creating vector search index...")
vector_store.create_vector_search_index(
dimensions=2048, # The dimensions of the vector embeddings to be indexed
wait_until_complete=60 # Number of seconds to wait for the index to build (can take around a minute)
)
print("Vector search index created successfully!")
except Exception as e:
print(f"Error creating vector search index: {e}")
try:
fulltext_index_exists = any(idx.get('name') == 'search_index' for idx in existing_indexes)
if fulltext_index_exists:
print("Search index already exists, skipping creation...")
else:
print("Creating search index...")
create_fulltext_search_index(
collection=collection,
field="title",
index_name="search_index",
wait_until_complete=60 # Number of seconds to wait for the index to build (can take around a minute)
)
print("Search index created successfully!")
except Exception as e:
print(f"Error creating search index: {e}")

Crie um arquivo search_tools.py em seu projeto. Neste arquivo, você define as ferramentas de pesquisa que o agente usa para executar o RAG agente.

Copie e cole o seguinte código no seu arquivo search_tools.py.

  • plot_search: Esta ferramenta utiliza o objeto de armazenamento de vetor como um recuperador. Nos mínimos detalhes, o recuperador executa uma query do MongoDB Vector Search para recuperar documentos semanticamente semelhantes. Em seguida, a ferramenta retorna os títulos e gráficos dos documentos de filme recuperados.

  • title_search: essa ferramenta usa o recuperador de pesquisa de texto completo para recuperar documentos de filme que correspondam ao título de filme especificado. Em seguida, a ferramenta retorna o gráfico do filme especificado.

from langchain.agents import tool
from langchain_mongodb.retrievers.full_text_search import MongoDBAtlasFullTextSearchRetriever
from config import vector_store, collection
@tool
def plot_search(user_query: str) -> str:
"""
Retrieve information on the movie's plot to answer a user query by using vector search.
"""
retriever = vector_store.as_retriever(
search_type="similarity",
search_kwargs={"k": 5} # Retrieve top 5 most similar documents
)
results = retriever.invoke(user_query)
# Concatenate the results into a string
context = "\n\n".join([f"{doc.metadata['title']}: {doc.page_content}" for doc in results])
return context
@tool
def title_search(user_query: str) -> str:
"""
Retrieve movie plot content based on the provided title by using full-text search.
"""
# Initialize the retriever
retriever = MongoDBAtlasFullTextSearchRetriever(
collection=collection, # MongoDB Collection
search_field="title", # Name of the field to search
search_index_name="search_index", # Name of the MongoDB Search index
top_k=1, # Number of top results to return
)
results = retriever.invoke(user_query)
for doc in results:
if doc:
return doc.metadata["fullplot"]
else:
return "Movie not found"
# List of search tools
SEARCH_TOOLS = [ plot_search, title_search ]

Observação

Você pode definir qualquer ferramenta que precise para executar uma tarefa específica. Você também pode definir ferramentas para outros métodos de recuperação, como pesquisa híbrida ou recuperação de documento pai.

Crie um arquivo memory_tools.py em seu projeto. Nesse arquivo, você define as ferramentas que o agente pode usar para armazenar e recuperar interações importantes entre sessões para implementar a memória de longo prazo.

Copie e cole o seguinte código no seu arquivo memory_tools.py.

  • store_memory: esta ferramenta usa o armazenamento MongoDB MongoDB para armazenar interações importantes em uma coleção MongoDB.

  • retrieve_memory: essa ferramenta usa o armazenamento MongoDB do MongoDB para recuperar interações relevantes com base na query usando a pesquisa semântica.

from langchain.agents import tool
from langgraph.store.mongodb import MongoDBStore, create_vector_index_config
from config import embedding_model, MONGODB_URI
# Vector search index configuration for memory collection
index_config = create_vector_index_config(
embed=embedding_model,
dims=2048,
relevance_score_fn="dotProduct",
fields=["content"]
)
@tool
def save_memory(content: str) -> str:
"""Save important information to memory."""
with MongoDBStore.from_conn_string(
conn_string=MONGODB_URI,
db_name="sample_mflix",
collection_name="memories",
index_config=index_config,
auto_index_timeout=60 # Wait a minute for vector index creation
) as store:
store.put(
namespace=("user", "memories"),
key=f"memory_{hash(content)}",
value={"content": content}
)
return f"Memory saved: {content}"
@tool
def retrieve_memories(query: str) -> str:
"""Retrieve relevant memories based on a query."""
with MongoDBStore.from_conn_string(
conn_string=MONGODB_URI,
db_name="sample_mflix",
collection_name="memories",
index_config=index_config
) as store:
results = store.search(("user", "memories"), query=query, limit=3)
if results:
memories = [result.value["content"] for result in results]
return f"Retrieved memories:\n" + "\n".join(memories)
return "No relevant memories found."
MEMORY_TOOLS = [save_memory, retrieve_memories]

Crie um arquivo agent.py em seu projeto. Neste arquivo, você constrói o grafo que orquestra o fluxo de trabalho do agente. Esse agente usa o componente MongoDB Checkpointer para implementar a memória de curto prazo, permitindo várias conversas simultâneas com históricos separados.

O agente usa o seguinte fluxo de trabalho para responder às queries:

  1. Início: o agente recebe uma query do usuário.

  2. Nó do agente: o LLM vinculado à ferramenta analisa a query e determina se os FERRAMENTAS são necessários.

  3. Nó FERRAMENTAS (se necessário): Executa a pesquisa ou memória FERRAMENTAS apropriada.

  4. End: o LLM gera uma resposta final usando a saída do FERRAMENTAS.

Diagrama que mostra o fluxo de trabalho do agente LangGraph-MongoDB.
clique para ampliar

Copie e cole o código a seguir no arquivo .py do agente.

A implementação do agente consiste em vários componentes:

  • LangGraphAgent: classe de agente principal que orquestra o fluxo de trabalho

  • build_graph: Constrói o fluxo de trabalho do LangGraph e configura o checkpointer MongoDBSaver para a persistência da memória de curto prazo

  • agent_node: Principal tomador de decisões que processa mensagens e determina o uso da ferramenta

  • tools_node: Executa FERRAMENTAS solicitados e retorna resultados

  • route_tools: Função de roteamento condicional que determina a direção do fluxo de trabalho

  • execute: ponto de entrada principal que aceita um parâmetro thread_id para rastreamento de thread de conversa

from typing import Annotated, Dict, List
from typing_extensions import TypedDict
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import ToolMessage
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langgraph.checkpoint.mongodb import MongoDBSaver
from config import llm, mongo_client
from search_tools import SEARCH_TOOLS
from memory_tools import MEMORY_TOOLS
# Define the graph state
class GraphState(TypedDict):
messages: Annotated[list, add_messages]
# Define the LangGraph agent
class LangGraphAgent:
def __init__(self):
# Combine search tools with memory tools
self.tools = SEARCH_TOOLS + MEMORY_TOOLS
self.tools_by_name = {tool.name: tool for tool in self.tools}
# Create prompt template
self.prompt = ChatPromptTemplate.from_messages([
(
"system",
"You are a helpful AI chatbot."
" You are provided with tools to answer questions about movies."
" Think step-by-step and use these tools to get the information required to answer the user query."
" Do not re-run tools unless absolutely necessary."
" If you are not able to get enough information using the tools, reply with I DON'T KNOW."
" You have access to the following tools: {tool_names}."
),
MessagesPlaceholder(variable_name="messages"),
])
# Provide the tool names to the prompt
self.prompt = self.prompt.partial(tool_names=", ".join([tool.name for tool in self.tools]))
# Prepare the LLM with tools
bind_tools = llm.bind_tools(self.tools)
self.llm_with_tools = self.prompt | bind_tools
# Build the graph
self.app = self._build_graph()
def _build_graph(self):
"""Build and compile the LangGraph workflow."""
# Instantiate the graph
graph = StateGraph(GraphState)
# Add nodes
graph.add_node("agent", self._agent_node)
graph.add_node("tools", self._tools_node)
# Add edges
graph.add_edge(START, "agent")
graph.add_edge("tools", "agent")
# Add conditional edge
graph.add_conditional_edges(
"agent",
self._route_tools,
{"tools": "tools", END: END},
)
# Use the MongoDB checkpointer for short-term memory
checkpointer = MongoDBSaver(mongo_client, db_name = "sample_mflix")
return graph.compile(checkpointer=checkpointer)
def _agent_node(self, state: GraphState) -> Dict[str, List]:
"""Agent node that processes messages and decides on tool usage."""
messages = state["messages"]
result = self.llm_with_tools.invoke(messages)
return {"messages": [result]}
def _tools_node(self, state: GraphState) -> Dict[str, List]:
"""Tools node that executes the requested tools."""
result = []
messages = state["messages"]
if not messages:
return {"messages": result}
last_message = messages[-1]
if not hasattr(last_message, "tool_calls") or not last_message.tool_calls:
return {"messages": result}
tool_calls = last_message.tool_calls
# Show which tools the agent chose to use
tool_names = [tool_call["name"] for tool_call in tool_calls]
print(f"🔧 Agent chose to use tool(s): {', '.join(tool_names)}")
for tool_call in tool_calls:
try:
tool_name = tool_call["name"]
tool_args = tool_call["args"]
tool_id = tool_call["id"]
print(f" → Executing {tool_name}")
if tool_name not in self.tools_by_name:
result.append(ToolMessage(content=f"Tool '{tool_name}' not found", tool_call_id=tool_id))
continue
tool = self.tools_by_name[tool_name]
observation = tool.invoke(tool_args)
result.append(ToolMessage(content=str(observation), tool_call_id=tool_id))
except Exception as e:
result.append(ToolMessage(content=f"Tool error: {str(e)}", tool_call_id=tool_id))
return {"messages": result}
def _route_tools(self, state: GraphState):
"""
Uses a conditional_edge to route to the tools node if the last message
has tool calls. Otherwise, route to the end.
"""
messages = state.get("messages", [])
if len(messages) > 0:
ai_message = messages[-1]
else:
raise ValueError(f"No messages found in input state to tool_edge: {state}")
if hasattr(ai_message, "tool_calls") and len(ai_message.tool_calls) > 0:
return "tools"
return END
def execute(self, user_input: str, thread_id: str) -> str:
"""Execute the graph with user input."""
input_data = {"messages": [("user", user_input)]}
config = {"configurable": {"thread_id": thread_id}}
outputs = list(self.app.stream(input_data, config))
# Get the final answer
if outputs:
final_output = outputs[-1]
for _, value in final_output.items():
if "messages" in value and value["messages"]:
return value["messages"][-1].content
return "No response generated."

Expanda esta seção para obter detalhes sobre os componentes LangGraph usados no agente.

Este gráfico inclui os seguintes componentes principais:

  • Estado do Gráfico: mantém dados compartilhados em todo o fluxo de trabalho, rastreando as mensagens do agente, incluindo queries de usuários, respostas LLM e resultados de chamadas de ferramentas.

  • Nodes:

    • Nó do agente: processa mensagens, invoca o LLM e atualiza o estado com respostas LLM

    • Nó FERRAMENTAS: processa chamadas de ferramentas e atualiza o histórico de conversas com resultados

  • Edges, que conectam nós:

    • Limites normais: Rota do início ao nó do agente e do agente para o nó FERRAMENTAS

    • Edge condicional: Roteamentos condicionalmente dependendo da necessidade de FERRAMENTAS

  • Persistência: usa o checkpointer MongoDBSaver para salvar o estado da conversa em threads específicos, ativando a memória de curto prazo entre sessões. Você pode encontrar os dados do thread nas coleções checkpoints e checkpoint_writes.

Dica

Para saber mais sobre persistência, memória de curto prazo e o checkpointer do MongoDB , consulte os seguintes recursos:

Por fim, crie um arquivo chamado main.py em seu projeto. Esse arquivo executa o agente e permite a interação com ele.

Copie e cole o seguinte código no seu arquivo principal.py.

from agent import LangGraphAgent
from config import mongo_client
def main():
"""LangGraph and MongoDB agent with tools and memory."""
# Initialize agent (indexes are created during config import)
agent = LangGraphAgent()
thread_id = input("Enter a session ID: ").strip()
print("Ask me about movies! Type 'quit' to exit.")
try:
while True:
user_query = input("\nYour question: ").strip()
if user_query.lower() == 'quit':
break
# Get response from agent
answer = agent.execute(user_query, thread_id)
print(f"\nAnswer: {answer}")
finally:
mongo_client.close()
if __name__ == "__main__":
main()

Salve seu projeto e execute o seguinte comando. Quando você executar o agente:

  • O agente inicializa o armazenamento de vetor e cria os índices se eles ainda não existirem.

  • Você pode inserir uma ID de sessão para iniciar uma nova sessão ou continuar uma sessão existente. Cada sessão é persistente e você sempre pode retomar uma conversa anterior.

  • Faça perguntas sobre filmes. O agente gera uma resposta com base em suas FERRAMENTAS e interações anteriores.

A seguinte saída demonstra uma interação de amostra:

python main.py
Creating vector search index...
Vector search index created successfully!
Creating search index...
Search index created successfully!
Enter a session ID: 123
Ask me about movies! Type 'quit' to exit.
Your query: What are some movies that take place in the ocean?
🔧 Agent chose to use tool(s): plot_search
→ Executing plot_search
Answer: Here are some movies that take place in the ocean:
1. **20,000 Leagues Under the Sea** - A marine biologist, his daughter, and a mysterious Captain Nemo explore the ocean aboard an incredible submarine.
2. **Deep Rising** - A group of armed hijackers board a luxury ocean liner in the South Pacific Ocean, only to fight man-eating, tentacled sea creatures.
... (truncated)
Your query: What is the plot of the Titanic?
🔧 Agent chose to use tool(s): title_search
→ Executing title_search
Answer: The plot of *Titanic* involves the romantic entanglements of two couples aboard the doomed ship's maiden voyage
... (truncated)
Your query: What movies are like the movie I just mentioned?
🔧 Agent chose to use tool(s): plot_search
→ Executing plot_search
Answer: Here are some movies similar to *Titanic*:
1. **The Poseidon Adventure** - A group of passengers struggles to survive when their ocean liner capsizes at sea.
2. **Pearl Harbor** - Focused on romance and friendship amidst the backdrop of a historical tragedy, following two best friends and their love lives during wartime.
... (truncated)
Your query: I don't like sad movies.
🔧 Agent chose to use tool(s): save_memory
→ Executing save_memory
Answer: Got it—I'll keep that in mind. Let me know if you'd like recommendations that focus more on uplifting or happy themes!
(In different session)
Enter a session ID: 456
Your query: Recommend me a movie based on what you know about me.
🔧 Agent chose to use tool(s): retrieve_memories
→ Executing retrieve_memories
Answer: Based on what I know about you—you don't like sad movies—I'd recommend a fun, uplifting, or action-packed film. Would you be interested in a comedy, adventure, or family-friendly movie?
Your query: Sure!
🔧 Agent chose to use tool(s): plot_search, plot_search, plot_search
→ Executing plot_search
→ Executing plot_search
→ Executing plot_search
Answer: Here are some movie recommendations from various uplifting genres that suit your preferences:
### Comedy:
1. **Showtime** (2002): A spoof of buddy cop movies where two very different cops are forced to team up on a new reality-based TV cop show. It's packed with laughs and action!
2. **The Big Bus** (1976): A hilarious disaster film parody featuring a nuclear-powered bus going nonstop from New York to Denver, plagued by absurd disasters.
### Adventure:
1. **Journey to the Center of the Earth** (2008): A scientist, his nephew, and their mountain guide discover a fantastic and dangerous lost world at the earth's core.
2. **Jason and the Argonauts** (1963): One of the most legendary adventures in mythology, brought to life in this epic saga of good versus evil.
### Family-Friendly:
1. **The Incredibles** (2004): A family of undercover superheroes is forced into action to save the world while living in quiet suburban life.
2. **Mary Poppins** (1964): A magical nanny brings joy and transformation to a cold banker's unhappy family.
3. **Chitty Chitty Bang Bang** (1968): A whimsical adventure featuring an inventor, his magical car, and a rescue mission filled with fantasy.