The agent loop: think, act, observe, stop
An agent repeats the tool-use loop toward a goal. Step limits and repeat checks keep it from running forever.
Watch it animatedStep through it, with the running line highlighted. Free with an account.The idea
An agent is the tool-use loop run repeatedly with a goal. Each round the model looks at everything so far and decides what to do next. Either it asks for a tool, your code runs it and adds the result, or it writes a final answer and stops. Because the model decides the number of steps, your code must set the rules for stopping: a final answer, a hard step limit, and a check for repeated actions.
Code
public static async Task<string> RunAgentAsync(
IMessagesClient client, IReadOnlyList<ToolDef> tools, string goal, int maxSteps)
{
var messages = new List<Message> { Message.User(goal) };
var seen = new HashSet<string>();
for (int step = 1; step <= maxSteps; step++)
{
var reply = await client.SendAsync(messages, tools);
messages.Add(reply.AsMessage());
if (reply.StopReason == "end_turn") return reply.Text;
var call = reply.ToolUses.First();
if (!seen.Add(call.Signature()))
return "Stopped: the agent repeated an action.";
string result = await RunToolAsync(call);
messages.Add(Message.ToolResult(call.Id, result));
}
return "Stopped: step limit reached.";
}Tips
- Interview line: "An agent is a model in a loop with tools. The code owns the loop, so the code owns the stopping rules."
- Always have a step limit. Without it, a confused agent can loop, and spend time and tokens, indefinitely.
- Detect repetition (the same call again with the same input) and stop or change approach.
- The messages list is the agent’s memory. It grows every step, so long runs can reach the context window. Trim or summarize if needed.
- Keep risky tools (send, delete, pay) behind human approval. See the prompt injection lesson.
In the .NET library
Pass a CancellationToken through the loop and into every tool call so you can also stop an agent when the user closes the page, and add an overall time budget next to the step limit.