LangGraph vs plain chains: when orchestration becomes necessary
- LangGraph
- LangChain
- Architecture
There’s a temptation, as soon as you discover LangGraph, to model everything as a state graph. That’s not always the right call — a linear chain (prompt → model → parsing) stays easier to read, test and debug.
The signal that justifies a graph
The real signal isn’t “the project is complex” — it’s more specific than that: does the number of steps, or their order, depend on the outcome of a previous step?
- If no — the sequence is always the same — a chain is enough, even with several steps.
- If yes — an agent sometimes needs to re-check, sometimes fetch an extra source, sometimes stop early — that’s the signal you need a state graph rather than a fixed sequence.
A concrete example
In OZONE-AID, the diagnostic copilot follows this pattern: classify the fault, search the technical documentation, then either propose a diagnosis or ask the mechanic for more information before continuing. That conditional branch is exactly the kind of logic a linear chain handles poorly — it ends up turning into a chain of ifs around model calls, which a state graph expresses natively:
graph.add_conditional_edges(
"diagnose",
lambda state: "ask_more_info" if state["confidence"] < 0.6 else "propose_fix",
)
What it costs
Orchestration has a real cost: more surface for state bugs, less linear debugging, and a learning curve for the team. For a simple document summary or structured extraction, a plain chain is still the right choice — and usually faster to ship.