Migrate
从 CrewAI 迁移
为从 CrewAI 迁移到 JamJet 的开发者提供的代码对比和概念映射。
概念映射
| CrewAI | JamJet |
|---|---|
Agent(role, goal, backstory, tools) | @wf.step 搭配系统提示词 + MCP 工具 |
Task(description, agent, context) | 工作流步骤 — 上下文为共享状态 |
Crew(agents, tasks, process) | Workflow |
Process.sequential | 默认步骤顺序 |
Process.hierarchical | 编排器工作流 → 通过 A2A 调用子工作流 |
crew.kickoff(inputs) | wf.run_sync(State(...)) 或 jamjet run |
crewai_tools.SerperDevTool | MCP 工具节点 (type: tool, server: brave-search) |
| Memory (short/long term) | State 对象(短期);基于 Postgres 的运行时(长期) |
agent.verbose = True | 结构化事件日志 — 每个步骤可通过 jamjet inspect 查询 |
对比示例
一个双智能体团队 — 研究员和撰稿人 — 协作生成报告。
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)核心差异
Agent 与 Step
CrewAI 将 agent 视为具有角色、目标、背景故事和工具访问权限的不透明对象。JamJet 将这些视为它们的本质:一个系统提示词和一组工具。你的「agent」就是一个带有精心设计的系统提示词的 step —— 你拥有完全的控制权和可见性。
工具
CrewAI 有自己的工具生态系统(crewai_tools)。JamJet 使用 MCP —— 开放标准。任何 MCP 服务器都可以工作:Brave Search、GitHub、Postgres,或你自己的自定义服务器。不会被锁定在专有工具注册表中。
多智能体
CrewAI 的 Process.hierarchical 使用内部管理器 agent。JamJet 使用 A2A(Agent-to-Agent 协议)—— 一个开放标准,其中每个 agent 都是具有自己端点的独立工作流。编排器通过 type: a2a_task 节点将任务委托给专家。这种方式可以跨机器和组织扩展。
# 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可观测性
CrewAI 的详细模式打印人类可读的文本。JamJet 为每个 step 生成结构化事件 —— 可查询、可对比、可重放:
jamjet inspect exec-abc123 # 完整时间线
jamjet events exec-abc123 # 事件流持久性
CrewAI 没有内置的持久化机制。如果进程在运行中崩溃,你需要重新开始。JamJet 的 Rust 运行时持久化每个 step。崩溃恢复是自动的。
快速迁移指南
pip install jamjet- 将每个
Agent转换为@wf.step—— 将角色/目标/背景故事移入系统提示词 - 将
Task顺序转换为 step 声明顺序 —— 共享上下文变成状态字段 - 用 MCP 工具节点(YAML 中的
type: tool)替换crewai_tools - 用
wf.run_sync(State(...))替换crew.kickoff(inputs) - 对于多智能体层级结构:使用
type: a2a_task节点
提示: 在 jamjet-labs/jamjet-benchmarks 中查看完整的工作示例。