Duration 2 hours
Day 1 of 2

Learning Objectives

By the end of this module, students will be able to:

  • Create a minimal AgentBase instance
  • Understand the agent structure and required components
  • Run an agent locally
  • Use swaig-test to inspect agent output

Topics

1. AgentBase Fundamentals (30 min)

The Minimal Agent

Every agent starts with AgentBase:

from signalwire_agents import AgentBase

agent = AgentBase(name="my-agent")

if __name__ == "__main__":
    agent.run()

That’s it! This creates a working voice agent.

Constructor Parameters

Parameter Type Default Purpose
name str required Unique identifier for the agent
route str "/" URL path for the agent endpoint
host str "0.0.0.0" Server bind address
port int 3000 Server port

Naming Best Practices

  • Use lowercase with hyphens: customer-support
  • Be descriptive: order-status-agent
  • Avoid special characters
  • Keep it short but meaningful

2. Agent Structure (25 min)

Three-Part Pattern

Most agents follow this structure:

#!/usr/bin/env python3
"""Agent description."""

from signalwire_agents import AgentBase

# 1. Create agent
agent = AgentBase(
    name="support-agent",
    route="/support"
)

# 2. Configure agent
agent.prompt_add_section(
    "Role",
    "You are a helpful customer support agent."
)

agent.add_language("English", "en-US", "rime.spore")

# 3. Run agent
if __name__ == "__main__":
    agent.run()

Class-Based Pattern

For more complex agents, use a class:

#!/usr/bin/env python3
"""Class-based agent."""

from signalwire_agents import AgentBase


class SupportAgent(AgentBase):
    def __init__(self):
        super().__init__(
            name="support-agent",
            route="/support"
        )
        self._configure()

    def _configure(self):
        self.prompt_add_section(
            "Role",
            "You are a helpful customer support agent."
        )
        self.add_language("English", "en-US", "rime.spore")


if __name__ == "__main__":
    agent = SupportAgent()
    agent.run()

When to Use Each Pattern

Pattern Best For
Functional Simple agents, quick prototypes
Class-based Complex logic, multiple methods, state

3. Essential Configuration (25 min)

Setting the Prompt

The prompt defines your agent’s behavior:

agent.prompt_add_section(
    "Role",
    "You are a friendly receptionist at Acme Corp. "
    "You help callers reach the right department."
)

Setting Voice and Language

Configure how the agent sounds:

agent.add_language(
    "English",      # Language name
    "en-US",        # Language code
    "rime.spore"    # Voice identifier
)

Common Voice Options

Voice Style Best For
rime.spore Professional, clear Business
rime.marsh Warm, friendly Support
rime.cove Calm, measured Healthcare

Adding Filler Phrases

Make conversation natural:

agent.add_language(
    "English",
    "en-US",
    "rime.spore",
    speech_fillers=["Um", "Uh", "Well", "Let me think"],
    function_fillers=[
        "One moment...",
        "Let me check that...",
        "Sure thing..."
    ]
)

Note: Both speech_fillers and function_fillers must be provided together. See Module 1.6 for details.


4. Running Your Agent (20 min)

Local Development Server

python agent.py

Output:

INFO:     Started server process [12345]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:3000

Environment Variables

Control runtime behavior:

# Change port
PORT=5000 python agent.py

# Enable debug logging
DEBUG=1 python agent.py

# Set host
HOST=127.0.0.1 python agent.py

Stopping the Server

Press Ctrl+C to stop.


5. Testing with swaig-test (20 min)

Why swaig-test?

  • Test without making calls
  • Inspect generated SWML
  • Debug configuration issues
  • Faster iteration

Basic Commands

# View SWML output
swaig-test agent.py --dump-swml

# List available functions
swaig-test agent.py --list-tools

# Pretty print SWML
swaig-test agent.py --dump-swml | python -m json.tool

Understanding SWML Output

{
  "version": "1.0.0",
  "sections": {
    "main": [
      {
        "ai": {
          "prompt": {
            "text": "You are a friendly receptionist..."
          },
          "languages": [
            {
              "name": "English",
              "code": "en-US",
              "voice": "rime.spore"
            }
          ]
        }
      }
    ]
  }
}

Key SWML Elements

Element Purpose
version SWML specification version
sections.main Entry point for call flow
ai AI agent configuration
prompt.text System prompt
languages Voice configuration

Common Mistakes

1. Missing if __name__ == "__main__"

Wrong:

agent = AgentBase(name="my-agent")
agent.run()  # Runs on import!

Right:

agent = AgentBase(name="my-agent")

if __name__ == "__main__":
    agent.run()

2. Port Already in Use

ERROR: Address already in use

Fix: Use different port or kill existing process:

PORT=5001 python agent.py
# or
lsof -ti:3000 | xargs kill

3. No Prompt Set

Agent works but has no personality. Always set at least a basic prompt.


Key Takeaways

  1. AgentBase is the foundation - Every agent inherits from it
  2. Minimal is functional - Just name and run() works
  3. Configure for quality - Prompts and voice matter
  4. Test locally first - swaig-test before deployment
  5. Patterns matter - Choose functional or class-based based on complexity

Preparation for Lab 1.2

  • Review the agent patterns above
  • Have terminal ready
  • swaig-test installed and working

Lab Preview

In Lab 1.2, you will:

  1. Create a minimal agent
  2. Add prompt and voice configuration
  3. Test with swaig-test
  4. Inspect the generated SWML

Back to top

SignalWire AI Agents Certification Program