Your agent worked in the demo: it read a ticket, called three APIs, and posted a clean summary. Then production happened—duplicate emails, retry loops that burned through token budgets, and payloads your frontend could not parse.
The gap between a working prototype and a reliable agent is usually not the model. It is the API layer around it. Every tool call is an HTTP request that can fail, throttle, time out, or return an unexpected payload. If you do not test those calls like production API integrations, one bad response can become an incident.
The practical approach is to test agent behavior at the API boundary: define tool contracts, mock dependency failures, run realistic scenarios, and assert on requests, responses, retries, and guardrails. This guide covers five failure modes and how to test them with Apidog.
Agents fail at the API boundary, not in the prompt
When an agent behaves incorrectly in production, editing the prompt is often the first reaction. Sometimes that helps. More often, the agent received a slow, malformed, rate-limited, or unexpected API response and then made a confident decision using bad input.
A typical agent step has four parts:
- The model selects a tool.
- Your application converts that selection into an HTTP request.
- An external service returns a response.
- Your application passes the result back to the model.
Three of these four steps are standard API integration work. Treat them accordingly: validate schemas, mock failures, and assert on behavior.
The reliability question is not only, “Is the model smart enough?” It is also:
Have we tested the ways this agent’s API calls can fail?
Failure mode 1: Tool calls drift from the contract
A common failure is an agent generating a call that does not match the API contract. It may invent a parameter, omit a required field, send a string instead of an integer, or use valid fields with invalid values.
For example, a booking agent might call:
POST /reservations
{
"guests": "two"
}
when the API requires:
{
"guests": 2
}
The API might return a 400. Worse, it might return 200 OK with an error hidden in the response body, and the agent may continue as if the reservation succeeded.
How to test it
Treat every tool invocation as a contract test:
- Define an input schema for every tool.
- Validate required fields, types, enums, and formats.
- Run the agent against those contracts.
- Fail the test when the generated request does not conform.
For example, a reservation tool schema should make the expected type explicit:
{
"type": "object",
"required": ["guests", "date"],
"properties": {
"guests": {
"type": "integer",
"minimum": 1
},
"date": {
"type": "string",
"format": "date"
}
}
}
Use Apidog to store tool contracts and validate the agent’s outgoing requests against them. A mismatch should identify the exact invalid field before it reaches production.
For a deeper walkthrough, see testing an AI agent’s tool calls and testing agents that call your APIs.
Failure mode 2: Upstream errors and rate limits
Every dependency can return a 429, 500, malformed response, or timeout. A robust agent backs off and retries safely. A fragile one either gives up immediately or retries aggressively until it causes more throttling and drains its budget.
Patterns for this kind of agent error recovery are a recurring concern because healthy APIs do not exercise the failure handling you need to verify.
How to test it
Mock the dependency and return a controlled sequence of failures:
- Return
429 Too Many Requestswith aRetry-Afterheader. - Return
500 Internal Server Error. - Return a successful response.
- Assert that the agent retries correctly and eventually succeeds or exits safely.
Your tests should verify that the agent:
- Respects
Retry-After. - Uses backoff and jitter.
- Stops after a bounded number of retries.
- Avoids hammering an unavailable service.
- Opens a circuit breaker when appropriate.
- Reports a useful failure when recovery is exhausted.
A retry must also be safe. If the action sends an email, creates an order, or charges a customer, a repeated request must not repeat the side effect. Use an idempotency key for operations that can be retried.
A simple test scenario can look like this:
Attempt 1 -> 429 + Retry-After: 2
Attempt 2 -> 500
Attempt 3 -> 200
Expected:
- Wait before retrying
- Do not exceed configured retry limit
- Send the same idempotency key on retries
- Complete the action once
Read what a rate-limit-exceeded response means before simulating provider throttling. For implementation patterns, see AI agent error recovery.
Failure mode 3: Non-deterministic output
Even at temperature zero, model output is not always byte-for-byte identical. Hardware, batching, provider-side changes, and runtime differences can introduce variation. The long vLLM discussion on reproducibility shows why seeds and temperature are not enough.
If your tests compare exact response strings, they become flaky. Flaky tests get ignored, which is worse than having no test at all. The same principles described in what causes flaky tests apply to agent tests.
How to test it
Assert on structure and meaning instead of exact wording.
Avoid this:
expect(response.text).toBe("Your order total is $42.00.");
Prefer assertions like this:
expect(response).toMatchObject({
action: "order_summary",
total: expect.any(Number)
});
expect(response.total).toBeGreaterThanOrEqual(0);
expect(response.total).toBeLessThanOrEqual(cart.total);
Useful checks include:
- The response validates against a JSON schema.
- The correct tool was selected.
- The tool call has valid parameters.
- Required keys are present.
- Forbidden fields are absent.
- Numeric values are within acceptable ranges.
- The output contains the expected action or status.
For example, test the semantic requirement:
The reply must contain:
- a total
- a currency
- no customer payment details
- a total between 0 and the cart value
That test tolerates natural wording changes while still catching a real regression.
See testing non-deterministic AI agents for more strategies. If your agent stores context across runs, review how agent memory works as well.
Failure mode 4: Runaway cost
Agents loop, and loops cost money. A stuck agent can retry a failing operation thousands of times, repeatedly call the same tool, or keep expanding its context until a small workload becomes an expensive one.
Cost is a reliability issue, not just a finance issue. The same bugs that increase spending also make agents slow and unpredictable.
How to test it
Track cost-related signals for every test run:
- Number of model calls
- Number of tool calls
- Tokens per run
- Retry count
- Total execution time
- Context size
Then enforce limits:
max_tool_calls = 10
max_retries_per_request = 3
max_tokens_per_task = configured budget
max_execution_time = configured timeout
Your recovery-path tests should assert on call count, not only final success:
expect(mockApi.callCount).toBeLessThanOrEqual(3);
expect(agent.toolCallCount).toBeLessThanOrEqual(10);
An agent that reaches the correct answer after 40 API calls may still be a production incident waiting to happen.
For practical ways to reduce usage, see reducing agent token costs.
Failure mode 5: Missing guardrails
The most damaging failures happen when an agent successfully performs the wrong real-world action: sending an email, deleting a record, placing an order, or modifying production data.
The model may have followed its instructions exactly. The system failed because nothing stood between the model’s decision and a live, irreversible API call.
How to test it
Add explicit control points around side effects:
- Allowlist actions that can run without approval.
- Require human confirmation for destructive or irreversible actions.
- Add a dry-run mode that reports intended actions without executing them.
- Limit the scope of actions the agent can perform.
For example:
Allowed automatically:
- Read ticket
- Search customer record
- Draft email
Requires approval:
- Send email
- Delete record
- Issue refund
- Create order
Then test the guardrail path with mocked side-effecting endpoints:
Given:
- The agent decides to send an email
- Approval has not been granted
Expect:
- The agent creates a confirmation request
- The live email endpoint is not called
Do not assume the guardrail works because the code exists. Assert that the mock endpoint received zero calls until approval is provided.
The OWASP Top 10 for LLM applications is a useful checklist for identifying actions and data that need protection. For approval flows and blast-radius controls, see AI agent guardrails.
How to structure an agent test
The five failure modes use the same repeatable test structure:
Capture tool schemas
Define the request and response contracts for every tool the agent can call.Mock dependencies
Control status codes, timing, headers, bodies, and side effects.Run a scenario
Drive the agent through normal and failure paths, including conditions that live APIs will not reliably produce on demand.Assert on behavior
Validate request shape, retry behavior, call count, output structure, and guardrail activation.
A minimal test matrix might look like this:
| Scenario | Mock response | Expected behavior |
|---|---|---|
| Invalid tool argument |
400 validation error |
Agent reports or corrects invalid input |
| Rate-limited API |
429 with Retry-After
|
Agent backs off and retries within limits |
| Temporary outage |
500 then 200
|
Agent recovers without duplicate side effects |
| Malformed payload | Invalid JSON or missing field | Agent stops or handles the invalid response safely |
| Destructive action | Approval required | Agent requests confirmation and does not call live action |
Start with one tool, make it reliable, then add the next one.
The agent reliability checklist
Before shipping an agent, verify the following:
- [ ] Every tool call is validated against a schema.
- [ ] Contract violations fail a test.
- [ ]
429,500, timeout, and malformed-response cases are simulated. - [ ] Retry behavior uses backoff and has a bounded attempt count.
- [ ] Retried actions are idempotent and cannot double-charge or double-send.
- [ ] Tests assert on structure and meaning, not exact output strings.
- [ ] Token usage and tool-call counts are measured per run.
- [ ] Budget caps stop runaway loops.
- [ ] Destructive actions require an allowlist or human approval.
- [ ] Guardrail paths are tested with mocks.
Where Apidog fits—and where it does not
Apidog is not an agent framework, model host, or evaluation harness. It does not build or run your agent.
Its role is the API layer your agent depends on:
- Store and design contracts for agent tools.
- Validate outgoing requests against those contracts.
- Mock dependencies and failure responses such as
429,500, timeouts, and malformed bodies. - Assert on schemas, response shapes, required keys, and value ranges.
That makes it useful for rehearsing the API failures an agent must handle before users encounter them. For the broader QA context, read agentic AI testing.
Frequently asked questions
Is agent reliability a model problem or an engineering problem?
Mostly engineering. Model choice matters, but many production incidents come from bad tool calls, unhandled rate limits, missing idempotency, and missing guardrails.
Can I test an agent without hitting its real APIs?
Yes—and you should. Mock dependencies so you can force failures, control timing, and avoid real-world side effects. This is the reliable way to test recovery and approval paths.
How do I test output that changes on every run?
Assert on schemas, tool-call shape, required fields, forbidden fields, and numeric ranges instead of exact strings. See testing non-deterministic AI agents.
What should I test first?
Start with destructive-action guardrails and error recovery. These protect against the most expensive failures: harmful side effects and loops that drain your budget.
Start with one failure mode
You do not need to implement every test at once. Pick the failure mode with the highest risk—usually guardrails or error recovery—and test it this week.
Program the failure. Run the agent. Inspect the requests it makes and the actions it avoids.
When your agent handles a simulated 429 with bounded backoff instead of entering a budget-draining loop, you will have a stronger reason to trust it than a green demo.
Download Apidog to design tool contracts, mock dependency failures, and validate the API behavior your agent depends on.
Top comments (0)