Personalize conversations

Updated

Use variables to personalize an agent for each session.

Preview documentation

You're reading the Conversational AI Platform (Preview) docs. Switch to Main.

Variables let you customize an agent for each conversation and capture its key outcomes. You declare variables when you create an agent and pass their values when you start a session. You can also choose whether Agora retains each session's conversation data.

Understand the tech

A variable is a named value that the agent declares. Each variable has a type, and you use it in one or both of the following ways:

  • Personalize the conversation: Refer to the variable as {{variable_name}} in the agent's instructions, messages, or greeting.text. When you start a session, you pass its value in values, and the Platform replaces each placeholder with that value. The agent doesn't store values. You pass them for every session.
  • Extract outcomes: In the variable declaration, set extract to true and describe what the variable means. After the session ends, the Platform extracts the value from the conversation transcript. The Preview API doesn't return the extracted values yet.

You can also use variables in the LLM's failure message, the silence message, and generated filler word instructions.

Prerequisites

Before you begin, make sure that you have created an agent and started a session as described in Create an agent and start a session. The SDK examples use the client you create there.

Declare variables

When you create or update an agent, declare every variable the agent uses. A variable name starts with a lowercase letter and contains up to 64 lowercase letters, digits, and underscores.

In the following example, customer_name and plan personalize the conversation, and appointment_confirmed and follow_up_date are extracted after it ends:

Declare each variable with with_variable():

from agora_agent import Agent, DeepgramSTT, OpenAI, OpenAITTS

agent = (
    Agent(client=client)
    .with_stt(DeepgramSTT(model="nova-3", language="en-US"))
    .with_llm(
        OpenAI(
            model="gpt-4.1-mini",
            system_messages=[
                {
                    "role": "system",
                    "content": "You confirm appointments for Acme customers. The customer is {{customer_name}}, on the {{plan}} plan. Ask whether they can attend their appointment, and if not, when they want to reschedule.",
                }
            ],
            greeting_message="Hi {{customer_name}}, I am calling about your upcoming appointment.",
            greeting_configs={"on": "each_join"},
        )
    )
    .with_tts(OpenAITTS(model="tts-1", voice="alloy"))
    .with_variable("customer_name", type="str", required=True)
    .with_variable("plan", type="str", options=["basic", "pro"])
    .with_variable(
        "appointment_confirmed",
        type="bool",
        extract=True,
        description="Whether the customer confirmed that they can attend the appointment.",
    )
    .with_variable(
        "follow_up_date",
        type="date",
        extract=True,
        description="The date the customer wants to reschedule to, if they can't attend.",
    )
)

saved_agent = agent.save(name="Appointment agent")

Declare each variable with withVariable():

import { Agent, DeepgramSTT, OpenAI, OpenAITTS } from 'agora-agents';

const agent = new Agent({ client })
  .withStt(new DeepgramSTT({ model: 'nova-3', language: 'en-US' }))
  .withLlm(
    new OpenAI({
      model: 'gpt-4.1-mini',
      systemMessages: [
        {
          role: 'system',
          content:
            'You confirm appointments for Acme customers. The customer is {{customer_name}}, on the {{plan}} plan. Ask whether they can attend their appointment, and if not, when they want to reschedule.',
        },
      ],
      greetingMessage: 'Hi {{customer_name}}, I am calling about your upcoming appointment.',
      greetingConfigs: { on: 'each_join' },
    }),
  )
  .withTts(new OpenAITTS({ model: 'tts-1', voice: 'alloy' }))
  .withVariable('customer_name', { type: 'str', required: true })
  .withVariable('plan', { type: 'str', options: ['basic', 'pro'] })
  .withVariable('appointment_confirmed', {
    type: 'bool',
    extract: true,
    description: 'Whether the customer confirmed that they can attend the appointment.',
  })
  .withVariable('follow_up_date', {
    type: 'date',
    extract: true,
    description: "The date the customer wants to reschedule to, if they can't attend.",
  });

