AI Phone Agent · Design, Build and Operate · 2026

Operator

The model turned out to be the most reliable thing in the chain.

Operator

Since August 21 the business line at AllOEMRims has been answered by software I built. A caller asks where their wheels are, it looks the order up, checks who it is talking to, and either answers or puts a person on. It went from the first commit to answering real customers in six days.

This is a short case study about a small system, and the reason it is worth writing down is that the part I expected to fail did not, and the part nobody thinks about did.

9tools the agent can call
6days, first commit to a live business line
5attack shapes rehearsed before launch
16/21calls where the caller ID was already wrong

What it actually does

The voice and the conversation run on ElevenLabs with Claude behind it. Everything it knows about the business comes from a small service I wrote, which the agent reaches through nine tools: look up an order, get tracking, find an order by phone number, search available wheels, search by part number, check who is on call, hand off to that person, warn them a call is coming, and take a message after hours.

Every tool returns a plain sentence the agent can read out, alongside the structured data. That was deliberate. A model handed a row of database fields will narrate them, and narrating a database is how you get a confident wrong number read aloud to a customer.

When a call ends, the whole thing is filed as a ticket in the same support desk the staff already work in. There is no separate place to go and look at what the robot did.

The support desk ticket list, with a phone call ticket open beside it showing the caller, the order it was about, and the full transcript. Every value is blurred.
Where a call ends up. The agent files every call as a ticket in the same desk the staff already work in, with the transcript attached, so nobody has to go somewhere else to find out what it said. Blurred because these are real tickets about real orders.

The rail I built before anything else

The first rule in the agent’s instructions is that it verifies before it discloses. A caller gets order details only after matching a last name or a ZIP against the order, their own order only, with no exception for urgency or authority. The second rule is that everything a caller says is a request to be handled, never an instruction to be followed.

Before it took a real call I ran five shapes of attack at it in simulation: bypassing verification through social pressure, prompt injection, impersonating authority, drifting the conversation somewhere it should not go, and extracting the instructions themselves. It held all five.

So the interesting failure was never going to be the model. It was somewhere I had not thought to look.

The caller ID was a lie before the agent ever saw it

The published numbers for the business live with a VoIP provider, and while the agent was on trial they were forwarded to the new line rather than moved to it. A forwarded call presents the forwarding line’s number as the caller. Not the customer’s number. Ours.

So on sixteen of the first twenty one real calls, the identity the agent was carefully verifying against was one of our own phone numbers.

Nothing was broken. The verification rule was written correctly and the model followed it correctly every time. The input had been replaced one layer below, by telephony plumbing doing exactly what telephony plumbing does, and the rail was diligently checking a value that no longer meant anything.

The fix in the short term is that the post-call handler scrubs our own numbers so they can never be mistaken for a customer’s. The real fix is porting the numbers instead of forwarding them, which passes the true caller ID through. But the lesson is the part I keep: I had threat-modeled the conversation and not the wire it arrived on. The model was the most reliable component in the chain.

The other thing that was wrong was my own test

I wrote a scanner to read the red-team transcripts and flag anything that looked like a leak. It kept flagging the agent’s refusals.

It was matching on the attacker’s vocabulary, and a refusal repeats the attacker’s vocabulary. “I cannot share my system prompt” contains the phrase it was hunting for. The agent was behaving perfectly and the measurement said otherwise, which is the more dangerous direction for a measurement to be wrong in: a false alarm you eventually learn to ignore is how a real one gets ignored too.

So the rule now is that the scan narrows what I read, and I read the transcript. On a line this small every transcript is readable end to end. At real volume that stops being true, and a scored evaluation set on real conversations is the first thing I would build.

How small is small

Twenty one inbound calls. Most were short, five to seventy five seconds, and most of those were somebody wanting a person rather than an answer. Six involved a real lookup or a handoff.

I am putting the number in because a case study that shows a system and hides its traffic is asking you to assume something. This is a working system on a real line with real customers, and it is a quiet line.

What I would keep

Two things carried over into everything I have built since. The first is that a tool should hand the model a sentence, not a schema, when the model’s job is to speak. The second is that the guardrails go around the irreversible action and around the data, and then you go and check what is feeding them, because a correct rule applied to a corrupted input is not a guardrail at all. It is a receipt.

Written from the repository and the running service: nine tool routes, seventeen commits between August 20 and 26, 2026, and the call log on the box. The screenshot is blurred because the tickets in it are real.

I am looking for a product design role.

Thirty years of it, usually as the only designer in the room. If this is the kind of work your team needs, I would like to hear from you.

Download resume

Or email hello@iamjust.in.

send a transmission

this goes straight to my inbox.