JamJet
Migrate

Migración desde CrewAI

Comparación de código lado a lado y mapeo de conceptos para desarrolladores que migran de CrewAI a JamJet.

Mapeo de conceptos

CrewAIJamJet
Agent(role, goal, backstory, tools)@wf.step con system prompt + herramientas MCP
Task(description, agent, context)Paso de workflow — el contexto es estado compartido
Crew(agents, tasks, process)Workflow
Process.sequentialOrden de pasos por defecto
Process.hierarchicalWorkflow orquestador → sub-workflows vía A2A
crew.kickoff(inputs)wf.run_sync(State(...)) o jamjet run
crewai_tools.SerperDevToolNodo de herramienta MCP (type: tool, server: brave-search)
Memory (short/long term)Objeto State (corto plazo); runtime respaldado por Postgres (largo plazo)
agent.verbose = TrueLog de eventos estructurado — cada paso consultable con jamjet inspect

Ejemplo lado a lado

Un crew de dos agentes — investigador y redactor — colaborando para producir un informe.

CrewAI

from crewai import Agent, Crew, Process, Task
from crewai_tools import SerperDevTool

search_tool = SerperDevTool()

researcher = Agent(
    role="Research Analyst",
    goal="Find comprehensive, accurate information on the topic",
    backstory="Expert analyst with deep domain knowledge.",
    tools=[search_tool],
)

writer = Agent(
    role="Technical Writer",
    goal="Write clear, concise reports from research findings",
    backstory="Skilled writer for technical audiences.",
)

research_task = Task(
    description="Research the topic: {topic}",
    expected_output="Structured summary with bullet points and sources.",
    agent=researcher,
)

write_task = Task(
    description="Write a report on: {topic}",
    expected_output="Report with introduction, key findings, conclusion.",
    agent=writer,
    context=[research_task],
)

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

result = crew.kickoff(inputs={"topic": "durable AI workflow orchestration"})

JamJet

from openai import OpenAI
from pydantic import BaseModel
from jamjet import Workflow

client = OpenAI()

class State(BaseModel):
    topic: str
    research: str = ""
    report: str = ""

wf = Workflow("research-crew")

@wf.state
class CrewState(State):
    pass

@wf.step
async def research(state: CrewState) -> CrewState:
    # Role/goal/backstory live in the system prompt — you own it
    resp = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": (
                "You are an expert research analyst. "
                "Return a structured summary with bullet points."
            )},
            {"role": "user", "content": f"Research: {state.topic}"},
        ],
    )
    return state.model_copy(update={"research": resp.choices[0].message.content or ""})

@wf.step
async def write_report(state: CrewState) -> CrewState:
    resp = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "You are a skilled technical writer."},
            {"role": "user", "content": (
                f"Topic: {state.topic}\n"
                f"Research:\n{state.research}\n"
                "Write a comprehensive report."
            )},
        ],
    )
    return state.model_copy(update={"report": resp.choices[0].message.content or ""})

result = wf.run_sync(CrewState(topic="durable AI workflow orchestration"))
print(result.state.report)

Diferencias clave

Agents vs steps

CrewAI trata a los agentes como objetos opacos con roles, objetivos, historias de fondo y acceso a herramientas. JamJet los trata como lo que realmente son: un system prompt y un conjunto de herramientas. Tu "agente" es un step con un system prompt bien elaborado — tienes control total, visibilidad total.

Herramientas

CrewAI tiene su propio ecosistema de herramientas (crewai_tools). JamJet usa MCP — el estándar abierto. Cualquier servidor MCP funciona: Brave Search, GitHub, Postgres, tu propio servidor personalizado. Sin dependencia de un registro de herramientas propietario.

Multi-agente

El Process.hierarchical de CrewAI usa un agente administrador interno. JamJet usa A2A (protocolo Agent-to-Agent) — un estándar abierto donde cada agente es un workflow separado con su propio endpoint. Un orquestador delega a especialistas mediante nodos type: a2a_task. Esto escala entre máquinas y organizaciones.


# orchestrator/workflow.yaml

nodes:
  delegate-research:
    type: a2a_task
    agent_url: "{{ env.RESEARCH_AGENT_URL }}"
    input:
      query: "{{ state.topic }}"
    output_key: research
    next: write-report

Observabilidad

El modo verbose de CrewAI imprime texto legible para humanos. JamJet emite eventos estructurados para cada step — consultables, comparables, reproducibles:

jamjet inspect exec-abc123   # línea de tiempo completa
jamjet events exec-abc123    # flujo de eventos

Durabilidad

CrewAI no tiene persistencia incorporada. Si el proceso falla a mitad de la ejecución, comienzas de nuevo. El runtime de Rust de JamJet persiste cada step. La recuperación de fallos es automática.

Migración rápida

pip install jamjet
  1. Convierte cada Agent en un @wf.step — mueve role/goal/backstory al system prompt
  2. Convierte el orden de Task en orden de declaración de steps — el contexto compartido se convierte en campos de estado
  3. Reemplaza crewai_tools con nodos de herramientas MCP (type: tool en YAML)
  4. Reemplaza crew.kickoff(inputs) con wf.run_sync(State(...))
  5. Para jerarquías multi-agente: usa nodos type: a2a_task

tip: Ejemplos completos y funcionales en jamjet-labs/jamjet-benchmarks.

On this page