DEV Community

丁久
丁久

Posted on • Originally published at dingjiu1989-hue.github.io

Building Custom AI Agents with LangGraph: A Practical Guide

This article was originally published on AI Study Room. For the full version with working code examples and related articles, visit the original post.

Building Custom AI Agents with LangGraph: A Practical Guide

LangGraph extends LangChain with graph-based state machine orchestration for building reliable, multi-step AI agent workflows. Unlike traditional linear chains, LangGraph lets you define cyclic graphs with conditional routing, persistent state, and human-in-the-loop checkpoints.

Why LangGraph?

Most agent frameworks chain LLM calls linearly: call LLM, parse output, call tool, repeat. This breaks for complex tasks requiring loops, branching, or manual approval. LangGraph models agents as state graphs where each node is a computation step and edges define control flow.

The key innovations are state persistence across steps, conditional edges that route based on output content, and built-in checkpointing for pause-and-resume.

Installing and Setup

pip install langgraph langchain langchain-openai
Enter fullscreen mode Exit fullscreen mode

Python 3.10+ is required. LangGraph runs entirely locally — no external server needed.

Defining Your State Graph

Every LangGraph application starts with a state definition. The state is a typed dictionary that flows through all nodes:

from typing import TypedDict, Literal
from langgraph.graph import StateGraph, END

class AgentState(TypedDict):
    input: str
    messages: list
    output: str
    steps: int
Enter fullscreen mode Exit fullscreen mode

This state carries the user's input, the conversation history, the final output, and a step counter for loop control.

Building Nodes

Nodes are Python functions that receive the state and return updates. Each node focuses on one task:

  • call_llm — evaluates the current state and decides the next action
  • execute_tool — runs external API calls (search, calculator, database)
  • should_continue — a conditional edge function that routes to continue or end

Conditional Routing

Conditional edges are what make LangGraph powerful. A routing function inspects the state and returns the next node name:

def route(state):
    if 'SEARCH' in state['messages'][-1]:
        return 'search_tool'
    elif 'CODE' in state['messages'][-1]:
        return 'code_executor'
    else:
        return END

graph.add_conditional_edges('call_llm', route)
Enter fullscreen mode Exit fullscreen mode

The agent dynamically chooses paths based on LLM output.

Adding Memory and Checkpointing

LangGraph supports persistent memory via checkpointing. This enables pause-and-resume, human-in-the-loop approvals, and debugging:

from langgraph.checkpoint import MemorySaver

memory = MemorySaver()
graph = builder.compile(checkpointer=memory)
config = {'configurable': {'thread_id': 'session_1'}}

for event in graph.stream({'input': 'Analyze this data'}, config):
    print(event)
Enter fullscreen mode Exit fullscreen mode

Each checkpoint saves the full state so you can replay or inspect any step.

Human-in-the-Loop Patterns

A common pattern is pausing execution for human approval before executing destructive tools:

def human_approval(state):
    print(f'About to execute: {state["next_action"]}')
    approval = input('Approve? (y/n): ')
    if approval.lower() != 'y':
        return 'revise_prompt'
    return 'execute_tool'
Enter fullscreen mode Exit fullscreen mode

Wrap the node with interrupt_before to pause before sensitive steps. Essential for production agents that might issue API calls or modify databases.

Parallel Execution

LangGraph supports fan-out patterns where multiple nodes run in parallel:

graph.add_node('search_web')
graph.add_node('search_docs')
graph.add_node('search_vector_db')
graph.add_edge('call_llm', 'parallel_search')
Enter fullscreen mode Exit fullscreen mode

Each search node runs concurrently. A merge function combines results into a unified state update.

Performance Tips

  • Keep node functions pure — avoid side effects beyond the state update
  • Use checkpointer=None for simple stateless chains to reduce overhead
  • For production, use SQLiteSaver instead of MemorySaver to survive restarts
  • Limit graph depth to under 20 nodes for predictable latency

Real-World Example

A customer support agent built with LangGraph processes incoming tickets through classification, knowledge base search, escalation decision, and response generation — all with manual override at each stage. A startup using this pattern reduced ticket resolution time by 60% while maintaining human oversight on sensitive issues.

Summary

LangGraph transforms agent building from fragile linear chains into robust state machines. The graph model handles complex control flow naturally, and checkpointing makes production deployment safer.


Read the full article on AI Study Room for complete code examples, comparison tables, and related resources.

Found this useful? Check out more developer guides and tool comparisons on AI Study Room.

Top comments (0)