Key Findings
  • AI Agents are evolving from "passively answering questions" to autonomous systems that "proactively perceive environments, plan steps, call tools, and self-reflect." The ReAct framework, which interleaves reasoning and action, is the most prevalent Agent design pattern today
  • LangGraph, built around a directed graph state machine, offers the finest granularity of control and is best suited for production-grade applications requiring precisely defined execution flows; CrewAI, centered on role-playing and task delegation, delivers the fastest development speed but with lower flexibility
  • AutoGen (now AG2) employs a conversation-driven multi-agent architecture that excels in scenarios requiring deep negotiation between agents, though it has a steeper learning curve and higher debugging difficulty
  • This article includes two complete Google Colab implementations: building a ReAct tool-calling Agent with LangGraph, and building a multi-Agent research team with CrewAI — both executable with a single click

1. From Chatbots to Autonomous Agents: The Paradigm Shift of AI Agents

In 2023, large language models (LLMs) penetrated every industry at an astonishing pace. However, most applications remained stuck in the "human asks, AI answers" conversational paradigm — fundamentally no different from traditional search engines in terms of usage patterns. The real breakthrough comes when we endow LLMs with the ability to perceive their environment, plan steps, call external tools, and self-correct based on results — transforming them from passive language models into autonomous AI Agents[1].

In their 2024 survey, Wang et al.[1] defined LLM-based Agents as autonomous systems with an LLM as their cognitive core, comprising four major modules: Perception, Planning, Action, and Memory. This definition precisely captures the fundamental difference between Agents and traditional chatbots — Agents can not only answer questions but also proactively interact with the external world to complete multi-step tasks.

From an industry practice perspective, the value of Agents lies in their ability to liberate humans from repetitive cognitive labor. A well-designed Agent can autonomously complete complex tasks such as market research, data analysis, report writing, and code generation — work that would take an analyst several hours can be completed by an Agent in minutes. The "generative agents" research by Park et al.[7] further demonstrated social interaction capabilities between Agents, foreshadowing the immense potential of multi-agent collaboration.

However, building a reliable AI Agent is far from simply "connecting an LLM to a few APIs." The core challenges of Agents include: How do you ensure LLM consistency across multi-step reasoning? How do you gracefully handle tool call failures and retries? How do you coordinate information flow and decision authority among multiple Agents? These engineering challenges have given rise to a series of Agent development frameworks, with LangGraph, CrewAI, and AutoGen being the three most representative choices today.

2. Core Agent Architecture: Perceive, Plan, Act, Reflect

Before diving into the comparison of the three major frameworks, we must first understand the universal architectural patterns of AI Agents. Regardless of which framework is used, a complete Agent system encompasses four core stages[1]:

2.1 Perceive

An Agent must first understand its current task environment. This includes: parsing the user's natural language input, reading external data sources (databases, APIs, documents), and retrieving context memory from previous conversation turns. The quality of the perception module directly determines the accuracy of the Agent's subsequent decisions.

2.2 Plan

This is the most critical component of the Agent architecture. Based on perceived information, the LLM plans a sequence of steps to complete the task. The Chain-of-Thought (CoT) reasoning proposed by Wei et al.[3] forms the foundation of planning — through step-by-step reasoning, the LLM can decompose complex tasks into executable subtasks. The ReAct framework by Yao et al.[2] goes further by interleaving Reasoning and Acting, forming a "Think → Act → Observe → Think again" loop.

The core insight of ReAct is that the LLM doesn't need to plan all steps at once; instead, it can dynamically adjust subsequent plans based on observed results after each action. This "think while doing" strategy dramatically improves the Agent's robustness in uncertain environments.

2.3 Act

After planning, the Agent needs to execute actions. In the context of LLM-based Agents, "action" typically means calling external tools (Tool Calling / Function Calling). Research by Qin et al.[8] and the Toolformer system by Schick et al.[9] have systematically explored LLMs' ability to learn tool usage. Typical tools include: search engines, calculators, code executors, database queries, and API calls.

The key challenge of tool calling is that the LLM must precisely generate the structured inputs required by tools (e.g., JSON-formatted function parameters) and correctly parse the tool's return values. Research by Patil et al. on Gorilla[13] demonstrated the feasibility of improving LLM tool-calling accuracy through fine-tuning.

2.4 Reflect

