AgentBase

Learn how to build voice AI agents using AgentBase, from basic configuration to advanced prompt engineering and voice customization.
View as MarkdownOpen in Claude

What You’ll Learn

This chapter covers everything you need to build production-quality agents:

  1. AgentBase - The foundation class and its capabilities
  2. Static vs Dynamic - Choosing the right pattern for your use case
  3. Prompts & POM - Crafting effective prompts with the Prompt Object Model
  4. Voice & Language - Configuring voices and multi-language support
  5. AI Parameters - Tuning conversation behavior
  6. Hints - Improving speech recognition accuracy
  7. Call Flow - Customizing when and how calls are answered

Prerequisites

Before building agents, you should understand:

  • Core concepts from Chapter 2 (SWML, SWAIG, Lifecycle)
  • Basic Python class structure
  • How SignalWire processes calls

Agent Architecture Overview

Agent Components.
Agent Components

A Complete Agent Example

Here’s what a production agent looks like:

1from signalwire_agents import AgentBase, SwaigFunctionResult
2
3class CustomerSupportAgent(AgentBase):
4 """Production customer support agent."""
5
6 def __init__(self):
7 super().__init__(
8 name="customer-support",
9 route="/support"
10 )
11
12 # Voice configuration
13 self.add_language("English", "en-US", "rime.spore")
14
15 # AI behavior
16 self.set_params({
17 "end_of_speech_timeout": 500,
18 "attention_timeout": 15000,
19 "inactivity_timeout": 30000
20 })
21
22 # Prompts
23 self.prompt_add_section(
24 "Role",
25 "You are Alex, a friendly customer support agent for Acme Inc."
26 )
27
28 self.prompt_add_section(
29 "Guidelines",
30 body="Follow these guidelines:",
31 bullets=[
32 "Be helpful and professional",
33 "Ask clarifying questions when needed",
34 "Keep responses concise for voice",
35 "Offer to transfer if you cannot help"
36 ]
37 )
38
39 # Speech recognition hints
40 self.add_hints([
41 "Acme", "account number", "order status",
42 "refund", "billing", "representative"
43 ])
44
45 # Functions
46 self.define_tool(
47 name="check_order",
48 description="Look up an order by order number",
49 parameters={
50 "type": "object",
51 "properties": {
52 "order_number": {
53 "type": "string",
54 "description": "The order number to look up"
55 }
56 },
57 "required": ["order_number"]
58 },
59 handler=self.check_order
60 )
61
62 # Skills
63 self.add_skill("datetime")
64
65 # Post-call summary
66 self.set_post_prompt(
67 "Summarize: issue type, resolution, customer satisfaction"
68 )
69
70 def check_order(self, args, raw_data):
71 order_number = args.get("order_number")
72 # Your business logic here
73 return SwaigFunctionResult(
74 f"Order {order_number}: Shipped on Monday, arriving Thursday"
75 )
76
77if __name__ == "__main__":
78 agent = CustomerSupportAgent()
79 agent.run(host="0.0.0.0", port=3000)

Chapter Contents

SectionDescription
AgentBaseCore class and constructor options
Static vs DynamicChoosing the right pattern
Prompts & POMPrompt engineering for voice AI
Voice & LanguageVoice selection and multi-language
AI ParametersBehavior tuning
HintsSpeech recognition improvement
Call FlowCustomizing call answer behavior

Key Patterns

Pattern 1: Class-Based Agent

Best for complex agents with multiple functions:

1class MyAgent(AgentBase):
2 def __init__(self):
3 super().__init__(name="my-agent")
4 self.configure()
5
6 def configure(self):
7 # All configuration here
8 pass

Pattern 2: Functional Agent

Quick agents for simple use cases:

1from signalwire_agents import AgentBase
2
3agent = AgentBase(name="simple-agent")
4agent.add_language("English", "en-US", "rime.spore")
5agent.prompt_add_section("Role", "You are a helpful assistant.")
6agent.run()

Pattern 3: Multi-Agent Server

