Prompts, instructions & policy
Configure the Instructions and Policy steps of the bot wizard — system prompt, runtime context, post-call analysis, auto dispositions, and the conversation policy engine.
This page covers the two steps of the bot wizard where you tell the bot what to say and how to behave:
- Step 1: Instructions — the system prompt, per-call runtime context, post-call analysis, quality control, and auto dispositions.
- Step 2: Policy — the optional conversation policy engine for collection and motor-insurance-renewal calls.
Both steps live inside the bot creation wizard. If you haven't seen the wizard yet, read Create a bot first. The voice engines and call tools are covered separately in Voice pipeline and Tools & integrations.
You can jump back to any earlier step at any time by clicking its number in the stepper bar at the top of the wizard. Nothing is saved until you click Create Bot on the final step.
How variables work
Throughout these steps you will write {{variable}} tokens. At call time the platform replaces each token with a real value (a customer name, an amount, today's date). Variables come from a handful of named sources called namespaces.
| Source | Namespace | Example token |
|---|---|---|
| Campaign CSV column / dialout API | call.* | {{call.CUSTOMERNAME}} |
| CRM pre-fetch | crm.* | {{crm.due_amount}} |
| System-generated values (date, time) | system.* | {{system.current_date}} |
| Post-call result fields | result.* | {{result.recording_url}} |
| Post-call analysis output | analysis.* | {{analysis.DISPOSITION}} |
| Quality-control output | qc.* | {{qc.remarks}} |
You can also write a flat token without a namespace, which is convenient when ops owns the column names:
Hello {{CUSTOMERNAME}}, your pending amount is {{due_amount}}.A flat token first tries an exact match, then strips the prefix and searches a fixed, limited order: system. → crm. → call..
Flat tokens do not reach result.*, analysis.*, or qc.*. So {{DISPOSITION}} will not find analysis.DISPOSITION. Always namespace post-call values explicitly: {{analysis.DISPOSITION}}, {{result.recording_url}}, {{qc.remarks}}.
Tip
In prompts and the opening message, an unresolved token is left visible (the bot literally says the curly braces). That is intentional — if you hear {{customer_name}} on a test call, the column is missing or misspelled. Fix the CSV, the CRM mapping, or the prompt. For the complete list of every namespace and field, see Post-call variables.
Step 1: Instructions
This step is where you write the bot's brain: the standing instructions it always follows, the fresh context it gets for each individual call, and the prompts that run after the call ends to summarise and score it.
If you turn on the policy engine in Step 2, the system prompt you write here is kept only as a fallback and is not used during live calls. The platform builds the runtime prompt from your policy instead. A blue banner appears at the top of this step to remind you.
The two prompt fields
The bot's instructions are split into two boxes on purpose. The split lets the platform reuse the unchanging part of your prompt across every call, which keeps calls fast and cheap.
Static system prompt
The bot's permanent personality, rules, and policy. Identical on every call, so keep it free of per-customer values.
Dynamic runtime prompt
The fresh facts for this call — the customer's name, their due amount, today's date. This is where {{variables}} belong.
| Field | What to enter | Required | Notes |
|---|---|---|---|
| Static System Prompt | The bot's role, tone, rules, and conversation flow. Cacheable instructions only. | Yes (unless the policy engine is enabled) | Do not use {{}} variables here — this text must be byte-for-byte identical across calls so the backend can cache it. A live character count is shown below the box. |
| Dynamic Runtime Prompt | Per-call context that changes every call, written with variables, e.g. Customer name: {{crm.CUSTOMERNAME}}. Amount due: {{crm.due_amount}}. Today is {{system.current_date}}. | No | Variables from {{crm.*}}, {{call.*}}, and {{system.*}} are allowed and expected here. A live character count is shown. |
Putting customer-specific values (names, amounts, account numbers) in the Static System Prompt breaks caching and can leak one customer's data into another customer's call. Keep all per-call values in the Dynamic Runtime Prompt.
A worked example of how the two fields combine:
You are Kavya, a polite collections agent for Acme Finance.
Speak in Hindi, switch to English only if the customer does.
Never threaten the customer. Always offer the payment link if they agree to pay.Customer: {{crm.CUSTOMERNAME}}
Total due: {{crm.total_due}}
Days past due: {{crm.dpd}}
Today's date: {{system.current_date}}Post-call analysis
After the call ends, the platform can run the transcript through a language model to produce a structured summary (disposition, intent, notes). Use the collapse/expand control on the Post-Call Analysis section header to show or hide these fields.
| Field | What to enter | Required | Notes |
|---|---|---|---|
| Post-Call Analysis Prompt | Instructions describing the summary you want, including the JSON fields to produce (e.g. DISPOSITION, SUB_DISPOSITION, summary). | No | The fields you name here become available as {{analysis.*}} variables in the post-call push. A live character count is shown. |
| Callback Detection | Toggle on to inject callback-extraction fields into the analysis prompt, so the bot records when a customer asks to be called back. | No | Only takes effect if callback detection is also enabled on the campaign. See Callbacks. |
Using a different model for post-call work
Live calls run on a fast, low-latency language model. Post-call analysis and quality control don't need to be fast, so you can optionally run them on a slower, higher-accuracy model. Toggle Use a different model for post-call analysis to reveal the override fields.
| Field | What to enter | Required | Notes |
|---|---|---|---|
| Use a different model for post-call analysis | Toggle on to run analysis and QC on a separate, higher-accuracy model. | No | Off by default — analysis reuses the live-call model. |
| Post-Call Provider | Choose the language model (LLM) provider that runs analysis. | Only when the override is on | The list offers several hosted and self-hosted LLM providers. Pick the one your deployment has credentials for. |
| Post-Call Model | The model ID for the chosen provider, e.g. a "pro" or "thinking" tier model. | Yes, when the override is on | Free-text field. Enter any model ID the selected provider supports. |
| Thinking Level / Thinking Budget / Reasoning Effort | A reasoning-depth control whose label and options change with the model you picked. | No | Higher reasoning is more accurate but slower and costlier. For most analysis a low or medium setting is enough. |
| Project ID | The cloud project that hosts the model. | Only for one of the enterprise-cloud providers | Required for that provider; the call fails to start without it. |
| Location | The cloud region for the model. | No | Defaults to a standard region if left blank. |
Tip
Because post-call analysis runs after the customer has hung up, latency doesn't matter. This is the right place to spend accuracy budget — keep live calls on a fast model and use a stronger model here for cleaner dispositions.
Quality control (QC)
The Quality Control section (use its collapse/expand header to show it) lets the bot score each call against criteria you define.
| Field | What to enter | Required | Notes |
|---|---|---|---|
| QC Prompt | Instructions for scoring the call, including the score fields and any pass/fail rules you want. | No | The fields you define become {{qc.*}} variables in the post-call push. Runs on the same model as analysis (including the override above, if enabled). A live character count is shown. |
Auto dispositions
Not every call reaches the analysis model — very short calls, calls where the customer never spoke, voicemail, timeouts, and system errors are dispositioned by rule instead. The Auto Dispositions section (use its collapse/expand header) lets you map each of those conditions to the disposition values your CRM expects.
For each condition you can set up to three text values:
| Column | What to enter |
|---|---|
| DISPOSITION | The top-level disposition your CRM expects (e.g. RNR, Not Connected). |
| SUB_DISPOSITION | The second-level value (e.g. DSCN_PARTIAL). |
| CALLING_REMARKS | A free-text remark to attach. |
The conditions you can map:
| Condition | When it fires |
|---|---|
| RNR | The customer picked up but stayed silent the whole call (ring-no-response / dead air). |
| Voicemail / IVR | The bot detected an answering machine or IVR. |
| No Customer Message | The customer never spoke a single message, regardless of who hung up. |
| Timeout | The call hit the maximum duration and was auto-ended. |
| System Error | The pipeline failed to start or hit an unhandled error. |
Leave a condition's fields empty to send no disposition for that case. Filling them overrides the platform's built-in defaults for that bot. For the standard disposition meanings, see Dispositions.
Buttons on this step
| Button | What it does |
|---|---|
| Collapse / Expand (Post-Call Analysis) | Show or hide the post-call analysis and model-override fields. |
| Collapse / Expand (Quality Control) | Show or hide the QC prompt. |
| Collapse / Expand (Auto Dispositions) | Show or hide the auto-disposition mapping table. |
The wizard's Previous, Continue, and Cancel controls live in the shared wizard footer and behave the same on every step — see Create a bot.
Step 2: Policy
The policy step is an optional guided alternative to writing a system prompt by hand. Instead of free-form instructions, you fill in a structured form — company name, agent name, CRM field names, payment details — and the backend assembles a tested, compliance-aware system prompt for you at call time. It is purpose-built for two India-specific call types: loan collections and motor insurance renewals.
When the policy engine is enabled, an orange banner appears: "The manual system prompt will not be sent for calls while this policy is enabled." Your hand-written Step 1 prompt becomes a fallback only. Turn the policy engine off to go back to using your manual prompt.
Turning it on
| Field | What to enter | Required | Notes |
|---|---|---|---|
| Enable Policy Engine | Toggle on to switch this bot from a manual prompt to the structured policy. | No | Off by default. Every other field on this step only appears once this is on. |
Template and identity
| Field | What to enter | Required | Notes |
|---|---|---|---|
| Template | The kind of call this bot makes. Options: Collection — Recovery, Collection — Soft Early DPD, Collection — Soft Pre-Due, Collection — Decremental, Insurance — Motor Renewal. | No (but it drives the whole form) | Your choice decides which field groups below appear — collection templates show collection fields, the insurance template shows product fields. |
| Language Policy | How the bot handles language. Options: Hindi primary with English switch, or Hindi / Hinglish only. | No | Choose the second option for audiences who don't switch to English. |
| Company Name | The company the bot represents (spoken to the customer). | Yes | e.g. Acme Finance. |
| Agent Name | The name the bot uses for itself. | Yes | e.g. Kavya. |
Collection-specific fields
These appear when the template is any of the four Collection types.
| Field | What to enter | Required | Notes |
|---|---|---|---|
| High DPD Threshold | Days-past-due above which the bot treats the account as seriously overdue. | No | Defaults to 90. |
| Payment URL | The link to your payment portal. | No | The bot offers this when the customer agrees to pay. |
| Payment Channel (Hindi / English) | The spoken name for the payment portal in each language, e.g. भुगतान लिंक / payment link. | No | This is what the bot says when it refers to the link, so phrase it naturally. |
| Settlement Fallback | Toggle on to allow strict recovery calls to offer a settlement after the payment pushes have been made. | No | Collection templates only. |
Insurance-renewal-specific fields
These appear only when the template is Insurance — Motor Renewal.
| Field | What to enter | Required | Notes |
|---|---|---|---|
| Expiring Soon Window | Number of days before policy expiry within which the bot frames the renewal as "expiring soon". | No | Defaults to 30. |
| Product Name | The product's spoken name, used if the customer asks what they are being called about. | No | |
| Coverage Summary | A one-line recap of what the policy covers, spoken if the customer asks. | No | Keep it to a single sentence. |
| Customer Care Number | A support number the bot can offer. | No | Spoken digit-by-digit so the customer can note it down. |
| Vehicle Noun (Hindi / English) | The everyday word for the insured vehicle, e.g. गाड़ी / vehicle for a car, बाइक / bike for a two-wheeler. | No | Makes the bot sound natural in both languages. |
CRM field mapping
Your CRM's column names rarely match the names the policy expects. This section maps each policy field to the raw column name in your data, so the bot can quote real figures to the customer. The list of fields shown depends on the template.
Tip
The values you map here flow in as {{crm.*}} variables. If a figure comes out wrong or empty on a test call, check that the CRM column name you typed exactly matches your data source.
Compliance scenarios
These toggles arm the bot with safe, pre-written handling for sensitive situations. Which ones appear depends on the template.
| Scenario | What it handles | Templates |
|---|---|---|
| DND / do-not-call | The customer asks not to be contacted again. | Collection |
| Deceased borrower | The person called is reported deceased. | Collection (as "deceased borrower"); Insurance (as "deceased customer revealed") |
| LPP explicit disclosure | Required disclosure of late-payment penalties. | Collection |
| Abusive customer handling | The customer becomes abusive. | Collection and Insurance |
Each scenario is an independent on/off toggle — enable the ones your compliance team requires.
Redial context
When you call the same customer more than once, this section lets the bot open differently based on what happened last time.
| Field | What to enter | Required | Notes |
|---|---|---|---|
| TELE_REMARKS Field | The name of the CRM column that holds the notes from the previous call. | No | |
| Opening Map (JSON) | A JSON object mapping each possible remark value to an opening instruction for the bot. | No | Free-text JSON. A typo here means the bot falls back to its standard opening. |
A small example:
{
"promised_to_pay": "Gently remind the customer of their earlier promise to pay.",
"wrong_number": "Apologise briefly and confirm you have reached the right person.",
"asked_callback": "Acknowledge that the customer asked to be called back at this time."
}Buttons on this step
| Button | What it does |
|---|---|
| Collapse / Expand (section headers) | Show or hide each form group: Template & Identity, CRM Field Mapping, Collection Actions, Compliance Scenarios, Redial Context, and (insurance only) Product Identity. |
As on every step, Previous, Continue, and Cancel live in the shared wizard footer.
Where these settings show up later
- The values flow into live calls as the bot's instructions and as
{{crm.*}}/{{call.*}}/{{system.*}}variables. - The fields you define in the analysis and QC prompts become
{{analysis.*}}and{{qc.*}}variables you can push to your CRM — configure that in Tools & integrations. - Once the bot is created, you can edit any of these fields again from the bot detail page — see Bot detail.
- Before going live, place a test call to hear the opening and confirm variables resolve — see Test calls.
Create bot
How to use the bot creation wizard in the Ori console — the wizard header controls, the Identity step, and the Behavior step, field by field.
Voice pipeline
Configure the speech-to-text, language model, and voice engines that power a bot's conversation, plus turn-taking and interruption behavior.