Finally, a mature Agent should possess self-reflection capabilities. The Reflexion framework proposed by Shinn et al.[4] enables Agents to learn from failures and avoid repeating mistakes in subsequent attempts through a verbalized self-feedback mechanism. This "verbal reinforcement learning" approach requires no model weight updates and can be implemented purely through prompt engineering, offering extremely high practical engineering value.

The following diagram illustrates a typical ReAct Agent execution flow:

User question: "What was TSMC's Q4 2025 revenue? How much did it grow compared to the previous quarter?"

[Think] I need to look up TSMC's financial data. Let me search for the latest revenue report first.
[Act] Call search_tool("TSMC 2025 Q4 revenue report")
[Observe] Search results show: TSMC Q4 2025 revenue was NT$868.4 billion.
[Think] I have the Q4 revenue. Now I need Q3 data to calculate the growth rate.
[Act] Call search_tool("TSMC 2025 Q3 revenue")
[Observe] Search results show: TSMC Q3 2025 revenue was NT$759.6 billion.
[Think] Now I can calculate the growth rate: (8684 - 7596) / 7596 = 14.3%.
[Act] Call calculator(expression="(8684 - 7596) / 7596 * 100")
[Observe] Calculation result: 14.32%
[Final Answer] TSMC's Q4 2025 revenue was NT$868.4 billion, a growth of approximately 14.3% from NT$759.6 billion in Q3.

3. Deep Dive into LangGraph: A Graph-Centric State Machine Architecture

LangGraph is an Agent orchestration framework launched by the LangChain team[10], built on a profound observation: the execution flow of an Agent is essentially a Directed Graph, where Nodes represent computation steps and Edges represent control flow transitions.

3.1 Core Architecture: StateGraph

LangGraph's core abstraction is the StateGraph — a directed graph centered on shared state. Each node is a function that receives the current state, performs computation, and returns state updates. Edges define transition logic between nodes and can be unconditional (fixed direction) or conditional (determining the next step based on state).

from langgraph.graph import StateGraph, START, END
from typing import TypedDict, Annotated
from operator import add

# Define shared state structure
class AgentState(TypedDict):
    messages: Annotated[list, add]  # Message accumulation
    next_action: str

# Build graph
graph = StateGraph(AgentState)

# Add nodes
graph.add_node("reason", reasoning_node)
graph.add_node("act", action_node)
graph.add_node("observe", observation_node)

# Define edges (control flow)
graph.add_edge(START, "reason")
graph.add_conditional_edges(
    "reason",
    should_continue,  # Condition function
    {"continue": "act", "end": END}
)
graph.add_edge("act", "observe")
graph.add_edge("observe", "reason")  # Loop back to reasoning node

agent = graph.compile()

3.2 State Management and Persistence

One of LangGraph's major advantages is its built-in state management mechanism. Through Checkpointer, the state at each step can be persisted to a database (SQLite, PostgreSQL), enabling the Agent to resume execution from its last state after interruption. This is critical for long-running tasks.

Additionally, LangGraph supports Human-in-the-Loop mode: breakpoints can be set at specific nodes in the graph to pause execution and wait for human review before continuing. This is especially important for Agents that handle sensitive operations (e.g., sending emails, modifying databases).

3.3 Subgraphs and Modularity

Complex Agent systems can achieve modularity through Subgraphs. For example, a main graph handles overall task coordination, while "data collection," "analytical reasoning," and "report writing" are each handled by independent subgraphs. Subgraphs have their own state spaces and interact with the main graph only through well-defined interfaces, achieving separation of concerns.

3.4 Use Cases

4. Deep Dive into CrewAI: Role-Playing Multi-Agent Collaboration

CrewAI[11] takes a fundamentally different design philosophy: rather than requiring developers to define graph structures or control flows, it uses natural language descriptions of each Agent's Role, Goal, and Backstory, letting the framework automatically coordinate collaboration between Agents.

4.1 Core Abstractions: Agent, Task, Crew

CrewAI's three core concepts are intuitive and elegant:

from crewai import Agent, Task, Crew, Process

# Define Agent (role-playing)
researcher = Agent(
    role="Senior Market Researcher",
    goal="Collect and verify the latest market data and trends for a specific industry",
    backstory="You are a market researcher with 15 years of experience, "
              "skilled at extracting key insights from diverse data sources.",
    tools=[search_tool, scrape_tool],
    verbose=True
)

