On this page
Both of these build agents that call tools in a loop. The difference that matters is who is in charge of the loop.
In Strands, you hand the model a prompt and a set of tools, and the model picks what to do next, every turn, until it decides it is finished. In LangGraph, you draw the path in advance: these are the steps, this is the branch, here is where it goes back. The model fills in the thinking at each node.
Everything else in this comparison follows from that.
The short answer
Reach for Strands when the work is open-ended and the steps vary with the input: research, triage, "look at this and tell me what is wrong". These are the tasks where working out the flowchart is the hard part.
Reach for LangGraph when you already know the shape of the process and want it to run the same way every time. Approvals, document pipelines, anything a compliance officer will one day ask you to draw on a whiteboard.
What you actually write
A Strands agent is a prompt plus tools.
from strands import Agent, tool
@tool
def refund(order_id: str, cents: int) -> str:
"""Refund an order. Amounts over $100 need approval."""
return billing.refund(order_id, cents)
agent = Agent(
system_prompt="You handle billing questions for Northwind.",
tools=[refund, lookup_order, escalate],
)
agent("Customer says INV-2291 was charged twice.")You wrote three tools and a sentence. The model read the docstrings, called lookup_order first, spotted the duplicate charge, then called refund. It worked out the order on its own.
LangGraph asks for the shape instead:
from langgraph.graph import StateGraph, END
g = StateGraph(State)
g.add_node("lookup", lookup_order)
g.add_node("refund", issue_refund)
g.add_node("approval", human_approval)
g.add_edge("lookup", "triage")
g.add_conditional_edges("triage", route, {
"small": "refund",
"large": "approval",
})
g.add_edge("approval", "refund")
g.add_edge("refund", END)More lines, and that is the point. The refund over $100 reaches a human because an edge says so. The guarantee lives in the graph, which is exactly what makes it a guarantee.
The loop, in one picture
Strands runs the same cycle however complicated the task gets:
The loop ends when the model stops asking for tools. An agent that picks its own next step will happily keep exploring, so Strands ships turn limits, token budgets, and cancellation to bound it. Set those on day one and a long exploration stays predictable and affordable.
Head-to-head
| Strands Agents | LangGraph | |
|---|---|---|
| Who picks the next step | The model, at run time | The graph, written in advance |
| Comes from | AWS, Apache 2.0 | LangChain, MIT |
| Languages | Python and TypeScript | Python and JavaScript |
| Control flow | Emergent from the prompt and tools | Explicit nodes and edges |
| Human approval | A tool the model may call | An interrupt the graph must hit |
| Resuming after a crash | Session state you configure | Checkpointer, per-step snapshots |
| Multi-agent | Agent-as-tool, swarms | Subgraphs |
| Reads well when | The path varies | The path is the requirement |
| Debugging question | "Why did it choose that?" | "Which node returned that?" |
That last row is worth sitting with, because it is what the work feels like six months in. A Strands bug report says the agent did something surprising, and you read a trace and reason about a decision. A LangGraph bug report points at a node.
Where each one earns its keep
Strands suits open-ended work. An on-call agent reading logs, a research assistant working through sources, a support agent that has to work out what the customer means before it can act. The step list is different every time, so letting the model choose is the honest design. AWS runs it in production behind Amazon Q Developer, AWS Glue, and VPC Reachability Analyzer, all cases where the input decides the path.
It is also the shorter road for a team already on AWS. Bedrock AgentCore, Lambda, Fargate, and EKS are documented deployment targets, and tracing is on by default.
LangGraph suits work with a required shape. Contract review that pauses for a lawyer above a risk threshold. A claims pipeline where every branch is auditable. Anything where the process itself is the deliverable. The checkpointer is the other draw: state is snapshotted after each step, so a long-running graph survives a restart and can be resumed, inspected, or replayed step by step.
Checkpointing saves the state. Turning a saved state back into a running one takes something outside the graph: a supervisor, a queue, a scheduler.
They compose
A common and sensible arrangement gives LangGraph the parts of the process with rules: intake, routing, the approval gate, the write to the system of record. A Strands agent sits inside one node doing the open-ended part, like reading a messy attachment and reporting what it found.
That split is the same one we draw as the workflows layer of a stack: the process belongs to the team and is written down, and the model takes part in it rather than owning it.
If you are choosing under time pressure, one question settles it most of the time: can you draw the process on a whiteboard right now? If you can, draw it in LangGraph. If every attempt turns into "it depends what the input looks like", the model is the right thing to put in charge, and Strands is built for that.
For a wider view of the landscape, see our comparisons of LangGraph and LangChain, LangGraph and Pydantic AI, and CrewAI and LangGraph.
Sources
Written by
Cho Yin Yong
Principal AI Solutions Engineer, XY Space
Principal AI Solutions Engineer at XY Space. University of Toronto lecturer for five years, co-author of two patents, winner of two competitive AI awards, and nine years of regulated engineering leadership.
More from Cho Yin YongShare this article
Work with us
We build the systems these posts describe, and we'll tell you in the first call whether yours is worth building.
Start a project