Para agentes de IA: hay un índice de documentación disponible en https://www.mongodb.com/es/docs/llms.txt — versiones en markdown de todas las páginas están disponibles agregando .md a cualquier ruta URL.
Docs Menu

Añadir memoria a largo término a los agentes de CrewAI

En este tutorial, utilizará el paquete crewai-mongodb-memory para dar a un agente CrewAI una memoria duradera a largo plazo que persiste en MongoDB Atlas. El agente almacena las preferencias del usuario como registros de memoria y las recupera semánticamente con búsqueda vectorial de MongoDB, de modo que un equipo nuevo en una sesión posterior puede dar correctamente la respuesta recuperando los aprendizajes de una sesión anterior.

Para obtener más información sobre la integración de MongoDB CrewAI, consulta Integra MongoDB con CrewAI.

Para completar este tutorial, debes tener lo siguiente:

  • Python 3.10 o posterior.

  • Uno de los siguientes tipos de clúster de MongoDB:

  • Una clave de API de Voyage IA. Para crear una clave API, consulta Claves API del modelo.

  • Una clave API de grandes modelos de lenguaje (LLM), como Anthropic u OpenAI, para impulsar la inferencia del agente.

El backend de crewai-mongodb-memory implementa el protocolo de StorageBackend de CrewAI. Almacena cada memoria como un registro en una colección de MongoDB y utiliza la búsqueda vectorial de MongoDB para recuperar registros relevantes semánticamente. El backend utiliza los siguientes componentes:

  • MongoDBStorageBackend: Se conecta a su clúster de Atlas, almacena registros de memoria y ejecuta $vectorSearch query para recuperarlos.

  • MemoryRecord: Representa una sola memoria, incluido su contenido de texto, un ámbito jerárquico como /users/alex/preferences, categorías opcionales y su incrustación vectorial.

  • embed_text(): Genera incrustaciones de 1024dimensiones con el modelo voyage-4 de Voyage AI tanto para documentos almacenados como para consultas.

Debido a que la memoria reside en Atlas en lugar del contexto en proceso del equipo, cualquier equipo que se conecte al mismo clúster y ámbito puede recuperar las memorias almacenadas.

{
"_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"
]
}

Siga los siguientes pasos para compilar y ejecutar un agente que almacene y recupere las preferencias del usuario:

1
  1. Ejecuta los siguientes comandos en tu terminal para crear un nuevo directorio llamado crewai-memory-project e instalar las dependencias necesarias:

    mkdir crewai-memory-project
    cd crewai-memory-project
    pip install crewai-mongodb-memory crewai "crewai[google-genai]" voyageai python-dotenv
  2. En tu proyecto, crea un archivo .env y añade las siguientes líneas:

    ATLAS_URI="<connection-string>"
    VOYAGE_API_KEY="<voyage-api-key>"
    ANTHROPIC_API_KEY="<anthropic-api-key>"
    MODEL="<anthropic-model>"

    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.

2

Crea un archivo llamado main.py en tu proyecto y pega el siguiente 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):
@crewai_event_bus.on(CrewKickoffStartedEvent)
def on_crew_started(source, event):
print(f"Crew '{event.crew_name}' has started execution!")
@crewai_event_bus.on(CrewKickoffCompletedEvent)
def on_crew_completed(source, event):
print(f"Crew '{event.crew_name}' has completed execution!")
print(f"Output: {event.output}")
@crewai_event_bus.on(AgentExecutionCompletedEvent)
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)
@tool("remember_preference")
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}"
@tool("recall_preferences")
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 realiza lo siguiente:

  • Se conecta a su clúster de Atlas con MongoDBStorageBackend y garantiza que exista un índice de búsqueda vectorial de MongoDB en la colección de memoria.

  • Define dos herramientas, remember_preference y recall_preferences, que el agente llama para almacenar y recuperar recuerdos.

  • Define un agente de CrewAI que utiliza las herramientas de memoria y, a continuación, ejecuta un equipo que almacena las preferencias del usuario.

  • Ejecuta un segundo equipo completamente nuevo que recupera las preferencias almacenadas de Atlas y basa su recomendación en ellas.

3

Ejecuta el siguiente comando para ejecutar el 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.

Nota

Su resultado podría diferir, ya que las respuestas de LLM y las puntuaciones de búsqueda vectorial pueden variar entre ejecuciones.