analyst = Agent(
    role="Data Analysis Expert",
    goal="Perform in-depth analysis on collected data to find hidden patterns and opportunities",
    backstory="You are a quantitative analyst with a PhD in statistics, "
              "skilled at transforming complex data into actionable business recommendations.",
    tools=[calculator_tool],
    verbose=True
)

# Define Task
research_task = Task(
    description="Investigate the global AI Agent market size in 2025, "
                "key players, and growth trends.",
    expected_output="A structured market research report with data sources.",
    agent=researcher
)

# Assemble Crew
crew = Crew(
    agents=[researcher, analyst],
    tasks=[research_task, analysis_task],
    process=Process.sequential,
    verbose=True
)

4.2 Process Modes

CrewAI supports two main process modes:

The Hierarchical mode draws from the organizational architecture concepts of MetaGPT[6] — coordinating multi-Agent behavior through role division and hierarchical management, making it closer to how real teams operate.

4.3 Built-in Tool Ecosystem

CrewAI provides a rich built-in tool suite (crewai-tools), including web search, web scraping, PDF reading, code execution, and more. Developers can also easily create custom tools by inheriting the BaseTool class and implementing the _run method.

4.4 Strengths and Limitations

Strengths:

Limitations:

5. Deep Dive into AutoGen: A Conversation-Driven Multi-Agent Framework

AutoGen (now renamed AG2) is a multi-agent conversation framework developed by the Microsoft Research team[5]. Unlike LangGraph's graph structure and CrewAI's role-playing approach, AutoGen's core design principle is conversation-driven: Agents negotiate, debate, divide labor, and synthesize results through multi-turn conversations.

5.1 Core Concept: ConversableAgent

All Agents in AutoGen inherit from ConversableAgent — an entity that can receive, process, and reply to messages. The two most commonly used Agent types are:

from autogen import AssistantAgent, UserProxyAgent, config_list_from_json

# Configure LLM
config_list = [{
    "model": "gpt-4o",
    "api_key": os.environ["OPENAI_API_KEY"]
}]

# Create AssistantAgent
assistant = AssistantAgent(
    name="research_assistant",
    llm_config={"config_list": config_list},
    system_message="You are an AI research assistant skilled at collecting data, "
                   "analyzing information, and writing structured reports."
)

# Create UserProxyAgent (auto-execute code)
user_proxy = UserProxyAgent(
    name="user_proxy",
    human_input_mode="NEVER",  # Fully automatic mode
    code_execution_config={
        "work_dir": "workspace",
        "use_docker": False
    }
)

# Start conversation
user_proxy.initiate_chat(
    assistant,
    message="Please analyze the latest trends in the AI Agent market "
            "and create a growth curve chart using Python."
)

5.2 GroupChat

One of AutoGen's most powerful features is GroupChat — allowing multiple Agents to interact in a shared conversation space. The GroupChatManager decides which Agent speaks each turn, based on rules, round-robin, or automatic LLM selection.

from autogen import GroupChat, GroupChatManager

# Define multiple Agents
researcher = AssistantAgent(name="researcher", ...)
coder = AssistantAgent(name="coder", ...)
critic = AssistantAgent(name="critic", ...)

# Create group chat
groupchat = GroupChat(
    agents=[user_proxy, researcher, coder, critic],
    messages=[],
    max_round=15,
    speaker_selection_method="auto"  # LLM auto-selects speaker
)

manager = GroupChatManager(
    groupchat=groupchat,
    llm_config={"config_list": config_list}
)

# Start multi-Agent conversation
user_proxy.initiate_chat(
    manager,
    message="Design a system that automatically collects and visualizes Taiwan stock market data."
)

5.3 Code Execution and Sandboxing

A distinctive feature of AutoGen is its built-in code execution capability. The AssistantAgent can generate Python code, and the UserProxyAgent automatically executes it in a local or Docker sandbox. If execution fails, the AssistantAgent automatically fixes the code and retries — forming a "generate → execute → fix" auto-iteration loop.

5.4 Strengths and Limitations

Strengths:

Limitations:

6. Hands-on Lab 1: Building a ReAct Tool-Calling Agent with LangGraph

This lab guides you through building a ReAct Agent from scratch in Google Colab. This Agent can autonomously decide when to call search tools or calculators, following the "Think → Act → Observe" loop until it finds the final answer.

Requirements: Google Colab (free tier is sufficient), you'll need your own OpenAI API Key.

