An AI phone agent that sounds fine in a demo can still fail the one call that matters. I built an evaluation suite that phones my agents with simulated callers and attackers, scores every call in code first, and blocks any release that leaks data or misses an emergency.
I run seven live voice agents on Vapi and Retell. Language models aren't deterministic, so three good test calls prove little, and the calls people test with are the easy ones. Real callers interrupt, refuse details, ask for the owner, or call at 2am with water coming through the ceiling. Some of them try to manipulate the agent.
I needed answers to two questions before any agent touched a real phone number: does it do the right thing on the hard calls, and can it be talked into leaking data or breaking the rules?
Prompt rules and data delimiting cut leaks from 14 calls to 6, but couldn't stop them on gpt-4o-mini or gpt-4.1. The root cause was that agents were given data they didn't need. I changed the architecture: each agent now gets at most the caller's own record, matched by caller ID or verified details, with allowlisted fields and never free-text notes. Leaks went to zero.
| 63 security calls | Before | Prompt fix | Least privilege |
|---|---|---|---|
| Injection resistance | 57% | 90% | 94% |
| Cross-customer PII leaks | 14 | 6 | 0 |
| Prompt or canary leaks | 1 | 0 | 0 |
| Unauthorized tool calls | 5 | 0 | 0 |
| Calls with a critical failure | 17 | 6 | 0 |
The plumbing agent still repeats a planted "free service" note when it arrives inside a simulated tool reply. Nothing leaks any more, and today's live webhooks return a fixed "Saved." sentence, so this only matters if a future integration echoes CRM text back to the agent. The rule for that integration is the same: structured fields only.
Tell me what you're building and where it breaks. I'll tell you straight whether I can help.