Neste tutorial, você usa o crewai-mongodb-memory pacote para fornecer a um agente CrewAI uma memória de longo prazo durável que persiste no MongoDB Atlas. O agente armazena as preferências do usuário como registros de memória e as recupera semanticamente com o MongoDB Vector Search, para que uma equipe totalmente nova em uma sessão posterior possa responder corretamente recuperando aprendizados de uma sessão anterior.
Para saber mais sobre a integração do MongoDB CrewAI, consulte Integrar MongoDB com CrewAI.
Pré-requisitos
Para concluir este tutorial, você deve ter o seguinte:
Python 3.10 ou posterior.
Um dos seguintes tipos de cluster MongoDB :
Um cluster do Atlas executando a versão 6.0.11 do MongoDB, 7.0.2, ou posterior. Certifique-se de que seu endereço IP esteja incluído na lista de acesso do seu projeto Atlas.
Um sistema local do Atlas criado usando Python e Docker. Instale
atlas-local-lib-pyopip install atlas-local-lib-py() para criar e gerenciar implantações locais programaticamente. Para saber mais, consulte o repositório atlas-local-lib-py .Um cluster da MongoDB Community com o Search e o Vector Search instalados.
Uma chave de API do Voyage AI. Para criar uma chave de API, consulte Gerenciar chaves de API do modelo Voyage AI.
Uma chave de API de grandes modelos de linguagem (LLM), como Anthropic ou OpenAI, para alimentar a inferência do agente.
Como a memória do agente funciona com o MongoDB
O backend crewai-mongodb-memory implementa o protocolo StorageBackend do CrewAI. Ele armazena cada memória como um registro em uma coleção do MongoDB e usa a pesquisa vetorial do MongoDB para recuperar registros relevantes semanticamente. O backend usa os seguintes componentes:
MongoDBStorageBackend: Conecta-se ao seu cluster Atlas, armazena registros de memória e executa querys$vectorSearchpara recuperá-los.MemoryRecord: Representa uma única memória, incluindo seu conteúdo de texto, um escopo hierárquico como/users/alex/preferences, categorias opcionais e seu embedding de vetor.embed_text(): Gera embedding de 1024dimensões com o modelo Voyage AIvoyage-4para documentos armazenados e query.
Como a memória reside no Atlas em vez do contexto em processo da equipe, qualquer equipe que se conecte ao mesmo cluster e escopo pode recuperar as memórias armazenadas.
{ "_id": "cff7db8d-aa2e-4d82-8234-e4b8f1ccccb6", "content": "The user always prefers window seats on flights.", "scope": "/users/alex/preferences", "categories": [ "preference" ], "metadata": {}, "importance": 0.5, "created_at": { "$date": "2026-07-14T22:06:59.162Z" }, "last_accessed": { "$date": "2026-07-14T22:06:59.162Z" }, "source": null, "private": false, "embedding": [ 0.03147803992033005, 0.015906454995274544, -0.007409059442579746, 0.028631621971726418, ... ], "scope_ancestors": [ "/users", "/users/alex", "/users/alex/preferences" ] }
Criar e executar o agente
Conclua as seguintes etapas para criar e executar um agente que armazena e recupera as preferências do usuário:
Configure o ambiente.
Execute os seguintes comandos no seu terminal para criar um novo diretório denominado
crewai-memory-projecte instalar as dependências necessárias:mkdir crewai-memory-project cd crewai-memory-project pip install crewai-mongodb-memory crewai "crewai[google-genai]" voyageai python-dotenv No seu projeto, crie um arquivo
.enve adicione as seguintes linhas:ATLAS_URI="<connection-string>" VOYAGE_API_KEY="<voyage-api-key>" ANTHROPIC_API_KEY="<anthropic-api-key>" MODEL="<anthropic-model>" 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.
Criar o agente.
Crie um arquivo chamado main.py em seu projeto e cole o seguinte código:
from __future__ import annotations import os import sys import time import warnings from dotenv import load_dotenv load_dotenv() warnings.filterwarnings("ignore") from crewai import Agent, Crew, Task from crewai.tools import tool from crewai_mongodb_memory import MemoryRecord, MongoDBStorageBackend, embed_text from crewai.events import CrewKickoffStartedEvent, CrewKickoffCompletedEvent, AgentExecutionCompletedEvent from crewai.events import BaseEventListener DEMO_DB = "crewai_mem_agent_demo" SCOPE = "/users/alex/preferences" MODEL = os.environ.get("ANTHROPIC_MODEL", "anthropic/claude-3-5-sonnet-latest") EMBEDDING_MODEL = os.environ.get("VOYAGE_MODEL", "voyage-4") # Module-level backend handle so the function tools can reach it. _BACKEND: MongoDBStorageBackend | None = None _SESSION_LABEL = "" # Custom event listener for logging Crew and Agent events. class EventListener(BaseEventListener): def __init__(self): super().__init__() def setup_listeners(self, crewai_event_bus): def on_crew_started(source, event): print(f"Crew '{event.crew_name}' has started execution!") def on_crew_completed(source, event): print(f"Crew '{event.crew_name}' has completed execution!") print(f"Output: {event.output}") def on_agent_execution_completed(source, event): print(f"Agent '{event.agent.role}' completed task") print(f"Output: {event.output}") def banner(title: str) -> None: print(f"\n{'=' * 70}\n{title}\n{'=' * 70}") def embed(text: str, input_type: str) -> list[float]: """Generate embeddings with an explicit Voyage model.""" try: return embed_text(text, input_type=input_type, model=EMBEDDING_MODEL) except TypeError: # Backward compatibility for older crewai-mongodb-memory versions. return embed_text(text, input_type=input_type) def remember_preference(fact: str) -> str: """Store a durable user preference in MongoDB Atlas long-term memory.""" assert _BACKEND is not None rec = MemoryRecord( content=fact, scope=SCOPE, categories=["preference"], embedding=embed(fact, input_type="document"), ) _BACKEND.save([rec]) return f"Stored preference: {fact}" def recall_preferences(query: str) -> str: """Retrieve relevant user preferences from Atlas via $vectorSearch.""" assert _BACKEND is not None qv = embed(query, input_type="query") hits = _BACKEND.search(qv, scope_prefix=SCOPE, limit=3) if not hits: return "No relevant preferences found." for rec, score in hits: print(f" - [{score:.3f}] {rec.content}") return "\n".join(f"- {rec.content} (score={score:.3f})" for rec, score in hits) def build_agent() -> Agent: return Agent( role="Personal Concierge", goal="Help the user with durable long-term memory stored in MongoDB Atlas.", backstory=( """You remember user preferences across sessions. When the user shares a durable preference, call remember_preference. When a request may depend on what you know about them, call recall_preferences first and use the results.""" ), tools=[remember_preference, recall_preferences], llm=MODEL, verbose=True, ) def run_task(description: str, expected_output: str) -> str: """Run a single-task crew (a fresh crew each call is a fresh session).""" agent = build_agent() task = Task(description=description, expected_output=expected_output, agent=agent) crew = Crew(agent, [task]) return str(crew.kickoff()) def main() -> None: global _BACKEND, _SESSION_LABEL uri = os.environ.get("ATLAS_URI") # Fast fail if the required environment variables are not set. if not all([uri, os.environ.get("ANTHROPIC_API_KEY"), os.environ.get("VOYAGE_API_KEY")]): print("This script needs ATLAS_URI, ANTHROPIC_API_KEY, and VOYAGE_API_KEY.") sys.exit(1) print(f"=== CrewAI and MongoDB Atlas long-term memory (model={MODEL}) ===") _BACKEND = MongoDBStorageBackend(uri, database_name=DEMO_DB) _BACKEND.delete(scope_prefix=SCOPE) # clean slate for a repeatable run print("Ensuring Atlas Vector Search index (first build can take ~1 min)...") if not _BACKEND.ensure_vector_index(wait=True): print("Vector index did not become queryable in time.") sys.exit(1) print("Index queryable.") # Initialize the event listener for the agent. listener = EventListener() # Session 1: the agent learns and stores preferences. banner("SESSION 1 - agent stores durable preferences in Atlas") session_1_input = ( """The user says: 'I'm vegetarian, I avoid dairy, and I always prefer window seats on flights.' Store each durable preference.""" ) _SESSION_LABEL = "SESSION 1" print(f" {session_1_input}") out1 = run_task( description=session_1_input, expected_output="A short confirmation of what was stored.", ) print(f"\nAgent (session 1): {out1}") # Atlas indexing is asynchronous, so wait until the facts are searchable. print("\nWaiting for Atlas to index the new memories...") for _ in range(20): if _BACKEND.search(embed("food", input_type="query"), scope_prefix=SCOPE, limit=1): break time.sleep(2) print("Memories searchable.") # Session 2: a brand-new crew with no shared state recalls from Atlas. banner("SESSION 2 - fresh crew answers via recall_preferences") session_2_input = ( """The user is booking a long flight and pre-ordering an in-flight meal. Recommend a seat and a meal that fit their preferences.""" ) _SESSION_LABEL = "SESSION 2" print(f" {session_2_input}") out2 = run_task( description=session_2_input, expected_output="A seat and meal recommendation grounded in recalled preferences.", ) print(f"\nAgent (session 2, brand-new crew): {out2}") banner("Proof: direct $vectorSearch recall over stored preferences") hits = _BACKEND.search( embed("dietary and seating preferences", input_type="query"), scope_prefix=SCOPE, limit=5, ) for rec, score in hits: print(f" - [{score:.3f}] {rec.content}") _BACKEND.delete(scope_prefix=SCOPE) _BACKEND.close() print("\nDone - CrewAI stored and recalled preferences via MongoDB Vector Search.") if __name__ == "__main__": main()
Este script faz o seguinte:
Conecta-se ao seu cluster Atlas com
MongoDBStorageBackende garante que um índice de pesquisa vetorial do MongoDB exista na coleção de memória.Define um agente CrewAI que usa as ferramentas de memória e, em seguida, executa uma equipe que armazena as preferências do usuário.
Executa uma segunda equipe, totalmente nova, que recupera as preferências armazenadas do Atlas e baseia sua recomendação nelas.
Execute o arquivo.
Execute o seguinte comando para executar o script:
python main.py
====================================================================== SESSION 1 - agent stores durable preferences in Atlas ====================================================================== The user says: 'I'm vegetarian, I avoid dairy, and I always prefer window seats on flights.' Store each durable preference. Crew 'crew' has started execution! ╭────────────────────────────── 🤖 Agent Started ──────────────────────────────╮ │ │ │ Agent: Personal Concierge │ │ │ │ Task: The user says: 'I'm vegetarian, I avoid dairy, and I always prefer │ │ window seats on flights.' Store each durable preference. │ │ │ ╰──────────────────────────────────────────────────────────────────────────────╯ Tool remember_preference executed with result: Stored preference: The user is vegetarian.... Tool remember_preference executed with result: Stored preference: The user avoids dairy.... Tool remember_preference executed with result: Stored preference: The user always prefers window seats on flights.... [Finalize] todos_count=0, todos_with_results=0 ╭─────────────────────────── ✅ Agent Final Answer ────────────────────────────╮ │ │ │ Agent: Personal Concierge │ │ │ │ Final Answer: │ │ Stored: │ │ - The user is vegetarian. │ │ - The user avoids dairy. │ │ - The user always prefers window seats on flights. │ │ │ ╰──────────────────────────────────────────────────────────────────────────────╯ Agent 'Personal Concierge' completed task Output: Stored: - The user is vegetarian. - The user avoids dairy. - The user always prefers window seats on flights. Crew 'crew' has completed execution! Output: Stored: - The user is vegetarian. - The user avoids dairy. - The user always prefers window seats on flights. Agent (session 1): Stored: - The user is vegetarian. - The user avoids dairy. - The user always prefers window seats on flights. Waiting for Atlas to index the new memories... Memories searchable. ====================================================================== SESSION 2 - fresh crew answers via recall_preferences ====================================================================== The user is booking a long flight and pre-ordering an in-flight meal. Recommend a seat and a meal that fit their preferences. Crew 'crew' has started execution! ╭────────────────────────────── 🤖 Agent Started ──────────────────────────────╮ │ │ │ Agent: Personal Concierge │ │ │ │ Task: The user is booking a long flight and pre-ordering an in-flight │ │ meal. │ │ Recommend a seat and a meal that fit their preferences. │ │ │ ╰──────────────────────────────────────────────────────────────────────────────╯ - [0.794] The user always prefers window seats on flights. - [0.748] The user is vegetarian. - [0.739] The user avoids dairy. Tool recall_preferences executed with result: - The user always prefers window seats on flights. (score=0.794) - The user is vegetarian. (score=0.748) - The user avoids dairy. (score=0.739)... [Finalize] todos_count=0, todos_with_results=0 ╭─────────────────────────── ✅ Agent Final Answer ────────────────────────────╮ │ │ │ Agent: Personal Concierge │ │ │ │ Final Answer: │ │ I recommend booking a **window seat** for the long flight, since you │ │ prefer window seats. │ │ │ │ For your in-flight meal, choose a **vegetarian dairy-free meal**. If the │ │ airline offers specific meal codes, look for something like **VGML / vegan │ │ meal**, since that will typically meet both preferences: vegetarian and no │ │ dairy. │ │ │ ╰──────────────────────────────────────────────────────────────────────────────╯ Agent 'Personal Concierge' completed task Output: I recommend booking a **window seat** for the long flight, since you prefer window seats. For your in-flight meal, choose a **vegetarian dairy-free meal**. If the airline offers specific meal codes, look for something like **VGML / vegan meal**, since that will typically meet both preferences: vegetarian and no dairy. Crew 'crew' has completed execution! Output: I recommend booking a **window seat** for the long flight, since you prefer window seats. For your in-flight meal, choose a **vegetarian dairy-free meal**. If the airline offers specific meal codes, look for something like **VGML / vegan meal**, since that will typically meet both preferences: vegetarian and no dairy. Agent (session 2, brand-new crew): I recommend booking a **window seat** for the long flight, since you prefer window seats. For your in-flight meal, choose a **vegetarian dairy-free meal**. If the airline offers specific meal codes, look for something like **VGML / vegan meal**, since that will typically meet both preferences: vegetarian and no dairy. ====================================================================== Proof: direct $vectorSearch recall over stored preferences ====================================================================== - [0.770] The user always prefers window seats on flights. - [0.768] The user is vegetarian. - [0.754] The user avoids dairy. Done - CrewAI stored and recalled preferences via MongoDB Vector Search.
Observação
Sua saída pode ser diferente, pois as respostas do LLM e as pontuações de pesquisa vetorial podem variar entre as execuções.