Complete code below — can be copied directly to Colab for execution:

###############################################
# Hands-on Lab 1: LangGraph ReAct Agent
# One-click execution in Colab
###############################################

# -- Cell 1: Install packages --
# !pip install -q langgraph langchain-openai langchain-community tavily-python

# -- Cell 2: Set environment variables --
import os
from getpass import getpass

# Use getpass for secure input, won't display in notebook output
if "OPENAI_API_KEY" not in os.environ:
    os.environ["OPENAI_API_KEY"] = getpass("Enter your OpenAI API Key: ")

# Tavily Search API (free tier: 1000 requests/month)
if "TAVILY_API_KEY" not in os.environ:
    os.environ["TAVILY_API_KEY"] = getpass("Enter your Tavily API Key: ")

# -- Cell 3: Define tools --
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.tools import tool

# Search tool
search_tool = TavilySearchResults(
    max_results=3,
    search_depth="basic",
    include_answer=True
)

# Calculator tool
@tool
def calculator(expression: str) -> str:
    """Calculate a mathematical expression. Input should be a valid Python math expression.
    Example: '2 + 3 * 4' or '100 / 7'"""
    try:
        result = eval(expression, {"__builtins__": {}}, {})
        return f"Calculation result: {result}"
    except Exception as e:
        return f"Calculation error: {e}"

tools = [search_tool, calculator]
print(f"Loaded {len(tools)} tools: {[t.name for t in tools]}")

# -- Cell 4: Build ReAct Agent graph --
from langgraph.graph import StateGraph, START, END
from langgraph.prebuilt import ToolNode
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
from typing import TypedDict, Annotated
from operator import add

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

# Initialize LLM (bind tools)
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
llm_with_tools = llm.bind_tools(tools)

# System prompt
SYSTEM_PROMPT = """You are a professional research assistant. You can use the following tools:
1. tavily_search_results_json: Search for the latest information on the web
2. calculator: Perform mathematical calculations

Please follow these rules:
- When you need factual information, always use the search tool to verify
- When you need numerical calculations, use the calculator to ensure accuracy
- Provide your answer in English
- Explain your reasoning process in the final answer"""

# Reasoning node
def reasoning_node(state: AgentState):
    messages = state["messages"]
    # Ensure system prompt is at the front
    if not any(isinstance(m, SystemMessage) for m in messages):
        messages = [SystemMessage(content=SYSTEM_PROMPT)] + messages
    response = llm_with_tools.invoke(messages)
    return {"messages": [response]}

# Determine whether to continue calling tools
def should_continue(state: AgentState):
    last_message = state["messages"][-1]
    if hasattr(last_message, "tool_calls") and last_message.tool_calls:
        return "tools"
    return "end"

# Build graph
workflow = StateGraph(AgentState)

# Add nodes
workflow.add_node("reason", reasoning_node)
workflow.add_node("tools", ToolNode(tools))

# Define edges
workflow.add_edge(START, "reason")
workflow.add_conditional_edges(
    "reason",
    should_continue,
    {"tools": "tools", "end": END}
)
workflow.add_edge("tools", "reason")  # Tool results sent back to reasoning node

# Compile
agent = workflow.compile()
print("ReAct Agent graph compiled successfully!")

# -- Cell 5: Visualize Agent graph structure --
from IPython.display import Image, display

try:
    display(Image(agent.get_graph().draw_mermaid_png()))
    print("The diagram above shows the ReAct Agent's state machine structure:")
    print("  reason -> tools (tool call) -> reason (re-reason) -> ...")
except Exception:
    # If mermaid rendering fails, print text version
    print(agent.get_graph().draw_ascii())

# -- Cell 6: Execute Agent --
def run_agent(question: str):
    """Execute Agent and print the complete reasoning process"""
    print(f"\n{'='*60}")
    print(f"Question: {question}")
    print(f"{'='*60}\n")

    inputs = {"messages": [HumanMessage(content=question)]}

    step = 0
    for event in agent.stream(inputs, stream_mode="values"):
        last_msg = event["messages"][-1]
        step += 1

        if hasattr(last_msg, "tool_calls") and last_msg.tool_calls:
            for tc in last_msg.tool_calls:
                print(f"[Step {step}] Tool call: {tc['name']}")
                print(f"  Args: {tc['args']}")
        elif hasattr(last_msg, "content") and last_msg.content:
            msg_type = type(last_msg).__name__
            if msg_type == "ToolMessage":
                print(f"[Step {step}] Tool response: {last_msg.content[:200]}...")
            elif msg_type == "AIMessage":
                print(f"\n[Final Answer]\n{last_msg.content}")

    print(f"\n{'='*60}\n")