Multiple agents on one server:

1from signalwire_agents import AgentServer
2
3server = AgentServer()
4server.register(SupportAgent(), "/support")
5server.register(SalesAgent(), "/sales")
6server.register(BillingAgent(), "/billing")
7server.run(port=3000)

Testing Your Agent

Always test before deploying:

$# View SWML output
$swaig-test my_agent.py --dump-swml
$
$# List registered functions
$swaig-test my_agent.py --list-tools
$
$# Test a function
$swaig-test my_agent.py --exec check_order --order_number 12345

Let’s start with understanding AgentBase in depth.

Class Overview

AgentBase Inheritance.
AgentBase Inheritance

Constructor Parameters

1from signalwire_agents import AgentBase
2
3agent = AgentBase(
4 # Required
5 name="my-agent", # Unique agent identifier
6
7 # Server Configuration
8 route="/", # HTTP route path (default: "/")
9 host="0.0.0.0", # Bind address (default: "0.0.0.0")
10 port=3000, # Server port (default: 3000)
11
12 # Authentication
13 basic_auth=("user", "pass"), # Override env var credentials
14
15 # Behavior
16 auto_answer=True, # Answer calls automatically
17 use_pom=True, # Use Prompt Object Model
18
19 # Recording
20 record_call=False, # Enable call recording
21 record_format="mp4", # Recording format
22 record_stereo=True, # Stereo recording
23
24 # Tokens and Security
25 token_expiry_secs=3600, # Function token expiration
26
27 # Advanced
28 default_webhook_url=None, # Override webhook URL
29 agent_id=None, # Custom agent ID (auto-generated)
30 native_functions=None, # Built-in SignalWire functions
31 schema_path=None, # Custom SWML schema path
32 suppress_logs=False, # Disable logging
33 config_file=None # Load from config file
34)

Parameter Reference

ParameterTypeDefaultDescription
namestrRequiredUnique identifier for the agent
routestr”/“HTTP route where agent is accessible
hoststr”0.0.0.0”IP address to bind server
portint3000Port number for server
basic_authtupleNone(username, password) for auth
use_pomboolTrueEnable Prompt Object Model
auto_answerboolTrueAuto-answer incoming calls
record_callboolFalseEnable call recording
record_formatstr”mp4”Recording file format
record_stereoboolTrueRecord in stereo
token_expiry_secsint3600Token validity period
native_functionslistNoneSignalWire native functions
suppress_logsboolFalseDisable agent logs

Creating an Agent

1from signalwire_agents import AgentBase, SwaigFunctionResult
2
3
4class MyAgent(AgentBase):
5 def __init__(self):
6 super().__init__(name="my-agent")
7 self._setup()
8
9 def _setup(self):
10 # Voice
11 self.add_language("English", "en-US", "rime.spore")
12
13 # Prompts
14 self.prompt_add_section("Role", "You are a helpful assistant.")
15
16 # Functions
17 self.define_tool(
18 name="greet",
19 description="Greet the user",
20 parameters={},
21 handler=self.greet
22 )
23
24 def greet(self, args, raw_data):
25 return SwaigFunctionResult("Hello! How can I help you today?")
26
27
28if __name__ == "__main__":
29 agent = MyAgent()
30 agent.run()

Instance-Based

1from signalwire_agents import AgentBase
2
3agent = AgentBase(name="quick-agent")
4agent.add_language("English", "en-US", "rime.spore")
5agent.prompt_add_section("Role", "You are a helpful assistant.")
6agent.run()

Declarative (PROMPT_SECTIONS)

1from signalwire_agents import AgentBase
2
3
4class DeclarativeAgent(AgentBase):
5 PROMPT_SECTIONS = {
6 "Role": "You are a helpful customer service agent.",
7 "Guidelines": [
8 "Be professional and courteous",
9 "Ask clarifying questions when needed",
10 "Keep responses concise"
11 ],
12 "Rules": {
13 "body": "Always follow these rules:",
14 "bullets": [
15 "Never share customer data",
16 "Escalate complex issues"
17 ]
18 }
19 }
20
21 def __init__(self):
22 super().__init__(name="declarative-agent")
23 self.add_language("English", "en-US", "rime.spore")

