Guide · Advanced · 10 min
LangGraph reference guide: state graphs, memory, tools, and deployment
LangGraph orchestrates stateful agents, tools, and human approvals. Learn how to design a graph, manage its memory, and prepare an application for deployment.

LangGraph is an orchestration library that represents a workflow through shared state, processing nodes, and explicit transitions. It combines deterministic rules, model calls, tools, and human approval in an application that can retain its progress. Its reliability still depends on the storage, stopping conditions, and safeguards you build around external actions.
What does LangGraph do in an agent application?
LangGraph helps when you need to decide which step should run next, what data it should receive, and how a workflow should resume. This agent orchestration does not replace the language model or your business services. It coordinates their interactions.
Consider an assistant that handles customer requests. It identifies the request, looks up an order, prepares a proposal, waits for approval when necessary, and then performs an authorized action. The graph makes these steps visible and separates decisions made by the model from rules enforced by your application.
LangChain provides abstractions for models, messages, and tools, among other things; LangGraph gives you more direct control over transitions. To compare this approach with other available options, see our agent and framework directory and the article on AI agent frameworks.
Start with the level of control your application needs:
| Criterion | Sequential functions | Agent loop | Explicit graph |
|---|---|---|---|
| Execution path | Fixed in code | Partly chosen by the model | Defined transitions with constrained decisions |
| Intermediate state | Must be organized | Often centered on messages | Shared schema across steps |
| Human approval | Must be implemented | Depends on the implementation | Can become a step in the workflow |
| Design complexity | Limited for a short workflow | Grows as exceptions accumulate | Requires state and transition design |
A graph does not automatically make an answer correct. Its value lies in making decisions controllable and failures easier to understand.
Understanding state, nodes, and transitions
State holds the information needed for the rest of the workflow: the initial request, retrieved documents, verified results, a proposal, and approval status. A node receives that state and returns an update. Edges define the next steps, potentially based on a condition. The Graph API documentation describes these building blocks and graph compilation.
Keep facts separate from interpretations. An order reference retrieved from a business system does not have the same status as a category inferred by a model. Preserve their provenance so you can explain a decision and correct an interpretation without losing the original data.
Each field has an update rule, called a reducer. By default, a new value replaces the previous one; a custom rule can combine contributions instead. This distinction becomes essential when several branches produce results for the same field.
Prefer structured fields to an ever-growing block of text. An explicit status such as validation_requise is easier to test than a sentence in which the model suggests a review. Keep connections and secrets outside the persisted business state as well.
Finally, define exits before designing loops. For each step, identify success, recoverable failure, abandonment, and the need for intervention. A workflow is not sufficiently defined if you cannot explain how it stops.
Prerequisites and step 1: install the foundation
The practical section uses Python and starts without a model call. You should know how to define a function, work with a dictionary, read an exception, and manage project dependencies. For the local server introduced later, the documentation consulted on October 24, 2026, requires Python 3.11 or later.
Prepare an isolated environment using your usual environment manager. The official installation documentation provides this command, reproduced exactly:
pip install -U langgraph
This command installs or updates the available package; it does not lock dependencies for reproducible builds. Once you have validated your application, record the versions actually used in your dependency manager and retain its lockfile.
The following example requires no provider API key. When you add a model, install its integration according to its documentation and supply secrets to the process through a mechanism suited to your environment. Avoid copying them into examples, logs, or checkpoints.
Define a verification scenario before writing code, too. Here, a request will produce a draft, wait for a decision, and then reach a final status. The expected outcomes are straightforward: approval completes the workflow, rejection prevents it from proceeding, and neither path performs an external action.
This sequence lets you isolate orchestration errors from model or network errors.
Step 2: build a graph with human approval
The teaching example below adapts the official primitives. It builds a deterministic draft so you can examine the pause mechanism without depending on a generated response.
from typing import TypedDict
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import StateGraph, START, END
from langgraph.types import Command, interrupt
class Etat(TypedDict, total=False):
demande: str
brouillon: str
approuve: bool
statut: str
def preparer(etat: Etat):
return {
"brouillon": "Proposition à examiner : " + etat["demande"],
"statut": "en_attente",
}
def valider(etat: Etat):
decision = interrupt({
"action": "examiner_brouillon",
"brouillon": etat["brouillon"],
})
return {"approuve": decision is True}
def orienter(etat: Etat):
return "terminer" if etat["approuve"] else "refuser"
def terminer(etat: Etat):
return {"statut": "approuve_sans_envoi"}
def refuser(etat: Etat):
return {"statut": "refuse"}
builder = StateGraph(Etat)
builder.add_node("preparer", preparer)
builder.add_node("valider", valider)
builder.add_node("terminer", terminer)
builder.add_node("refuser", refuser)
builder.add_edge(START, "preparer")
builder.add_edge("preparer", "valider")
builder.add_conditional_edges("valider", orienter)
builder.add_edge("terminer", END)
builder.add_edge("refuser", END)
graph = builder.compile(checkpointer=InMemorySaver())
config = {"configurable": {"thread_id": "demande-demo"}}
pause = graph.invoke(
{"demande": "Préparer une réponse au client"},
config=config,
)
print(pause)
# Call after an explicit decision in your application.
resultat = graph.invoke(Command(resume=True), config=config)
print(resultat["statut"])
The call to interrupt pauses the workflow; resuming it passes a value through Command. The interrupt documentation requires, among other things, a checkpointer, a thread identifier, and a serializable payload.
In this example, True represents approval that has already been obtained. A real interface must authenticate the person, display the exact draft, and pass along their decision. The thread identifies the workflow; it does not prove that a user has permission to access it.
Check the rejection path separately, using another thread and resuming with False. You now have an initial routing check without having authorized any message to be sent.
Step 3: organize memory and persistence
LangGraph distinguishes between two complementary mechanisms: a checkpointer retains a thread’s state, while a store retains application data that can be used across threads. The persistence documentation explains this distinction.
| Criterion | Checkpointer | Store |
|---|---|---|
| Retained data | Snapshots of graph state | Application-defined information |
| Logical scope | A specific thread | Multiple threads, depending on your design |
| Common use | Workflow continuity and resumption | Lasting preferences or knowledge |
| Design question | Where should the workflow resume? | What should be available later? |
InMemorySaver is suitable for a demonstration within the same process. It should not be described as storage that survives a restart. For a durable application, choose persistent storage compatible with your operational requirements.
Agent memory also requires rules for both content and technical handling. Information proposed by a model should not become a lasting fact without verification. Record its source, scope, and, where relevant, the period for which it remains valid.
Keeping history and sending all of it to the model are separate decisions. You can retain events for auditing while preparing a smaller context for each call. The article on AI agent memory explores this difference.
Define deletion behavior as well. Removing a preference from the store may leave copies in earlier states, traces, or backups. Inventory those locations before claiming that a piece of data has been deleted.
Step 4: add a model and controlled tools
Once you understand the deterministic workflow, replace the draft preparation step with a model call. Keep approval and business rules in code. An instruction asking a model to respect a limit does not replace enforcement of that limit.
The official quickstart presents a loop in which the model proposes tool calls, a node executes them, and the observations return to the model. Use this structure as a starting point, adding controls specific to your application.
For each tool, define:
- Accepted arguments and how they are validated.
- Required permissions and the scope of accessible data.
- The timeout and recoverable errors.
- External effects and approval requirements.
- The structured result expected by subsequent graph steps.
A read tool and a write tool should have separate permissions. If an assistant only needs to prepare a response, its access to a messaging service should not allow it to send messages.
Prompt injection remains possible through documents and tool results. Treat this content as data: it cannot expand permissions or cancel a required approval. Safeguards must remain active even if the model follows a hostile instruction.
When a service returns an incomplete result, avoid turning it into apparent success. Return a usable status: no result, access denied, timeout, or invalid data. The graph can then choose an explicit next step.
Step 5: make external actions safe to resume
Checkpointers save snapshots at super-step boundaries and support capabilities such as inspecting history. A checkpoint does not, however, create a shared transaction with your messaging service, accounting software, or payment service.
Consider a message that is successfully sent, followed by a crash before its confirmation is saved. When the workflow resumes, your application may not know whether the message was sent. It must be able to retrieve that information instead of blindly repeating the action.
For sensitive operations, use an idempotency key recognized by the target service or a business record that lets you verify the result. Retain a stable operation reference that does not depend on how the model phrases the request.
Code before an interruption within a node may run again when execution resumes. Place external effects after the necessary decision and design them to tolerate repeated execution. Avoid a large node that combines research, approval, and sending.
Apply different retry policies to different errors, too. A temporary network problem may justify another attempt; a permission denial generally requires a different decision. Invalid input must be corrected before calling the service again.
Document the expected behavior after an interruption at each sensitive boundary. This analysis often reveals more defects than a test in which every service responds normally.
Step 6: start the local server and prepare deployment
To explore an application as a service, the official local server procedure, consulted on October 24, 2026, provides the following commands:
pip install -U "langgraph-cli[inmem]"
langgraph new path/to/your/app --template new-langgraph-project-python
cd path/to/your/app
pip install -e .
The path shown is an example to adapt. The generated template provides a starting structure; you need to integrate your graph and check its declaration in the application configuration.
The procedure also asks you to create a .env file from the supplied template and enter a LangSmith key. Keep this file out of the repository, then run:
langgraph dev
This command starts a development environment. Use the displayed addresses to inspect the application and check workflows in Studio. Successful local execution does not yet validate production persistence, isolation, or service capacity.
The deployment documentation presents LangSmith Cloud alongside hybrid and self-hosted options. Hosting the library inside your own service is also an architectural choice, with operational responsibilities to plan for.
The current name is LangSmith Deployment; the former name, LangGraph Platform, may still appear in older resources. Check the terms of your chosen offering. The availability of the library does not mean that all associated services are available under the same terms.
Operating the graph: permissions, budget, and evaluation
Before opening the application to users, associate each thread with an identity and an authorized scope. The server must control access to states, resumptions, and documents. Separation through prompt instructions is not enough to isolate different customers’ data.
For approvals, bind the decision to the exact version of the action. Approval of a draft should not authorize a recipient or amount that changes afterward. Set an expiration policy as well, and define what happens when an approval request remains unanswered.
Measure cost at the level of the completed task. Model calls, large tool results, retries, and abandoned workflows all contribute to the budget. The LLM pricing calculator helps estimate the token-related component; account for storage and operations separately.
Prepare a set of scenarios covering success, rejection, missing data, unavailable tools, and attempts to bypass controls. Check transitions and the actions actually performed, beyond the wording of the final response. The guide to evaluating an AI agent provides a method for tracking performance.
Traces should help you locate an error without unnecessarily accumulating private data. Record useful execution identifiers, statuses, and durations; mask secrets and control access. The guide to securing an AI agent expands on these measures.
Common problems
The workflow starts again without recovering its history. Check the checkpointer, its availability, and the thread identifier. A new identifier refers to a different workflow; storage held only in memory disappears when the process ends.
Earlier data disappears. Examine the update rules for the affected field. Replacing a value may be appropriate for a status but unsuitable for a collection of results that should accumulate.
Resuming the workflow repeats an action. Look for external effects before an interruption or inside an operation that may run again. Then check idempotency and whether the target service lets you look up the result.
The loop keeps running without making progress. Add a business-level stopping condition, a budget, and detection of repetitive attempts. Simply increasing the technical limit postpones the problem.
The model reports success that the business system does not confirm. Make the final status depend on structured confirmation from the service. A generated response is not proof that an action occurred.
The prototype works, but users block one another. Examine concurrent access to the same thread and business resources. Define a coordination policy before allowing multiple simultaneous operations.
Checklist before launch
- The schema distinguishes source data, interpretations, and decisions.
- Every branch has an exit and a stopping condition.
- Validated dependencies are locked and documented.
- Storage survives restarts, and restoration has been verified.
- Threads and memory are isolated according to actual permissions.
- Tools validate their arguments and have limited permissions.
- Approval covers the exact action that will be executed.
- External effects tolerate resumption without uncontrolled duplication.
- Evaluated scenarios include errors, rejections, and interruptions.
- Budget, traces, data retention, and deletion policies are defined.
Related pages
Frequently asked questions
Do you need LangChain to use LangGraph?
No. You can call your models and services from ordinary functions. LangChain abstractions become useful when you want shared interfaces for messages, models, and tools.
Can LangGraph run without a language model?
Yes. A graph can orchestrate deterministic functions alone. This lets you check routing, interruptions, and state updates before adding model calls.
Does a checkpoint prevent a tool from running twice?
A checkpoint alone cannot guarantee this in an external system. For sensitive operations, provide an idempotency key and a way to check whether the action has already taken place.
Can you host a LangGraph application on your own infrastructure?
Yes, but embedding the library in your own service and deploying Agent Server are separate choices. Check the terms and dependencies of your chosen deployment option before sizing your infrastructure.
When does LangGraph add too much complexity?
If your workflow follows a short path without recovery or intermediate approval, ordinary functions may be enough. A graph becomes useful when explicit transitions and state make failures easier to manage.