blog about dark mmfilesi
Agentic Frameworks · ·10 min ·Beginner

Introducción a CrewAI

Introducción a CrewAI, un framework muy divertido para sistemas multiagente.

1. Introducción

Otro de los grandes frameworks para trabajar con agentes es CrewAI, un framework escrito en Python de código abierto para orquestar múltiples agentes IA que colaboran entre sí.

Su filosofía se basa en dividir el trabajo entre especialistas para abordar proyectos complejos, tal y como hacemos los seres humanos, siguiendo el viejo adagio de divide et impera, divide y vencerás. Para entender el potencial de la estrategia podemos pensar en la necesidad de escribir un artículo riguroso sobre la mitología del reino nabateo de Petra. Con un agente único, el flujo sería algo así:

[Un solo agente]
  1 ▸ busca información
  2 ▸ la procesa
  3 ▸ redacta el artículo
  4 ▸ lo revisa
  5 ▸ produce el output

Y este flujo es problemático. El agente tiene que ser bueno en todo a la vez -búsqueda, síntesis, redacción y crítica- y, en la práctica, los LLMs tienen dificultades para ser simultáneamente el investigador y el crítico de su propio trabajo. Además, el contexto puede saturarse, la calidad baja, y los errores se propagan sin que nadie los cuestione.

Con CrewAI, el mismo flujo se convierte en:

[Investigador]
  1 ▸ busca y sintetiza fuentes
  2 ▸ Le pasa la información al..

[Redactor]
  3 ▸ escribe el artículo a partir de la investigación.
  4 ▸ Le pasa la información al..

[Editor]
  5 ▸ revisa, corrige y mejora el resultado final

De esta manera, cada agente trabaja en su área de especialidad. El output de uno es el input del siguiente. El resultado es más robusto, más fácil de depurar y más fácil de mejorar: si la redacción falla, ajustas al Redactor sin tocar al Investigador.

Así, CrewAI puede ser una alternativa interesante frente a LangChain y derivados en sistemas agénticos que requieren múltiples pasos especializados que se benefician de agentes distintos (investigar, escribir, revisar, validar…), sobre todo cuando el resultado necesita calidad contrastada, no solo velocidad.

Por el contrario, no es la mejor opción si el caso de uso es un chatbot conversacional simple, una cadena de un solo paso, o un sistema donde se necesita control muy granular sobre cada transición de estado (para eso LangGraph es más adecuado).

En síntesis, CrewAI es un framework específicamente diseñado para sistemas multi-agente. No da bloques genéricos, sino un modelo de programación de alto nivel: agentes con roles, tareas, equipos y procesos de coordinación. El objetivo es que pienses en quién hace qué, no en cómo se conectan las llamadas.

Por último, aclarar en esta introducción que hay que distinguir dos cosas:

  • CrewAI el framework: el que instalas y usas en tu código. Es open source, licencia MIT. Está en GitHub, puedes ver el código, modificarlo y usarlo libremente en proyectos comerciales.
  • CrewAI AMP: su plataforma enterprise con interfaz visual, monitorización, etcétera. es un producto comercial de pago.

Para este tutorial usaremos solo el framework open source. La plataforma de pago no nos hace falta. Está pensada principalmente para equipos no técnicos y organizaciones que quieren desplegar crews como APIs sin gestionar infraestructura propia.

2. Conceptos fundamentales

Antes de escribir una sola línea de código, conviene entender los cuatro bloques con los que se construye cualquier sistema en CrewAI. Son pocos y ortogonales entre sí, cada uno tiene una responsabilidad clara y no se solapa con los demás.

2.1 Los cuatro pilares

2.1.1. Agent

Es la unidad básica del sistema. Un agente es un LLM al que se le asigna una identidad de trabajo, esto es, un rol, un objetivo y un contexto (backstory). Estos tres campos condicionan directamente cómo vael modelo va a interpretar las instrucciones y qué tipo de respuestas produce.

Volviendo al ejemplo de antes, la mitología de Petra, podemos preparar un agente que tenga el rol de investigadora histórica y su objetivo sea el análisis mitológico.

