Skip to content

Best practices

Writing prompts for voice

How prompt writing changes when every word is spoken aloud, and which assistant field each kind of instruction belongs in.

A prompt that reads well on a screen usually fails out loud. The caller cannot skim it, cannot scroll back to the part they missed, and will start talking over anything that runs long. The same wording that produces a good chat answer produces a bad phone call. Writing for voice is a different craft, not a shorter version of the same one.

What follows is that craft, and where each kind of instruction belongs on an OnCore assistant.

Where prompt text lives#

An assistant's spoken behavior comes from several fields at once. Knowing which one to reach for is half the work.

SurfaceFieldWhat belongs in it
Shared system promptpromptId → a promptPersona, tone, and rules you want several assistants to share
This assistant's rulesdeveloperPromptBehavior specific to one assistant, injected into the default system prompt
Values that changeparametersFacts referenced from the prompt as {{placeholders}}
Small behavior tweaksCustom instructionsUp to six titled rules, 500 characters each
Step-by-step flowsTask groupsAn ordered sequence the assistant works through when taskDrivenMode is on
Opening linefirstMessageThe exact words that start the call
Closing lineendOfCallMessageThe exact words before the assistant hangs up
Silence promptsidleMessagesWhat the assistant says when the caller has gone quiet
Tool behaviorA tool's description and instruction.stepsWhen to call your endpoint, and what to say around the call
Post-call analysissummaryPrompt, structuredDataPrompt, categoriesHow the call is summarized and classified afterwards
Hand-off briefingwhisperSummaryPromptIdWhat a colleague hears before a warm transfer connects
Return messagewarmReturnMessageWhat the caller hears when a hand-off goes unanswered

Two properties of this set matter more than any individual field.

They compose, they do not replace. A developerPrompt, a shared prompt, six custom instructions, and a linked task group all reach the same conversation. When an edit produces no change in behavior, another surface is usually supplying the behavior you are trying to remove. Calls and assistant behavior walks through untangling that.

Configuration is read when a call starts. A call already in progress keeps the configuration it began with, so every prompt change is tested by placing a new call.

Write turns, not paragraphs#

In text, a long answer is generous: the reader takes what they need and ignores the rest. Spoken, a long answer is an obstacle: it arrives one word at a time, at a fixed speed, and the caller has to sit through all of it.

The unit of a voice prompt is the turn: one thing said, then the floor handed back. Instruct for it explicitly.

text
Answer in one or two sentences, then stop and let the caller respond.
Never list more than three options at once. If there are more, name the
three most common and offer to go through the rest.
Ask one question at a time. Do not stack a second question onto the first.

Two consequences of getting this wrong:

  • Long turns get cut off. The caller barges in partway through, the assistant stops speaking, and everything after the interruption is simply never said, including the question you needed answered. You can tune how easily that happens with interruptionPlan (minDuration, 0 to 5 seconds of sustained speech; minWords, 0 to 10 transcribed words), but tuning the barge-in threshold is a worse fix than not monologuing.
  • Stacked questions get one answer. Ask "What is your name and what date were you thinking?" and you will reliably get a name and silence, or a date and silence. Then the assistant asks again, and the caller feels unheard.

If the assistant genuinely has to deliver something long (terms, a list of times, an address), have it say so first and check: "There are six slots free that afternoon. Do you want me to run through them, or narrow it down first?"

Formatting is silence#

Everything the assistant produces is spoken. Markdown, bullets, numbered lists, headings, emphasis, emoji, and tables have no spoken form: at best they vanish, at worst they are read out as punctuation.

Say so in the prompt, because a language model's default habit is to format:

text
Never use bullet points, numbered lists, markdown, or emoji. Everything you
say is read aloud. Use plain spoken sentences and connect items with words
like "and", "or", and "after that".

The same rule applies to anything you inject. A {{placeholder}} filled with a markdown table, or knowledge-base content pasted from a formatted document, becomes spoken punctuation. Store values in the form you want heard: "10am to 10pm, seven days", not "| Mon-Sun | 10:00-22:00 |".

Say numbers the way people say them#

Digits and symbols are where written and spoken text diverge hardest, and the assistant says whatever it writes. Tell it the spoken form you want.

WrittenWhat you want heard
$1,250.00"twelve hundred and fifty dollars"
2026-08-17"the seventeenth of August"
+1 555 555 0123grouped in threes and fours, slowly
A4B9"A as in alpha, four, B as in bravo, nine"
[email protected]"jo dot smith at example dot com"

A workable instruction:

text
Read phone numbers and reference codes digit by digit, grouped, with a
short pause between groups. Never say a code as a word. Read money as
words, not symbols. Say dates as a person would say them, never as
numbers separated by dashes.

Reference codes deserve their own rule. If callers routinely read back booking references or member numbers, ask the assistant to use a phonetic alphabet for letters. "B as in bravo" costs a second and removes the most common source of a wrong record.

Confirm before you commit#

The caller is on a phone line, possibly outdoors, possibly on speaker. Speech recognition is good, not perfect, and a misheard name is invisible until something goes wrong downstream. So the rule is simple: anything the assistant is about to act on gets read back first.

text
Before booking, changing, or cancelling anything, repeat the details back
in one sentence and wait for a yes. Spell names back letter by letter.
Read phone numbers and email addresses back digit by digit or word by word.
If the caller corrects you, repeat the corrected version back once more.

