Orchestration Frameworks

Multi-Agent Orchestration

Master the software frameworks used to design, run, and orchestrate complex multi-agent architectures. Compare LangGraph, AutoGen, and CrewAI, and learn how to manage shared state, define custom loops, execute tools, and handle user input.

Concepts Frameworks Setup Guide Usage Examples Best Practices FAQ

Core Orchestration Concepts

Foundational principles for designing multi-agent communication and state flows.

State Management

Unlike single chat loops, multi-agent systems maintain a shared state (schema) updated by different agents. State tracking ensures that data generated by a research agent is correctly formatted and accessible to a writer agent.

Routing & Control Flows

Determines which agent acts next. Flows can be sequential (A -> B -> C), hierarchical (supervisor routes to specialists), or cyclical graphs (retrying execution when tests fail).

Human-in-the-Loop

A critical mechanism to pause agent workflows for human approval, manual edits, or feedback. Used for high-stakes actions like budget decisions, deleting database tables, or publishing articles.

Tool Calling & Binding

The interface where models decide to run external functions. Frameworks automatically parse the LLM's JSON request, invoke the target API, and pass the results back to the agent's memory thread.

Thread-Safe Memory

Agents need memory across conversations. Frameworks support short-term memory (current workflow thread) and long-term memory (persisted user profile settings, past executions, feedback history).

Agent Collaboration

How agents converse. Can be collaborative (sharing a blackboard/state), conversational (exchanging messages in a group chat), or cooperative (executing parallel sub-tasks).

Comparing Frameworks

Choose the right tool based on your system design requirements.

Framework Core Pattern Key Strengths Best For
LangGraphState Machine Graph (Nodes & Edges)Infinite cyclical loops, explicit state transitions, granular controlComplex enterprise workflows, custom state graphs
CrewAIRole-Based Assembly (Agents -> Tasks)Easy role definition, clean OOP code, structured outputsSequential document workflows, autonomous squads
AutoGenConversational Event-Driven LoopsNative group chats, dynamic routing, code execution execution environmentCollaborative problem-solving, code writing systems

Setup Guide

Install package dependencies for each framework.

LangGraph Setup

# Install via pip
pip install langgraph langsmith

# Optional: install community tools
pip install langchain-community \
  langchain-openai

# Setup environment
export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_API_KEY=lsv2_...

CrewAI Setup

# Install core crewai package
pip install crewai

# Install tool extensions
pip install 'crewai[tools]'

# Set keys
export OPENAI_API_KEY=sk-...
export OPENAI_MODEL_NAME=gpt-4o

AutoGen Setup

# Install python package (v0.4+)
pip install autogen-agentchat \
  autogen-ext

# Set keys
export OPENAI_API_KEY=sk-...
export GEMINI_API_KEY=AIza...

Usage Examples

Practical implementations for each orchestration framework.

LangGraph (State Graph)
from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, START, END

# Define state
class State(TypedDict):
  messages: list

# Define nodes
def agent(state: State):
  return {"messages": ["hello"]}

# Construct graph
builder = StateGraph(State)
builder.add_node("agent", agent)
builder.add_edge(START, "agent")
builder.add_edge("agent", END)

graph = builder.compile()
graph.invoke({"messages": []})
CrewAI (Role-Based OOP)
from crewai import Agent, Task, Crew

# Define agent role
writer = Agent(
  role="Tech Writer",
  goal="Write blog posts",
  backstory="An experienced editor"
)

# Define task
task = Task(
  description="Write a post on Kafka",
  expected_output="A markdown post",
  agent=writer
)

# Form squad
crew = Crew(
  agents=[writer],
  tasks=[task]
)
crew.kickoff()
AutoGen (Chat Loop)
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_ext.models.openai import OpenAIChatCompletionClient

async def main():
  client = OpenAIChatCompletionClient(model="gpt-4o")
  agent1 = AssistantAgent("writer", model_client=client)
  agent2 = AssistantAgent("editor", model_client=client)

  team = RoundRobinGroupChat([agent1, agent2], max_turns=3)
  await team.run(task="Draft a pitch")

asyncio.run(main())

Best Practices

Guidelines for building reliable production-grade agentic systems.

🔄 Loop Control

  • • Always set a maximum recursion limit (e.g. 50 steps)
  • • Track agent loop tokens to prevent infinite API spend
  • • Use schema verification to fail-fast on malformed agent responses
  • • Detect repeating states and trigger fallback routing

💡 State Partitioning

  • • Keep the global state schema as minimal and clean as possible
  • • Allow agents to maintain private local scratchpad contexts
  • • Serialize state updates atomically to support concurrent runs
  • • Implement schema versioning for live system migration

🔍 Tracing & Observability

  • • Connect tracing dashboards like LangSmith or Phoenix
  • • View complete execution paths: nodes visited and variables updated
  • • Log prompt templates separately from runtime outputs
  • • Track cost per execution run for budgeting controls

Frequently Asked Questions

When should I choose LangGraph over CrewAI?
Choose LangGraph if your application requires custom state definitions, explicit loop transitions (such as retrying a code fix), or advanced human approval pauses. Choose CrewAI if your process is mostly sequential, role-based, or requires rapid out-of-the-box setup without drawing node maps.
How do agents call tools asynchronously?
The LLM outputs a tool-call JSON object (indicating name and args). The orchestration framework intercepts this payload, executes the bounded Python function (often using async engines like asyncio to handle multiple calls in parallel), and returns the results to the conversation history database.
How does Human-in-the-Loop actually work in code?
In LangGraph, you define a graph compile setting with interrupt_before or interrupt_after specific nodes. When execution hits this point, the thread pauses, saves state to a persistent database checkpoint, and waits for a user payload. The API restarts execution by calling graph.resume(thread_id, user_payload).
How do you handle memory in a multi-agent group chat?
In conversational frameworks like AutoGen, memory is handled by either broadcasting the entire dialogue history to all participating agents, or utilizing a summary node that compresses past exchanges before sending them to the LLM. This prevents token usage from scaling exponentially.
How do I secure an agent executing custom code tools?
Never run generated code directly on your host machine. Always execute code tools within isolated sandboxes: use secure runtime sandboxes like E2B, Docker containers with limited profiles, or serverless execution APIs. Enforce resource quotas, network rules, and max timeouts on the runtimes.