Key Methods

Configuration Methods

1# Voice and Language
2agent.add_language(name, code, voice) # Add language support
3agent.set_languages(languages) # Set all languages at once
4
5# Prompts
6agent.prompt_add_section(title, body) # Add prompt section
7agent.prompt_add_subsection(parent, title) # Add subsection
8agent.set_post_prompt(text) # Set post-call summary prompt
9
10# AI Parameters
11agent.set_params(params_dict) # Set AI behavior parameters
12agent.set_param_value(key, value) # Set single parameter
13
14# Speech Recognition
15agent.add_hints(hints_list) # Add speech hints
16agent.add_hint(hint_string) # Add single hint
17
18# Functions
19agent.define_tool(name, description, ...) # Define SWAIG function
20agent.add_skill(skill_name) # Add a skill
21
22# Pronunciation
23agent.add_pronunciation(replace, with_text) # Add pronunciation rule

Runtime Methods

1# Start server
2agent.run(host="0.0.0.0", port=3000)
3
4# Get SWML document
5swml = agent.get_swml()
6
7# Access components
8agent.pom # Prompt Object Model
9agent.data_map # DataMap builder

Agent Lifecycle

Agent Lifecycle.
Agent Lifecycle

Configuration File

Load configuration from a YAML/JSON file:

1agent = AgentBase(
2 name="my-agent",
3 config_file="config/agent.yaml"
4)
1# config/agent.yaml
2name: my-agent
3route: /support
4host: 0.0.0.0
5port: 3000

Environment Variables

AgentBase respects these environment variables:

VariablePurpose
SWML_BASIC_AUTH_USERBasic auth username
SWML_BASIC_AUTH_PASSWORDBasic auth password
SWML_PROXY_URL_BASEBase URL for webhooks behind proxy
SWML_SSL_ENABLEDEnable SSL
SWML_SSL_CERT_PATHSSL certificate path
SWML_SSL_KEY_PATHSSL key path
SWML_DOMAINDomain for SSL

Multi-Agent Server

Run multiple agents on one server:

1from signalwire_agents import AgentServer
2
3
4class SupportAgent(AgentBase):
5 def __init__(self):
6 super().__init__(name="support", route="/support")
7 # ... configuration
8
9
10class SalesAgent(AgentBase):
11 def __init__(self):
12 super().__init__(name="sales", route="/sales")
13 # ... configuration
14
15
16# Register multiple agents
17server = AgentServer()
18server.register(SupportAgent())
19server.register(SalesAgent())
20server.run(host="0.0.0.0", port=3000)

Access agents at:

  • http://localhost:3000/support
  • http://localhost:3000/sales

Best Practices

  1. Use class-based agents for anything beyond simple prototypes
  2. Organize configuration into logical private methods
  3. Set explicit credentials in production via environment variables
  4. Use meaningful agent names for logging and debugging
  5. Test with swaig-test before deploying
1class WellOrganizedAgent(AgentBase):
2 def __init__(self):
3 super().__init__(name="organized-agent")
4 self._configure_voice()
5 self._configure_prompts()
6 self._configure_functions()
7 self._configure_skills()
8
9 def _configure_voice(self):
10 self.add_language("English", "en-US", "rime.spore")
11 self.set_params({
12 "end_of_speech_timeout": 500,
13 "attention_timeout": 15000
14 })
15
16 def _configure_prompts(self):
17 self.prompt_add_section("Role", "You are a helpful assistant.")
18
19 def _configure_functions(self):
20 self.define_tool(
21 name="help",
22 description="Get help",
23 parameters={},
24 handler=self.get_help
25 )
26
27 def _configure_skills(self):
28 self.add_skill("datetime")
29
30 def get_help(self, args, raw_data):
31 return SwaigFunctionResult("I can help you with...")