Skip to main content
Technology & EngineeringAi Agent Orchestration433 lines

agent-frameworks

Comparison of major AI agent frameworks: LangGraph, CrewAI, AutoGen, Semantic Kernel, and Claude Agent SDK. Covers when to use each framework, their trade-offs, core patterns, practical setup examples, and migration strategies between frameworks.

Quick Summary18 lines
Compare and choose between major agent frameworks. Understand trade-offs, see setup patterns, and know when to switch.

## Key Points

- You need complex branching logic (if X then agent A, else agent B).
- You want persistence and resumability (built-in checkpointing).
- You need human-in-the-loop at specific graph nodes.
- Your workflow has cycles, retries, or conditional paths.
- Steep learning curve for the graph abstraction.
- Verbose for simple agent loops.
- Tight coupling to LangChain ecosystem.
- You have a clear division of agent roles and responsibilities.
- Tasks flow naturally in a sequential or hierarchical pattern.
- You want quick prototyping of multi-agent systems.
- Less control over individual agent behavior.
- Role/backstory prompting can be unreliable.
skilldb get ai-agent-orchestration-skills/agent-frameworksFull skill: 433 lines
Paste into your CLAUDE.md or agent config

Agent Frameworks

Compare and choose between major agent frameworks. Understand trade-offs, see setup patterns, and know when to switch.


Framework Overview

FrameworkBest ForLanguageKey Pattern
LangGraphComplex stateful workflowsPython/JSGraph-based state machines
CrewAIMulti-agent role-based teamsPythonCrew of specialized agents
AutoGenConversational multi-agentPythonAgent chat groups
Semantic KernelEnterprise .NET/Python appsC#/PythonPlugin-based AI orchestration
Claude Agent SDKClaude-native agent buildingPythonTool-use agent loops

LangGraph

LangGraph models agents as state machines with nodes (functions) and edges (transitions). Best for complex workflows where you need explicit control over the execution graph.

from langgraph.graph import StateGraph, START, END
from langgraph.prebuilt import ToolNode
from langchain_anthropic import ChatAnthropic
from langchain_core.tools import tool
from typing import TypedDict, Annotated
from langgraph.graph.message import add_messages


# Define state
class AgentState(TypedDict):
    messages: Annotated[list, add_messages]


# Define tools
@tool
def search_web(query: str) -> str:
    """Search the web for information."""
    return f"Search results for: {query}"


@tool
def calculate(expression: str) -> str:
    """Evaluate a math expression."""
    return str(eval(expression))


tools = [search_web, calculate]
model = ChatAnthropic(model="claude-sonnet-4-20250514").bind_tools(tools)


# Define nodes
def agent_node(state: AgentState):
    response = model.invoke(state["messages"])
    return {"messages": [response]}


def should_continue(state: AgentState):
    last_message = state["messages"][-1]
    if last_message.tool_calls:
        return "tools"
    return END


# Build graph
graph = StateGraph(AgentState)
graph.add_node("agent", agent_node)
graph.add_node("tools", ToolNode(tools))
graph.add_edge(START, "agent")
graph.add_conditional_edges("agent", should_continue, {"tools": "tools", END: END})
graph.add_edge("tools", "agent")

app = graph.compile()

# Run
result = app.invoke({
    "messages": [{"role": "user", "content": "What is 25 * 47?"}]
})

When to use LangGraph:

  • You need complex branching logic (if X then agent A, else agent B).
  • You want persistence and resumability (built-in checkpointing).
  • You need human-in-the-loop at specific graph nodes.
  • Your workflow has cycles, retries, or conditional paths.

Trade-offs:

  • Steep learning curve for the graph abstraction.
  • Verbose for simple agent loops.
  • Tight coupling to LangChain ecosystem.

CrewAI

CrewAI models agents as team members with roles, goals, and backstories. Best for multi-agent collaboration on well-defined tasks.

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

# Define agents with roles
researcher = Agent(
    role="Senior Research Analyst",
    goal="Find comprehensive, accurate data on the given topic",
    backstory="You are an expert researcher with 15 years of experience "
              "in data analysis and information synthesis.",
    tools=[SerperDevTool()],
    llm="claude-sonnet-4-20250514",
    verbose=True,
)

writer = Agent(
    role="Technical Writer",
    goal="Transform research into clear, engaging content",
    backstory="You are a skilled writer who makes complex topics accessible.",
    llm="claude-sonnet-4-20250514",
    verbose=True,
)

editor = Agent(
    role="Editor",
    goal="Ensure accuracy, clarity, and proper formatting",
    backstory="You are a meticulous editor with an eye for detail.",
    llm="claude-sonnet-4-20250514",
    verbose=True,
)