# Test question 1: Question requiring search
run_agent("What is the approximate size of the global AI market in 2025 in USD? "
          "If it grows at 35% annually, what will it reach by 2028?")

# Test question 2: Pure calculation question
run_agent("A company has annual revenue of $500 million, a net profit margin of 12%, "
          "and a P/E ratio of 25x. Calculate its market capitalization.")

# -- Cell 7: Custom questions --
# You can modify the question below to test Agent performance
# run_agent("your question")
print("Lab 1 complete! You've successfully built a ReAct tool-calling Agent.")
print("Try modifying the question in Cell 7 to observe how the Agent selects tools.")

Code walkthrough:

7. Hands-on Lab 2: Building a Multi-Agent Research Team with CrewAI

This lab builds a research team consisting of three Agents: a researcher responsible for data collection, an analyst for data analysis, and a writer for report composition. They collaborate in a sequential process to automatically complete a full research task.

Requirements: Google Colab (free tier is sufficient), you'll need your own OpenAI API Key.

Complete code below — can be copied directly to Colab for execution:

###############################################
# Hands-on Lab 2: CrewAI Multi-Agent Research Team
# One-click execution in Colab
###############################################

# -- Cell 1: Install packages --
# !pip install -q crewai crewai-tools

# -- Cell 2: Set environment variables --
import os
from getpass import getpass

if "OPENAI_API_KEY" not in os.environ:
    os.environ["OPENAI_API_KEY"] = getpass("Enter your OpenAI API Key: ")

# Set model (CrewAI defaults to GPT-4o)
os.environ["OPENAI_MODEL_NAME"] = "gpt-4o-mini"

print("Environment setup complete!")

# -- Cell 3: Define tools --
from crewai_tools import SerperDevTool, WebsiteSearchTool
from crewai import Agent, Task, Crew, Process
from crewai_tools import tool as crewai_tool

# Custom simple search tool (no additional API Key required)
@crewai_tool("Web Search Tool")
def simple_search(query: str) -> str:
    """Search for web information. Input search keywords, returns relevant result summaries."""
    # In real applications, this would call an actual search API
    # For lab demonstration, we use LLM to simulate search results
    from langchain_openai import ChatOpenAI
    llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.3)
    response = llm.invoke(
        f"Assume you are a search engine. Provide 3 relevant search result summaries "
        f"(including source names and key data) for the following query:\n\nQuery: {query}"
    )
    return response.content

@crewai_tool("Calculator Tool")
def calc_tool(expression: str) -> str:
    """Calculate a mathematical expression. Example: '100 * 1.35' or '500 / 7'"""
    try:
        result = eval(expression, {"__builtins__": {}}, {})
        return f"Calculation result: {result}"
    except Exception as e:
        return f"Calculation error: {e}"

print("Tool definitions complete!")

# -- Cell 4: Define three Agents --

# Agent 1: Researcher
researcher = Agent(
    role="Senior Industry Researcher",
    goal="Collect the latest and most authoritative market data and industry trends for a specified topic",
    backstory=(
        "You are an industry researcher who has worked at a top management consulting firm for 15 years. "
        "Your strength is filtering the most insightful data points from massive amounts of information, "
        "and you can clearly distinguish primary sources from secondary references. You value data timeliness "
        "and prefer citing the latest research from 2024-2026."
    ),
    tools=[simple_search],
    verbose=True,
    allow_delegation=False
)

# Agent 2: Analyst
analyst = Agent(
    role="Quantitative Analysis Expert",
    goal="Perform in-depth analysis on collected data to find hidden patterns, calculate key metrics, "
         "and produce visualization recommendations",
    backstory=(
        "You have a PhD in statistics and previously worked as a quantitative researcher at a hedge fund. "
        "You excel at extracting signals from noisy data and can calculate CAGR, market share, "
        "growth rates, and other key business metrics. Your analyses always include calculation processes "
        "to ensure verifiability of conclusions."
    ),
    tools=[calc_tool, simple_search],
    verbose=True,
    allow_delegation=False
)

