LangGraph LangChain Agent
In LLM application development, enabling a model to make autonomous decisions and invoke tools lies at the heart of building intelligent agents. LangChain originally addressed this through its Agent and AgentExecutor abstractions. LangGraph, the newer orchestration framework from the LangChain team, replaces the opaque execution loop with an explicit graph structure. This article examines the underlying principles, key differences, and practical patterns for both approaches.
A LangChain Agent is fundamentally an LLM-driven decision cycle. At each turn, the model receives the user input along with descriptions of available tools. It then decides whether to answer directly or invoke a specific tool. The tool result is fed back into the model, triggering another round of reasoning. This cycle repeats until the model produces a final answer.
This pattern is commonly known as ReAct (Reasoning + Acting). In the classic implementation, developers wrap the loop using AgentExecutor:
from langchain.agents import create_react_agent, AgentExecutor
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
executor.invoke({"input": "What is the weather in Beijing today?"})
AgentExecutor is convenient and ready to use out of the box, but it is a black box. The loop logic, termination conditions, and error retry behavior are all encapsulated internally. Once requirements move beyond a single agent calling tools, customization becomes expensive and difficult.
LangGraph: Explicit State Graphs
LangGraph abstracts agent execution as a state graph. Its core concepts include:
- State: A shared data structure that flows between nodes, typically defined with
TypedDictor Pydantic. - Node: A function that executes specific logic, reads the current state, and returns state updates.
- Edge: A fixed transition between two nodes.
- Conditional Edge: A dynamic transition determined by the current state, enabling branches and loops.
- Checkpoint: Persistence support for state, useful for multi-turn conversation memory, breakpoint recovery, and human-in-the-loop intervention.
Building a Minimal Agent with LangGraph
The following example implements a model-tool loop using LangGraph:
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import ToolNode
def call_model(state: MessagesState):
response = llm.bind_tools(tools).invoke(state["messages"])
return {"messages": [response]}
def should_continue(state: MessagesState):
last_message = state["messages"][-1]
return "tools" if last_message.tool_calls else END
builder = StateGraph(MessagesState)
builder.add_node("agent", call_model)
builder.add_node("tools", ToolNode(tools))
builder.add_edge(START, "agent")
builder.add_conditional_edges("agent", should_continue)
builder.add_edge("tools", "agent")
graph = builder.compile()
graph.invoke({"messages": [("user", "What is the weather in Beijing today?")]})
This code makes the advantages of LangGraph explicit. The loop is expressed as a direct edge from tools back to agent, while the termination condition is controlled by the should_continue function. Developers retain full visibility and control over every step. For standard ReAct behavior, the prebuilt langgraph.prebuilt.create_react_agent can generate an equivalent graph without manual construction.
AgentExecutor vs LangGraph
| Dimension | AgentExecutor | LangGraph |
|---|---|---|
| Process control | Encapsulated black-box loop | Explicit graph structure, freely customizable |
| Loops and branches | Limited support | Conditional edges support arbitrary topologies |
| State management | Implicit internal maintenance | Explicit state with optional persistence |
| Human collaboration | Difficult to implement | Built-in interrupt and human-in-the-loop support |
| Multi-agent collaboration | Not fundamentally supported | Native support via subgraphs and shared state |
| Ideal use cases | Simple tool invocation | Complex workflows, long-running tasks |
Selection Guidance
- Simple tasks: When the model only needs to call a few tools,
langgraph.prebuilt.create_react_agentis sufficient. It serves as a modern replacement for the classic agent pattern. - Complex workflows: For multi-step planning, multi-agent collaboration, human approval, failure retries, or long-running task recovery, use LangGraph to define a custom graph structure.
- Legacy systems: The original
AgentExecutoris officially treated as a legacy API. New projects should avoid it.
Conclusion
LangChain Agent established the paradigm of "LLM plus tools plus a reasoning loop," while LangGraph liberates that paradigm from a black box and turns it into a programmable, observable, and persistent graph structure. LangGraph can be viewed as the evolution of LangChain Agent: it preserves the core agent idea while providing the flexibility and control needed to build production-grade, complex intelligent applications. Understanding this evolution helps teams make sound technical decisions in real-world projects.