Voisnap Docs
Guides

Build a Voice Agent

End-to-end guide to creating, testing, and iterating on a production-ready voice AI agent on Voisnap.

Build a Voice Agent

This guide walks through the complete lifecycle of a production voice agent — from writing your first system prompt to reviewing real conversation data and iterating.

Goal: Deploy a customer support voice agent for a fictional e-commerce company (Acme Corp) that can handle order status inquiries, billing questions, and returns.


1. Plan your agent

Before touching the API, answer these questions:

What is the agent's primary job?

Acme Corp customer support — handle inbound calls about orders, billing, and returns.

What should the agent NOT do?

It should not process refunds directly. It should not discuss competitor products.

When should it transfer to a human?

Angry customers, legal threats, complex disputes, anything requiring system access.

What is the agent's persona?

Name: "Aria". Tone: warm, professional, concise. US English.


2. Write the system prompt

A great system prompt is the most important factor in agent quality. Follow these guidelines:

  • State the role and company clearly in the first sentence
  • Define what to do AND what not to do
  • Keep responses short — this is a voice channel, not email
  • Include escalation criteria explicitly
  • Add company-specific knowledge directly in the prompt for small amounts of info
You are Aria, a friendly customer support agent for Acme Corp, an e-commerce company.

## Your role
Handle inbound customer calls about: order status, shipping, billing questions, returns and exchanges, and account issues.

## Response guidelines
- Keep each response to 1–2 sentences unless the customer asks for detail
- Speak naturally — use contractions ("I'll", "that's", "you're")
- Confirm you've understood the customer's issue before responding
- If you don't know something, say "Let me check that for you" (then use your tools)

## What you must NOT do
- Do not process refunds or issue credits — offer to transfer to billing team instead
- Do not discuss competitor products or prices
- Do not make promises about shipping times you cannot confirm

## Escalation triggers — transfer immediately if:
- Customer uses threatening language
- Customer mentions legal action or a lawyer
- Customer has a HIPAA-related question (medical equipment)
- 3 unsuccessful attempts to resolve the issue

## Transfer instructions
When transferring: "I'm going to connect you with a specialist who can help with that. One moment please."
Transfer to: +1-800-555-0101 (billing), +1-800-555-0102 (shipping disputes)

## Company info
- Return window: 30 days for most items, 15 days for electronics
- Free shipping on orders over $75
- Order tracking: customers can check at acme.com/orders with their order number
- Business hours: Mon–Fri 8am–8pm, Sat 9am–5pm ET

3. Create the agent

import voisnap
 
client = voisnap.VoisnapClient(api_key="vsnp_live_...")
 
SYSTEM_PROMPT = """You are Aria, a friendly customer support agent for Acme Corp...
[paste full prompt from above]
"""
 
agent = client.agents.create(
    name="Aria – Acme Support",
    description="Inbound customer support — orders, billing, returns",
    persona={
        "name": "Aria",
        "personality": "warm, professional, concise",
        "role": "customer support specialist"
    },
    voice={
        "provider": "elevenlabs",
        "voice_id": "EXAVITQu4vr4xnSDxMaL",  # Bella — warm female voice
        "stability": 0.5,
        "similarity_boost": 0.75,
    },
    llm={
        "provider": "openai",
        "model": "gpt-4o",
        "temperature": 0.6,   # slightly lower = more consistent
        "max_tokens": 300,
    },
    transcription={
        "provider": "deepgram",
        "model": "nova-2",
        "language": "en-US",
        "smart_format": True,
    },
    system_prompt_template=SYSTEM_PROMPT,
    first_message="Thank you for calling Acme support! This is Aria. How can I help you today?",
    first_message_mode="assistant_speaks_first",
    end_call_phrases=["goodbye", "have a great day", "thanks, bye"],
    max_duration_seconds=600,
    max_idle_time_seconds=12,
    silence_detection={
        "enabled": True,
        "timeout_seconds": 8,
        "message": "Are you still there?"
    },
    dtmf_enabled=True,
    ai_disclosure_message="Just so you know, you're speaking with an AI assistant.",
    recording={"enabled": True, "format": "mp3", "storage_retention_days": 90},
    analysis_config={
        "enabled": True,
        "sentiment_analysis": True,
        "intent_detection": True,
        "summary_enabled": True,
        "custom_fields": [
            {
                "name": "resolution_status",
                "type": "enum",
                "options": ["resolved", "escalated", "callback_scheduled", "unresolved"]
            },
            {"name": "issue_category", "type": "string"},
        ]
    },
)
print(f"Agent created: {agent.id}")

