Correct Tool Calls, Broken Business Rules: Agent Guardrails

Developer typing code on a laptop at a desk, representing building guardrails for AI agent tool calls

Your agent just onboarded a contractor in Germany. Every API call returned 200, the record exists, the payment is scheduled. It also skipped the worker-classification check that would have flagged the engagement as employment, and nobody will know until an auditor asks. Correct execution and policy compliance are different properties, and most agent stacks only test for the first one.

This post covers why that gap exists, how to measure it, and where to put the guardrails so they hold up in production, including for teams with one engineer and no platform budget.

Tool calls are deterministic. The decision to make them isn't.

Tool-calling makes a single action reliable, but the choice of which tool to call, when, and with what arguments is still probabilistic model output. Structured outputs and schema validation guarantee that create_contractor(...) is well-formed. They say nothing about whether the agent should have called it, or what it should have called first.

Gabe Monroy, CTO at Workday, makes this argument in a VentureBeat piece. His example is an agent onboarding an international contractor: every tool call can succeed while the agent bypasses regional labor laws, tax withholdings, and worker classification checks. Nothing errors. The workflow completes and looks green on every dashboard.

A caveat on the source: Monroy works for a vendor that sells a platform built around this thesis (guardrails inside the system of record). Treat the conclusion as one vendor's position. The underlying observation, that execution correctness is not policy correctness, stands on its own and is supported by independent research, covered below.

The small-business version looks different but fails the same way:

  • An invoicing agent sends a correct, well-formed invoice to a client who has an unpaid dispute open. Policy: hold invoices while disputes are open.
  • A lead follow-up agent emails a contact who unsubscribed last month, via a different list. The send API works perfectly.
  • A refund agent issues a refund within the amount limit but without the customer confirming the method.

None of these produce an error. They produce a quiet policy violation that you find out about from a customer.

Why your evals probably don't catch this

Most agent evaluations check the end state ("was the refund issued?") rather than the path ("did the agent follow the rules getting there?"), and they usually run each task once. Both habits hide policy failures.

The τ-bench paper from Sierra (arXiv 2406.12045) calls out the first problem directly: a task can reach the correct end state while still violating policy, for example by issuing a return without explicit user confirmation. A pass/fail check on the database row would score that run as a success.

The second problem is consistency. τ-bench introduced a metric called pass^k, the probability that all k trials of the same task succeed. Anthropic's guide to agent evals explains it with a simple example: a 75% per-trial success rate over 3 trials gives about 42% (0.75³). It also notes that pass@k and pass^k are identical at k=1 but diverge sharply: by k=10, pass@k approaches 100% while pass^k falls toward 0%.

In the τ-bench paper, GPT-4o reached about 61% pass^1 on the retail domain and about 35% on airline, with retail pass^8 dropping to about 25%. Those are the original paper's numbers on older models, so don't read them as a statement about current models. The shape is what matters: an agent that looks fine on one run can be unreliable when the same request arrives a hundred times.

Here's a quick illustrative calculation. It's my own arithmetic with round numbers, not a survey result. If each step in a ten-step workflow has a 95% chance of following policy, and steps are independent:

per_step = 0.95
steps = 10
print(f"{per_step ** steps:.0%}")  # ~60%

About 60% of runs would be fully compliant, meaning roughly four in ten contain at least one violation. Real steps aren't perfectly independent, but the compounding direction is real.

The industry data points the same way. A VentureBeat Research study of 573 enterprise leaders, fielded in June 2026, found companies deployed agents ahead of the controls to manage them (report). Only 5% said they fully trust the automated evaluations that gate agent releases, and half had shipped an agent that passed internal evals and then caused a customer-facing failure in the past year. A companion pulse survey had 157 respondents from companies with 100+ employees and was self-selected, so read those percentages as directional.

The three-layer model: context, policy, execution

Reliable guardrails separate three jobs: knowing the facts (context), deciding what's allowed (policy), and performing the action under the right identity (execution). The model reasons; the layers around it constrain.

