LangChain and LangGraph 1.0 in Practice
LangChain 1.0 and LangGraph 1.0 shipped on 22 October 2025 with a commitment to avoid breaking changes until 2.0. We examine create_agent and its middleware hooks, checkpointer-backed persistence, human-in-the-loop interrupts, and migration from legacy chains to langchain-classic — while stating what stable APIs still do not solve.
The Cost of a Moving Target
LangChain was widely regarded as unstable. Between 2023 and 2025, teams moved first from chains to LCEL runnables and then to prebuilt agents. Each deprecation cycle consumed engineering time without changing the system's business value. For production systems, that API churn became the strongest argument against the framework — and a common reason to implement agent loops in-house.
On 22 October 2025, LangChain released version 1.0 of both langchain and langgraph, in Python and TypeScript, with an explicit commitment: no breaking changes until 2.0. This article examines what the releases contain, how the new primitives behave in practice, and what a migration from 0.x actually involves.
What Shipped on October 22
LangChain 1.0 is a rebuild around one abstraction. create_agent implements the standard tool-calling loop and runs on the LangGraph runtime; it replaces create_react_agent, which is now deprecated in langgraph.prebuilt. The package surface shrinks to agent building blocks. Python 3.9 support is dropped after its October 2025 end of life; 1.0 requires Python 3.10 or newer.
LangGraph 1.0 is the quieter release. Its APIs for durable execution, streaming, and state management were already in production use at companies such as Uber, LinkedIn, and Klarna; the 1.0 label stabilizes them with almost no breaking changes. A second LangChain addition is standard content blocks: a provider-agnostic content_blocks property that normalizes reasoning traces, citations, and tool calls across model providers.
create_agent and the Middleware Contract
create_agent runs model calls and tool calls in a loop until the model stops requesting tools. Customization does not happen by subclassing but through middleware: objects that implement up to six hooks around the loop. Node-style hooks return state updates; wrap-style hooks control the call itself and can short-circuit, retry, or swap models per request.
LangChain ships prebuilt middleware for summarization at a token threshold, PII redaction, call limits, and human-in-the-loop approval. Composition follows web-server middleware semantics: before_* hooks run in declaration order, after_* hooks in reverse, and wrap_* hooks nest. This change has the greatest effect on daily work because behavior that once required forking the agent graph can now be declared as a separate component.
| Hook | Runs | Typical use |
|---|---|---|
| before_agent | Once when the agent starts | Load memory, validate input |
| before_model | Before each model call | Trim history, redact PII |
| wrap_model_call | Around each model call | Retries, caching, model switching |
| wrap_tool_call | Around each tool call | Intercept results, gate execution |
| after_model | After each model response | Guardrails, human approval |
| after_agent | Once when the agent completes | Persist results, cleanup |
Checkpointers Make State Durable
A checkpointer persists graph state after every super-step, keyed by a thread_id passed in the run configuration. That single mechanism enables conversation continuity, fault-tolerant resumption after crashes, time-travel debugging, and interrupts. InMemorySaver is for development only; SqliteSaver and PostgresSaver survive process restarts and are the production options.
The mechanism has two important limits. A checkpointer stores thread-scoped short-term state and does not replace a memory system; knowledge shared across threads requires the separate store interface. Checkpointing also does not deduplicate side effects. Because a node re-executes from its beginning on resume, external calls must be idempotent or cleanly isolated.
Interrupts for Human Approval
The interrupt() function pauses a graph at an arbitrary point inside a node. The runtime saves state through the checkpointer, surfaces a JSON-serializable payload to the caller under __interrupt__, and waits indefinitely. Resuming means invoking the graph again with Command(resume=value) and the same thread_id; the value becomes the return value of interrupt().
In create_agent, HumanInTheLoopMiddleware packages this pattern: it declares which tools require approval and which decisions are allowed — approve, edit, or reject — before a tool call executes. One caveat carries over from the runtime: the interrupted node restarts from its beginning on resume, so any code before the interrupt() call runs twice. Place side effects after the approval point.
Migrating off Legacy Chains
In 1.0, imports of LLMChain, ConversationChain, the retriever modules, the indexing API, and the hub fail. They moved to langchain-classic, installable alongside 1.0; changing the import prefix to langchain_classic restores the old behavior. This step is mechanical and buys time. It is not modernization — langchain-classic carries the deprecated code as-is.
The actual modernization path replaces chain classes with runnable composition — prompt | model | parser — or, where tools are involved, with create_agent. LLMChain has been deprecated since version 0.1.17, and its replacement APIs are now documented and stable. Since the 0.3 line receives security patches and critical fixes until December 2026, teams have a realistic but finite migration window.
Prebuilt agents migrate separately. create_react_agent still works but is deprecated; the replacement is create_agent from langchain.agents. The mapping is close: the prompt parameter becomes system_prompt, and pre- and post-model hooks become middleware. Tool error handling moves into wrap_tool_call middleware. Plan a day per agent for the rename plus a regression run — not more, in our experience.
What 1.0 Does Not Solve
API stability is a contract about signatures, not about behavior. Agents remain nondeterministic; pinning the framework does not pin model output. Evaluation suites, tracing, and regression tests stay mandatory. The stability promise also covers only langchain and langgraph — provider packages such as langchain-openai and langchain-anthropic version independently and follow their providers' API changes.
Middleware raises the ceiling and demands discipline. Six hooks across several stacked middleware produce interleavings that must be reasoned about explicitly; ordering bugs are silent. Checkpointed state is versioned data of your application: when your state schema evolves, migrating persisted threads is your responsibility, not the framework's.
Outlook from November 2025
We at Blue IT Systems read the 1.0 releases as the start of consolidation. With stable interfaces, middleware becomes a unit of reuse; we expect an ecosystem of third-party middleware packages — guardrails, cost controls, audit logging — within months. Durable execution and interrupt-based approval will become table stakes for every agent framework, not differentiators.
The open question is how much framework remains necessary as models absorb more of the loop. If planning and tool selection continue moving into the models, frameworks will concentrate on runtime concerns such as persistence, approval, and observability. That is precisely where LangGraph has placed its bet. Whether create_agent truly remains unchanged until 2.0 will be the decisive test of the promise made on 22 October.
Sources
- LangChain and LangGraph Agent Frameworks Reach v1.0 (LangChain Blog, 22 Oct 2025)
- Agent Middleware (LangChain Blog, 8 Sep 2025)
- LangChain 1.0 now generally available (LangChain Changelog, 22 Oct 2025)
- LangChain v1 Migration Guide (LangChain Docs, accessed 17 Nov 2025)
- LangChain raises $125M to build the platform for agent engineering (LangChain Blog, 20 Oct 2025)
