Enviado por admin el
Después de dos décadas trabajando con Asterisk y FreePBX, los desarrolladores de telecomunicaciones nos hemos enfrentado a una realidad frustrante: las soluciones de agentes de voz con IA son caras, propietarias y poco flexibles. Asterisk AI Voice Agent surge como la respuesta open source que el ecosistema necesitaba.
Este proyecto representa un cambio fundamental en cómo construimos sistemas de voz inteligentes: en lugar de depender de plataformas cerradas y costosas, ahora podemos integrar la IA conversacional directamente con nuestra infraestructura Asterisk existente, manteniendo control total sobre privacidad, costos y funcionalidad.
¿Qué es Asterisk AI Voice Agent?
Asterisk AI Voice Agent es una plataforma modular y lista para producción que integra Asterisk/FreePBX con proveedores de IA modernos. A diferencia de otras soluciones, no requiere proveedores de telefonía externos ni reemplazar tu infraestructura existente.
Características Distintivas
Verdaderamente Open Source
- Licencia MIT sin restricciones
- Transparencia total del código
- Sin vendor lock-in
Arquitectura Modular
- Elige entre proveedores cloud, locales o híbridos
- Mezcla componentes STT, LLM y TTS según necesites
- Cambia proveedores sin reescribir código
Nativo de Asterisk
- Integración directa vía ARI (Asterisk REST Interface)
- Funciona con Asterisk 18+, FreePBX, VitalPBX
- Sin hardware especializado ni servicios externos
Privacidad y Costos
- Modo híbrido local: audio permanece on-premise
- Costos tan bajos como $0.001-0.003/minuto (solo LLM)
- Control total de datos sensibles
Arquitectura Técnica
Diseño de Dos Contenedores
La arquitectura se divide en dos componentes principales:
┌─────────────────┐ ┌───────────┐ ┌───────────────────┐
│ Asterisk Server │◀────▶│ ai-engine │◀────▶│ AI Provider │
│ (ARI, RTP) │ │ (Docker) │ │ (Cloud o Local) │
└─────────────────┘ └───────────┘ └───────────────────┘
│ ▲
│ WS │ (Solo Local Hybrid)
▼ │
┌─────────────────┐
│ local-ai-server │
│ (Docker) │
└─────────────────┘
ai-engine (Orquestador Ligero)
- Conecta con Asterisk vía ARI
- Gestiona el ciclo de vida de llamadas
- Enruta audio desde/hacia proveedores IA
- Maneja el estado de sesiones
local-ai-server (Opcional)
- Ejecuta modelos STT/TTS locales
- Vosk para speech-to-text
- Piper para text-to-speech
- Interface WebSocket
Principios de Diseño
Separación de Responsabilidades El procesamiento de IA está aislado del manejo de llamadas. Esto permite escalar cada componente independientemente y facilita el debugging.
Pipelines Modulares La arquitectura de pipeline permite combinar diferentes proveedores:
- STT (Speech-to-Text): Deepgram, Vosk, Google
- LLM (Large Language Model): OpenAI, Google Gemini, local
- TTS (Text-to-Speech): ElevenLabs, Deepgram, Piper, Google
Flexibilidad de Transporte Soporta dos modos de transporte de audio:
- AudioSocket: TCP directo, menor latencia, ideal para full agents
- ExternalMedia RTP: Compatible con pipelines modulares, battle-tested
Cinco Configuraciones Golden Baseline
El proyecto incluye cinco configuraciones validadas en producción, cada una optimizada para diferentes casos de uso.
1. OpenAI Realtime (Recomendado para Inicio Rápido)
# config/ai-agent.golden-openai-realtime.yaml
stt:
provider: "openai_realtime"
llm:
provider: "openai_realtime"
model: "gpt-4o-realtime-preview-2024-12-17"
temperature: 0.8
max_tokens: 4096
tts:
provider: "openai_realtime"
Características:
- IA conversacional moderna de OpenAI
- Tiempo de respuesta: <2 segundos
- Voces naturales y expresivas
- Manejo de interrupciones (barge-in)
Ideal para:
- Despliegues enterprise
- Setup rápido
- Calidad conversacional premium
Costos aproximados:
- Input: $5/millón de tokens audio (~$0.10/minuto)
- Output: $20/millón de tokens audio (~$0.40/minuto)
2. Deepgram Voice Agent
# config/ai-agent.golden-deepgram.yaml
stt:
provider: "deepgram"
model: "nova-2-ea"
language: "es"
llm:
provider: "openai"
model: "gpt-4o-mini"
tts:
provider: "deepgram"
model: "aura-asteria-en"
Características:
- Etapa "Think" avanzada para razonamiento complejo
- Tiempo de respuesta: <3 segundos
- STT y TTS de Deepgram
- LLM de OpenAI para flexibilidad
Ideal para:
- Ecosistema Deepgram existente
- Aplicaciones que requieren razonamiento complejo
- Transcripción en tiempo real de alta calidad
Costos aproximados:
- Deepgram STT: $0.0043/minuto
- OpenAI LLM: ~$0.001/minuto
- Deepgram TTS: $0.015/1K caracteres
3. Google Live API (IA Multimodal)
# config/ai-agent.golden-google-live.yaml
stt:
provider: "google_live"
llm:
provider: "google_live"
model: "gemini-2.0-flash-exp"
temperature: 0.8
tts:
provider: "google_live"
Características:
- Gemini 2.0 Flash con capacidades multimodales
- Tiempo de respuesta: <2 segundos
- Procesamiento avanzado de lenguaje natural
- Integración nativa con ecosistema Google
Ideal para:
- Usuarios del ecosistema Google Cloud
- Aplicaciones que requieren IA avanzada
- Procesamiento multimodal
4. ElevenLabs Agent (Calidad de Voz Premium)
# config/ai-agent.golden-elevenlabs-agent.yaml
stt:
provider: "elevenlabs_conversational"
llm:
provider: "elevenlabs_conversational"
agent_id: "your-agent-id"
tts:
provider: "elevenlabs_conversational"
Características:
- Voces ultra-realistas de ElevenLabs
- IA conversacional integrada
- Tiempo de respuesta: <2 segundos
- Soporte nativo de herramientas (tool calling)
Ideal para:
- Prioridad en calidad de voz
- Conversaciones muy naturales
- Aplicaciones customer-facing premium
5. Local Hybrid (Enfocado en Privacidad)
# config/ai-agent.golden-local-hybrid.yaml
stt:
provider: "vosk"
model: "vosk-model-small-es-0.42"
llm:
provider: "openai"
model: "gpt-4o-mini"
temperature: 0.7
tts:
provider: "piper"
model: "es_ES-mls_10246-low"
audio_format: "wav"
Características:
- STT/TTS local + LLM en cloud
- El audio nunca sale del servidor
- Solo texto enviado al LLM cloud
- Tiempo de respuesta: 3-7 segundos
- Costos: ~$0.001-0.003/minuto (solo LLM)
Ideal para:
- Cumplimiento normativo (HIPAA, GDPR)
- Privacidad de audio
- Control de costos
- Instalaciones sin internet estable
Requisitos de Hardware:
- CPU: 4+ cores (arquitectura moderna 2020+)
- RAM: 8GB+ recomendado
- Disco: 2GB (modelos + workspace)
Sistema de Tool Calling: Acciones en el Mundo Real
Una de las características más poderosas introducidas en v4.1+ es el sistema de tool calling, que permite al agente de IA ejecutar acciones reales en la telefonía.
Arquitectura Unificada
El sistema de herramientas está diseñado para funcionar con cualquier proveedor de LLM que soporte function calling:
# src/tools/base_tool.py
class BaseTool(ABC):
"""Base class for all tools"""
@abstractmethod
def get_schema(self) -> dict:
"""Return OpenAI function calling schema"""
pass
@abstractmethod
async def execute(self, **kwargs) -> ToolResult:
"""Execute the tool"""
pass
Herramientas Disponibles
1. Transfer Tool (Transferencia Unificada)
Maneja tres tipos de transferencia en una sola herramienta:
{
"name": "transfer",
"description": "Transfer call to extension, queue, or ring group",
"parameters": {
"destination": "1001", # Extension number
"destination_type": "extension", # o "queue" o "ringgroup"
"context": "from-internal"
}
}
Ejemplo de uso:
Llamante: "Transfiere mi llamada al equipo de ventas"
Agente: "Te conecto con nuestro equipo de ventas inmediatamente"
[Transferencia a cola de ventas con música de espera]
Tipos soportados:
- Extensions: Transferencia directa a endpoint SIP/PJSIP
- Queues: Transferencia a colas ACD con anuncios de posición
- Ring Groups: Múltiples agentes suenan simultáneamente
2. Cancel Transfer Tool
Permite cancelar una transferencia en progreso:
{
"name": "cancel_transfer",
"description": "Cancel an in-progress transfer"
}
Ejemplo:
Agente: "Te transfiero a soporte..."
Llamante: "Mejor cancela eso"
Agente: "Sin problema, he cancelado la transferencia. ¿En qué más puedo ayudarte?"
3. Voicemail Tool
Ruta la llamada a un buzón de voz:
{
"name": "leave_voicemail",
"description": "Route caller to voicemail",
"parameters": {
"extension": "1001",
"context": "default"
}
}
Ejemplo:
Llamante: "¿Puedo dejar un mensaje de voz para Juan?"
Agente: "¡Por supuesto! Te transfiero al buzón de Juan"
[Ruta al buzón de voz, llamante graba mensaje]
4. Hangup Tool
Finaliza la llamada de forma elegante:
{
"name": "hangup_call",
"description": "End call gracefully with farewell",
"parameters": {
"farewell_message": "Gracias por llamar. ¡Que tengas un buen día!"
}
}
5. Email Tools
Envío automático de resúmenes: Después de cada llamada, los administradores reciben:
- Transcripción completa de la conversación
- Duración y metadata de la llamada
- Información del llamante
- Formato HTML profesional
Transcripciones solicitadas por el llamante:
Llamante: "¿Puedes enviarme una transcripción de esta llamada por email?"
Agente: "¡Con gusto! ¿Qué dirección de email debo usar?"
Llamante: "juan punto garcia arroba gmail punto com"
Agente: "Es juan.garcia@gmail.com, ¿correcto?"
Llamante: "Sí"
Agente: "¡Perfecto! Te enviaré la transcripción pronto"
[Email enviado con transcripción completa]
Configuración de Herramientas
La configuración se realiza en config/ai-agent.yaml:
tools:
enabled: true
available_tools:
- name: "transfer"
enabled: true
config:
allowed_destinations:
- type: "extension"
pattern: "^[1-9][0-9]{3}$" # 1000-9999
- type: "queue"
pattern: "^[5][0-9]{3}$" # 5000-5999
- type: "ringgroup"
pattern: "^[6][0-9]{3}$" # 6000-6999
- name: "leave_voicemail"
enabled: true
config:
voicemail_context: "default"
- name: "send_email_summary"
enabled: true
config:
recipients:
- "admin@example.com"
use_resend: true
- name: "request_transcript"
enabled: true
config:
email_validation: true
max_attempts: 3
Validación de Tool Calling
El proyecto incluye validación completa en v4.3+:
# Ejecutar tests de integración
pytest tests/integration/test_tools.py -v
# Test específico de transferencias
pytest tests/integration/test_tools.py::test_transfer_to_extension -v
# Validar con llamada real
agent troubleshoot --call-id=<call-id> --check-tools
Estado de Validación:
- ✅ OpenAI Realtime
- ✅ Deepgram Voice Agent
- ✅ Google Live API
- ✅ Local Hybrid
- ✅ ElevenLabs Conversational
Interfaz de Administración Web (v1.0)
El proyecto incluye una interfaz web moderna para gestión completa del sistema.
Características Principales
Dashboard en Tiempo Real
- Métricas del sistema actualizadas cada 5 segundos
- Estado de contenedores Docker
- Uso de CPU, memoria y disco
- Llamadas activas y totales
Asistente de Configuración Visual
- Reemplaza el CLI
agent quickstart - Guía paso a paso para configurar proveedores
- Validación de API keys en tiempo real
- Generación automática de dialplan
Gestión de Configuración
- CRUD completo para proveedores, pipelines, contextos
- Editor YAML con syntax highlighting (Monaco)
- Validación de configuración
- Respaldo y restauración
Logs en Vivo
- Streaming de logs vía WebSocket
- Filtrado por nivel (INFO, WARNING, ERROR)
- Búsqueda en tiempo real
- Descarga de logs
Autenticación JWT
- Login seguro con tokens
- Gestión de contraseñas
- Roles y permisos (próximamente)
Instalación y Acceso
# Iniciar Admin UI
docker compose up -d admin-ui
# Acceder en el navegador
http://localhost:3003
# Credenciales por defecto
Usuario: admin
Contraseña: admin
Importante: Cambia la contraseña por defecto inmediatamente después del primer login.
Arquitectura del Admin UI
┌───────────────┐
│ Frontend │ React + TypeScript
│ (Port 3003) │ Monaco Editor, Chart.js
└───────┬───────┘
│ HTTP/WS
┌───────▼───────┐
│ Backend │ Express + TypeScript
│ Auth JWT │ WebSocket para logs
└───────┬───────┘
│
┌───────▼───────┐
│ ai-engine │ Python FastAPI
│ /health │ Métricas + Logs
└───────────────┘
CLI Tools para Operaciones
El proyecto incluye herramientas CLI listas para producción:
Instalación del CLI
# Instalación con un comando (Linux/macOS/Windows)
curl -sSL https://raw.githubusercontent.com/hkjarral/Asterisk-AI-Voice-Agent/main/scripts/install-cli.sh | bash
# El binario se instala en ~/.asterisk-ai-voice-agent/bin/agent
# Se agrega automáticamente al PATH
Comandos Principales
agent quickstart Asistente interactivo de configuración:
agent quickstart
- Guía paso a paso para selección de proveedor
- Validación de API keys
- Test de conexión ARI con Asterisk
- Generación automática de dialplan
agent dialplan Genera snippets de configuración dialplan:
agent dialplan
Salida ejemplo:
[from-ai-agent]
exten => s,1,NoOp(Asterisk AI Voice Agent v4.4.1)
same => n,Stasis(asterisk-ai-voice-agent)
same => n,Hangup()
agent config validate Valida configuración YAML:
# Solo validar
agent config validate
# Validar y auto-corregir
agent config validate --fix
agent doctor Health check del sistema:
# Check completo
agent doctor
# Con auto-fix
agent doctor --fix
Verifica:
- Conectividad ARI
- Estado de contenedores Docker
- Validación de configuración
- API keys de proveedores
- Puertos y networking
agent troubleshoot Analiza llamadas específicas:
agent troubleshoot --call-id=<channel-id>
Muestra:
- Timeline completo de la llamada
- Estado de herramientas ejecutadas
- Errores y warnings
- Métricas de latencia
agent demo Demuestra características del sistema:
agent demo
Guía de Instalación Paso a Paso
Requisitos Previos
Sistema Operativo:
- Ubuntu 22.04/24.04 (recomendado)
- Debian 11/12
- RHEL/AlmaLinux 8/9
- CentOS Stream
Software:
- Docker 20.10+
- Docker Compose 2.0+
- Asterisk 18+ con ARI habilitado
- 4GB RAM mínimo (8GB recomendado para Local Hybrid)
Instalación en Asterisk Vanilla
Edita directamente /etc/asterisk/extensions.conf:
[from-internal]
exten => 5000,1,NoOp(AI Voice Agent Test)
same => n,Answer()
same => n,Stasis(asterisk-ai-voice-agent)
same => n,Hangup()
exten => 5000,n,Playback(vm-goodbye)
same => n,Hangup()
Configuración ARI en /etc/asterisk/ari.conf:
[general]
enabled = yes
pretty = yes
[asterisk]
type = user
read_only = no
password = SuperSecurePassword123
Configuración de Proveedores
OpenAI Realtime API
Obtener API Key:
- Visita https://platform.openai.com/api-keys
- Crea nuevo API key
- Copia y guarda de forma segura
Configuración en .env:
OPENAI_API_KEY=sk-proj-...
Configuración del modelo:
# config/ai-agent.yaml
llm:
provider: "openai_realtime"
model: "gpt-4o-realtime-preview-2024-12-17"
temperature: 0.8
max_tokens: 4096
initial_greeting: "Hola, soy tu asistente virtual. ¿En qué puedo ayudarte hoy?"
prompt: |
Eres un asistente telefónico profesional y amable.
Tu objetivo es ayudar a los llamantes de manera eficiente.
Habla de forma natural y conversacional.
Deepgram Voice Agent
Obtener API Key:
- Visita https://console.deepgram.com/
- Crea cuenta o inicia sesión
- Genera API key en la sección de credenciales
Configuración:
# .env
DEEPGRAM_API_KEY=your-deepgram-api-key
OPENAI_API_KEY=sk-proj-... # Para el LLM
# config/ai-agent.yaml
stt:
provider: "deepgram"
model: "nova-2-ea"
language: "es"
llm:
provider: "openai"
model: "gpt-4o-mini"
tts:
provider: "deepgram"
model: "aura-asteria-en"
Google Live API (Gemini)
Obtener credenciales:
- Visita https://console.cloud.google.com/
- Crea o selecciona proyecto
- Habilita Gemini API
- Genera API key
Configuración:
# .env
GOOGLE_API_KEY=your-google-api-key
# config/ai-agent.yaml
stt:
provider: "google_live"
llm:
provider: "google_live"
model: "gemini-2.0-flash-exp"
temperature: 0.8
tts:
provider: "google_live"
ElevenLabs Conversational AI
Setup de agente:
- Visita https://elevenlabs.io/app/conversational-ai
- Crea nuevo agente conversacional
- Copia el Agent ID
- Genera API key
Configuración:
# .env
ELEVENLABS_API_KEY=your-elevenlabs-api-key
ELEVENLABS_AGENT_ID=your-agent-id
# config/ai-agent.yaml
stt:
provider: "elevenlabs_conversational"
llm:
provider: "elevenlabs_conversational"
agent_id: "${ELEVENLABS_AGENT_ID}"
tts:
provider: "elevenlabs_conversational"
Local Hybrid (Privacidad Máxima)
No requiere API keys para STT/TTS, solo para el LLM:
# .env
OPENAI_API_KEY=sk-proj-... # Solo para LLM
Descargar modelos:
# El contenedor local-ai-server descarga automáticamente
# los modelos al iniciarse por primera vez
# Vosk (STT)
# - vosk-model-small-es-0.42 (~40MB)
# Piper (TTS)
# - es_ES-mls_10246-low (~15MB)
Configuración:
# config/ai-agent.yaml
stt:
provider: "vosk"
model: "vosk-model-small-es-0.42"
sample_rate: 8000
llm:
provider: "openai"
model: "gpt-4o-mini"
temperature: 0.7
tts:
provider: "piper"
model: "es_ES-mls_10246-low"
audio_format: "wav"
sample_rate: 22050
Monitoreo y Observabilidad
Métricas con Prometheus
El sistema expone 50+ métricas en el endpoint /metrics:
Métricas de llamadas:
# Total de llamadas
ai_agent_calls_total{status="completed"} 150
ai_agent_calls_total{status="failed"} 3
# Llamadas activas
ai_agent_active_calls 5
# Duración promedio
ai_agent_call_duration_seconds_sum / ai_agent_call_duration_seconds_count
Métricas de IA:
# Latencia de STT
ai_agent_stt_latency_seconds{provider="deepgram"}
# Tokens de LLM
ai_agent_llm_tokens_total{model="gpt-4o-mini",type="input"}
ai_agent_llm_tokens_total{model="gpt-4o-mini",type="output"}
# Latencia de TTS
ai_agent_tts_latency_seconds{provider="deepgram"}
Métricas de herramientas:
# Ejecuciones de herramientas
ai_agent_tool_executions_total{tool="transfer",status="success"}
ai_agent_tool_executions_total{tool="transfer",status="failed"}
# Latencia de herramientas
ai_agent_tool_latency_seconds{tool="transfer"}
Dashboards de Grafana
El sistema incluye 5 dashboards pre-configurados:
1. System Overview
- Estado general del sistema
- Llamadas activas y totales
- Uso de recursos (CPU, RAM, disco)
- Tasa de errores
2. Call Analytics
- Distribución de duración de llamadas
- Llamadas por hora/día
- Tasa de éxito vs fallos
- Llamadas concurrentes
3. AI Performance
- Latencia de cada componente (STT, LLM, TTS)
- Distribución de tiempos de respuesta
- Uso de tokens
- Errores por proveedor
4. Tool Execution
- Herramientas más usadas
- Tasa de éxito de transferencias
- Emails enviados
- Latencia de ejecución
5. Transport Metrics
- Calidad de audio (jitter, packet loss)
- Throughput de RTP
- Estadísticas de AudioSocket
- Errores de red
Acceso a Grafana
# Iniciar monitoreo si no está activo
docker compose -f docker-compose.monitoring.yml up -d
# Acceder a Grafana
URL: http://tu-servidor:3000
Usuario: admin
Contraseña: admin # Cambiar en primer login
# Los dashboards se importan automáticamente desde monitoring/grafana/dashboards/
Alertas Configuradas
Alertas críticas:
- Llamadas fallando (>5% en 5 minutos)
- CPU >80% durante 5 minutos
- Memoria >90%
- Disco <10GB libre
Alertas de advertencia:
- Latencia alta de IA (>5 segundos)
- Errores de herramientas (>10% en 15 minutos)
- Packet loss >2%
Configuración de alertas en monitoring/grafana/provisioning/alerting/.
Casos de Uso Reales
1. Recepcionista Virtual para Consultorio Médico
Requisitos:
- Privacidad HIPAA compliant
- Agendamiento de citas
- Manejo de emergencias
- Horario español
Configuración:
# config/ai-agent.yaml
pipeline: "local_hybrid" # Audio permanece local
llm:
provider: "openai"
model: "gpt-4o"
temperature: 0.6
initial_greeting: |
Buenos días, habla con la recepción del Consultorio Médico González.
¿En qué puedo ayudarle hoy?
prompt: |
Eres la recepcionista virtual del Consultorio Médico Dr. González.
FUNCIONES PRINCIPALES:
1. Agendar citas médicas (usa transfer a extensión 200)
2. Proporcionar información de horarios (Lunes a Viernes 9-18h)
3. Identificar emergencias y transferir al 112
4. Dar indicaciones para llegar a la clínica
REGLAS IMPORTANTES:
- NUNCA des consejos médicos
- Para emergencias, deriva inmediatamente
- Sé empático y profesional
- Confirma siempre nombre completo y teléfono
INFORMACIÓN DE LA CLÍNICA:
- Dirección: Calle Principal 123, Madrid
- Teléfono: +34 91 234 5678
- Email: info@consultoriogonzalez.es
tools:
enabled: true
available_tools:
- name: "transfer"
enabled: true
config:
allowed_destinations:
- type: "extension"
number: "200" # Recepcionista humana
- type: "extension"
number: "201" # Enfermería
- type: "queue"
number: "5000" # Cola médicos
Dialplan AsteriskPBX:
[from-pstn]
; Todas las llamadas entrantes al AI agent
exten => _X.,1,NoOp(Incoming call from ${CALLERID(num)})
same => n,Set(CHANNEL(language)=es)
same => n,GotoIf($["${CALLERID(num)}" = "112"]?emergency,s,1) ; Emergencias directas
same => n,Set(__TRANSFER_CONTEXT=from-internal)
same => n,Stasis(asterisk-ai-voice-agent)
same => n,Hangup()
[emergency]
exten => s,1,NoOp(Emergency call)
same => n,Dial(SIP/emergency-line)
same => n,Hangup()
Resultado:
- 90% de llamadas manejadas por IA
- Reducción de carga en recepción humana
- Disponibilidad 24/7
- Cumplimiento HIPAA (audio local)
- Costo: ~$0.002/minuto
2. Soporte Técnico de ISP
Requisitos:
- Troubleshooting básico
- Escalamiento a técnicos nivel 2
- Agendamiento de visitas técnicas
- Soporte multilingüe
Configuración:
# config/ai-agent.yaml
pipeline: "openai_realtime" # Respuestas rápidas
llm:
provider: "openai_realtime"
model: "gpt-4o-realtime-preview-2024-12-17"
temperature: 0.7
initial_greeting: |
Bienvenido al soporte técnico de FibraNet.
Soy su asistente virtual. ¿Con qué problema de conexión puedo ayudarle?
prompt: |
Eres un agente de soporte técnico de FibraNet ISP.
PROCEDIMIENTOS DE TROUBLESHOOTING:
1. Identifica el tipo de servicio (fibra, ADSL, móvil)
2. Verifica síntomas: sin conexión, lento, intermitente
3. Guía pasos básicos:
- Reinicio de router (desconectar 30 segundos)
- Verificar cables y luces LED
- Test de velocidad
ESCALAMIENTO:
- Problemas físicos → transferir a técnico nivel 2 (ext 300)
- Facturación → transferir a administración (ext 400)
- No resuelto en 5 minutos → escalar
AGENDA VISITAS:
- Usa herramienta transfer a cola 5100 (agendamiento)
Siempre pide número de cliente y valida servicio contratado.
tools:
enabled: true
available_tools:
- name: "transfer"
enabled: true
config:
allowed_destinations:
- type: "extension"
number: "300" # Técnico L2
- type: "queue"
number: "5100" # Agendamiento
- type: "extension"
number: "400" # Facturación
- name: "request_transcript"
enabled: true # Cliente puede pedir resumen por email
Integración con CRM:
# Webhook para actualizar ticket en CRM
# POST a /webhooks/ticket-update al finalizar llamada
import requests
@app.post("/webhooks/ticket-update")
async def update_crm_ticket(call_data: dict):
"""Actualiza CRM con resultado de llamada"""
ticket_data = {
"customer_id": call_data["caller_id"],
"issue_type": call_data["detected_issue"],
"resolution": call_data["resolution_status"],
"transcript": call_data["transcript"],
"duration": call_data["call_duration"],
"escalated": call_data["was_escalated"]
}
response = requests.post(
"https://crm.example.com/api/tickets",
json=ticket_data,
headers={"Authorization": f"Bearer {CRM_API_KEY}"}
)
return {"status": "updated", "ticket_id": response.json()["ticket_id"]}
Métricas alcanzadas:
- 70% de problemas resueltos por IA
- Tiempo medio de resolución: 3.5 minutos
- Satisfacción de cliente: 4.2/5
- Reducción de llamadas escaladas: 60%
- Costo: $0.35-0.50 por llamada
3. Sistema de Encuestas Post-Venta
Requisitos:
- Encuestas automáticas después de compra
- Detección de insatisfacción
- Escalamiento a atención al cliente
- Registro en base de datos
Configuración:
# config/ai-agent.yaml
pipeline: "deepgram" # Balance calidad/costo
llm:
provider: "openai"
model: "gpt-4o-mini"
temperature: 0.5
initial_greeting: |
Hola, le llamo de parte de TechStore para conocer su opinión
sobre su reciente compra. ¿Tiene un minuto para responder
una breve encuesta?
prompt: |
Eres un encuestador virtual de TechStore.
ENCUESTA (mantén conversación natural):
1. ¿Cómo califica la calidad del producto? (1-5)
2. ¿El tiempo de entrega fue satisfactorio? (Sí/No)
3. ¿Cómo fue su experiencia con nuestro servicio? (1-5)
4. ¿Recomendaría TechStore a amigos? (Sí/No)
5. ¿Algún comentario adicional?
DETECCIÓN DE PROBLEMAS:
- Calificación ≤2 en cualquier pregunta → mostrar empatía
- Cliente muy insatisfecho → ofrecer transferir con manager
- Problema grave → usar herramienta transfer inmediatamente
Al finalizar:
- Agradece participación
- Menciona que recibirán email con resumen
Mantén tono profesional pero amigable. Escucha activamente.
tools:
enabled: true
available_tools:
- name: "transfer"
enabled: true
config:
allowed_destinations:
- type: "queue"
number: "6000" # Cola customer service
- name: "send_email_summary"
enabled: true
config:
recipients:
- "surveys@techstore.com"
include_transcript: true
include_sentiment: true
Script de procesamiento:
# scripts/process_survey.py
import json
from datetime import datetime
async def process_survey_call(call_data: dict):
"""Procesa llamada de encuesta y extrae datos estructurados"""
# Analizar transcripción con LLM
analysis = await analyze_survey_transcript(
transcript=call_data["transcript"]
)
survey_data = {
"survey_id": call_data["call_id"],
"customer_id": extract_customer_id(call_data["caller_id"]),
"date": datetime.now().isoformat(),
"responses": {
"product_quality": analysis["ratings"]["product"],
"delivery_satisfaction": analysis["ratings"]["delivery"],
"service_rating": analysis["ratings"]["service"],
"would_recommend": analysis["would_recommend"],
"comments": analysis["extracted_comments"]
},
"sentiment_score": analysis["overall_sentiment"], # -1 a 1
"needs_followup": analysis["needs_followup"],
"escalated": call_data["was_transferred"]
}
# Guardar en base de datos
await db.surveys.insert_one(survey_data)
# Si necesita seguimiento, crear ticket
if survey_data["needs_followup"]:
await create_followup_ticket(survey_data)
return survey_data
async def analyze_survey_transcript(transcript: str) -> dict:
"""Usa LLM para extraer datos estructurados de la encuesta"""
prompt = f"""
Analiza esta transcripción de encuesta y extrae:
1. Calificaciones numéricas mencionadas (1-5)
2. Respuestas Sí/No
3. Comentarios textuales
4. Sentiment general (-1 negativo, 0 neutral, 1 positivo)
5. Si requiere seguimiento urgente
Transcripción:
{transcript}
Responde en JSON.
"""
# Llamada a OpenAI u otro LLM
response = await openai.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"}
)
return json.loads(response.choices[0].message.content)
Dialplan para llamadas outbound:
[survey-outbound]
exten => s,1,NoOp(Outbound Survey Call)
same => n,Set(CHANNEL(language)=es)
same => n,Wait(2) ; Dar tiempo al cliente a responder
same => n,Stasis(asterisk-ai-voice-agent,survey_context)
same => n,Hangup()
; Originate desde AMI o ARI
; Action: Originate
; Channel: PJSIP/customer_number@trunk
; Context: survey-outbound
; Exten: s
; Priority: 1
; Async: yes
Resultados:
- Tasa de completitud: 68% (vs 12% email)
- Tiempo promedio encuesta: 2.5 minutos
- Detección automática de problemas: 95%
- Costo por encuesta: $0.08-0.12
- ROI: 340% en 6 meses
Optimización y Tuning
Reducción de Latencia
1. Configuración de AudioSocket (Más Rápido)
AudioSocket tiene menor latencia que ExternalMedia RTP:
# config/ai-agent.yaml
audio_transport: "audiosocket" # vs "externalmedia"
audiosocket:
host: "0.0.0.0"
port: 9092
codec: "slin" # Linear PCM, sin compresión
Configuración Asterisk:
; extensions.conf
[from-ai-agent]
exten => s,1,NoOp()
same => n,Answer()
same => n,AudioSocket(40325ec2-5efc-4d74-bcd1-4e9a6969c285,server.example.com:9092)
same => n,Hangup()
Ventajas de AudioSocket:
- Streaming TCP directo
- Sin negociación RTP
- Latencia ~50-100ms menor
- Ideal para full agents (OpenAI Realtime, ElevenLabs)
2. Optimización de Pipeline Híbrido
Para Local Hybrid, estas configuraciones reducen latencia:
stt:
provider: "vosk"
model: "vosk-model-small-es-0.42" # Modelo pequeño pero rápido
sample_rate: 8000 # Menor sample rate = menos datos
llm:
provider: "openai"
model: "gpt-4o-mini" # Modelo más rápido
max_tokens: 150 # Respuestas más cortas
temperature: 0.7
stream: true # IMPORTANTE: streaming de respuestas
tts:
provider: "piper"
model: "es_ES-mls_9972-low" # Modelo low quality es más rápido
audio_format: "wav"
length_scale: 1.0 # Velocidad normal
noise_scale: 0.667
3. Barge-In (Interrupciones)
Configuración óptima para detección de habla durante respuesta de IA:
barge_in:
enabled: true
sensitivity: 0.5 # 0-1, más alto = más sensible
cooldown_ms: 500 # Milisegundos de silencio antes de permitir interrupción
min_speech_duration_ms: 300 # Duración mínima de habla para considerar interrupción válida
Calidad de Audio
Configuración para Máxima Calidad:
# Mejor calidad TTS
tts:
provider: "elevenlabs"
model_id: "eleven_multilingual_v2"
voice_settings:
stability: 0.5
similarity_boost: 0.75
style: 0.0 # 0 = consistente, 1 = expresivo
optimize_streaming_latency: 2 # 0-4, menor = mejor calidad
# Mejor calidad STT
stt:
provider: "deepgram"
model: "nova-2" # Modelo premium
language: "es"
smart_format: true # Puntuación automática
diarize: false
# Audio de alta resolución
audio:
sample_rate: 16000 # vs 8000
channels: 1
codec: "pcm_s16le"
Trade-offs:
- Mejor calidad = Mayor latencia (200-500ms adicionales)
- Mayor sample rate = Mayor ancho de banda
- Recomendado para aplicaciones premium
Reducción de Costos
Estrategia 1: Modelo Local + Cloud LLM (Híbrido)
pipeline: "local_hybrid"
# Audio procesado localmente (sin costo)
stt:
provider: "vosk" # Gratis
tts:
provider: "piper" # Gratis
# Solo LLM en cloud
llm:
provider: "openai"
model: "gpt-4o-mini" # $0.15/1M input, $0.60/1M output tokens
Costo estimado: $0.001-0.003 por minuto
Estrategia 2: Deepgram con Modelo Económico
stt:
provider: "deepgram"
model: "base" # vs "nova-2" premium
# base: $0.0043/min vs nova-2: $0.0059/min
tts:
provider: "deepgram"
model: "aura-asteria-en"
# $0.015/1K caracteres
llm:
provider: "openai"
model: "gpt-4o-mini" # vs "gpt-4o"
Costo estimado: $0.015-0.025 por minuto
Estrategia 3: Caching de Respuestas Frecuentes
# src/utils/response_cache.py
import hashlib
from typing import Optional
class ResponseCache:
"""Cache respuestas comunes para reducir llamadas a LLM"""
def __init__(self, redis_client):
self.cache = redis_client
self.ttl = 3600 # 1 hora
def get_cached_response(self, user_input: str) -> Optional[str]:
"""Busca respuesta en cache"""
key = self._generate_key(user_input)
return self.cache.get(key)
def cache_response(self, user_input: str, response: str):
"""Guarda respuesta en cache"""
key = self._generate_key(user_input)
self.cache.setex(key, self.ttl, response)
def _generate_key(self, text: str) -> str:
"""Genera key consistente para input similar"""
# Normalizar texto
normalized = text.lower().strip()
# Eliminar variaciones menores
normalized = re.sub(r'\s+', ' ', normalized)
# Hash
return f"response:{hashlib.md5(normalized.encode()).hexdigest()}"
# Uso en pipeline
@router.post("/process-utterance")
async def process(utterance: str):
# Intentar cache primero
cached = response_cache.get_cached_response(utterance)
if cached:
logger.info("Cache hit, skipping LLM call")
return {"response": cached, "from_cache": True}
# Si no está en cache, llamar a LLM
response = await llm.generate(utterance)
# Cachear respuesta
response_cache.cache_response(utterance, response)
return {"response": response, "from_cache": False}
Ahorro: 30-50% en costos de LLM para preguntas frecuentes
Monitoreo de Performance
Configurar alertas de latencia:
# monitoring/grafana/provisioning/alerting/latency-alerts.yaml
apiVersion: 1
groups:
- name: ai_latency
interval: 1m
rules:
- alert: HighSTTLatency
expr: ai_agent_stt_latency_seconds > 2.0
for: 5m
labels:
severity: warning
annotations:
summary: "Alta latencia en STT"
description: "Latencia de STT es {{ $value }}s (>2s)"
- alert: HighLLMLatency
expr: ai_agent_llm_latency_seconds > 3.0
for: 5m
labels:
severity: warning
annotations:
summary: "Alta latencia en LLM"
description: "Latencia de LLM es {{ $value }}s (>3s)"
- alert: HighTTSLatency
expr: ai_agent_tts_latency_seconds > 1.5
for: 5m
labels:
severity: warning
annotations:
summary: "Alta latencia en TTS"
description: "Latencia de TTS es {{ $value }}s (>1.5s)"
Dashboard de latencia:
-- Query Prometheus para percentiles de latencia
histogram_quantile(0.50,
rate(ai_agent_stt_latency_seconds_bucket[5m])
) as p50_stt,
histogram_quantile(0.95,
rate(ai_agent_stt_latency_seconds_bucket[5m])
) as p95_stt,
histogram_quantile(0.99,
rate(ai_agent_stt_latency_seconds_bucket[5m])
) as p99_stt
Troubleshooting Común
Problema 1: Llamadas No Entran a Stasis
Síntomas:
- Llamada suena pero no entra al agent
- Logs muestran: "Stasis application not found"
Diagnóstico:
# Verificar estado de ARI
asterisk -rx "ari show apps"
# Debe mostrar: asterisk-ai-voice-agent
# Verificar conexión del engine
docker compose logs ai-engine | grep -i "ari"
Solución:
# 1. Verificar credenciales ARI en .env
cat .env | grep ARI
# 2. Test de conexión ARI
agent doctor --check-ari
# 3. Reiniciar ai-engine
docker compose restart ai-engine
# 4. Verificar que el contenedor está corriendo
docker compose ps
Problema 2: Audio Entrecortado o Sin Audio
Síntomas:
- Se escucha audio con cortes
- Cliente no escucha al agent
- Agent no escucha al cliente
Diagnóstico:
# Verificar codec configurado
asterisk -rx "pjsip show endpoint <endpoint> | grep codec"
# Ver estadísticas RTP
asterisk -rx "rtp show stats"
# Revisar logs de transport
docker compose logs ai-engine | grep -i "audio\|rtp"
Solución para AudioSocket:
# config/ai-agent.yaml
audio_transport: "audiosocket"
audiosocket:
host: "0.0.0.0"
port: 9092
codec: "slin" # Importante: Linear PCM
buffer_size: 320 # Bytes por frame
; extensions.conf
[from-ai-agent]
exten => s,1,Answer()
same => n,AudioSocket(uuid,<IP>:9092) ; Reemplazar <IP>
same => n,Hangup()
Solución para ExternalMedia:
# config/ai-agent.yaml
audio_transport: "externalmedia"
rtp:
bind_address: "0.0.0.0"
port_range: "10000-20000"
codec: "ulaw" # o "alaw"
Verificar NAT/Firewall:
# Abrir puertos RTP
sudo firewall-cmd --add-port=10000-20000/udp --permanent
sudo firewall-cmd --reload
# Para AudioSocket
sudo firewall-cmd --add-port=9092/tcp --permanent
sudo firewall-cmd --reload
Problema 3: Alta Latencia en Respuestas
Síntomas:
- Agent tarda >5 segundos en responder
- Conversación se siente lenta
Diagnóstico:
# Ver métricas de latencia
agent troubleshoot --call-id=<id> --show-latency
# O desde Grafana
# Dashboard: AI Performance
# Panel: Response Time Breakdown
Análisis de componentes:
# Ver latencia por componente
import json
def analyze_call_latency(call_id: str):
"""Analiza latencia desglosada de una llamada"""
metrics = get_call_metrics(call_id)
breakdown = {
"stt_avg": metrics["stt_latency_avg"],
"llm_avg": metrics["llm_latency_avg"],
"tts_avg": metrics["tts_latency_avg"],
"network_avg": metrics["network_latency_avg"],
"total_avg": sum([
metrics["stt_latency_avg"],
metrics["llm_latency_avg"],
metrics["tts_latency_avg"],
metrics["network_latency_avg"]
])
}
# Identificar cuello de botella
bottleneck = max(breakdown.items(), key=lambda x: x[1])
print(f"Latencia total: {breakdown['total_avg']:.2f}s")
print(f"Cuello de botella: {bottleneck[0]} ({bottleneck[1]:.2f}s)")
print(json.dumps(breakdown, indent=2))
return breakdown
Soluciones:
# Si STT es el cuello de botella
stt:
provider: "deepgram" # Más rápido que Vosk local
model: "nova-2-general"
# Si LLM es el cuello de botella
llm:
model: "gpt-4o-mini" # vs "gpt-4o"
max_tokens: 150 # Limitar tokens
stream: true # Streaming de respuesta
# Si TTS es el cuello de botella
tts:
provider: "deepgram" # Más rápido que ElevenLabs
model: "aura-asteria-en"
Problema 4: Tools No Se Ejecutan
Síntomas:
- Agent menciona hacer algo pero no lo hace
- Transferencias no funcionan
- Emails no se envían
Diagnóstico:
# Verificar configuración de tools
agent config validate --check-tools
# Ver logs de ejecución de tools
docker compose logs ai-engine | grep -i "tool"
# Test específico de tool
pytest tests/integration/test_tools.py::test_transfer -v
Verificaciones:
- Schema de herramienta correcto:
# En el LLM provider, verificar schema
def get_tools_schema(self) -> list:
return [
{
"type": "function",
"function": {
"name": "transfer",
"description": "Transfer call to extension",
"parameters": {
"type": "object",
"properties": {
"destination": {"type": "string"},
"destination_type": {"type": "string"}
},
"required": ["destination"]
}
}
}
]
- Contexto de transferencia:
# config/ai-agent.yaml
tools:
enabled: true
transfer:
context: "from-internal" # Contexto Asterisk correcto
allowed_destinations:
- type: "extension"
pattern: "^[1-9][0-9]{3}$"
- Prompt del LLM incluye instrucciones:
llm:
prompt: |
Tienes acceso a las siguientes herramientas:
- transfer: Transferir llamada a extensión, cola o ring group
- send_email: Enviar email con transcripción
Usa estas herramientas cuando sea apropiado.
Ejemplo: Si cliente pide hablar con ventas, usa transfer.
Problema 5: Crash del Contenedor local-ai-server
Síntomas:
- Contenedor local-ai-server se reinicia constantemente
- Logs muestran "Killed" o "OOM"
Diagnóstico:
# Ver logs
docker compose logs local-ai-server --tail=100
# Verificar uso de recursos
docker stats local-ai-server
# Ver eventos del contenedor
docker events --filter container=asterisk-ai-voice-agent-local-ai-server-1
Causas comunes:
- Memoria insuficiente (OOM Killer):
# docker-compose.yml
services:
local-ai-server:
deploy:
resources:
limits:
memory: 4G # Aumentar de 2G a 4G
reservations:
memory: 2G
- Modelo muy grande:
# config/ai-agent.yaml
stt:
provider: "vosk"
model: "vosk-model-small-es-0.42" # vs "vosk-model-es-0.42" (grande)
- Múltiples instancias concurrentes:
# Limitar llamadas concurrentes en config/ai-agent.yaml
concurrency:
max_calls: 5 # Reducir de 10 a 5
queue_size: 20
Solución:
# 1. Aumentar memoria disponible
docker compose down
# Editar docker-compose.yml con límites más altos
docker compose up -d
# 2. Usar modelo más pequeño
cp config/ai-agent.golden-local-hybrid-small.yaml config/ai-agent.yaml
docker compose restart ai-engine
# 3. Verificar swap habilitado
sudo swapon --show
# Si no tiene swap:
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
Roadmap y Futuro
El proyecto está en desarrollo activo. Aquí están las características planificadas:
v4.5 (Q1 2025)
Características principales:
- ✅ Soporte completo de ElevenLabs Conversational AI
- ✅ Admin UI v1.0 con setup wizard visual
- ⏳ Integración con CRMs (Salesforce, HubSpot)
- ⏳ Soporte multi-tenant
- ⏳ API REST para gestión programática
Mejoras de herramientas:
- ⏳ Tool: SMS notification (Twilio integration)
- ⏳ Tool: Calendar scheduling (Google Calendar, Outlook)
- ⏳ Tool: Database queries (PostgreSQL, MySQL)
- ⏳ Tool: External API calls (generic webhook)
v5.0 (Q2 2025)
IA Avanzada:
- ⏳ Sentiment analysis en tiempo real
- ⏳ Detección de emociones en voz
- ⏳ Análisis automático de calidad de llamadas
- ⏳ Recomendaciones de mejora de prompts
Escalabilidad:
- ⏳ Kubernetes deployment manifests
- ⏳ Load balancing automático
- ⏳ Redis para estado compartido
- ⏳ Horizontal scaling de ai-engine
Monitoreo:
- ⏳ Integración con Datadog, New Relic
- ⏳ Dashboards específicos por caso de uso
- ⏳ Alertas ML para anomalías
- ⏳ Reportes automáticos ejecutivos
v5.5 (Q3 2025)
Proveedores Adicionales:
- ⏳ Azure Cognitive Services (STT/TTS)
- ⏳ Amazon Transcribe/Polly
- ⏳ IBM Watson
- ⏳ Anthropic Claude (LLM)
Funcionalidades:
- ⏳ Multi-idioma automático (detección de idioma)
- ⏳ Transcripción en vivo para supervisores
- ⏳ Grabación selectiva con consentimiento
- ⏳ Barge-in configurable por contexto
Contribuciones de la Comunidad
El proyecto está abierto a contribuciones. Áreas prioritarias:
-
Nuevos proveedores de IA
- Implementar nuevos STT/LLM/TTS providers
- Guía de implementación de providers
-
Herramientas adicionales
- Integración con servicios externos
- Guía de desarrollo de tools
-
Casos de uso verticales
- Configuraciones especializadas por industria
- Ejemplos documentados
-
Traducciones
- Documentación en otros idiomas
- Prompts y greetings localizados
Cómo contribuir:
- Lee CONTRIBUTING.md
- Únete al Discord
- Revisa issues abiertos
Conclusión
Asterisk AI Voice Agent representa un avance significativo en la democratización de agentes de voz inteligentes. Al combinar la flexibilidad de Asterisk con el poder de la IA moderna, el proyecto ofrece:
Ventajas Clave:
- Control Total: Infraestructura open source sin vendor lock-in
- Flexibilidad: Arquitectura modular que se adapta a tus necesidades
- Privacidad: Opción de procesar audio completamente local
- Costo-Efectivo: Desde $0.001/minuto con configuración híbrida local
- Listo para Producción: 5 configuraciones validadas y herramientas de operación
Casos de Uso Validados:
- Recepción virtual 24/7
- Soporte técnico automatizado
- Encuestas post-venta
- Agendamiento de citas
- Cualificación de leads
Comunidad Activa:
- 150+ estrellas en GitHub
- Desarrollo activo con releases mensuales
- Canal de Discord para soporte
- Documentación extensa y ejemplos
Si estás buscando implementar agentes de voz con IA en tu infraestructura Asterisk, este proyecto ofrece la base sólida que necesitas sin comprometer control ni privacidad.
Recursos Adicionales
Enlaces Importantes
Proyecto:
Guías Específicas:
Para Desarrolladores:
Demo en Vivo
Prueba el sistema llamando a: (925) 736-6718 (solo USA)
Presiona:
- 5 → Google Live API
- 6 → Deepgram Voice Agent
- 7 → OpenAI Realtime
- 8 → Local Hybrid
- 9 → ElevenLabs Agent
Comunidad y Soporte
Obtener Ayuda:
- Discord - Soporte comunitario en tiempo real
- GitHub Issues - Reportar bugs
- GitHub Discussions - Preguntas generales
Contribuir:
¿Te ha resultado útil este artículo? Comparte tu experiencia con Asterisk AI Voice Agent en los comentarios.
Licencia: MIT Autor del artículo: VozToVoice.org Fecha: Diciembre 2024 Proyecto: Asterisk AI Voice Agent por Haider Jarral
Comentarios recientes