const savedAgent = await agent.save({ name: 'Appointment agent' });

Declare each variable with WithVariable():

agent := agentkit.NewAgent(client).
	WithStt(vendors.NewDeepgramSTT(vendors.DeepgramSTTOptions{Model: "nova-3", Language: "en-US"})).
	WithLlm(vendors.NewOpenAI(vendors.OpenAIOptions{
		Model: "gpt-4.1-mini",
		SystemMessages: []map[string]interface{}{
			{
				"role":    "system",
				"content": "You confirm appointments for Acme customers. The customer is {{customer_name}}, on the {{plan}} plan. Ask whether they can attend their appointment, and if not, when they want to reschedule.",
			},
		},
		GreetingMessage: "Hi {{customer_name}}, I am calling about your upcoming appointment.",
		GreetingConfigs: map[string]interface{}{"on": "each_join"},
	})).
	WithTts(vendors.NewOpenAITTS(vendors.OpenAITTSOptions{Model: "tts-1", Voice: "alloy"})).
	WithVariable("customer_name", agentkit.VariableDefinition{Type: "str", Required: true}).
	WithVariable("plan", agentkit.VariableDefinition{Type: "str", Options: []any{"basic", "pro"}}).
	WithVariable("appointment_confirmed", agentkit.VariableDefinition{
		Type:        "bool",
		Extract:     true,
		Description: "Whether the customer confirmed that they can attend the appointment.",
	}).
	WithVariable("follow_up_date", agentkit.VariableDefinition{
		Type:        "date",
		Extract:     true,
		Description: "The date the customer wants to reschedule to, if they can't attend.",
	})

savedAgent, err := agent.Save(ctx, agentkit.SaveOptions{Name: "Appointment agent"})
if err != nil {
	log.Fatal(err)
}

Send a request to Create an agent or Update an agent with the variables in variables, keyed by name:

curl --request POST \
  --url https://preview.ai.agora.io/conversational-ai/v1/projects/<your_app_id>/agents \
  --header 'Authorization: Basic <your_base64_encoded_credentials>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "agent_name": "Appointment agent",
  "instructions": "You confirm appointments for Acme customers. The customer is {{customer_name}}, on the {{plan}} plan. Ask whether they can attend their appointment, and if not, when they want to reschedule.",
  "greeting": {
    "mode": "text",
    "on": "each_join",
    "text": "Hi {{customer_name}}, I am calling about your upcoming appointment."
  },
  "variables": {
    "customer_name": {
      "type": "str",
      "required": true
    },
    "plan": {
      "type": "str",
      "options": ["basic", "pro"]
    },
    "appointment_confirmed": {
      "type": "bool",
      "extract": true,
      "description": "Whether the customer confirmed that they can attend the appointment."
    },
    "follow_up_date": {
      "type": "date",
      "extract": true,
      "description": "The date the customer wants to reschedule to, if they can't attend."
    }
  },
  "pipeline": {
    "mode": "cascaded",
    "asr": { "credential": { "mode": "managed" }, "vendor": "deepgram", "model": "nova-3", "language": "en-US" },
    "llm": { "credential": { "mode": "managed" }, "vendor": "openai", "style": "openai", "model": "gpt-4.1-mini" },
    "tts": {
      "credential": { "mode": "managed" },
      "vendor": "minimax",
      "params": { "model": "speech-2.6-turbo", "voice_setting": { "voice_id": "English_captivating_female1", "speed": 1 } }
    }
  }
}'

Each variable takes the following fields:

FieldDescription
typeRequired. The data type: str, int, float, bool, date, or datetime. Pass date and datetime values as ISO 8601 strings, for example "2026-09-30" and "2026-09-30T14:00:00Z".
requiredWhether you must pass a value when you start a session. The default is false.
optionsThe allowed values, 1 to 100 unique items of the declared type. Values you pass must be one of them, and extraction chooses one of them.
extractWhether to extract the variable from the conversation after the session ends. The default is false. An agent can have up to 50 extract variables.
descriptionRequired when extract is true. Up to 2,000 characters. Describe what the variable means as a clear extraction instruction, such as "Whether the customer confirmed that they can attend the appointment."