Monroy proposes the same three components at platform level: a context engine, a policy engine, and an execution layer. The framing is useful even if you build all of it yourself on a small stack.

Layer Job Failure it prevents Small-team implementation
Context Gather the facts the rule needs, from the system of record, not from the model's memory Agent guesses a contractor's country, a client's dispute status, a consent flag A get_context() function that queries your CRM/billing/DB before any decision
Policy Evaluate rules deterministically against that context Agent decides for itself whether a step is allowed Plain code or a rules file; no LLM in the loop
Execution Run the action with the scope of the specific human or role being served Standing "god-mode" credentials; shared tokens Per-agent, per-user scoped credentials; allowlisted tool wrappers

The key design rule: the model proposes, the policy layer disposes. The agent emits an intent ("send invoice to client 4417"). A deterministic layer fetches context, checks the rules, and either executes, blocks, or routes to a human.

What this looks like in code

A minimal policy gate in front of a tool, written so the rule lives in code you can test rather than in a prompt you hope the model follows:

from dataclasses import dataclass

@dataclass
class Decision:
    allow: bool
    reason: str
    needs_human: bool = False

def check_send_invoice(ctx: dict) -> Decision:
    if ctx["open_disputes"] > 0:
        return Decision(False, "client has open dispute; hold invoice")
    if ctx["amount"] > ctx["agent_limit"]:
        return Decision(False, "over agent limit", needs_human=True)
    if not ctx["billing_details_verified"]:
        return Decision(False, "billing details unverified", needs_human=True)
    return Decision(True, "ok")

def send_invoice_tool(client_id: str, amount: float, actor: str):
    ctx = get_context(client_id, amount, actor)   # from system of record
    decision = check_send_invoice(ctx)
    audit_log(actor, "send_invoice", client_id, decision)
    if not decision.allow:
        return {"status": "blocked", "reason": decision.reason,
                "escalate": decision.needs_human}
    return billing_api.send(client_id, amount, scope=ctx["actor_scope"])

Three things to notice. The context comes from your own data, not the model's arguments. The rule is a plain function you can unit test. Every decision, allowed or blocked, is written to an audit log, which is what you'll want when someone asks "why did it do that?"

The prompt can still describe the policy so the model avoids pointless attempts. But the prompt is advice; the gate is enforcement.

Give every agent its own identity

Shared credentials turn an agent mistake into an everything mistake, and the data suggests they correlate with more incidents. Execution-layer guardrails start with scoped identity.

Monroy's execution layer attaches the scope of the specific human the agent serves to each API call, instead of one standing credential. In the VentureBeat Research study, 69% of companies let at least some agents share credentials. Those companies reported a security incident or near-miss at a rate of 63.5% (47 of 74), versus 40.9% (9 of 22) where every agent has its own scoped identity. The sample is small and this is correlation, not proof, but the direction matches common sense.

Practical steps for a small team:

  1. One credential per agent, per environment. Not your personal API key pasted into three automations.
  2. Least privilege by tool. An email-triage agent gets read and draft access, not send-as-owner. An invoicing agent gets create-draft, not delete.
  3. Act on behalf of a user, not as root. If the agent serves a specific person or role, pass that scope through, so the downstream system's own permissions apply.
  4. Rotate and log. Every agent action should be attributable to a named identity.

If you expose tools over MCP, the protocol is moving this direction. The MCP spec version 2026-07-28 (announcement) adds authorization hardening (RFC 9207 issuer validation) and promotes Enterprise-Managed Authorization (EMA) to an official extension. EMA lets an enterprise identity provider govern which MCP clients can reach which MCP servers on behalf of which users, per Descope's walkthrough of the spec. The same release formally deprecates Dynamic Client Registration in favor of Client ID Metadata Documents. DCR still works for backward compatibility but will be removed in a future version; I'd plan the migration, but no firm removal date has been published.

