our lives lengthy earlier than LangGraph. This can be a clear indication of LangGraph closing a spot. In different phrases, LangGraph does issues which can be extra sophisticated or not attainable to do with LangChain.
On this article, we’ll go over 4 key variations between LangChain and LangGraph, and the way they affect the code we write to construct agentic workflows.
Let’s first point out that these should not competing instruments. LangGraph is a part of the LangChain ecosystem. It’s sort of an extension constructed on high of LangChain.
1. Pipeline vs Loops

LangChain is a pipeline with a transparent route:

We chain parts collectively however in a single route, which appears like this in code:
chain = immediate | mannequin | parser
output = chain.invoke(enter)
We are able to nonetheless department, run steps in parallel, and assemble DAGs, however the default abstraction is information being moved ahead by way of a pipeline.
This construction is sufficient for fixing many issues comparable to
- Retrieve paperwork, then generate a solution
- Extract fields, then save them
- Summarize textual content, then classify it
Nevertheless, with regards to sending backward, we have to write an outer Python loop. Therefore, the appliance handles the remaining, not LangChain.
However, LangGraph treats loops as a part of the workflow itself. It’s mainly a graph with nodes and edges.
- A node performs a selected process.
- A traditional edge defines fastened transitions between nodes.
- A conditional edge decides the place to go subsequent.
Due to the conventional and conditional edges, we are able to route again to earlier nodes with out a hustle. Right here is the diagram of a customer support agent I constructed with LangGraph:

Buyer represents the enter node, AI Agent is the mannequin, worth and reserving engines are the opposite nodes. We are able to trip between nodes.
2. Stateless vs Stateful
A LangChain pipeline doesn’t maintain a state inside itself. Every runnable normally receives an enter and returns an output. State is handed ahead within the type of a dictionary, message, or a customized object.
That is sufficient when every step wants solely the earlier step’s outcome. Nevertheless, as soon as we have now a extra advanced workflow with loops or branches, it’s on us to trace the present draft, validation errors, dialog historical past, retry counts, and many others.
We are able to handle all of that writing further Python code however, as we talked about earlier, it’s not a part of the chain.
LangGraph creates stateful brokers so the state is a part of the graph. We declare a schema for the state, normally within the type of a TypedDict . For instance, right here is the state object of my customer support agent:
class AgentState(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
booking_details: BookingDetails
calculated_price: NotRequired[float | None]
time_options: NotRequired[list[TimeOption]]
selected_slot: NotRequired[TimeOption | None]
standing: BookingStatus
booking_id: NotRequired[str | None]
A node doesn’t need to reconstruct the whole state. It could possibly do partial updates and LangGraph handles it easily. On this agent, we have now a worth engine node, which solely updates the calculated_price within the agent state:
def calculate_price_node(state: AgentState) -> dict[str, Any]:
return {"calculated_price": calculate_price(state["booking_details"])}
LangGraph then merges that replace into the prevailing state.
State fields can even have reduces for values written by a number of nodes or similar node a number of occasions. For instance, the messages area of the customer support agent state is up to date after each buyer message so we have now a diminished (add_messages ) for this area ( messages: Annotated[list[AnyMessage], add_messages]).
With out a reducer, a brand new worth usually replaces the previous worth, which is one thing we must always keep away from when conserving observe of chat historical past.
3. Human-breaks-the-loop vs Human-in-the-loop
We’ve witnessed brokers making essential errors. So, particularly for some important duties, we could wish to intervene with brokers operations.
Suppose an agent prepares a database migration, refund, or manufacturing deployment. We could need a human-in-the-loop to approve it earlier than agent truly executes.
With a traditional LangChain pipeline, the frequent method is to construct that pause into the appliance surrounding the pipeline. A typical method could be:
- Run the chain till it proposes an motion.
- Save the proposal someplace.
- Return management to an API or job queue.
- Await an approval occasion.
- Reconstruct the required context.
- Begin the following portion of the workflow.
This method works however requires a number of work. It sounds extra like a human-breaks-the-loop and reconstructs it.
However, LangGraph offers dynamic interrupt() calls inside nodes. Interrupts enable us to pause graph execution at particular factors and anticipate exterior enter to proceed.
Once we set off an interrupt, LangGraph saves the graph state so we don’t want to fret about dropping data or information.
Dynamic interrupts can embody a payload and resume with a human response. Right here is an instance:
from langgraph.sorts import interrupt
def approval_node(state: State):
accepted = interrupt({
"query": "Run this migration?",
"sql": state["sql"],
})
return {"accepted": accepted}
4. Restarts vs Resume
When a step in a traditional chain fails, the only solution to recuperate is commonly to invoke the chain once more. This may be an costly choice as a result of previous mannequin calls, retrieval queries, transformations, different instrument calls must be repeated.
We are able to add caching and write customized resume logic however these wouldn’t be a part of the chain. Much like our discussing in earlier factors, these are dealt with on the appliance degree, not in LangChain.
LangGraph has one thing referred to as checkpointer, which is a state persistence layer that saves a snapshot of an agent’s graph state at each step of execution.
As a way to activate it, we simply want compile the graph with a checkpointer:
graph.compile(checkpointer=checkpointer)
Checkpoints permits for resuming after a failure slightly than restarting the whole workflow. This protects us the price (each money and time) of executing the profitable operations once more.
We are able to additionally examine the state earlier than a problematic code or restart execution from any of the sooner checkpoints.
When to make use of which
We are able to keep on with LangChain pipelines when the workflow is usually predictable and forward-moving comparable to:
- Customary RAG pipelines,
- Easy question-answering bots,
- Doc extraction and classification duties,
- Summarization
If the management circulate is advanced and constitutes the key a part of our agentic system, we must always think about using LangGraph.
A typical use case could be coding assistants that generate, check, and restore code.
LangGraph can be a greater match for workflows with repeated planning and evaluating actions.
As we talked about within the “restarts vs resume” part, purposes that require pause, persist, and resume can benefit from the stateful LangGraph brokers.
Use LangChain when your software is finest understood as a pipeline. Use LangGraph when it’s higher understood as a stateful system.
Thanks for studying!
