Pass values when you start a session

When you start a session, pass the values, keyed by variable name. The values apply to this session only.

session = saved_agent.create_session(
    channel="<your_channel_name>",
    token="<your_rtc_token>",
    agent_uid="1002",
    remote_uids=["1001"],
    values={"customer_name": "Ada", "plan": "pro"},
)
session_id = session.start()
const session = savedAgent.createSession({
  channel: '<your_channel_name>',
  token: '<your_rtc_token>',
  agentUid: '1002',
  remoteUids: ['1001'],
  values: { customer_name: 'Ada', plan: 'pro' },
});
const sessionId = await session.start();
session := savedAgent.CreateSession(agentkit.CreateSessionOptions{
	Channel:    "<your_channel_name>",
	Token:      "<your_rtc_token>",
	AgentUID:   "1002",
	RemoteUIDs: []string{"1001"},
	Values:     map[string]any{"customer_name": "Ada", "plan": "pro"},
})
sessionID, err := session.Start(ctx)
if err != nil {
	log.Fatal(err)
}

Send a request to Start a session with the values in values:

curl --request POST \
  --url https://preview.ai.agora.io/conversational-ai/v1/projects/<your_app_id>/sessions \
  --header 'Authorization: Basic <your_base64_encoded_credentials>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "agent_id": "3f6c2a9e-8d1b-4e7a-9c55-0b2f7d1e4a10",
  "values": {
    "customer_name": "Ada",
    "plan": "pro"
  },
  "transport": {
    "type": "rtc",
    "channel": "<your_channel_name>",
    "token": "<your_rtc_token>",
    "uid": "1002",
    "subscribe_uids": ["1001"]
  }
}'

The Platform checks the values when the session starts:

  • Each key must be a variable that the agent declares.
  • Each value must match the variable's type, and one of its options if it has any.
  • You must pass a value for every variable with required set to true. If one is missing, the request fails with 400 MissingRequiredField, and no session starts.
  • null values are rejected.

Expansion runs once. A value that contains a placeholder isn't expanded again.

When you create a campaign, you pass values for each contact instead. An ephemeral session takes values in the same way, for the variables declared in its agent.

Choose whether Agora retains conversation data

When you start a session, set the data retention to choose how Agora handles the session's conversation data:

  • 30_days: Agora retains the data for 30 days. This is the default.
  • none: Agora doesn't retain the data, and extraction doesn't run.

For example, use none when a caller declines to have the conversation recorded:

session = saved_agent.create_session(
    channel="<your_channel_name>",
    token="<your_rtc_token>",
    agent_uid="1002",
    remote_uids=["1001"],
    values={"customer_name": "Ada", "plan": "pro"},
    data_policy={"retention": "none"},
)
const session = savedAgent.createSession({
  channel: '<your_channel_name>',
  token: '<your_rtc_token>',
  agentUid: '1002',
  remoteUids: ['1001'],
  values: { customer_name: 'Ada', plan: 'pro' },
  dataPolicy: { retention: 'none' },
});
session := savedAgent.CreateSession(agentkit.CreateSessionOptions{
	Channel:    "<your_channel_name>",
	Token:      "<your_rtc_token>",
	AgentUID:   "1002",
	RemoteUIDs: []string{"1001"},
	Values:     map[string]any{"customer_name": "Ada", "plan": "pro"},
	DataPolicy: &agentkit.SessionDataPolicy{Retention: "none"},
})

Set data_policy.retention in the request to Start a session:

"data_policy": {
  "retention": "none"
}

You set the data policy when the session starts, and you can't change it afterward.

Reference

For more information, see the following pages:

API reference