Confirm the things that are expensive to get wrong (names, numbers, dates, quantities, addresses) and skip the things that are not. An assistant that confirms everything is exhausting, and callers stop listening to confirmations they hear five times.

Two related settings:

  • phoneNumberPassThrough lets the assistant reference the caller's own number ("Would you like to use the number ending in 595?") instead of asking them to recite it. That is both faster and more accurate. With it off, the assistant always asks, in which case make sure your prompt has it read the number back.
  • Capture forms are the better tool when you are collecting a fixed set of typed answers. Each field has its own question, an optional prompt steering how it is asked, and the results are delivered to the recipients you name. The structure lives in the form rather than in prose you have to keep re-describing.

Never leave the caller in silence#

Silence on a phone line reads as a dropped call. Within about two seconds, callers say "hello?", and if that lands mid-turn it registers as an interruption. Three places to close the gaps:

While a tool runs. A tool call is a live request inside the conversation. A tool's body.messages can carry a request-start filler spoken while it runs, either fixed text or phrased by the model. "Let me check that for you" costs nothing and buys you the round trip.

When the caller goes quiet. idleMessages are spoken after idleTimeoutSeconds of silence, at most idleMessageMaxSpokenCount times. Write them as escalating checks rather than repeats of the same line ("Are you still there?", then "I'll stay on the line for a moment", then a graceful close), so a caller who has genuinely walked away ends the call cleanly instead of holding an open line.

Between a question and an answer the assistant has to think about. Instruct it to acknowledge first and answer second: "Good question, one moment" beats a pause.

Tell it what to do when it does not know#

Most of the damage a voice assistant does is confident invention: a price it has not been given, a policy it inferred, an appointment it implied it had made. A prompt that only describes what the assistant can do leaves the model to improvise the rest.

Write the boundary and the exit together:

text
If you do not know something, say you do not know and offer to have someone
call back. Never guess a price, a policy, an availability, or a delivery
date. If the caller asks for something outside bookings and opening hours,
say it is outside what you can help with and offer to put them through.

Then make the exit real. An instruction to "put them through" needs a transfer reason that actually matches the situation and a destination that answers. If that destination is not always staffed, the warm-return mode is what stops the caller landing in a ringing void.

Put moving facts in parameters, not in prose#

Opening hours, branch names, and prices belong in parameters and are referenced from developerPrompt as {{placeholders}}. One prompt then serves every location, and updating a fact is a value change rather than a prompt rewrite.

The keys must line up exactly
{
  "developerPrompt": "We are open {{opening_hours}} at {{branch_name}}.",
  "parameters": { "opening_hours": "10am to 10pm", "branch_name": "Newtown" }
}

The names must match character for character. {{openingHours}} is not filled by opening_hours. The caller simply hears the literal braces, which is the single most common cause of an assistant saying something obviously wrong.

Where parameters apply

At call start, OnCore substitutes assistant parameters across the assembled voice prompt. That includes the shared prompt, developerPrompt, custom instructions, and per-call custom prompt sections. An unmatched {{key}} remains literal.

Task instructions are separate: they do not receive assistant parameters. Task groups use single-brace placeholders such as {booking_id} for call context and outputs from earlier tasks. Capture-form fields use that form's own properties for their documented {{property}} placeholders.

Choose the smallest surface that can carry the change#

When behavior needs adjusting, the instinct is to edit the main prompt. Usually something smaller is correct, and smaller changes are easier to reverse when a Tuesday's calls come back worse than a Monday's.

You want to…Reach for
Change persona or tone everywhereThe shared prompt: several assistants can point at one
Change one assistant's rulesdeveloperPrompt
Add a small, standalone ruleA custom instruction: titled, capped at six, easy to delete
Update a factparameters
Enforce an order of stepsA task group, with per-assistant instructionOverride for the one venue that differs
Collect a fixed set of answersA capture form
Change when a tool firesThe tool's description: that text is what the model selects on
Change how expressive the voice soundsdeliveryMode and expressiveOptions, not prose about tone

That last row is worth dwelling on. Delivery (pacing, fillers, laughter) is a configuration setting on the assistant, not something to litigate in the prompt. Asking a prompt to "sound warm and natural" mostly spends words; deliveryMode addresses it directly, and expressiveOptions.instructionsAppend exists for guidance that genuinely is about delivery. Both modes depend on the voice you picked. Voices that do not support the mode keep their normal delivery. Read Expressive mode or Emotion tagging before writing prompt text to compensate, and Eleven v3 audio tags if the voice is eleven_v3 and you want to write tags by hand.

Hear it before you ship it#

Voice prompts cannot be reviewed by reading. Three cheap checks, in order:

Read the assistant's lines out loud#

You will catch stacked questions, unspeakable formatting, and sentences that run out of breath faster than any review will.

Place a real call#

Browser calling gets you a live conversation with the same assistant without dialling anything, and accepts a per-call firstMessage so you can jump straight into the part you are testing.

Read the transcript afterwards#

The transcript on the end-of-call report shows what was actually said versus what you intended, including the turns that ran long enough to be interrupted. Do this after every prompt change for the first few days.

Then change one thing at a time. Prompt surfaces compose, so editing three of them at once and placing one call tells you nothing about which edit did what.

Next steps#