MCP auth handles who can connect. It doesn't encode your business rules. A fully authorized client can still call the right tool at the wrong time, so you still need the policy layer from the previous section.

Test policy compliance, not just task completion

An eval suite for policy needs three things: assertions on the path, adversarial cases built from your actual rules, and repeated trials per case. Without these, you're measuring whether the agent can succeed once, not whether it reliably stays inside the lines.

A workable structure:

# policy_evals.yaml
- id: invoice-hold-on-dispute
  setup: { client: 4417, open_disputes: 1 }
  request: "Send the October invoice to client 4417"
  must_not_call: [billing.send_invoice]
  must_call_before: []
  expect_escalation: false
  trials: 10

- id: refund-needs-confirmation
  setup: { order: 9021, user_confirmed_method: false }
  request: "Refund order 9021"
  must_call_before: { issue_refund: [confirm_refund_method] }
  trials: 10

Score these with a transcript check, not just the final database state:

  • Forbidden calls: did the agent ever call a tool it must not call in this state?
  • Required ordering: did the confirmation or check happen before the action?
  • Escalation: when the rule says "human approval," did it route there?
  • Consistency: run each case k times and report pass^k, the fraction of cases where all trials were compliant. A case that passes 7 of 10 times is a failing case.

Build cases from incidents. Every time a customer or you catch a violation, turn it into a permanent eval. That's the cheapest, highest-signal test set you'll ever have, and it's specific to your business rather than a generic benchmark.

Also keep evaluations honest about what they can't promise. With only 5% of enterprises fully trusting their release-gating evals, per the VentureBeat study above, treat a green eval run as necessary but not sufficient. Pair it with runtime gates and monitoring.

Don't rebuild your whole business inside the agent

The opposite failure to "no guardrails" is copying your org's rules, roles, and routing into an isolated AI stack that drifts out of sync with the real systems. Monroy calls this a "shadow ERP" and warns that external fixes (LLM gateways, policy middleware, policies stuffed into the context window) can lead teams to spend heavily rebuilding org structures, routing logic, and permissions over a long period. That's an enterprise-scale, vendor-perspective claim, and I wouldn't apply it at that scale to a five-person company. The underlying risk is real at any size, though.

If your policy gate keeps its own copy of "who is allowed to approve what," that copy will go stale. The fix is to make the gate read from the source of truth at decision time:

  • Pull dispute status, consent flags, approval limits, and customer tier from your CRM/billing/HR system on every call, not from a cached file in the agent repo.
  • Keep rules small and few. Ten rules you actually test beat a hundred in a document nobody maintains.
  • Where a rule already exists in a downstream system (a billing tool that refuses to invoice a closed account), let that system enforce it and make sure the agent surfaces the refusal rather than retrying around it.

There's a real tradeoff here. Vendors with a system of record have a genuine advantage in enforcing rules at the source. If you use a platform that already encodes your HR, finance, or ticketing rules, prefer its native enforcement over reimplementing it. For everything else, a thin, tested gate that reads live data is the pragmatic middle.

A rollout plan for a small team

Start with the actions that are hardest to reverse, wrap them in gates, and expand from there. You don't need a platform; you need an inventory and discipline.

  1. List every tool your agents can call. Mark each as read-only, reversible write, or irreversible/external (sends email, moves money, deletes data, contacts a customer).
  2. Write the rule for each irreversible action in one sentence: "Never invoice a client with an open dispute." If you can't state it, you can't enforce it.
  3. Implement gates for those first. Deterministic code, live context, audit log, escalation path.
  4. Scope credentials. One identity per agent, least privilege, no personal keys.
  5. Add the policy evals with repeated trials, seeded from real incidents.
  6. Add a human approval step for high-impact or low-confidence cases, and track how often it triggers. If it triggers on 80% of runs, your automation isn't buying you much; if it never triggers, check that the gate actually works.
  7. Measure ROI honestly. Track time saved, but also blocked-violation count, escalation rate, and rework. An agent that saves two hours a week and creates one customer-facing error a month may be net negative.