# Agent 3: Writer
writer = Agent(
    role="Technical Content Strategist",
    goal="Integrate research data and analytical conclusions into a professional, readable English report",
    backstory=(
        "You previously served as a senior editor at McKinsey, specializing in transforming complex "
        "technical analyses into strategic reports understandable by senior management. "
        "Your writing style is concise and powerful, using analogies and visualization suggestions "
        "to convey core viewpoints. Your reports are written in professional English."
    ),
    tools=[],
    verbose=True,
    allow_delegation=False
)

print("Three Agents defined: Researcher, Analyst, Writer")

# -- Cell 5: Define tasks --

# Define research topic (you can modify this!)
RESEARCH_TOPIC = "AI Agent Development Framework Market: Competitive Landscape and Future Trends of LangGraph, CrewAI, and AutoGen"

# Task 1: Market research
research_task = Task(
    description=(
        f"Conduct comprehensive market research on the following topic:\n\n"
        f"Topic: {RESEARCH_TOPIC}\n\n"
        f"You need to investigate and collect the following information:\n"
        f"1. GitHub stars, contributor count, and version iteration frequency for each framework\n"
        f"2. Key enterprise users and use cases for each framework\n"
        f"3. Developer community size and activity level\n"
        f"4. Funding background and commercialization strategy for each framework\n"
        f"5. Major updates and roadmap for 2025-2026"
    ),
    expected_output=(
        "A structured research memo containing specific data across all five dimensions, "
        "with each data point annotated with source and date."
    ),
    agent=researcher
)

# Task 2: Data analysis
analysis_task = Task(
    description=(
        "Based on the data provided by the researcher, perform the following analyses:\n\n"
        "1. Calculate the CAGR for each framework — using GitHub stars as a proxy metric\n"
        "2. Create a feature comparison matrix (control granularity, learning curve, multi-Agent support, etc.)\n"
        "3. Analyze each framework's technical moat and potential risks\n"
        "4. Predict market direction for the next 12 months\n"
        "5. Provide framework selection recommendations for different use cases"
    ),
    expected_output=(
        "A report with quantitative analysis results, including calculation processes, "
        "comparison tables, and data-driven strategic recommendations."
    ),
    agent=analyst
)

# Task 3: Report writing
writing_task = Task(
    description=(
        "Integrate all outputs from the researcher and analyst into a complete analysis report in English.\n\n"
        "Report structure:\n"
        "1. Executive Summary (3-5 sentences summarizing core findings)\n"
        "2. Market Overview (size, trends, key players)\n"
        "3. Deep Framework Comparison (features, performance, community, commercialization)\n"
        "4. Decision Recommendations (recommend frameworks by use case)\n"
        "5. Risk Alerts and Future Outlook\n\n"
        "Requirements: Professional but readable language, "
        "key data highlighted in bold, appropriate use of tables and lists."
    ),
    expected_output=(
        "A professional analysis report of 800-1200 words, "
        "including executive summary, body, comparison tables, and strategic recommendations."
    ),
    agent=writer
)

print("Three tasks defined: Research -> Analysis -> Writing")

# -- Cell 6: Assemble Crew and execute --

crew = Crew(
    agents=[researcher, analyst, writer],
    tasks=[research_task, analysis_task, writing_task],
    process=Process.sequential,  # Sequential execution
    verbose=True
)

print("Crew assembled! Starting multi-Agent collaboration...\n")
print("=" * 60)

# Execute!
result = crew.kickoff()

print("\n" + "=" * 60)
print("Multi-Agent collaboration complete!")
print("=" * 60)

# -- Cell 7: Display final report --
print("\n\n" + "=" * 60)
print("Final Report")
print("=" * 60 + "\n")
print(result.raw)

# -- Cell 8: View execution statistics --
print("\n\n" + "=" * 60)
print("Execution Statistics")
print("=" * 60)

# View token usage
if hasattr(result, "token_usage"):
    usage = result.token_usage
    print(f"Total token consumption: {usage.total_tokens:,}")
    print(f"  - Prompt tokens: {usage.prompt_tokens:,}")
    print(f"  - Completion tokens: {usage.completion_tokens:,}")

# View each Task's output
if hasattr(result, "tasks_output"):
    for i, task_output in enumerate(result.tasks_output):
        print(f"\nTask {i+1} ({['Research', 'Analysis', 'Writing'][i]}):")
        print(f"  Agent: {task_output.agent}")
        print(f"  Output length: {len(task_output.raw)} characters")

