Strands Agents, or less scaffolding around the model
Strands is an open AWS toolkit for building agents, resting on the premise that the less you impose on the model in advance, the better. You supply a model, instructions, and a set of tools, and leave the decision about what to call and in what order to it.
The project is released under a permissive licence and, despite its origin, requires no AWS infrastructure. It works with models from various vendors, and integration with Amazon's services is a convenient default rather than a condition of use.
The approach stands opposed to libraries building an explicit flow graph. There you describe the path, here you describe the possibilities and the model picks the path. Both schools have their arguments, and below I describe when each wins.
The simplest working agent
pip install strands-agents strands-agents-toolsfrom strands import Agent, tool
@tool
def check_stock(sku: str) -> int:
"""Returns the number of units available in the warehouse for a product code."""
return warehouse.count(sku)
@tool
def place_order(sku: str, units: int) -> str:
"""Places an order and returns its number."""
return orders.create(sku, units)
agent = Agent(
tools=[check_stock, place_order],
system_prompt="You handle orders. Always check stock before placing one.",
)
print(agent("Order two pairs of shoes with code BT-42."))A tool is an ordinary function with a decorator. The name, argument types, and the docstring become the schema the model sees, so there is no separate definitions file to maintain alongside the code.
That is convenient and carries one consequence worth remembering from the start. A function's description stops being a comment for a developer and becomes part of the prompt. A sentence stating plainly when to call the tool raises accuracy more than any change to the system instruction, while a description like "helper function for stock" tells the model nothing.
A loop that happens by itself
The toolkit takes on the cycle you write by hand against a raw API: sending the request, reading the tool call request, executing the function, returning the result, and repeating until a final answer.
That sounds minor until you count how many things must be handled correctly inside that loop. Concurrent calls to several tools in one turn. A function error that should return to the model as a message rather than crash the program. A turn limit protecting against circling. Conversation history trimmed once it exceeds the context window.
The last of those is the most often skipped in a hand rolled implementation. A conversation grows with every turn, since it carries all previous messages and tool results, so a long run either hits the context limit or costs many times more than you assumed. The toolkit handles trimming and summarising history, and checking which strategy it defaults to before shipping to production pays off.
Streaming works at the event level, so beyond the answer forming you can show the user that the agent is currently checking warehouse stock. On a run lasting half a minute that difference decides whether somebody waits.
Multi agent patterns
Version one added four arrangements for combining agents, and the differences deserve understanding, since they cover different needs.
Agent as a tool is the simplest variant: one agent calls another exactly as it calls an ordinary function. It suits splitting by specialism, where a main agent routes a question to the right expert.
A swarm is a group of agents working a shared problem with the ability to hand off. Flexible and hardest to predict, since the speaking order emerges from the run.
A graph is a deterministic arrangement: nodes joined by edges, executed according to dependencies, where one node's output feeds the next node's input. That is the choice for processes that must run identically every time.
A workflow describes tasks with explicitly declared dependencies, closer to a classic scheduler than to a conversation.
The practical guidance matches other libraries of this class: start with the simplest arrangement you can defend. Agent as a tool covers surprisingly many cases, while a swarm looks the most interesting and most often disappoints in production, since the same input produces different runs.
Ready made and custom tools
A separate package supplies dozens of ready tools, and knowing what is there before writing your own equivalents pays off.
The set covers file operations, code execution, HTTP requests, memory handling, image work, and integrations with cloud services. For a prototype that saves an hour, and incidentally provides a good template showing how to describe your own functions.
Three rules for custom tools save the most trouble.
The first concerns return values. A function should return data rather than a finished sentence for the user, since composing the answer is the model's job. A tool returning "Sorry, I could not find that product" instead of an empty value denies the model the chance to react sensibly and breaks the answer in another language.
The second concerns errors. An exception raised in a tool should return to the model as a message, so it can correct the arguments and retry. Code tearing down the whole run at the first typo in a product name wastes an ability this arrangement gives for free.
The third concerns scope. A tool doing one thing is chosen more accurately than a tool with seven modes driven by a parameter. The model chooses from the description, and a description of seven modes at once is inherently vague.
Tool security
This part deserves separate treatment, since with control handed to the model the risk looks different from an explicit flow.
Arguments passed to a function come from text the model generated, and the model also reads input data, including content fetched externally. That means a document with an embedded instruction can influence which tool gets called and with what.
Three safeguards solve most of that. The first is splitting tools into reading and state changing, with the latter requiring confirmation or operating on a narrow, explicitly bounded scope. The second is isolating anything executing code or system commands, in an environment without network access and with a time limit. The third is passing identifiers rather than sensitive data, substituting real values only inside the function, out of the conversation's reach.
Remember too that an agent's permissions are the permissions of the process it runs in. An agent started under a role with broad access to cloud resources can do exactly as much as that role allows, regardless of what you wrote in the system instructions.
Models and portability
The library does not tie you to one vendor, which in a toolkit published by a cloud provider deserves noting.
Beyond Amazon's services, supported models include Claude, OpenAI, Google's offerings, and models run locally through Ollama. Switching vendor means swapping the model object passed to the agent.
A protocol for communication between agents from different vendors is supported too, which matters when your agent must talk to somebody else's. Compatibility across such standards is sometimes partial, so verify your specific case before writing it into an architecture document.
That portability has a practical use when comparing models. The same agent run against three different models on your own set of cases says more than any public benchmark, since it measures your task rather than an averaged one.
Know, though, that portable code does not mean portable behaviour. Models differ in how readily they call tools, how they handle several calls in one turn, and how they react to an error returned by a function. A system instruction tuned for one model can give markedly worse results after switching vendor, despite you not touching a single line of code. That is another reason a set of cases with expected results is necessary here rather than optional.
Deployment and observability
An agent is an ordinary Python object, so deployment needs no special runtime. It runs in a serverless function, in a container, on a cluster, and in a managed service meant for agents, with the code staying the same in that last case.
That last property is more convenient than it sounds. An agent run locally and an agent in a managed service are the same code invoked the same way, so local development does not differ from production, and that removes a whole class of differences surfacing only after a deploy.
Tell that service apart from the same vendor's older console product, since the names get confused. Bedrock Agents let you assemble an agent by clicking, with no code, but it now goes by Agents Classic, has been closed to new accounts since 30 July 2026, and its model catalogue is frozen. Starting a project on this cloud therefore means choosing between this toolkit and that service's successor, with the Agents Classic route shut regardless of how well it would fit.
Telemetry uses a widely adopted format, so runs plug into tooling the team already has. A single run appears as a tree: model calls, tool calls, timings, and token usage.
Three measures deserve watching from day one. Turns per task says whether the agent circles instead of finishing. Cost per task says whether the solution scales. The share of tasks completing successfully, measured over a fixed set of cases, says whether a change to the instructions improved anything. That third is the only one letting you compare two versions of an agent, and it is checked least often.
Strands against the alternatives
| Option | Strength | Weakness | Pick it when |
|---|---|---|---|
| Strands Agents | Very little code, deployment into AWS services | Control handed to the model, less oversight | A team on AWS infrastructure |
| LangGraph | Explicit graph, state control, mature diagnostics | More concepts and code up front | A process demanding repeatability |
| Microsoft Agent Framework | A .NET variant, checkpoints | Gravity towards Azure | A company on Microsoft technologies |
| OpenAI Agents SDK | Minimal concepts, quick start | Narrower orchestration scope | A simple agent with tools |
The split runs along one question: who decides the order of steps. If a process has known stages and must run identically every time, an explicit graph wins, since it gives repeatability and a place to point at when something breaks. If the task is open ended and a rigid plan gets in the way, model driven control gives shorter code and better results.
The second criterion is infrastructure. A team working in Amazon's services gets integration here that competing libraries lack, and that is sometimes decisive regardless of the rest.
The third, as always, is the question of necessity. An agent with three tools and one step is a small amount of code calling the model directly, with no intermediary library. An orchestration layer earns its place only once you need history management, retries, observability, or several agents working at once.
Common mistakes
The first is tool descriptions written for a developer. The model sees only the name, the types, and the description, so a sentence stating when to call a function matters more than what it does.
The second is no turn limit and no cost cap. An agent in a loop will make dozens of calls before anybody notices, and a ceiling is the only mechanism working without your attention.
The third is ignoring the conversation history strategy. A long run either hits the context limit or costs many times more than you assumed.
The fourth is handing the model a process with known steps. Model driven control is an advantage on open ended tasks and a drawback where the order is fixed anyway.
The fifth is tools without isolation. A function running system commands or modifying data should carry approval or constraints, since the arguments come from text the model generated.
The sixth is migrating or tuning without a set of test cases. Agents do not return values comparable with an equals sign, so without expected results, judging a change is guesswork.
FAQ
Does Strands require an AWS account?
No. The toolkit is open and works with models from various vendors, locally run ones included. Integration with Amazon's services is a convenient default rather than a condition of use.
How does it differ from LangGraph?
In who decides the order of steps. LangGraph has you describe a flow graph, here you describe tools and the model picks the path. A graph gives repeatability and easier diagnosis, model driven control gives shorter code and better results on open ended tasks.
How are tools defined?
As ordinary functions with a decorator. The name, argument types, and docstring form the schema the model sees, so there is no separate definitions file to maintain alongside the code.
Does it suit multi agent systems?
Yes, four arrangements are available: agent as a tool, swarm, graph, and workflow. Start with the first, since it covers most cases, while the freer arrangements are harder to predict in production.
How do I tell whether it fits my project?
Build one real process from your own system in it and measure three things: cost per run, response time, and how quickly you establish the cause after a failed run. The third measure decides most often and is checked least.
Documentation sits on the project site, and the code in the GitHub repository.