researcher = Agent(
  role="Investigadora de mitología comparada",
  goal="Analizar la mitología del reino nabateo de Petra con rigor académico",
  backstory="""Eres una investigadora especializada en mitología comparada, 
  formada en la tradición de Georges Dumézil. Analizas los sistemas 
  religiosos buscando estructuras profundas: patrones funcionales, 
  arquetipos y paralelos entre culturas. No te limitas a catalogar 
  dioses, buscas el sistema que los organiza y su relación con otras mitologías.""",
)

2.1.2. Task

Una tarea es la unidad de trabajo. Define qué hay que hacer, qué se espera como resultado y qué agente es el responsable de ejecutarla.

from crewai import Task

research_task = Task(
  description="""Investiga en profundidad la mitología del reino nabateo de Petra.""",
  expected_output="""Un informe estructurado de al menos 500 palabras con 
  secciones claramente diferenciadas y datos contrastados.""",
  agent=researcher,
)

El campo expected_output es importante. Le indica al agente exactamente qué forma debe tener su respuesta, lo que reduce la ambigüedad y mejora la calidad del output.

2.1.3. Crew

La Crew, que podemos traducir como tripulación, es el contenedor que agrupa agentes y tareas, y el orquestador que los pone a trabajar juntos. Aquí se define también el tipo de proceso que gobierna la ejecución.

from crewai import Crew, Process

crew = Crew(
  agents=[researcher, writer, editor],
  tasks=[research_task, writing_task, editing_task],
  process=Process.sequential,
)

2.1.3. Process

El proceso define el orden y la lógica de ejecución de las tareas. CrewAI ofrece dos modos principales:

  • Process.sequential: las tareas se ejecutan una tras otra, en el orden en que se definen. El output de cada tarea está disponible para la siguiente. Es el modo más simple y el que usaremos en la mayor parte del tutorial.
  • Process.hierarchical: existe un agente manager que actúa como coordinador. Decide qué agente ejecuta qué tarea y en qué orden, de forma dinámica. Es más potente pero requiere más configuración.

2.2. Un equipo de trabajo

La forma más rápida de interiorizar CrewAI es pensar en él como un sistema para montar un equipo de trabajo:

CrewAIEquivalente humano
AgentUn trabajador con un perfil concreto
TaskUn encargo con entregable definido
CrewEl equipo y su forma de organizarse
ProcessLa metodología de trabajo (secuencial, con manager…)

Con este modelo en mente, diseñar una Crew se convierte en una pregunta concreta: ¿qué perfiles necesitamos, qué tiene que entregar cada uno y en qué orden?

Para nuestro pipeline sobre los nabateos la tripulación podría ser esta:

  • Un agente investigador que recopile y sintetice información histórica
  • Un agente redactor que convierta esa investigación en un artículo bien estructurado
  • Un agente editor que revise el resultado y lo pula antes de la entrega final

Estos tres agentes, con sus tres tareas encadenadas en proceso secuencial, son el esqueleto del proyecto. Vamos a empezar a construirlo.

3. Instalación y configuración del entorno

3.1. Requisitos previos

CrewAI necesita Python 3.10 o superior, hasta 3.13. Antes de nada, conviene verificar la versión instalada:

python --version

También es recomendable uv, el gestor de paquetes y entornos virtuales que CrewAI usa internamente. Es significativamente más rápido que pip y gestiona las dependencias de forma más limpia. Si no está instalado:

bashcurl -LsSf https://astral.sh/uv/install.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.sh | iex"

3.2. Instalación y creación del proyecto

CrewAI tiene una CLI que genera automáticamente la estructura del proyecto. Es la forma recomendada de empezar:

# Instalamos CrewAI
uv tool install crewai

# Creamos el proyecto con el nombre normalizado que queramos
crewai create crew petra_mythology

# Entramos en el proyecto
cd petra_mythology

# Instalamos las dependencias
crewai install

# Añadimos el proveedor que vayamos a usar
uv add "crewai[anthropic]"

Durante la instalación nos pregunta el proveedor que queremos (Gemini, OpenAI, whatever), el modelo y la api key de la plataforma que vamos a usar. Podemos responderlas en el proceso o definir eso más adelante.

Cuando termina con las preguntas, crew se pone em marcha y hace varias cosas a la vez: crea la estructura de carpetas, inicializa un entorno virtual con uv y genera los archivos base con código de ejemplo que se puede modificar. Algo así.