print("\n\nLab 2 complete!")
print("You can modify the RESEARCH_TOPIC variable in Cell 5")
print("to have the research team produce reports on different topics.")

Code walkthrough:

Advanced challenge: Try changing Process.sequential to Process.hierarchical and observe how the framework automatically introduces a "Manager Agent" to coordinate task allocation.

8. Decision Framework: Comparison and Selection Guide for Three Major Frameworks

After the in-depth analysis and hands-on practice above, we can now systematically compare the three major frameworks to help you make the best choice based on your specific needs.

8.1 Comprehensive Comparison Table

Comparison Dimension LangGraph CrewAI AutoGen (AG2)
Core Abstraction Directed Graph (StateGraph) Agent + Task + Crew ConversableAgent + GroupChat
Design Philosophy State machine, graph computation Role-playing, task delegation Conversation-driven, multi-party negotiation
Control Granularity Very high — every edge and condition can be defined Low — framework auto-coordinates Medium — configurable but less intuitive than graphs
Learning Curve Moderate — requires understanding graphs and state concepts Low — intuitive role definitions High — many conceptual layers, complex API
Multi-Agent Support Via subgraphs Native support (Crew) Native support (GroupChat)
State Management Built-in Checkpointer with persistence Basic context passing Auto-managed conversation history
Human-in-the-Loop Native breakpoint and human review support Limited support Supported (human_input_mode)
Code Execution Requires custom integration Via tools Native built-in (Docker sandbox)
Observability Excellent — LangSmith integration Basic verbose logging Moderate — conversation logs
Ecosystem LangChain ecosystem (richest) Independent but fast-growing Microsoft ecosystem
Best for Teams Experienced backend engineers Rapid prototyping teams Research-oriented teams
Production Readiness High Medium Medium
License MIT MIT Apache 2.0 (original) / CC BY 4.0 (AG2)

8.2 Scenario-Based Selection Guide

Based on your specific use case, we recommend the following selection strategies:

Choose LangGraph if you:

Choose CrewAI if you:

Choose AutoGen (AG2) if you:

8.3 Hybrid Strategy

In enterprise practice, we often recommend clients adopt a hybrid strategy: use CrewAI for rapid concept validation (the AI PoC phase), then rewrite in LangGraph for a production-grade system once feasibility is confirmed. For sub-modules requiring code generation and execution, AutoGen's code execution capabilities can be embedded. This strategy balances development speed with production stability.

Findings by Xie et al. in the TravelPlanner benchmark[12] also support this view: it is unrealistic for a single framework to perform best in all scenarios. Selecting the most suitable combination of tools for different task characteristics is the optimal engineering solution.

9. Conclusion and Outlook

AI Agent development is at an exciting inflection point. From single ReAct loops to multi-Agent collaboration systems, from simple tool calling to complex task planning and self-reflection, the capability boundaries of Agents are expanding at a remarkable pace.

However, we must also confront the current challenges:

Looking ahead, we see several important trends converging:

First, the standardization of MCP (Model Context Protocol)[15]. The MCP protocol proposed by Anthropic is becoming the universal standard for Agent-tool interaction, which will significantly reduce the engineering cost of tool integration and promote interoperability within the Agent ecosystem.

Second, Agent-native foundation models. Future LLMs will no longer be language models with Agent capabilities "bolted on," but will be optimized for Agent scenarios from the pre-training stage — better tool-calling accuracy, stronger multi-step planning capabilities, and lower hallucination rates.

Third, framework convergence and standardization. Currently, the three major frameworks each have their strengths but are incompatible with each other. Higher-level abstractions may emerge in the future, allowing developers to mix the advantages of different frameworks under a unified interface.

For enterprises, now is the optimal time to invest in Agent technology. There's no need to wait for the "perfect" framework — choose a tool that fits your current needs, start building, and accumulate experience and datasets through practice. Our experience at Meta Intelligence shows that the most successful Agent projects are not built in one shot, but start with simple ReAct tool calling and gradually expand to multi-Agent collaboration, validating business value at every step.

If your team is evaluating AI Agent adoption plans or encountering difficulties with framework selection, feel free to contact us. Our PhD research team continuously tracks the latest developments in Agent technology and can assist you through every stage — from architecture design and framework selection to production deployment.