Building a Voice Support Agent in 15 Minutes
In this tutorial, we'll build a complete voice support agent that can greet callers, understand their intent, connect them to screen-sharing sessions, or have a free-form AI conversation -- all from three markdown files.
Live Demo: SOS.Support runs this exact stack for Wholesale Computers and Technology -- handling real tech support calls and sales inquiries 24/7.
Step 1: Define Your Procedures
First, we define what our voice agent can DO. Each action maps a human-readable name to an Elixir function implementation.
# System Procedures
## Actions
### Say
Speak text to the user.
**Implementation**: `NanobotPlugin.Actions.say/2`
**Params**: `text` (string)
### Listen
Capture user speech via STT.
**Implementation**: `NanobotPlugin.Queries.listen/1`
**Returns**: `text` (string)Step 2: Write the Workflow
The workflow defines the conversation flow as a state machine. Each state has a trigger (when to activate), actions (what to do), and transitions (where to go next).
# Voice Support Workflow
## States
### Greeting
**Trigger**: `Event.eq(:type, :call_started)`
**Actions**:
- `Say: "Hello, this is Alex with Support."`
- `Transition: Listening`
### Listening
**Trigger**: `Event.eq(:type, :transcript)`
**Actions**:
- `Query: Analyze($text)`
- **If** `intent == :connect`:
- `Say: "Enter code {session_code}"`
- `Transition: Connecting`Step 3: Wire the Topology
MODULES.md connects everything together. The VoiceHandler compiles your workflow, the Resilience plugin protects against crashes, and the MainBus routes all events through the handler chain.
Deploy and Watch
$ goldclaw deploy
Workflow Engine compiled successfully
VoiceHandler module compiled from WORKFLOW.md
Resilience Plugin registered
AMCP connected to RabbitMQ
TTS is working and resampling from 24kHz to 16kHz
Common phrases are being pre-cached in the backgroundThat's it. Your voice agent is live, handling calls, and self-healing if anything goes wrong.