petra_mythology/
├── .env                    # claves de API (nunca se sube a git)
├── .gitignore
├── pyproject.toml          # dependencias del proyecto
├── README.md
├── AGENTS.md               # instrucciones para agentes de código (Claude Code, Codex...)
├── knowledge/              # archivos de conocimiento estático (PDFs, TXTs...)
   └── user_preference.txt
└── src/
    └── petra_mythology/
        ├── config/
   ├── agents.yaml     # configuración de los agentes
   └── tasks.yaml      # configuración de las tareas
        ├── tools/
   └── custom_tool.py  # herramientas personalizadas
        ├── __init__.py
        ├── crew.py             # definición de la Crew
        └── main.py             # punto de entrada

3.3. Configuración de claves de API

Las claves, claro está, se encuentran en el archivo .env

MODEL=claude-haiku-4-5-20251001
ANTHROPIC_API_KEY=sk-patatas

CrewAI carga estas variables automáticamente al arrancar. No hace falta ninguna configuración adicional. Por defecto, si no se especifica nada más, CrewAI usa gpt-4o-mini como modelo. Para cambiar el modelo por defecto se añade al .env o se especifica por agente directamente en el código, como veremos más adelante.

Al menos para las pruebas, se podría usar un modelo que corra en local, por ejemplo, con Ollama.

En el .env simplemente se pone:

MODEL=ollama/llama3.2 # o el que sea
API_BASE=http://localhost:11434

Y Ollama tiene que estar corriendo en local con el modelo descargado. La pega es que los modelos locales pequeños (7B, 8B) rinden bastante peor en tareas que requieren razonamiento complejo, seguir instrucciones detalladas en la backstory y mantener el rol a lo largo de una tarea larga. Para un pipeline de investigación y redacción, probablemente la calidad del output sea decepcionante comparado con los modelos más baratos de las plataformas, como Haiku 4.5.

4. Los cimientos

Ahora que el entorno está listo, ya podemos preparar la primera versión funcional del pipeline. En esta sección escribiremos el código mínimo para tener tres agentes trabajando juntos, sin herramientas externas todavía, sin memoria, sin Flows. Solo los cimientos.

4.1. Ejemplo con Python

CrewAI permite definir agentes y tareas de dos maneras:

  • YAML: declarativa, limpia, separa configuración de lógica. Es el enfoque recomendado por CrewAI para proyectos que crecen.
  • Python puro: más explícita, todo en un mismo sitio. Más fácil de seguir cuando se está aprendiendo.

Por ejemplo, así se definiría un agente en Python.

from crewai import Agent, Task, Crew, Process

researcher = Agent(
    role="Investigadora de mitología comparada",
    goal="""Analizar ...""",
    backstory="""Eres ...""",
    verbose=True,
)

Pero creo que mediante YAML es más elegante, ya que separa la lógica de la configuración. Si luego hay que ajustar algo en algún agente, se toca el YAML sin abrir el código. Es el principio de separación de responsabilidades aplicado a sistemas multi-agente: el YAML describe, el Python ejecuta.

4.2. Configuración de los agentes

En src/petra_mythology/config/agents.yaml definimos los agentes del sistema en formato YAML, del cual recordemos que es un formato de serialización de datos legible por humanos, muy usado para archivos de configuración. Su gran ventaja es que representa estructuras complejas (listas, diccionarios, texto multilínea) de forma limpia, sin llaves ni comillas innecesarias.

En mi ejemplo, algo así.

researcher:
  role: "Investigadora de mitología comparada"
  goal: >
    Analizar la mitología del reino nabateo de Petra con rigor académico,
    identificando estructuras profundas, patrones funcionales y paralelos
    con otras tradiciones religiosas del Oriente Próximo antiguo.
  backstory: >
    Eres una investigadora especializada en mitología comparada, formada
    en la tradición intelectual de Georges Dumézil. No te limitas a catalogar
    dioses y rituales, buscas el sistema que los organiza: las funciones
    sociales que reflejan, los arquetipos que encarnan, las estructuras que
    comparten con otras mitologías semíticas y del Oriente Próximo.
    Trabajas siempre con fuentes académicas y distingues con precisión
    entre evidencia contrastada y especulación.

