~13 min
Anthropic draws a specific line between two things people often lump together as "agentic." A workflow is a system where LLMs and tools are orchestrated through code paths you wrote in advance — you decide the order of steps, even if an LLM call happens at each one. An agent is a system where the LLM itself dynamically directs its own process and tool usage, deciding what to do next based on what it's learned so far, with you controlling the goal and the guardrails rather than every branch.
That distinction matters because agents aren't automatically the better choice. Anthropic's own guidance is to find the simplest solution possible and add complexity only when it's actually needed — often that means a single, well-optimized LLM call with retrieval and good examples, or a workflow with a fixed sequence of steps, rather than a full agent loop at all.
An agent, stripped down, is a loop: the model plans what to do next, calls a tool, and receives feedback from the environment — a tool's return value, an error message, the result of running code — before deciding what to do after that. Anthropic's own description of this loop stresses that gaining "ground truth" from the environment at each step is what lets the agent actually assess its progress, rather than just asserting that it's making progress.
That loop needs an exit. Most of the time the task simply finishes — the model decides it's done and stops calling tools. But because a model can misjudge its own progress, it's common practice to add an explicit stopping condition on top of that, most often a maximum number of iterations, so a confused loop can't run indefinitely. Human checkpoints are the other common brake: pausing for a person's input at a natural decision point, or whenever the agent hits something it can't resolve on its own.
python
def run_agent(user_task, tools, max_iterations=10):
messages = [{"role": "user", "content": user_task}]
for step in range(max_iterations):
response = call_model(messages, tools=tools)
messages.append(response.message)
if not response.tool_calls:
return response.message # model decided it's done
for call in response.tool_calls:
result = execute_tool(call)
messages.append(tool_result_message(call, result))
return "Stopped: reached max_iterations without finishing."Whether to reach for an agent at all comes down to predictability. Anthropic's guidance: agents fit open-ended problems where you can't predict the number of steps needed and can't hardcode a fixed path — a coding agent that has to figure out which files to touch is a good example, since that's genuinely different for every task. Workflows fit everything with a knowable shape, because a fixed path is easier to test, debug, and trust.
The trade-off runs in both directions. An agent's autonomy means higher cost (more model calls per task) and higher latency, and it opens the door to compounding errors — a wrong turn early in a long loop can steer everything that follows. Anthropic's own recommendation is to test extensively in sandboxed environments and pair autonomy with the kind of guardrails covered later in this module, rather than granting an agent unrestricted reach on the strength of a few successful runs.
No — this is exactly the kind of fixed, predictable sequence Anthropic's own guidance points toward a workflow for. An agent adds cost, latency, and unpredictability for a task that doesn't need the model to decide its own next step.