internal/website/blog/23.md
June 16, 2026 • Asim Aslam
The interesting failures of an autonomous agent aren't dramatic. It calls the same tool with the same arguments over and over, making no progress. It takes thirty steps on a task that needed three, quietly running up cost. It performs an action that a human, or a policy, should have stood in front of. When an agent runs on its own, there's no one watching to catch any of it.
A useful way to think about this — which came up in a community discussion recently — is to separate orchestration from execution safety. The model decides what to do; that's orchestration. Whether a decided action is actually allowed to run is a separate concern, and it shouldn't be tangled into the model or the services. Go Micro keeps them apart: every tool call an agent makes passes through one choke point, and that's where the guardrails live. They apply uniformly to service calls, custom tools, and delegate, and they touch neither the model nor your services.
There are three.
MaxSteps bounds the total tool executions in one request. Past the limit, calls are refused and the model is told to stop and summarize. It's the blunt backstop against runaway cost.
micro.NewAgent("worker", micro.AgentMaxSteps(8))
This is the one the discussion was really about, and the one we didn't have. MaxSteps bounds how many calls, but not whether they're the same call. An agent can spend its entire budget calling one tool with identical arguments — each call succeeds, and none of them moves anything forward. A circuit breaker won't catch it either, because a circuit breaker reacts to failures, and a pointlessly repeated call isn't failing.
LoopLimit catches it: it bounds how many times the agent may call the same tool with the same arguments in one request. When the limit is hit, the call is refused with a message that names the loop, so the model changes approach instead of spinning:
loop detected: you have already called "search.Search.Query" with the same arguments 3 times and the result will not change. Stop repeating it — try a different approach, or finish with what you have.
That refusal-with-reason is what lets the agent recover on its own. It's on by default (a lenient 3), because identical repeated calls are never useful; AgentLoopLimit(0) disables it.
micro.NewAgent("worker", micro.AgentLoopLimit(3))
ApproveTool is a hook called before each action runs. Return false to block it, with a reason the model sees — for human-in-the-loop approval, spend limits, allow/deny lists, or any policy:
micro.NewAgent("worker", micro.AgentApproveTool(
func(tool string, input map[string]any) (bool, string) {
if strings.HasPrefix(tool, "billing_") {
return false, "billing actions require sign-off"
}
return true, ""
}))
ApproveTool is also where an external safety layer plugs in. It sees every tool call before execution and can veto, so you can route decisions to your own rules, a budget service, or a third-party runtime-policy engine — without Go Micro depending on any of them. That's the value of separating the two concerns: orchestration stays in the agent, execution safety stays in the hook, and you can replace the safety layer without touching the agent. Loop detection ships built in because it's near-universal; everything beyond it is a policy you supply.
When agents reach tools through the MCP gateway, the gateway adds its own per-tool policies, independent of the agent: RateLimit (requests per second) and CircuitBreaker (a tool that fails repeatedly is temporarily blocked, so a failing dependency doesn't cascade). With the agent-side guardrails that's a complete set — bound the count, stop the spin, gate the action, rate-limit and circuit-break at the edge.
None of this matters much when you're sitting in a chat watching the agent work — you are the guardrail. It matters when no one is. An agent triggered by an event, running unattended, needs to fail safely and recover by itself rather than burning resources in a loop nobody sees. Guardrails aren't a feature bolted onto agents; for an autonomous agent they're part of what makes it safe to run at all.
See the Agent Guardrails guide for the full reference.