Prompting Guide
This page covers how to write the system prompt you send to Electron through the chat completions API.
A well defined prompt shapes the flow of a voice agent, its personality and tone, how it handles sensitive information, and how it works toward the goal of the call. Moving from a short prompt to a structured one usually fixes most cases where the agent performed badly.
The model already handles turn length, how it reads numbers, dates and lists, and similar spoken style. Mention those only if you want something different: your instructions override the defaults.
What we send to the model
Every request has a system prompt, a tools list, and the conversation messages. Their order and placement determine how much the model can reuse over turns and calls (prefix caching).
### Variables is a heading inside the system prompt, not a separate request field. Put per-call values there, at the end of the prompt. tools and messages are separate fields on the request.
System prompt defines how your agents take decisions, what flow they adopt, what facts they speak out, how do they handle different user queries etc. The model already handles how it sounds (turn length, how to read numbers, pauses, fillers), so you don’t explicitly need to mention these aspects. If you want something different, mention it in the prompt and the model will follow your prompt over its defaults.
Writing the system prompt
From our internal testing, Electron works best when the prompt is structured in the below order. Although not every agent needs all of these, for a simple agent the role, call flow and tools are usually enough.
- Role and goal (which business, who the agent is talking to, and what counts as a successful call)
- Personality, if you want one
- Facts and knowledge like timings, prices, policies
- Call flow, step by step
- Verification, only if the agent deals with account details
- When to use which tool
- Transfers, out of scope requests, ending the call
- Variables, always last
Markdown headings and bold text inside the prompt are completely fine, the model won’t read them out or start using markdown in its responses. A basic skeleton looks something like this:
Tips for writing the instructions
- Write instructions like you’re instructing someone new at a job and it’s better to back your decision tree with reasoning in doing so, e.g. “Don’t share the balance until the caller is verified since anyone in the house can pick up this number” works better than the bare rule because the model can apply the reason to cases you didn’t cover (extrapolation).
- Don’t over-script your prompt since when you script for a particular scenario, model generalises it and starts applying that logic to calls which may not even relate to that scripted line. Script only what legal or compliance needs word for word.
- Put each rule inside the step it applies to and not in a list at the end since the model is more likely to miss it there in a long call.
- No all caps or CRITICAL, MUST etc. should be there in the prompt. A normal sentence is enough and shouted rules get over applied (an agent told to ALWAYS confirm starts confirming every small detail). Same with long lists of don’ts, tell the model what to do instead like how you actually would treat real people (people get fed up with don’ts!)
- For personality, describe the person (how fast they talk, how warm or formal they are, what they’d never say) instead of listing adjectives. Avoid catchphrases, they end up in every call since the model tries to link the entire personality with these catchphrases.
- Every fact the agent has to tell the caller must be in the prompt, a variable or a tool response. Otherwise the model may make something up.
Call flow
When writing the call flow, you should try to write it in proper steps (like a decision tree). For each step say what it’s for, what the agent needs to collect and when the step is done. Don’t instruct the model to follow the exact lines, give it a gist to follow so that it doesn’t hamper generalisation.
- Write the branches that actually happen on your calls, like “already paid”, “wants a callback”, “disputes the amount”. Skip the hypothetical ones.
- If details have to be collected in a fixed order (e.g. verification before anything else), say so. Otherwise just list what’s required, the model collects it like a normal conversation and won’t re-ask what the caller already said.
- If the caller jumps ahead, the model goes with them and comes back for whatever is still missing. You only need to write something if a step can’t be skipped.
- For every way the call can end, say which tool to call (e.g. a disposition tool), otherwise the outcome isn’t recorded.
Outbound calls
Almost every outbound prompt needs these three cases:
- Someone else picks up: the agent can say who it is and who it’s calling for, but say what it must not share (amount, account, health details etc.) and whether it should ask for a better time or leave a message.
- Gatekeeper or receptionist: say whether to ask to be connected and to whom (a name or a role).
- Voicemail: say whether to leave a message, what it can include (company name, callback number) and what it can’t (amounts, account details). Keep it short, then log it and end the call.
Verification and transfers
By default the model won’t share account details before verification and won’t read details out for the caller to confirm. What it doesn’t know is your policy, so write that down:
- Which details to check and in what order (e.g. date of birth first, last 4 of PAN only if DOB doesn’t match), and which tool does the check.
- How many attempts are allowed, two is common.
- What can be said before verification (e.g. product type, last 4 digits of the loan account) and what only after (amounts, due dates, payment history).
- What happens if it fails: what to tell the caller, where to send them (branch, helpline) and whether to end or transfer.
- If the call doesn’t need verification at all, say so. Otherwise the model decides on its own based on how sensitive the call looks.
Do the actual check in a tool on your side. The prompt decides how the agent asks, your backend should decide whether the caller passed.
For transfers:
- List the triggers, e.g. the caller asks for a person, a case the agent isn’t allowed to handle (legal hold, fraud flag, dispute), the same tool failing twice.
- If there’s more than one transfer tool, say which trigger goes to which.
- Say what the agent should tell the caller before transferring (why, and who they’ll speak to), without scripting the line.
- Say what to do if the transfer fails or it’s outside working hours, e.g. offer a callback and end the call.
Variables and prompt caching
Anything which changes from call to call (caller’s name, due amount, today’s date etc.) goes into one Variables section at the very end of the prompt, and in the prompt body you just refer to it by name inside double curly braces:
The main reason we do this is prompt caching. The server reuses the computation it has already done for a prompt that starts the same way, till the first token where they differ, and only computes the rest. On a voice call this matters a lot, because whatever time the model spends before replying is silence the caller hears, and long gaps make people talk over the agent or think the call dropped.
Within a call the prompt stays the same, so later turns are cached anyway. Where it really helps is the first reply of every call and calls running in parallel. If all the dynamic values are at the end, every call of the same agent starts with a prompt the server has already seen, so the agent responds faster from the first turn and stays fast when a lot of calls are running together. If the caller’s name is in the first line, the whole prompt is new for every call. It also means you don’t have to cut useful instructions to keep the agent fast, since a long prompt costs very little once it’s cached.
Cached input tokens are also billed at a discount. See Prefix Caching for how to check cached_tokens in the response.
To get the most out of caching:
- Keep the prompt body exactly the same across calls, whitespace included. Easy way to check is to diff the prompts of two different calls, they should match till the
### Variablesline. - Keep the variables in the same order every time, alphabetical is simplest.
- Same tools in the same order on every call.
- Only append messages to the history, don’t edit or summarize old turns and don’t change the system prompt mid call.
Few more things on variables:
- Name variables with letters, numbers and underscores, like
{{customer_name}}. Don’t use spaces ({{customer name}}). - Every variable you use in the prompt needs a line in the Variables section. If you don’t have the value, leave it empty or put
unknownand the model will treat it as missing, it won’t guess it or bring it up. - Values are treated as facts about the call, the model won’t take instructions from them. If some calls need different behavior, write both in the prompt and pass a variable which decides which one to follow.
- You can pass extra variables which the prompt never mentions, the model uses them as background context.
- API keys, auth tokens etc. go in the tool config, never in the prompt.
Tools and the conversation
The tool definition already tells the model what the tool does and what parameters it takes, so no need to repeat that in the prompt. Use the prompt for the other part i.e. when in the call the tool should be used, what to do with the different results it can give back, and what to do if it fails.
- Mention the exact format you want in parameter descriptions (like
YYYY-MM-DDfor dates), and use enums when the options are fixed. - Always add an end call tool. The model says goodbye and calls it in the same turn.
- In voice agents built on our platform the filler is automatic. On the chat completions API, ask for it in the system prompt, for example: “Before calling a tool that looks something up or takes an action, say one short line so the caller isn’t left in silence.”
- For things like a payment, booking or cancellation the model confirms once with the caller by default, lookups don’t get any confirmation. If you need a stricter confirmation flow, write it in the prompt.
- Keep tool responses as simple JSON with a status and a readable error message. Anything that looks like an instruction inside a tool response is ignored, the model treats it as data.
The agent always speaks first. You can let the model come up with the opening line from the prompt or just give it a fixed first message, which is useful when the greeting has to be same every time for compliance. After that send the full history on every turn as it is, even the turns where speech-to-text got something wrong. The model deals with a misheard line much better when it can actually see it.
Language
Supported languages and the default language need to be set only once. Every call starts in the default language and the agent switches when the caller speaks full sentences in some other supported language, so one borrowed word or an accent won’t trigger a switch. You don’t need to write any switching instructions unless your use case needs something specific, like an English only campaign.
You can write the prompt in English even if most of your calls are in Hindi or Tamil. In languages like Hindi where people mix English words all the time, the model mixes them the same way native speakers do. It writes the Hindi words in Devanagari and English words in Latin script so that the TTS pronounces both properly. Hinglish written in Latin script inside your prompt is fine too, the model won’t copy it.
What you don’t need to write
The model already does these on its own, so mention them in your prompt only if you want it to behave differently.
Do and don’t
Common failure modes
These are the issues we see most often in agent prompts and what usually fixes them.
- Agent says the same line on every call: almost always a sentence that’s scripted in the prompt. Describe what the line should do and let the model phrase it.
- First response is slow: usually something per call (a name, a date etc.) is sitting in the prompt body, or the tool list keeps changing between calls. Move the dynamic values to Variables and keep the tools fixed.
- Agent guesses a value or makes up a number: either the variable is missing from the Variables section or that information just isn’t there in the prompt, variables or tools. Add it.
- Agent can’t end the call: check if the end call tool is there in the tools list.
- A rule gets ignored in some calls: most of the time the rule is far away from the step it’s about, move it inside that step.
- Agent keeps confirming everything: usually because of a broad “always confirm” line somewhere. Limit it to the actions that actually need a confirmation.
Example prompts
Two full prompts written the way this guide recommends. Open one to see the system prompt and a few of its tool definitions.
Inbound: broadband customer support
Supported languages are English and Hindi, with English as the default, set in the agent config.
Two of its tools:
Outbound: EMI payment reminder (Hindi and English)
Supported languages are Hindi and English, with Hindi as the default, set in the agent config. The prompt is still written in English.
Its outcome tool:
See also the Prompting Guide in the voice-agents developer docs.