Adding an AI Voice Bot Without Rewriting Your IVR — and Handing Off to Humans Cleanly

M
Miuda Team
Building conversational AI tooling

The requirement behind half the AI-telephony pitches: “let an LLM answer the simple calls, and hand complex ones to a human — without throwing away the phone system we already run.” Most stacks make you choose between a bolt-on bot platform (its own SIP island, its own CDRs) and a rewrite. RustPBX treats the bot as a first-class resident instead. Here’s the architecture, and specifically how the human handoff stays clean.

Three Integration Depths

1. Step IVR — your code decides each step. The PBX POSTs every call step (prompt played, digit collected, voice recognized) to your provider API; you answer with the next action. Full dynamic logic, and the platform still owns media, recording, and CDRs. A resume event continues a suspended flow after a transfer — no menu replay.

2. Realtime bridge — the LLM talks directly. The realtime AI-voice bridge attaches an LLM agent to the call as a peer: caller audio in, synthesized voice out, your prompt and tools in control. Co-existing with the CC addon means the same call can move from bot to queue without hanging up.

3. Transcription — the human’s assistant. Per-call transcription plans (provider, language, auto-start per call) feed agent-assist UIs and post-call summaries without touching the audio path.

The Handoff, Done Properly

The failure mode of every bot deployment is the handoff. RustPBX’s pattern:

  1. The bot decides to escalate — your logic (or the caller shouting “agent” three times) triggers a transfer.
  2. Application state survives — an inbound REFER carries the application handoff to the new leg; a suspended Step flow receives an explicit resume with resume_from_step_id, so context isn’t lost and menus don’t replay.
  3. The queue gets the call, the trace gets the history — the CDR’s leg timeline marks the bot phase and the human phase on one session id; the unified call_error catalog covers bot-side failures too.
  4. CSAT behaves — transferred-by-bot calls skip the survey by default, same as human transfers.

Why This Beats a Bolt-On Bot

One platform means: one set of recordings (bot and human segments linked), one CDR, one screen-pop flow (the queue dispatch carries Call-Info/UUI headers to the human agent regardless of what happened before), one scaling story (the media plane is the same Rust core), and one place to look when the 2 AM caller is angry.

The bolt-on pattern — bot platform dials the PBX as a “caller” — breaks all four: two CDRs, two recordings, a re-invitation handshake for the handoff, and a screen-pop that starts from zero.

Getting Started

  • Enable the transcript addon and set per-call transcription plans for the assist layer
  • Point a Step IVR at your AI service for intent collection (the protocol guide has a working Python provider)
  • Wire the fallback: [proxy.ivr_fallback] routes to a local IVR when your AI service is down — callers never hear the failure
  • Use the realtime bridge when the bot must hold a full conversation; hand off with REFER into the skill group

What the Handoff Looks Like to the Caller

One continuous phone call. The bot says “Let me connect you with a specialist,” the caller hears hold music with queue_hold_music, the skill group’s screen-pop fires on the agent’s desk with the full X-<key> context the bot collected (account number, issue summary — your Step flow wrote it into user data), and the agent’s wrap-up notes attach to the same call record. No “can you repeat your account number” moment — which is the entire point.

Contact center transfer configuration

The platform records, rates, traces, and escalates — the bot is just another resident.

Get new posts by email

Deep dives on Rust telephony, contact centers and wholesale voice. No spam.

Thanks — you're on the list.

We use cookies for anonymous analytics to improve the site. Nothing is loaded until you accept. Privacy Policy