# Define tasks
research_task = Task(
    description="Research the current state of quantum computing in 2026. "
                "Focus on practical applications and recent breakthroughs.",
    expected_output="A structured research brief with key findings and sources.",
    agent=researcher,
)

writing_task = Task(
    description="Write a 1000-word article based on the research.",
    expected_output="A well-structured article with introduction, body, and conclusion.",
    agent=writer,
    context=[research_task],  # This task depends on research
)

editing_task = Task(
    description="Edit the article for clarity, accuracy, and engagement.",
    expected_output="A polished, publication-ready article.",
    agent=editor,
    context=[writing_task],
)

# Create crew and run
crew = Crew(
    agents=[researcher, writer, editor],
    tasks=[research_task, writing_task, editing_task],
    verbose=True,
)

result = crew.kickoff()

When to use CrewAI:

  • You have a clear division of agent roles and responsibilities.
  • Tasks flow naturally in a sequential or hierarchical pattern.
  • You want quick prototyping of multi-agent systems.

Trade-offs:

  • Less control over individual agent behavior.
  • Role/backstory prompting can be unreliable.
  • Limited support for complex conditional logic.

AutoGen

AutoGen focuses on multi-agent conversations. Agents talk to each other in a group chat pattern.

from autogen import AssistantAgent, UserProxyAgent, GroupChat, GroupChatManager

# Create agents
coder = AssistantAgent(
    name="Coder",
    system_message="You are an expert Python programmer. Write clean, tested code.",
    llm_config={"model": "claude-sonnet-4-20250514"},
)

reviewer = AssistantAgent(
    name="Reviewer",
    system_message="You are a code reviewer. Review code for bugs, style, "
                   "and best practices. Suggest improvements.",
    llm_config={"model": "claude-sonnet-4-20250514"},
)

tester = AssistantAgent(
    name="Tester",
    system_message="You are a QA engineer. Write and run tests for the code. "
                   "Report any failures.",
    llm_config={"model": "claude-sonnet-4-20250514"},
)

user = UserProxyAgent(
    name="User",
    human_input_mode="NEVER",
    code_execution_config={"work_dir": "workspace"},
)

# Group chat
group_chat = GroupChat(
    agents=[user, coder, reviewer, tester],
    messages=[],
    max_round=12,
)

manager = GroupChatManager(
    groupchat=group_chat,
    llm_config={"model": "claude-sonnet-4-20250514"},
)

# Start conversation
user.initiate_chat(
    manager,
    message="Build a Python function that finds the shortest path in a weighted graph "
            "using Dijkstra's algorithm. Include tests.",
)

When to use AutoGen:

  • Agents need to debate, critique, and iterate on each other's work.
  • The interaction pattern is conversational rather than pipeline-based.
  • You want automatic code execution as part of the agent loop.

Trade-offs:

  • Conversations can go off-track or loop endlessly.
  • Hard to impose strict execution order.
  • The group chat manager adds latency and cost.

Semantic Kernel

Microsoft's framework for enterprise AI applications. Plugin-based architecture, strong .NET support.

import semantic_kernel as sk
from semantic_kernel.connectors.ai.anthropic import AnthropicChatCompletion
from semantic_kernel.functions import kernel_function


# Initialize kernel
kernel = sk.Kernel()
kernel.add_service(AnthropicChatCompletion(
    ai_model_id="claude-sonnet-4-20250514",
    service_id="claude",
))


# Define plugins as classes
class MathPlugin:
    @kernel_function(description="Add two numbers")
    def add(self, a: float, b: float) -> float:
        return a + b

    @kernel_function(description="Multiply two numbers")
    def multiply(self, a: float, b: float) -> float:
        return a * b


class FilePlugin:
    @kernel_function(description="Read a file's contents")
    def read_file(self, path: str) -> str:
        with open(path) as f:
            return f.read()

    @kernel_function(description="Write content to a file")
    def write_file(self, path: str, content: str) -> str:
        with open(path, "w") as f:
            f.write(content)
        return f"Written to {path}"


# Register plugins
kernel.add_plugin(MathPlugin(), "math")
kernel.add_plugin(FilePlugin(), "files")

# Create agent settings with auto function calling
settings = kernel.get_prompt_execution_settings_from_service_id("claude")
settings.function_choice_behavior = "auto"

# Invoke
result = await kernel.invoke_prompt(
    "Calculate 25 * 47 and save the result to result.txt",
    settings=settings,
)

When to use Semantic Kernel:

  • You are building in a .NET/C# environment.
  • You need enterprise features: telemetry, dependency injection, plugin management.
  • You want a plugin marketplace and reusable components.

