Tutorial Image: LangGraph Tutorial: Building Agent Graphs - Unit 2.2 Exercise 9

LangGraph Tutorial: Building Agent Graphs - Unit 2.2 Exercise 9

Learn how to build agent graphs in LangGraph for dynamic, tool-enabled conversations. Explore node implementation, flow control, and state management to create advanced AI systems.

๐ŸŽฏ What You'll Learn Today

LangGraph Tutorial: Building Agent Graphs - Unit 2.2 Exercise 9

This tutorial is also available in Google Colab here or for download here

Joint Initiative: This tutorial is part of a collaboration between AI Product Engineer and the Nebius Academy.

This tutorial demonstrates how to build and configure agent graphs in LangGraph, showing proper node construction, edge configuration, and state management.

Key Concepts Covered

  1. Graph Construction and Configuration
  2. Node Implementation
  3. Edge and Flow Control
  4. State Management
from typing import Annotated, Literal, TypedDict
!pip install langchain-core
!pip install langgraph
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
from langgraph.graph import END, START, StateGraph
from langgraph.graph.message import add_messages

Step 1: State Definition

Define state structure for our agent graph.

Why This Matters

Proper state structure is crucial because

  1. Maintains conversation context
  2. Tracks execution progress
  3. Enables tool management

Debug Tips

  1. State Structure Issues:
  • Verify all required fields
  • Check type annotations
  • Monitor state transitions
class State(TypedDict):
    """State container for agent graph system.

    Notes:
        - messages tracks conversation flow
        - current_step tracks execution state
        - tool_name tracks selected tools
        - tool_output stores execution results

    Attributes:
        messages: Conversation history with proper typing
        current_step: Current execution phase
        tool_name: Currently selected tool
        tool_output: Latest tool result
    """

    messages: Annotated[list[BaseMessage], add_messages]
    current_step: str
    tool_name: str | None
    tool_output: str | None

Step 2: Node Implementation

Create nodes for the agent graph.

Why This Matters

Node implementation is critical because

  1. Defines system behavior
  2. Manages state transitions
  3. Handles tool interactions

Debug Tips

  1. Node Implementation Issues:
  • Verify state updates
  • Check message handling
  • Monitor tool selection
def tool_selector(state: State) -> State:
    """Select appropriate tools based on conversation.

    Notes:
        - Handles initial message
        - Implements tool selection logic
        - Updates state immutably

    Args:
        state: Current conversation state

    Returns:
        Updated state with tool selection
    """
    if not state.get("messages"):
        return {
            **state,
            "messages": [HumanMessage(content="What would you like to know?")],
            "current_step": "waiting_for_input",
        }

    last_message = state["messages"][-1].content.lower()

    # Tool selection logic
    if "weather" in last_message:
        tool = "weather_tool"
        response = "I'll check the weather for you."
    elif "calculate" in last_message:
        tool = "calculator_tool"
        response = "I'll help you with that calculation."
    else:
        tool = "search_tool"
        response = "I'll search for that information."

    return {
        **state,
        "tool_name": tool,
        "messages": state["messages"] + [AIMessage(content=response)],
        "current_step": "tool_selected",
    }
def tool_executor(state: State) -> State:
    """Execute selected tool and manage results.

    Notes:
        - Verifies tool selection
        - Simulates tool execution
        - Updates state with results

    Args:
        state: Current conversation state

    Returns:
        Updated state with execution results
    """
    tool_name = state.get("tool_name")
    if not tool_name:
        return state

    # Simulate tool execution
    if tool_name == "weather_tool":
        output = "The weather is sunny and 22ยฐC"
    elif tool_name == "calculator_tool":
        output = "The result is 42"
    else:
        output = "Here's what I found from the search"

    return {**state, "tool_output": output, "current_step": "tool_executed"}
def result_processor(state: State) -> State:
    """Process and format tool execution results.

    Notes:
        - Verifies tool output
        - Formats response
        - Updates conversation

    Args:
        state: Current conversation state

    Returns:
        Updated state with processed results
    """
    tool_output = state.get("tool_output")
    if not tool_output:
        return state

    response = f"Here's what I found: {tool_output}"

    return {
        **state,
        "messages": state["messages"] + [AIMessage(content=response)],
        "current_step": "result_processed",
    }

Step 3: Flow Control

Implement flow control logic for the graph.

Why This Matters

Flow control is essential because

  1. Manages conversation progression
  2. Handles termination conditions
  3. Enables proper routing

Debug Tips

  1. Flow Control Issues:
  • Check routing conditions
  • Verify state transitions
  • Monitor termination
def get_next_step(state: State) -> Literal["continue", "end"]:
    """Determine next step in conversation flow.

    Notes:
        - Checks current step
        - Determines continuation
        - Handles termination

    Args:
        state: Current conversation state

    Returns:
        Next step identifier
    """
    return "end" if state.get("current_step") == "result_processed" else "continue"

Step 4: Graph Construction

Build and configure the agent graph.

Why This Matters

Graph construction is crucial because

  1. Defines system structure
  2. Configures execution flow
  3. Enables proper routing

Debug Tips

  1. Graph Construction Issues:
  • Verify node connections
  • Check edge conditions
  • Monitor graph compilation
def create_agent_graph() -> StateGraph:
    """Create complete agent graph configuration.

    Notes:
        - Initializes graph
        - Adds all nodes
        - Configures edges
        - Sets up routing

    Returns:
        Configured StateGraph
    """
    graph = StateGraph(State)

    # Add nodes
    graph.add_node("tool_selector", tool_selector)
    graph.add_node("tool_executor", tool_executor)
    graph.add_node("result_processor", result_processor)

    # Configure edges
    graph.add_edge(START, "tool_selector")
    graph.add_edge("tool_selector", "tool_executor")
    graph.add_edge("tool_executor", "result_processor")

    # Add conditional routing
    graph.add_conditional_edges(
        "result_processor", get_next_step, {"continue": "tool_selector", "end": END}
    )

    return graph

Step 5: System Demonstration

Test the agent graph system.

Why This Matters

System demonstration verifies

  1. Proper execution flow
  2. Correct state updates
  3. Expected behavior
def demonstrate_graph():
    """Demonstrate agent graph functionality."""
    graph = create_agent_graph()
    chain = graph.compile()

    # Initialize state
    state = {
        "messages": [HumanMessage(content="What's the weather like?")],
        "current_step": "start",
        "tool_name": None,
        "tool_output": None,
    }

    print("Agent Graph Demonstration")
    print("========================")

    result = chain.invoke(state)

    print("\nFinal Conversation:")
    for msg in result["messages"]:
        speaker = "Human" if isinstance(msg, HumanMessage) else "Assistant"
        print(f"{speaker}: {msg.content}")

Common Pitfalls

  1. Incorrect state structure
  2. Missing edge conditions
  3. Improper node connections
  4. Poor error handling

Key Takeaways

  1. State management is critical
  2. Node implementation must be consistent
  3. Edge configuration defines flow
  4. Proper testing validates behavior

Next Steps

  1. Add error handling
  2. Implement state validation
  3. Add conversation history
  4. Enhance tool integration

Expected Output

Agent Graph Demonstration

Final Conversation

Human: What's the weather like?
Assistant: I'll check the weather for you.
Assistant: Here's what I found: The weather is sunny and 22ยฐC
if __name__ == "__main__":
    demonstrate_graph()

Rod Rivera

๐Ÿ‡ฌ๐Ÿ‡ง Chapter