writer:
  role: "Redactora de divulgación histórica"
  goal: >
    Transformar la investigación académica sobre la mitología nabatea
    en un artículo riguroso pero accesible para el gran público.
  backstory: >
    Escribes con el estilo y la sensibilidad de Mary Beard: cercana sin
    ser condescendiente, rigurosa sin ser árida. Sabes que la divulgación
    histórica es encontrar el ángulo humano que hace que el pasado importe. 
    Tu prosa es clara, tu estructura es sólida
    y nunca sacrificas el matiz por la comodidad.

editor:
  role: "Editor"
  goal: >
    Revisar el artículo y garantizar que cumple los estándares de rigor,
    claridad y estructura antes de su publicación.
  backstory: >
    Eres un editor experimentado en publicaciones de divulgación histórica
    y científica. Tu trabajo es mejorar. Corriges
    inconsistencias, refuerzas la estructura, eliminas redundancias y te
    aseguras de que el tono sea consistente de principio a fin.

Por cierto, recordemos que, en YAML, el operador > permite escribir texto multilínea que se trata como una sola cadena. Es ideal para backstories y descripciones largas y mucho más legible que un string de Python con saltos de línea explícitos.

4.3. Configuración de las tareas

A continuación definimos las tareas que asociaremos a los agentes en src/petra_mythology/config/tasks.yaml.

research_task:
  description: >
    Investiga en profundidad la mitología del reino nabateo de Petra.
    Cubre los siguientes aspectos:
    - El panteón nabateo: principales divinidades, sus atributos y funciones
    - Rituales y prácticas religiosas documentadas
    - Sincretismo religioso: influencias griegas, egipcias y árabes
    - Estructuras míticas profundas: patrones funcionales y arquetipos recurrentes
    - Fuentes académicas y estado actual de la investigación
  expected_output: >
    Un informe académico estructurado de al menos 600 palabras, con secciones
    claramente diferenciadas, que identifique no solo los elementos del panteón
    nabateo sino las estructuras que los organizan.
  agent: researcher

writing_task:
  description: >
    A partir del informe de investigación, escribe un artículo de divulgación
    sobre la mitología del reino nabateo de Petra. El artículo debe:
    - Tener una introducción que enganche al lector
    - Estar estructurado en secciones con subtítulos claros
    - Ser riguroso pero accesible para alguien sin formación especializada
    - Tener entre 800 y 1200 palabras
    - Terminar con una reflexión sobre el legado o la relevancia actual
  expected_output: >
    Un artículo de divulgación histórica completo, bien estructurado,
    con subtítulos, listo para publicar.
  agent: writer
  context:
    - research_task

editing_task:
  description: >
    Revisa el artículo de divulgación y mejóralo donde sea necesario.
    Comprueba:
    - Coherencia interna y consistencia del tono
    - Claridad de la estructura y los subtítulos
    - Precisión histórica respecto al informe de investigación
    - Calidad de la introducción y el cierre
    - Eliminación de redundancias o afirmaciones vagas
  expected_output: >
    El artículo revisado y mejorado, listo para publicación, con una nota
    breve al final explicando los principales cambios realizados.
  agent: editor
  context:
    - writing_task

El campo context en YAML funciona igual que en Python: le indica a CrewAI qué outputs anteriores debe pasar como contexto a esa tarea. Es el mecanismo que encadena el trabajo del equipo; description y expected_output hablan por sí solos: la descripción de la tarea y el resultado esperado.

4.4 El código de orquestación

Con la configuración en YAML terminada, vamos a crew.py, ya sí en Python, donde formamos la tripulació en una clase que lleva como decorador @CrewBase:

from crewai import Agent, Task, Crew, Process
from crewai.project import CrewBase, agent, task, crew

@CrewBase  # lee automáticamente los YAMLs de agents y tasks
class PetraMythology:
    agents_config = "config/agents.yaml"  # ruta al YAML de agentes
    tasks_config = "config/tasks.yaml"    # ruta al YAML de tareas

    @agent  # registra este método como agente de la Crew
    def researcher(self) -> Agent:
        return Agent(config=self.agents_config["researcher"], verbose=True)

    @agent
    def writer(self) -> Agent:
        return Agent(config=self.agents_config["writer"], verbose=True)

    @agent
    def editor(self) -> Agent:
        return Agent(config=self.agents_config["editor"], verbose=True)

    @task  # registra este método como tarea de la Crew
    def research_task(self) -> Task:
        return Task(config=self.tasks_config["research_task"])

    @task
    def writing_task(self) -> Task:
        return Task(config=self.tasks_config["writing_task"])

    @task
    def editing_task(self) -> Task:
        return Task(config=self.tasks_config["editing_task"])

    @crew  # ensambla agentes y tareas en la Crew final
    def crew(self) -> Crew:
        return Crew(
            agents=self.agents,   # poblado automáticamente por @agent
            tasks=self.tasks,     # poblado automáticamente por @task
            process=Process.sequential,  # las tareas se ejecutan en orden
            verbose=True,
        )

