An AI agent should be tested as a stochastic, stateful control system rather than as a text generator. The unit of quality is not merely the final response. It is the relationship between an intended task, the actions taken by the agent, the state changes produced in the environment, and the final outcome.
This distinction is supported by the emerging evaluation literature. AgentBench evaluates LLMs in interactive environments rather than only static question answering, while recent production guidance from Anthropic and OpenAI treats traces, tools, handoffs, graders, datasets and end-state verification as separate evaluation surfaces.
1. Define the agent as a system
Production agent assurance architecture
The browser or API executes the journey; trace collection preserves the trajectory; deterministic, semantic and outcome evaluators establish release evidence.
- 01User taskIntent + constraints
- 02AgentModel + prompt + policy
- 03Tools / RAGActions + evidence
- 04EnvironmentState changes
- 05TraceTrajectory + evidence
- 06EvaluatorsContract + semantic + outcome
- 07Release gatePass / investigate / block
Model the system under test as a tuple: A = (M, H, P, T, S, E), where M is the model, H is the agent harness or orchestrator, P is policy and instruction context, T is the available tool set, S is mutable state, and E is the external environment.
This matters because two agents using the same model can have materially different behaviour when their tool permissions, memory policy, orchestration logic or guardrails differ. Testing only the model therefore confounds component quality with system quality.
Define the task contract before execution. A useful contract specifies the initial state, user input, permitted actions, forbidden actions, expected outcome, escalation policy, safety constraints and evidence required to establish success.
2. Separate task success from response quality
A production agent can produce a fluent answer while failing the task. Conversely, it can complete the task while phrasing the response differently from a reference answer.
Use at least three layers: outcome verification, trajectory verification and response evaluation.
Outcome verification asks what changed in the environment. For example, did the order actually get cancelled? Did the appointment actually exist? Was the database record changed only when authorization was satisfied?
Trajectory verification asks how the agent reached the outcome. It should expose tool selection, parameters, sequencing, retries, handoffs, policy checks and state transitions.
Response evaluation asks whether the final communication was correct, complete, relevant, appropriately uncertain and compliant with the interaction contract.
Anthropic explicitly distinguishes the transcript from the final environment outcome in its agent-evaluation model; this is a useful design principle for enterprise QA.
3. Treat the trace as a first-class test artifact
A trace should contain at least: task identifier, model/version, prompt or instruction version, environment, timestamps, user turns, model outputs, tool calls, tool arguments, tool results, state transitions, guardrail decisions, handoffs, final response and final environment state.
Do not make hidden chain-of-thought a test dependency. What matters for assurance is observable execution evidence: tool calls, arguments, retrieved evidence, state mutations, policy decisions and externally visible outputs.
The trace enables failure localization. A failed outcome may originate from intent recognition, retrieval, planning, authorization, tool execution, state management or response generation. Without a trace, these failures collapse into the unhelpful label 'AI failed'.
4. Deterministic checks should dominate where determinism exists
Use code-based assertions for exact contracts: allowed tool names, required parameters, schema validity, authorization state, maximum transaction amount, mandatory confirmation, routing rules, HTTP status, database state and escalation destinations.
For example:
expect(trace.intent).toBe('delivery_status');expect(trace.tools).toContain('get_tracking_status');expect(trace.authorization).toBe('verified');The principle is simple: do not use a probabilistic judge to evaluate a property that the system specification defines exactly.
5. Use semantic graders only for semantic properties
Semantic evaluation is appropriate for correctness across paraphrases, completeness, relevance, groundedness, conversational quality and business-rule adherence where several valid responses exist.
A rubric should decompose the judgment. Instead of 'Is this answer good?', define atomic criteria such as factual correctness, required-fact coverage, evidence support, prohibited-claim absence and appropriate uncertainty.
LLM-as-a-judge is useful but cannot be treated as an unquestionable oracle. Research has identified position, verbosity, self-enhancement and other biases, and one study demonstrated that changing answer order can substantially change model-judge rankings.
Therefore calibrate the judge against human-labelled examples, randomize presentation order where pairwise comparison is used, measure agreement, inspect disagreement cases and periodically revalidate the evaluator when the model or rubric changes.
6. Account for stochasticity statistically
A single pass is weak evidence for a stochastic agent. If the same task can produce different trajectories, evaluate repeated trials and report the distribution.
For a binary success criterion, estimate pass rate p-hat = successes / trials and attach uncertainty rather than presenting the point estimate as a universal truth. For important comparisons, use confidence intervals or appropriate paired statistical tests and keep the same task set, environment and evaluation protocol across candidates.
Repeated trials are especially important when failures are low-frequency. A system that passes 19 of 20 trials has observed success of 95%, but that sample does not establish that its long-run failure probability is exactly 5%.
7. Build capability and regression suites separately
Capability evaluations answer: can the new system perform behaviours it previously could not? Regression evaluations answer: did a change break behaviour that previously worked?
Capability suites can deliberately contain difficult tasks and initially low pass rates. Regression suites should contain proven business-critical scenarios and have strict release criteria.
This separation prevents an improving capability score from hiding regressions in mature functionality. Anthropic describes the same distinction between capability and regression evals.
8. Design adversarial and metamorphic tests
Static happy-path tests are insufficient for agents. Generate controlled transformations that should preserve behaviour: paraphrase the request, alter irrelevant wording, reorder independent information, change locale where supported, introduce benign spelling variation, or vary non-semantic formatting.
A metamorphic relation specifies how outputs or actions should relate when an input transformation is applied. Recent research surveys hundreds of metamorphic relations for LLM systems and shows their usefulness when a direct oracle is unavailable.
Also test boundary conditions: missing identifiers, conflicting facts, stale state, repeated requests, tool timeout, empty retrieval, malformed tool result, unauthorized action and ambiguous intent.
9. Test state as a formal dimension
For multi-turn agents, define state variables explicitly. Test creation, update, persistence, reset, isolation and conflict resolution.
A robust suite should include sequence-sensitive cases such as: establish customer A, switch identity, request data, reset session, repeat; or provide an identifier in turn one and a different identifier in turn three.
State defects are often invisible in isolated single-turn tests because the failure is a transition property rather than a response property.
10. Test tools as security and correctness boundaries
For each tool define preconditions, authorization, valid parameters, side effects, idempotency expectations, retry semantics and prohibited uses.
A correct final answer does not compensate for an unauthorized intermediate action. Similarly, a tool call with a syntactically valid but semantically incorrect identifier is a defect even if the model later recovers.
The test oracle should inspect both the tool call and the resulting state.
11. Test failure recovery deliberately
Inject failures rather than waiting for them to occur naturally. Test timeout, 429, 500, empty result, malformed payload, stale result, permission denial, unavailable dependency and contradictory data.
The expected behaviour should be explicit: retry, alternate tool, ask for clarification, escalate, or stop. Never leave recovery as an emergent model behaviour without a testable policy.
12. Define release gates by failure severity
Agent evaluation control matrix
Use different oracles for different failure classes instead of asking one evaluator to judge the entire system.
| Layer | Primary oracle | Evidence | Typical failure |
|---|---|---|---|
| Execution | Deterministic | Trace + tool call | Wrong action |
| Contract | Schema / rule | Arguments + state | Invalid parameter |
| Behaviour | Trajectory constraints | Ordered trace | Unsafe sequence |
| Semantics | Calibrated evaluator | Response + rubric | Wrong meaning |
| Outcome | Business state | Backend / environment | Task not completed |
| Safety | Adversarial regression | Attack + trace | Control bypass |
A single weighted score is dangerous when critical failures are sparse. Use layered gates: critical journeys must pass; authorization and safety invariants must pass; deterministic contracts must pass; semantic quality must exceed defined thresholds; unexplained critical regressions must be zero.
A release policy should distinguish severity from frequency. One unauthorized financial transaction can be unacceptable even if 999 harmless conversations passed.
13. Close the EDD loop
Evaluation-Driven Development turns requirements and failures into executable knowledge: requirement → test → execution → evidence → failure → root cause → regression case → release gate.
Start with 20–50 high-value cases drawn from real requirements and failures rather than waiting for a huge dataset. Anthropic reports this as a practical starting point and emphasizes that eval suites become increasingly valuable when maintained throughout the agent lifecycle.
The mature architecture is therefore not 'Playwright plus an LLM assertion'. It is a layered assurance system in which browser/API execution, deterministic contracts, semantic grading, trace analysis, security testing and production feedback reinforce one another.
Reference implementation pattern
Test case → isolated environment → agent execution → trace collector → deterministic evaluator → semantic evaluator → outcome verifier → severity classifier → evidence store → release gate → regression dataset.
For browser-based agents, Playwright can provide isolated fixtures, user-facing locators, web-first assertions and traces; the AI-specific evaluation layer then operates on the resulting conversation and execution evidence.
Expert checklist
- Is success defined as an environment outcome rather than only a response?
- Can every important tool call and parameter be inspected?
- Are state transitions and handoffs observable?
- Are deterministic requirements evaluated deterministically?
- Is the semantic judge calibrated against human labels?
- Are repeated trials used where stochasticity matters?
- Are capability and regression suites separated?
- Are metamorphic, adversarial and failure-injection tests present?
- Can every production incident become a reproducible regression case?
- Are critical failures gated independently of aggregate scores?
The objective of agent testing is not to make probabilistic systems deterministic. It is to make important behaviours measurable, falsifiable, reproducible enough for engineering decisions, and protected against regression.