4. Provision and assign a phone number

# Search for a number in the 800 area
results = client.telephony.numbers.search(
    country="US",
    area_code="800",
    capabilities=["voice"],
    provider="twilio"
)
 
# Provision the first available
number = client.telephony.numbers.provision(
    phone_number=results[0].phone_number,
    provider="twilio",
    friendly_name="Acme Support Line"
)
print(f"Provisioned: {number.phone_number}")
 
# Assign to agent
client.telephony.numbers.assign(
    number_id=number.id,
    agent_id=agent.id
)
print("Number assigned!")

5. Activate and test

# Activate
client.agents.activate(agent.id)
 
# Trigger a test call to your own phone
test = client.agents.test(
    agent.id,
    channel="phone",
    phone_number="+1YOUR_PHONE",  # your number
    metadata={"test_scenario": "order_status_inquiry"}
)
print(f"Test call initiated: {test.test_session_id}")

Call your phone and interact with the agent. Test these scenarios:

  1. Asking about an order status
  2. Requesting a refund (should transfer or explain)
  3. Asking about return policy
  4. Being rude (should de-escalate and offer transfer)

6. Review the transcript and analysis

After each test call:

import time
 
# Wait a few seconds for processing
time.sleep(5)
 
# Find the conversation
convs = list(client.conversations.list(agent_id=agent.id, limit=1))
conv = convs[0]
 
print(f"\n=== Call summary ({conv.duration_seconds}s) ===")
print(f"Sentiment: {conv.analysis.sentiment} ({conv.analysis.sentiment_score:.2f})")
print(f"Intent: {conv.analysis.intent}")
print(f"Outcome: {conv.analysis.custom_fields.get('resolution_status')}")
print(f"\nSummary: {conv.analysis.summary}")
 
print("\n=== Transcript ===")
transcript = client.conversations.transcript(conv.id)
for turn in transcript.turns:
    role = "🤖 Aria" if turn.speaker == "agent" else "👤 User"
    print(f"\n{role}:\n  {turn.text}")

7. Iterate on the system prompt

Common issues and fixes:

IssueFix
Agent gives too-long responsesAdd "Limit each response to one sentence."
Agent hallucinates infoMove info into a knowledge base; add "Only state facts from your training data or tools."
Agent doesn't transfer when it shouldMake escalation triggers more explicit and add them as endCallPhrases-like instructions
Agent sounds roboticIncrease voice stability to 0.65, reduce LLM temperature to 0.5
Agent interrupts too quicklyAdjust endpointing: increase utterance_end_ms to 1200

After each prompt change, publish a new version:

client.agents.update(agent.id, system_prompt_template=UPDATED_PROMPT)
client.agents.publish(agent.id, notes="Reduced response length, improved transfer triggers")

8. Monitor in production

After going live, check these metrics weekly:

stats = client.agents.stats(
    agent.id,
    date_from="2025-06-01",
    date_to="2025-06-30"
)
print(f"Total calls: {stats.total_conversations}")
print(f"Avg duration: {stats.avg_duration_seconds:.0f}s")
print(f"Transfer rate: {stats.outcome_breakdown.get('escalated', 0) / stats.total_conversations:.1%}")
print(f"Resolution rate: {stats.outcome_breakdown.get('resolved', 0) / stats.total_conversations:.1%}")
print(f"Avg sentiment: {stats.avg_sentiment_score:.2f}")

A healthy support agent typically shows:

  • Transfer rate: 10–20%
  • Resolution rate: 65–80%
  • Avg sentiment: >0.65
  • Avg duration: 2–4 minutes

On this page