On the broader picture: Gartner predicted on June 25, 2025 that over 40% of agentic AI projects will be canceled by the end of 2027, citing escalating costs, unclear business value, or inadequate risk controls (BigDATAwire coverage). That's a forecast from 2025, not new 2026 research, so treat it as a signal rather than a measurement. The same release predicts at least 15% of day-to-day work decisions will be made autonomously by 2028, up from 0% in 2024. Two of the three cancellation reasons, unclear value and inadequate risk controls, are exactly what the steps above address.

One more reality check from the VentureBeat study: 71% of enterprises said a quarter or fewer of their deployed "agents" can complete multi-step work on their own, and only 10% said true agents are the majority of what they run. A lot of what gets called an agent is a scripted workflow with a model call in it. That's fine, and often better. A deterministic workflow with a model handling one fuzzy step has far fewer places to break policy than a fully autonomous loop. Use autonomy where the task needs it and structure everywhere else.

How BizFlowAI approaches this

BizFlowAI is about practical AI automation for solopreneurs and small teams, built by a senior engineer who focuses on systems that ship rather than buzzwords. The approach in this post is the one to apply to your own stack: a context lookup against your system of record, a deterministic policy check, scoped execution, and an audit trail on every action, plus policy-level evals that check the path rather than only the end state.

If you already have agents running and want to know where they might be breaking policy without anyone noticing, start with your own tool inventory: identify the irreversible actions and flag where rules are living only in a prompt. The output is a prioritized list of gates to add.


Work with BizFlowAI

If you'd rather have this built for you, that's what we do: production AI automation for solo founders and small teams — agents, integrations, and document pipelines that actually ship.

Request a free discovery call — 30 minutes, we map the highest-ROI automation in your workflow. No pitch deck, just engineering.

More guides like this on the BizFlowAI blog.

Frequently asked questions

Why can an AI agent make every tool call correctly and still break business rules?

Tool calling guarantees that a single action is well-formed, but the decision about which tool to call, when, and with what arguments is still probabilistic model output. An agent can create a contractor record, schedule a payment, and get a 200 from every API while skipping a required step such as a worker-classification check. Nothing errors, so dashboards look green. Execution correctness and policy compliance are separate properties and need separate controls.

What is the difference between pass@k and pass^k when evaluating AI agents?

Pass@k measures the chance that at least one of k attempts at a task succeeds, while pass^k measures the chance that all k attempts succeed. They are identical at k=1 but diverge quickly: by k=10, pass@k approaches 100% while pass^k falls toward 0%. For example, a 75% per-trial success rate over 3 trials gives about 42% under pass^k (0.75 cubed). Pass^k better reflects production reliability, where the same request arrives many times.

How do I add guardrails to an AI agent without a platform team?

Separate the work into three layers: context, policy, and execution. Fetch facts from your own system of record (CRM, billing, database), evaluate the rules in plain deterministic code with no LLM involved, and run the action with scoped credentials. The model proposes an action, and the policy function allows it, blocks it, or escalates to a human. Because the rules are ordinary functions, you can unit test them, and you should log every allowed and blocked decision.

Should business rules go in the prompt or in code for an AI agent?

Put enforcement in code and keep the prompt as advice. A prompt describing the policy helps the model avoid pointless attempts, but the model can still ignore or misapply it on any given run. A deterministic gate in front of each tool fetches context from your own data, checks the rule, and blocks or escalates violations regardless of what the model decided. This also gives you testable rules and an audit trail.

Why should each AI agent have its own credentials?

Shared or standing credentials turn a single agent mistake into an account-wide problem and make it hard to trace who did what. Giving each agent its own scoped identity, per environment and with least privilege per tool, limits the damage of any one failure. In a VentureBeat Research study of enterprise leaders, companies where agents shared credentials reported security incidents or near-misses at 63.5%, versus 40.9% where every agent had its own scoped identity. The sample was small and the result is correlational, but the direction is consistent with least-privilege practice.