Trade-offs:

  • Heavier abstraction layer than needed for simple agents.
  • Python support lags behind C#.
  • More boilerplate for basic use cases.

Claude Agent SDK

Anthropic's own SDK for building agents with Claude. Minimal abstraction, direct access to Claude features.

from anthropic.agent import Agent, tool

@tool
def read_file(path: str) -> str:
    """Read a file and return its contents."""
    with open(path) as f:
        return f.read()

@tool
def write_file(path: str, content: str) -> str:
    """Write content to a file."""
    with open(path, "w") as f:
        f.write(content)
    return f"Wrote {len(content)} characters to {path}"

@tool
def run_command(command: str) -> str:
    """Run a shell command."""
    import subprocess
    result = subprocess.run(command, shell=True, capture_output=True, text=True)
    return result.stdout + result.stderr

agent = Agent(
    model="claude-sonnet-4-20250514",
    tools=[read_file, write_file, run_command],
    system="You are a helpful coding assistant.",
)

result = agent.run("Read the file app.py, find any bugs, and fix them.")
print(result)

When to use Claude Agent SDK:

  • You are building Claude-native agents.
  • You want minimal boilerplate and direct API access.
  • You need extended thinking, computer use, or other Claude-specific features.

Trade-offs:

  • Claude-only (not model-agnostic).
  • Newer framework with a smaller ecosystem.
  • Less built-in support for complex multi-agent patterns.

Decision Guide

Choose based on your primary need:

Need complex state machines / conditional routing?
  -> LangGraph

Need role-based multi-agent teams?
  -> CrewAI

Need agents that debate/critique each other?
  -> AutoGen

Need enterprise .NET integration?
  -> Semantic Kernel

Building Claude-native with minimal abstraction?
  -> Claude Agent SDK

Just need a simple agent loop?
  -> Skip frameworks, write it yourself (see agent-architecture skill)

Migration Patterns

From Raw API to LangGraph

The main change is wrapping your agent logic in graph nodes and making state explicit.

# Before: raw loop
messages = [{"role": "user", "content": task}]
while True:
    response = client.messages.create(...)
    if done:
        break
    messages.append(...)

# After: LangGraph
class State(TypedDict):
    messages: Annotated[list, add_messages]

def agent(state): ...
def should_continue(state): ...

graph = StateGraph(State)
graph.add_node("agent", agent)
# ... build graph

From CrewAI to LangGraph

Replace roles with graph nodes. Replace task dependencies with edges.

# CrewAI: implicit flow through task dependencies
crew = Crew(agents=[researcher, writer], tasks=[research_task, write_task])

# LangGraph: explicit graph
graph.add_node("research", research_node)
graph.add_node("write", write_node)
graph.add_edge("research", "write")

The general migration principle: move from implicit orchestration (framework manages control flow) to explicit orchestration (you define the exact graph). This trades convenience for control.

Install this skill directly: skilldb add ai-agent-orchestration-skills

Get CLI access →

Related Skills

agent-architecture

Core patterns for building AI agent systems: the observe-think-act loop, ReAct pattern implementation, tool-use cycles, memory systems (short-term and long-term), and planning strategies. Covers how to structure an agent's main loop, manage state between iterations, and wire together perception, reasoning, and action into a reliable autonomous system.

Ai Agent Orchestration368L

agent-error-recovery

Handling failures in AI agent systems: retry strategies with backoff, fallback tools, graceful degradation, human-in-the-loop escalation, stuck-loop detection, and context recovery after crashes. Covers practical patterns for making agents robust against tool failures, API errors, and reasoning dead-ends.

Ai Agent Orchestration470L

agent-evaluation

Testing and evaluating AI agents: trajectory evaluation, task completion metrics, tool-use accuracy measurement, regression testing, benchmark suites, and A/B testing agent configurations. Covers practical approaches to measuring whether agents are working correctly and improving over time.

Ai Agent Orchestration553L

agent-guardrails

Safety and control systems for AI agents: input and output validation, action authorization, rate limiting, cost controls, content filtering, scope restriction, and audit logging. Covers practical implementations for keeping agents within bounds while maintaining their usefulness.

Ai Agent Orchestration564L

agent-memory

Memory systems for AI agents: conversation history management, summarization strategies, vector-based long-term memory, entity memory, episodic memory, and memory retrieval patterns. Covers practical implementations for giving agents persistent, searchable memory across sessions and within long-running tasks.

Ai Agent Orchestration443L

agent-planning

Planning strategies for AI agents: chain-of-thought prompting, tree-of-thought exploration, plan-and-execute patterns, iterative refinement, task decomposition, and goal tracking. Covers practical implementations that make agents more reliable at complex, multi-step tasks by thinking before acting.

Ai Agent Orchestration459L