作者檢視語音智能體工具逾時設為兩分鐘,來電者只等八秒
Every Tool in My Voice Agents Had a Two-Minute Timeout. Callers Give You Eight Seconds.
作者檢視自己建立的 9 個 Retell AI 語音智能體匯出檔,發現每個自訂工具的逾時均設為 120000 毫秒,來電者可能只容忍八秒靜默。他建議電話號碼在 AI 故障時仍可轉接真人或有人查閲的語音信箱,並按實測延遲設定逾時,只為冪等操作重試。來電者資料應獨立於故障工具保存,並以合成來電、來電量歸零警報及一頁故障手冊監察和處理事故。
When a web service goes down, the user gets an error page. Ugly, but honest. When a voice agent goes down, the caller gets silence, and silence on a phone line reads as "this business is closed." They hang up and call the next result on Google. Nobody files a bug report.
So I now design the failures first. This is the engineering version of an outage plan I wrote up for clients, plus a confession from my own agent exports.
A call is a dependency chain you rent
When I scope an agent, I write out every service a single call touches, in order:
- The business's existing number and carrier, often forwarding to a new number.
- The telephony layer, usually Twilio or the voice platform's own numbers.
- The voice platform, Retell AI in most of my work, which runs the conversation.
- Speech-to-text, the LLM and the text-to-speech voice, which the platform orchestrates but which may come from different providers.
- The tool layer: n8n workflows, a calendar, GoHighLevel.
- The human fallback: a transfer number, a ring group, a voicemail box.
"The AI is down" is not one incident. It is five or six, and each one sounds different to the caller:
- Top of the chain breaks (forwarding changed, number detached from the agent, telephony billing hold): the phone rings into nothing. The worst case.
- Tool layer breaks (calendar times out, n8n workflow deactivated, CRM rejects the write): the agent answers, collects a name, and then cannot book. Pickup rate stays healthy, so dashboards look fine.
- A model or voice provider degrades: higher latency, a glitchy voice, bad transcription. People hang up mid-sentence.
The design job is deciding what each failure sounds like.
Rule one: the number always terminates somewhere
My first rule is that the phone number must always end at something that works without the AI: a human, a ring group, or at worst a voicemail box someone actually checks.
If the number lives in Twilio, configure its fallback handler, which runs when the primary one fails, to forward to a backup line or record a voicemail and email it. The worst outage becomes a slightly worse phone experience instead of a dead line.
If the business forwards its line to the agent, overflow forwarding (staff ring first) has a fallback built in; all-calls forwarding has none unless you build one.
Either way, the client can turn forwarding off in two minutes. That is the manual circuit breaker, and it does not need me awake.
The test I use: if the voice platform vanished right now, what would a caller hear? If the answer is "nothing," fix that before touching the prompt.
Rule two: degrade to a message taker
This is where my own exports got interesting. I keep JSON exports of nine Retell agents I have built in one folder (I have mined it before for tool parameter design and a config diff that went wrong). I grepped them for failure handling, expecting to feel good.
The good news: every single prompt has a tool failure rule. The shape is identical across all nine:
If a tool fails: apologize briefly, retry once. If second failure:
"I apologize for the inconvenience. Let me have someone from the
team call you back to get this scheduled." End call.
Right instinct: no invented slots, no infinite loop, a human promise at the end. Reading it as an engineer, though, four things bother me.
The timeout is two minutes
Every custom tool across the nine exports has the same setting:
{
"type": "custom",
"name": "checkCalendar",
"timeout_ms": 120000,
"speak_during_execution": false
}
So "if a tool fails" can mean the model waits up to two minutes before it learns anything failed, and "retry once" can double that. Meanwhile speak_during_execution is false, so nothing is said while the request hangs. The prompt does tell the agent to say a short bridge like "let me check on that" before calling a tool, but a bridge covers a second or two, not a stalled webhook.
A two-minute timeout on a user-facing web request would get flagged in review. On a phone call, a caller gives you maybe eight seconds of silence. I had tuned the prompt rule and never revisited the timeout under it. It should sit near the real p99 of the n8n workflow plus headroom, and the retry should not exist for anything that is not idempotent. (Booking twice because the first request was slow, not failed, is its own bug; I wrote about that class of problem in you can retry a write, you cannot retry an email.)
"Please call us back" may point at the agent
Several of the fallback lines tell the caller to call the business back at its main number. That is fine if that number reaches staff. If that number is the one forwarded to the agent, the fallback is a loop: the caller rings back into the same broken tool and hears the same apology.
I have not verified the routing for every one of those agents, and that is the point: the fallback text lives in the prompt, the routing lives in a carrier dashboard, and nothing connects them. The fix is a different path, not a different sentence: a transfer that bypasses the agent, or a captured message and a callback.
"End call" can drop the caller's details
The agent has usually collected a name, a number and the reason for calling by the time the calendar fails. Then it ends the call. Whether those details survive depends on whether the post-call pipeline captures them, and if the failing tool is the CRM write, writing the message to the CRM does not help.
My rule now is that caller details land somewhere independent of the failing tool: a team notification or a stored record that a post-call workflow can replay once the CRM is back.
Only two agents can hand off
Only 2 of the 9 exports have a transfer_call tool. For the rest, a tool outage leaves the agent with exactly two moves: apologize, or hang up. A tool outage is precisely when a live transfer earns its keep, which is the argument I made in your voice agent needs three exits, not one. My own exports are the counterexample.
One thing the platform already did for me
Every export has fallback_voice_ids set to two alternate voice providers, so a bad day at the primary text-to-speech provider means a different voice, not a mute agent. Real automatic failover, and it works because the platform owns both sides of the switch. I did not design it, which is also why it was the one layer already covered.
Rule three: alert on absence, not just errors
The embarrassing outage is the one the client reports to you at 10am. Two checks catch most of what dashboards miss.
A scheduled synthetic call. A real call to the agent's number from outside the stack: wait for the greeting, ask one scripted question, check the post-call event arrived. It is the only thing that catches top-of-chain failures, because a broken forwarding rule produces no error in the voice platform. From its point of view, no call ever arrived.
Zero-volume alerts. Errors are easy to alert on. Silence is not. Track normal call volume per hour per business and alert when it drops to zero during hours that usually have calls. A clinic that gets a dozen calls on a weekday morning and has received none since 8am has a problem, even if nothing threw.
Rule four: a runbook beats clever automation
Automatic switching between, say, two LLM providers can fail in more confusing ways than the outage itself. An untested model behind the same prompt is a different agent, and it needs the same regression tests as any other change.
So each agent gets a one-page runbook written with the client: who gets alerted, the kill switch (with screenshots of the carrier or Twilio setting), and who works through the message backlog afterward.
The checklist I now run before launch
- The number has a fallback route that ends at a human or a checked voicemail, and that route bypasses the agent.
- Tool timeouts are set from measured latency, and retries only exist for idempotent calls.
- Caller details are captured somewhere independent of the CRM.
- A transfer tool exists, or there is a written reason it does not.
- A synthetic call and zero-volume alerts watch the real number.
- A one-page runbook names the kill switch and who handles the backlog.
The honest target is not an agent that never goes down. It is that no outage produces dead air, loses a caller's details, or lasts longer than it takes a named human to notice and flip a switch.
The full client-facing version of this outage plan is on my site: What Happens When Your AI Voice Agent Goes Down.
What does your stack do when a dependency stalls instead of failing? I am curious whether anyone has found a clean way to keep prompt-level fallback text and carrier-level routing in sync, because right now mine live in two places that never talk.
來源:DEV Community · dev.to