Your AI agent can pass a polished demo and still be unfit for production. The failure usually appears when a person interrupts, supplies information out of order, changes direction, or triggers a partial tool failure. At that point, a longer system prompt does not give you more control. It makes the system’s behavior harder to inspect.
If you are deciding whether an agent is ready, focus on where state lives, which actions the model may choose, how failures become regression tests, and what evidence you retain. The operating principle is simple: let the model handle language and bounded judgment; let software own permissions, transitions, persistence, and recovery.
Key takeaways
- Define reliability as an explicit product contract with terminal states, critical invariants, quality criteria, and recovery behavior.
- Keep the transcript as evidence, not as the only source of state. Persist the facts and decisions the workflow needs.
- Place the model inside a controller that limits available tools and validates every transition.
- Run structural checks for prohibited failures and substantive checks for missed meaning. They answer different questions.
- Convert real failures into permanent regression cases instead of treating each incident as an isolated prompt problem.
- Collect enough telemetry to reconstruct decisions without turning observability into unrestricted surveillance.
Start with a reliability contract, not a model choice
Reliability does not mean that the agent sounds helpful most of the time. It means the system completes a defined job under known conditions, respects its constraints throughout the job, and enters a safe recovery path when it cannot continue.
Write that definition before comparing models. Otherwise, teams optimize whatever is easiest to notice in a demo: tone, answer fluency, or an impressive happy path. Those qualities matter, but none tells you whether the agent attributed information to the right person, called the right tool, preserved state after a timeout, or avoided an action it was not authorized to take.
A usable reliability contract contains the following:
- Task boundary: State what the agent is allowed to accomplish and what remains outside its role. An agent that recommends a refund and an agent that issues one are different products.
- Terminal states: Define successful completion, user cancellation, human handoff, policy refusal, recoverable technical failure, and unrecoverable failure. A conversation ending is not automatically a successful outcome.
- Critical invariants: Identify conditions that must never be violated, such as using data from the wrong account, revealing a protected identity, or executing a write action without authorization.
- Quality criteria: Describe what a good result contains. Include evidence use, relevance, completeness, tone, and whether the agent recognizes ambiguity that changes the consequence of an answer.
- Recovery behavior: Specify what the agent preserves, what it tells the user, which operations may be retried safely, and when it must stop or hand off.
The distinction between invariants and quality criteria is important. An invariant is a gate. You do not average a privacy breach against several fluent answers. A quality criterion is graded: the response may be usable but shallow, correct but poorly prioritized, or strong enough to release without review.
| Failure class | What it looks like | Primary control | How to test it |
|---|---|---|---|
| Workflow | The agent skips consent, repeats a completed step, or loses its place after a detour. | Explicit state and guarded transitions | Assert the permitted state sequence and required checkpoints. |
| Data | The answer uses stale, unsupported, or cross-account information. | Provenance, retrieval filters, and validation | Inspect evidence identifiers and test conflicting or missing data. |
| Action | A tool call is unauthorized, malformed, or duplicated. | Capability limits, preconditions, and idempotency | Validate the tool trace and resulting system state. |
| Judgment | The answer is technically valid but misses the user’s intent or an important pattern. | Task rubric and independent analysis | Score against anchored examples and review disagreements. |
| Experience | Long pauses, interruptions, or poor recovery make the task unusable. | Latency budgets, turn handling, and fallback design | Replay realistic timing, silence, interruption, and reconnect cases. |
| Privacy | The output exposes an identity or the logs retain more sensitive content than required. | Deterministic disclosure rules and data minimization | Test prohibited combinations and inspect retained telemetry. |
Write critical invariants as executable assertions wherever possible. The system can check that the user is authenticated before exposing a tool, that a write request carries an idempotency key, that retrieved evidence belongs to the active account, and that a required confirmation exists. Reserve model-based grading for qualities that genuinely require judgment.
This contract also changes the build-or-buy conversation. A vendor demo may prove that a model can conduct the interaction. It does not prove that your product can enforce its own permissions, retain the right state, reconstruct a failure, or roll back a problematic change. Ask who owns each control and whether you can test it independently.
Put a workflow controller around the model
Reliable behavior begins as an architecture decision, not a prompt-writing contest. A model is good at interpreting messy language and producing useful language. It should not also be the only database, policy engine, workflow manager, and permissions layer.
The controller can be a state machine, a workflow engine, or application code with explicit transition rules. The implementation matters less than the separation of responsibility. The controller knows the current state, exposes only the capabilities allowed in that state, validates the model’s proposed output, executes approved operations, and persists the result before the workflow advances.
Your persisted state might include the current task phase, facts already collected, unresolved questions, evidence references, consent and policy flags, pending tool operations, confirmed actions, and the reason for a handoff. Keep these as typed fields with provenance. Do not make downstream behavior depend on the model rediscovering them from an ever-growing transcript.
For every state, specify:
- The data required on entry.
- The prompts, knowledge, and tools available while the state is active.
- The completion condition.
- The permitted next states.
- The output validation applied before transition.
- The fallback when input is ambiguous, validation fails, or a dependency is unavailable.
- The actions that are forbidden even if the model requests them.
A typical turn should then follow an inspectable sequence:
- Load the latest persisted state and policy context.
- Expose only the tools and transitions permitted from that state.
- Ask the model to interpret the new input and return a structured proposal.
- Validate the proposal against its schema, permissions, and business rules.
- Execute any approved tool operation with timeout and duplicate-call protection.
- Persist the resulting state before presenting a success response.
- Route validation failures, uncertain results, and dependency failures to an explicit recovery path.
A state machine does not have to make the conversation rigid. It should control progress while allowing language to be flexible. In a realistic voice interview, a participant may answer three planned questions in the opening response. A survey-like bot asks those questions again because it only knows its script position. A stateful agent marks the covered topics, extracts supporting evidence, identifies what remains unclear, and chooses the next useful question.
This is the practical difference between sequence and coverage. The sequence tells the system where it is. Coverage tells it what the user has already supplied. Reliable conversational products need both.
Keep tools narrower than the conversation
Tool design determines how much damage a mistaken inference can cause. A broad tool that accepts natural-language instructions pushes policy interpretation into the model. A narrow tool with typed arguments, explicit preconditions, and a constrained result gives the surrounding system something it can verify.
- Separate read capabilities from write capabilities so that exploration does not silently become execution.
- Validate account, resource, permission, and policy scope outside the model.
- Make write operations idempotent so a retry cannot duplicate the effect.
- Check the postcondition instead of assuming a successful API response completed the user’s goal.
- Require explicit user confirmation when ambiguity could create a material or difficult-to-reverse consequence.
- Return structured error categories that the controller can route, rather than dumping raw system errors back into the conversation.
Do not ask the model to remember whether a tool already ran. Persist the operation identifier and result. Do not ask it to infer whether the user has permission. Check the permission. Prompts can explain policy, but software should enforce policy.
For voice, latency is part of correctness
A voice agent can produce a semantically excellent answer and still fail the interaction. Long silence invites the user to speak again. Overlapping turns can cause duplicate questions or actions. A late response can sound disconnected from the moment it addresses.
That is why reasoning-heavy models can be a poor fit for live voice. The extra deliberation may improve a difficult analysis, but time to first token affects turn-taking. Select the model for the state it serves: a responsive conversational model for the live turn, and a slower analytical model for work that can happen after the user finishes speaking.
Instrument speech recognition, model response start, speech synthesis start, tool latency, and total turn latency separately. Then test interruption, false starts, silence, background noise, dropped connections, and reconnection. An end-to-end latency number tells you that a turn was slow; component timing tells you where to fix it.
Turn failure modes into an evaluation system
An eval suite is not a folder of impressive conversations. It is a versioned set of cases that represent the ways your product must behave, including the ways it has already failed.
Each case should carry enough information to reproduce and judge the behavior:
- The scenario, user goal, and consequence if the system gets it wrong.
- The initial state, policy context, available data, and allowed tools.
- The persona or input sequence, including interruptions and ambiguous requests where relevant.
- The expected state transitions and terminal state.
- Required evidence, tool effects, and recovery behavior.
- Forbidden claims, disclosures, transitions, and actions.
- An anchored rubric for qualities that cannot be checked deterministically.
- The complete trace needed to explain the score.
Start with known failures. Personas derived from failed calls are especially useful because they preserve the behavior that exposed a weakness: answering out of order, withholding detail, changing tone, misunderstanding the task, or pushing the workflow into an awkward transition. Sanitize sensitive material, preserve the failure mechanism, and add the case to the permanent regression suite.
Every material incident should produce an eval before the fix is declared complete. Otherwise, the team remembers the lesson only until a later prompt, model, provider, or tool change reintroduces the same behavior.
Separate structural checks from substantive checks
Structural and substantive evaluations solve different problems. Structural checks ask whether the system broke a rule: Did it use the required schema? Did it attribute evidence to the right person? Did it call an allowed tool? Did it repeat a side effect? Did it cross an anonymity boundary? Did it reach a valid terminal state?
Make these checks deterministic whenever the required fact exists in system state. Exact validators are easier to debug and harder for a fluent answer to fool.
Substantive checks ask whether the agent understood what mattered. Did it notice the central theme? Did it distinguish strong evidence from a passing remark? Did it ask a useful follow-up? Did it overstate a weak pattern? Did the final synthesis omit an important contradiction?
For synthesis tasks, use a structural pass and an independent substantive pass. The structural pass catches prohibited errors. The substantive pass re-examines the underlying evidence with fewer formatting constraints and looks for patterns the production pass may have missed. One asks, “What did the system do wrong?” The other asks, “What did the system fail to notice?”
Do not implement the substantive check as the same prompt run again and call the agreement proof. Give the evaluator the original evidence, the task definition, and a clear rubric. Ask it to identify both supported findings and omissions. Route disagreements with material consequences to human review until you understand which judgment is failing.
Use gates, not one blended score
A single average score can conceal the failure that matters most. Keep critical invariants as separate release gates. Then report qualitative performance by scenario, task state, risk class, model version, and tool path. A candidate that improves tone while introducing occasional unauthorized actions is not an improvement.
Anchor qualitative rubrics with observable descriptions such as “unsupported,” “supported but incomplete,” and “supported, complete, and appropriately prioritized.” Examples should show why each anchor earned its label. This creates a reviewable standard and reduces the temptation to accept an evaluator’s unexplained overall impression.
Run the same relevant suite when you change a model, provider, system prompt, tool schema, retrieval policy, state transition, or safety rule. Store the candidate and current-production results side by side with their component versions. You need to know not only that a score changed, but which behavior changed and why.
Offline evals are necessary, but they cannot represent every production condition. Treat them as a release filter. Production telemetry and controlled human review provide the feedback loop that expands the suite.
Observe decisions without creating a surveillance system
When an agent fails, the final response is rarely enough to identify the cause. You need to know what state the system loaded, what context it retrieved, which options it exposed to the model, what the model proposed, what validation accepted or rejected, what tools actually did, and which fallback ran.
Capture an event trail that includes:
- Conversation and task identifiers that connect events without exposing content in every dashboard.
- State entry, exit, transition reason, and terminal outcome.
- Model, provider, prompt, policy, workflow, and tool-schema versions.
- References to retrieved records and the filters used to select them.
- Redacted tool arguments, validation results, operation identifiers, and postconditions.
- Latency for each model, retrieval, tool, and voice component.
- Fallbacks, denied actions, retries, handoffs, user corrections, and abandonment points.
Logging every raw transcript by default is not observability. It creates another searchable store of sensitive customer material. Decide the purpose, consent basis, access policy, redaction process, and retention rule before capturing conversational content. Keep routine operational events separate from restricted content, and make access auditable.
Early products still need close inspection. Recruit design partners who explicitly agree to that review and understand how their data will be used. As the product matures, automated flags for customer value, sentiment, and product quality can direct reviewers toward questionable interactions instead of making routine transcript reading the operating model.
Encode privacy rules outside the prose prompt
Sensitive synthesis makes the architecture test especially clear. A model can be instructed to protect anonymity, but the underlying data access and disclosure rules should not depend on the model remembering that instruction.
For example, a feedback product can require corroboration before presenting critical feedback and display a provider group only when it contains three or more eligible contributors. Those constraints belong in the aggregation and policy layers. The model should receive only evidence that has passed them, and an output validator should check the result again before disclosure.
The same pattern applies beyond feedback. Filter account scope before retrieval, restrict fields before generation, and verify disclosures after generation. If the evidence does not satisfy the policy, the system should omit the claim, generalize it according to an approved rule, request more information, or hand off. It should not invite the model to improvise a privacy decision.
Make the operating view diagnostic
Your dashboard should distinguish task completion from conversation completion. Track successful tool postconditions, human handoffs and their eventual outcomes, repeated states, user corrections, denied actions, abandonment, component latency, and critical incidents. Break results down by workflow, state, scenario, model version, and relevant user context. Aggregate performance can hide a path that is reliable for common requests and brittle for an important minority.
Every alert should point to an owner and a playbook. A state loop needs a workflow response. A malformed action needs a tool-schema or validation response. Unsupported claims need a data or evidence response. Latency concentrated in speech synthesis needs a different response from latency concentrated in model inference. “The agent was bad” is not an actionable incident category.
Release one bounded workflow before expanding autonomy
A broad agent creates too many interacting variables at once. Start with a vertical slice that has a recognizable user outcome, a manageable tool surface, explicit terminal states, and a safe fallback. Prove that slice before adding adjacent jobs.
This sequencing has worked even for a complex voice product: its self-discovery flow was shipped and validated a month before feedback collection existed, with synthesis added later. The useful lesson is not the calendar interval. It is the separation of risks. Conversation flow, feedback collection, and synthesis each fail differently and deserve their own evidence.
A practical rollout sequence is:
- Offline replay: Run curated, adversarial, and sanitized failure cases. Disable external writes and inspect state transitions as well as final answers.
- Shadow operation: Let the agent produce decisions beside the existing process without executing side effects. Compare proposed states, evidence, and actions.
- Supervised design-partner use: Work with informed participants, keep the capability boundary narrow, and make human takeover immediate.
- Limited production: Allow only the tool scopes and user paths that have passed their gates. Monitor every critical invariant and recovery path.
- Measured expansion: Add a workflow, tool permission, cohort, or model change only after its failure modes and rollback path are understood.
Do not enter a stage because the previous one ran for a convenient amount of time. Enter when the evidence is ready. The relevant eval suite should have no critical-invariant failures. Required handoffs and fallbacks should work. Telemetry should reconstruct the decision path. Support owners should know how to contain a bad outcome. Component versions should be deployable and reversible.
Isolate meaningful changes when possible. If you replace the model, rewrite the prompt, expand the tool set, and change the workflow together, a better aggregate result will not tell you which change helped, and a regression will be expensive to locate. Run candidates against the current production baseline, inspect differences by scenario, and deploy with a rollback target already identified.
When a failure occurs, classify it before editing the prompt:
- Use a prompt or example change when the allowed reasoning was sound but the instruction or output language was unclear.
- Use a state or controller change when the system forgot progress, allowed an invalid transition, or failed to recover.
- Use a data or retrieval change when the model lacked the evidence needed to answer.
- Use a tool or policy change when the capability was too broad or validation was too weak.
- Reduce autonomy when the task cannot be bounded or independently verified at the consequence level you are willing to accept.
Your next move is to choose the highest-consequence path in the agent you are building. Write its terminal states, critical invariants, allowed actions, and recovery route. Turn the most instructive failures you already have into eval cases. If you cannot identify who owns a transition and what evidence proves it was correct, keep the rollout narrow until you can.
References
- Product Talk — Building an AI Voice Agent for 360 Degree Feedback: How Your360 AI Uses State Machines, Evals, and Layered Synthesis
- Product School — One Architecture Decision That Fixes Failing AI Agents







