Voice AI Best Practices
How to build a voice AI that works well on the phone: write instructions for the ear, collect details that transcribe badly, keep actions fast and speakable, check identity from the live transcript, set up transfers that are answered, enable data collection for the Phone Call channel, and test on a demo number.
These practices follow from how the voice AI works. Most of your chat setup carries over to calls: the same workflows, bot rules, knowledge and actions. What changes is that every word is heard, not read.
Write for the ear
- Keep replies short. The caller can't skim or scroll back. One point per reply and one question at a time work best.
- Don't script lists, links or formatting. A bullet list, a table or a URL doesn't work when spoken. If the caller needs a link or a long reference, have the AI offer to email it, with an action that sends it (for example using
send_outbound_email). - Scope channel-specific behaviour to the Phone Call channel. For a rule that only makes sense on calls, such as "ask callers to spell their email address", set its channels to Phone Call rather than writing "if on a call..." in a general rule. The same goes for workflows: a workflow can be limited to Phone Call under Available Channels.
- Keep the greeting short. The caller can't interrupt it, and it's spoken word for word. Say who is answering and invite the caller to speak.
Collect details that transcribe badly
Email addresses, order numbers, postcodes and names are the details most often transcribed wrongly.
- Prefer what you already have. The AI knows the caller's phone number (see
shareCallerNumberWithAi). If your actions can look customers up by phone number, the caller doesn't have to spell anything. - Ask for one detail at a time, and have the AI read it back before using it.
- Built-in lookups are lenient on calls. On chat, lookups by email, phone number, address, zip code or subscription ID require it to appear in the conversation exactly. On calls they don't, because spoken details rarely survive transcription character for character.
Identity checks in custom actions
A custom action that checks the caller's identity shouldn't compare a value letter for letter with the transcript. Instead, read what was said from context["liveCallContext"] and let an LLM judge the match with llm_classify_binary:
def execute_action(context):
live_call = context.get("liveCallContext")
if not live_call or not live_call["messages"]:
return {"verified": False, "message": "Ask the caller for their postcode first."}
expected = "SW1A 1AA" # e.g. from your CRM, found by the caller's phone number
said = [m["text"] for m in live_call["messages"] if m["sender"] == "customer"]
verified = llm_classify_binary(
f"Did the caller say a postcode that matches {expected}? "
"The text is a phone transcript, so allow for transcription errors "
"such as spelled-out letters and spaces.",
said,
fallback=False,
)
return {"verified": verified}context["conversation"]["messages"] doesn't help here: during a call it contains only the greeting.
Keep actions fast and speakable
- Every action is silence for the caller. The AI says one short line, then waits for the result. Aim for actions that return in a few seconds. An action that takes longer than a minute fails.
- Avoid chains of actions in one turn. Actions run one at a time, so three lookups in a row are three waits. Combine them into one action where you can.
- Return what the AI should say, not raw data. A short result like
{"status": "shipped", "expected": "Thursday"}is easy to speak. Long lists, IDs and URLs are not. - Tell the AI what to do on failure. Return a clear message, such as "The order system is unavailable. Offer to have someone call back." The AI gets your action's error message, so make it say what to do next.
Transfers that work
- Enable
transferConversationin a workflow, as on other channels: see human escalation. Then add destinations in the voice AI settings. - Name destinations by what they're for, such as "Sales" or "Billing". The AI chooses a destination by its name.
- Use destinations that always answer, such as a queue or a number with its own voicemail. To send callers to your team in the Octocom help desk, use the
your_teamdestination: Octocom rings your available agents one by one, and plays the line's voicemail greeting if nobody answers. Set a voicemail greeting so callers can always leave a message.
Collect data from calls
Data collection runs on the transcript after the call ends. New data collection prompts don't include the Phone Call channel by default: add it to each prompt that should run on calls, or set the prompt to all channels.
Test before going live
- Call one of the demo numbers and enter the voice AI's access code followed by
#. See Get a phone number. - Try the calls you expect: a common question, a lookup, a transfer, and a caller who goes quiet.
- Open the conversation in the help desk after the call: the transcript and recording show exactly what the AI heard and said.
- Change one thing at a time. Settings and instructions apply from the next call.
One language per voice AI
Each voice AI speaks one language. To serve several languages, use one number per language, for example behind your own phone menu that sends callers to the right number.