El decorador @CrewBase lee los YAMLs automáticamente. Los decoradores @agent, @task y @crew registran cada método y pueblan self.agents y self.tasks sin que haya que gestionarlos manualmente. El resultado es un código de orquestación que apenas cambia aunque el proyecto crezca. Toda la variabilidad vive en los YAMLs.

Por otra parte, con verbose=True activado, en consola se verá el proceso de razonamiento de cada agente en tiempo real, la mejor manera de entender qué está haciendo el sistema y detectar dónde falla cuando algo no sale como se espera.

4.5. El punto de entrada

Con todo ya listo, solo faltaría definir el punto de entrada de la aplicación, que se encuentra en src/petra_mythology/main.py. Aquí hay Tiene cinco funciones principales:

  • run(): ejecuta la Crew normalmente. El diccionario de inputs permite pasar variables que se interpolan dinámicamente en los YAMLs. Por ejemplo, si en tasks.yaml se escribe {topic}, se sustituye por el valor que se pase aquí.
  • train(): entrena la Crew durante N iteraciones para mejorar su comportamiento. CrewAI guarda el aprendizaje en un archivo que se indica como argumento.
  • replay(): reejecuta la Crew desde una tarea concreta, sin tener que empezar desde cero. Muy útil cuando una tarea intermedia falla y no se quiere repetir todo el pipeline.
  • test(): ejecuta la Crew en modo evaluación, comparando los outputs contra un LLM evaluador que se pasa como argumento.
  • run_with_trigger(): ejecuta la Crew desde un payload JSON externo. Es el punto de entrada cuando la Crew se despliega como API y recibe llamadas desde fuera.

Para el tutorial, de momento solo usaremos run() y adaptaremos el inputs a nuestro proyecto. Además, podemos añadir una función para que saque el contenido en un .md, para consultarlo más allá de la consola. Algo así.

def run():
    """
    Run the crew.
    """
    inputs = {
        # 'topic': 'AI LLMs',
        'topic': 'mitología del reino nabateo de Petra',
        'current_year': str(datetime.now().year)
    }

    try:
        result = PetraMythology().crew().kickoff(inputs=inputs)
        # esto no sería necesario, 
        # pero es para mostrar cómo acceder al resultado final de la Crew 
        # y guardarlo en un archivo
        with open("output/articulo_nabateos.md", "w", encoding="utf-8") as f:
            f.write(result.raw)
    except Exception as e:
        raise Exception(f"An error occurred while running the crew: {e}")

Con todo listo, ya solo faltaría lanzar el proceso.

crewai run

Primero se lanza el agente investigador, le entrega el trabajo al redactor y, por último, el editor lo deja listo para ser publicado.

Crew Execution Completed
Name: PetraMythology
ID: 05b0c2ee-f46d-49b6-b1b1-c5d76272a7d4
Final Output: # LOS DIOSES DE PETRA: LA MITOLOGÍA SECRETA DEL REINO NABATEO

## Introducción: Cuando los mercaderes adoraban montañas  

Imagina una caravana cruzando el desierto de Arabia en el siglo II antes de Cristo. Los mercaderes nabateos transportan incienso y mirra desde el corazón de la Península Arábiga hacia los mercados helenísticos del Mediterráneo. Por la noche, acampan en Petra, esa ciudad de piedra roja que emerge de las rocas como si la montaña misma hubiera sido esculpida en templo. Allí ofrecen sacrificios a Dushara, su dios supremo, cuyo nombre significa "Señor de la Montaña".

[...]

Esta sería la versión mínima funcional del pipeline. En próximos posts de esta serie vemos cómo darles herramientas a los llms para que trabajen con información actualizada en lugar de depender solo del conocimiento del LLM y otras muchas más características interesantes de este framework.

mmfilesi · 2026