Migration von CrewAI
Code-Vergleich und Konzept-Mapping für Entwickler, die von CrewAI zu JamJet wechseln.
Konzept-Mapping
| CrewAI | JamJet |
|---|---|
Agent(role, goal, backstory, tools) | @wf.step mit System-Prompt + MCP-Tools |
Task(description, agent, context) | Workflow-Step — Kontext ist gemeinsamer State |
Crew(agents, tasks, process) | Workflow |
Process.sequential | Standard-Step-Reihenfolge |
Process.hierarchical | Orchestrator-Workflow → Sub-Workflows via A2A |
crew.kickoff(inputs) | wf.run_sync(State(...)) oder jamjet run |
crewai_tools.SerperDevTool | MCP-Tool-Node (type: tool, server: brave-search) |
| Memory (short/long term) | State-Objekt (kurzfristig); Postgres-gestütztes Runtime (langfristig) |
agent.verbose = True | Strukturiertes Event-Log — jeder Step abfragbar mit jamjet inspect |
Side-by-Side-Beispiel
Ein Zwei-Agenten-Crew — Researcher und Writer — arbeiten zusammen, um einen Bericht zu erstellen.
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)Hauptunterschiede
Agents vs. Steps
CrewAI behandelt Agents als undurchsichtige Objekte mit Rollen, Zielen, Hintergrundgeschichten und Tool-Zugriff. JamJet behandelt diese als das, was sie tatsächlich sind: einen System-Prompt und eine Reihe von Tools. Ihr "Agent" ist ein Step mit einem sorgfältig ausgearbeiteten System-Prompt — Sie haben vollständige Kontrolle und vollständige Transparenz.
Tools
CrewAI hat ein eigenes Tool-Ökosystem (crewai_tools). JamJet verwendet MCP — den offenen Standard. Jeder MCP-Server funktioniert: Brave Search, GitHub, Postgres, Ihr eigener Custom-Server. Kein Vendor-Lock-in an ein proprietäres Tool-Register.
Multi-Agent
CrewAIs Process.hierarchical verwendet einen internen Manager-Agent. JamJet nutzt A2A (Agent-to-Agent-Protokoll) — ein offener Standard, bei dem jeder Agent ein separater Workflow mit eigenem Endpoint ist. Ein Orchestrator delegiert über type: a2a_task-Nodes an Spezialisten. Dies skaliert über Maschinen und Organisationen hinweg.
# orchestrator/workflow.yaml
nodes:
delegate-research:
type: a2a_task
agent_url: "{{ env.RESEARCH_AGENT_URL }}"
input:
query: "{{ state.topic }}"
output_key: research
next: write-reportObservability
CrewAIs Verbose-Modus gibt menschenlesbaren Text aus. JamJet emittiert strukturierte Events für jeden Step — abfragbar, vergleichbar, wiederholbar:
jamjet inspect exec-abc123 # vollständige Timeline
jamjet events exec-abc123 # Event-StreamDurability
CrewAI hat keine eingebaute Persistenz. Wenn der Prozess während der Ausführung abstürzt, fangen Sie von vorne an. JamJets Rust-Runtime persistiert jeden Step. Crash Recovery ist automatisch.
Schnellstart-Migration
pip install jamjet- Konvertieren Sie jeden
Agentin einen@wf.step— verschieben Sie Rolle/Ziel/Hintergrundgeschichte in den System-Prompt - Konvertieren Sie
Task-Reihenfolge in Step-Deklarationsreihenfolge — gemeinsamer Kontext wird zu State-Feldern - Ersetzen Sie
crewai_toolsdurch MCP-Tool-Nodes (type: toolin YAML) - Ersetzen Sie
crew.kickoff(inputs)durchwf.run_sync(State(...)) - Für Multi-Agent-Hierarchien: verwenden Sie
type: a2a_task-Nodes
tip: Vollständige funktionierende Beispiele in jamjet-labs/jamjet-benchmarks.