Your API Returned 200 OK. Your AI Agent Still Failed.
Your API Returned 200 OK. Your AI Agent Still Failed.
The Core Problem
For most backend systems, 200 OK is comforting. It means the request reached the server, passed validation, and completed successfully. For an AI agent, however, 200 OK can hide one of the most dangerous failure modes in modern software: the API did exactly what the agent asked - but the agent asked for the wrong thing.
Consider an AI-powered banking assistant. A customer says: "Refund the duplicate payment from yesterday." The agent retrieves several transactions, identifies what it believes is the duplicate, and calls:
POST /refunds
The request is authenticated. The agent is authorised. The transaction ID exists. The refund API processes the request successfully. HTTP / 1.1 200 OK
Every technical dashboard is green. But the agent selected the wrong transaction. The API succeeded. The business outcome failed.
As AI systems evolve from chatbots that recommend actions into agents that execute them, backend engineers need to rethink what "success" actually means.
Three Levels of Success
Traditional systems usually measure success at several technical layers. At the network layer: Did the request reach the service? At the API layer: Did the service return a successful response? At the database layer: Did the transaction commit? That works reasonably well when deterministic application code has already decided what operation should happen.
Agentic systems change this relationship. An AI agent may be given tools such as findCustomer(), lookupTransaction(), issueRefund(), cancelOrder(), sendEmail(), disableAccount(), restartService(), and createRefund(). The model then determines: Which tool should I call? Which parameters should I use? Should I retry? What should I do next?
We have introduced probabilistic reasoning before deterministic side effects. That means we need another definition of success.
Level 1: Transport Success
Did the technical request complete? HTTP / 1.1 200 OK
Level 2: Execution Success
Did the backend perform the requested operation? Refund created successfully.
Level 3: Intent Success
Did the system perform the right action, on the right resource, for the right user, under the right conditions, exactly as intended?
For a refund, this means: Correct customer, Correct transaction, Correct amount, Correct reason, Correct approval. Exactly once.
The first two are familiar engineering problems. The third becomes much more important once AI starts selecting and sequencing actions dynamically.
Failure Mode 1: The API Correctly Executes the Wrong Decision
Consider this user request: "Refund the most recent duplicate charge." The agent receives:
[
{
"id": "TX-18419",
"amount": 2500,
"merchant": "ABC Store"
},
{
"id": "TX-18491",
"amount": 2500,
"merchant": "ABC Store"
}
]
The agent incorrectly chooses TX-18491 and sends:
{
"transactionId": "TX-18491",
"amount": 2500
}
The backend validates the request. The account has sufficient authority. The transaction exists. The refund executes. Technically, there is no error. But the customer wanted another transaction refunded. This is an important distinction: API correctness does not guarantee semantic correctness. The service knows how to refund a transaction. It does not necessarily know whether the AI chose the correct transaction.
Failure Mode 2: The Agent Retries Something That Already Worked
Imagine the refund really is correct. The agent calls the service. The refund succeeds. But the response is lost. The agent sees:
Timeout
It reasons: "The refund probably failed. I should retry." The second call also succeeds. Without protection, one user intent may produce multiple real-world side effects.
This problem is familiar to payment engineers and distributed-systems developers. The difference is that with autonomous agents, retries may not come from a predefined retry library. The model itself can decide: "Let me try that again." That makes idempotency even more important.
Failure Mode 3: Every Tool Succeeds, but the Workflow Is Wrong
Imagine an account-closing agent. It successfully executes:
- ✅ Cancel subscription
- ✅ Revoke API credentials
- ✅ Delete files
- ✅ Generate final invoice
- ✅ Close account
Every API returns success. But company policy requires: Export compliance archive BEFORE Delete files. The agent skipped the archive. Five green tool calls. One invalid business process. This is why agent observability cannot stop at: Tool call succeeded. We need to ask: Was the workflow itself valid?
Architectural Principles for Safe Agent Actions
To mitigate these failures, adopt these principles:
Give Every Important Action an Intent ID
Agents need a business-level identifier that represents the objective, not just technical identifiers. For example:public record AgentIntent ( UUID intentId, String userId, String action, String resourceId, IntentStatus status, String resultId ) {}With an enum:
public enum IntentStatus { PENDING, EXECUTING, COMPLETED, REQUIRES_REVIEW, FAILED }Before executing a mutation, check if the intent is already completed rather than blindly retrying.
Put a Deterministic Gate Between Reasoning and Mutation
For high-impact actions, insert a verification step outside the model's probabilistic reasoning:User Goal → AI Agent → Intent + Policy Gate → Tool Gateway → Business API → Outcome VerificationBefore issuing a refund, deterministic code can verify:
- Transaction belongs to authenticated user
- Transaction is refundable
- Amount ≤ remaining refundable amount
- Approval threshold is satisfied
- Intent has not already completed
The system verifies, the API executes, and the system verifies again.
Define Preconditions and Postconditions
Tools should expose strong contracts:tool: issue_refund preconditions: - transaction belongs to authenticated customer - transaction is refundable - amount <= remaining refundable balance execution: idempotency_required: true postconditions: - refund record exists - refund references expected transaction - refund amount matches approved amount - ledger state reconciles approvalSuccess is not simply: function returned successfully. It becomes: preconditions satisfied + action executed + postconditions verified.
Beyond HTTP: Higher-Level Metrics
Observability needs to move above HTTP. A dashboard focused solely on availability hides critical issues:
| Metric | Current Focus | Required Shift |
|---|---|---|
| Availability | refund-api availability: 99.99% |
Verified outcome rate |
| Tool-call success | tool-call success rate: 98.9% |
Duplicate action rate |
| Latency | average API latency: 310 ms |
Policy violation rate |
| Human oversight | None tracked | Human override rate |
A meaningful SLO might look like: 99.95% of high-impact agent intents complete with a verified business outcome and no duplicate side effect. This tells us far more than API availability.
A Safer End-to-End Example
Suppose a user tells an AI commerce agent: "Cancel my duplicate order and refund it." Instead of immediately executing actions, the workflow could be:
- Create intent
CANCEL_DUPLICATE_ORDER_9821 - Retrieve candidate orders
- Deterministically verify:
- Same customer
- Duplicate item
- Matching amount
- Cancellable state
- Generate action preview: Cancel Order A1842 Refund £74.99
- Request human confirmation if required
- Cancel order using intent ID
- Issue refund using same intent context
- Verify:
order == CANCELLEDandrefund == CONFIRMEDandrefund amount == £74.99 - Mark intent
COMPLETED - Tell user: "Done"
Step 10 is the important part. The agent does not say "done" because it received 200 OK. It says "done" because the system verified the intended business outcome.
Six Controls for High-Impact Agent Actions
For any agent capable of moving money, modifying production systems, changing permissions, deleting information, or performing irreversible actions, implement these six controls:
- Explicit intent - Persist the actual business objective.
- Least-privilege tools - Expose only capabilities required for the task.
- Deterministic preconditions - Keep critical business rules outside the model.
- Idempotent mutations - Design retries so repeating a request does not repeat the side effect.
- Independent postcondition verification - Verify the resulting state using trusted systems.
- Outcome-level auditability - Connect: User intent → agent decision → policy result → tool call → API response → verified business state instead of Prompt → Tool → 200 OK → "Done!".
Final Thought
We are investing enormous effort in making AI agents smarter. Better models. More context. More tools. Longer workflows. Greater autonomy. But once an agent can modify the real world, the hardest production question may not be "Can the model determine what to do?" It may be: "How do we prove that what it just did was actually what the user intended?"
The most dangerous failure may never generate an exception. It may not trigger PagerDuty. It may not appear in the error logs. Every service may remain healthy. All you may see is:
HTTP / 1.1 200 OK
The API succeeded. The AI agent completed its task. And the business still lost. That is why production agentic AI needs more than successful tool calls. It needs verified outcomes.
Comments
No comments yet. Start the discussion.