Integración de Verbio en Asterisk
Miércoles, Mayo 23rd, 2007
Verbio es un sistema de reconocimiento y síntesis de voz (ASR y TTS) independiente del locutor. Mediante un AGI podemos llamar a Verbio para así crear un IVR controlado mediante voz en vez de marcaciones.
Usando las diferentes gramáticas que nos ofrece Verbio o las creadas por nosotros mismos, podemos reconocer teléfonos, DNI, nombres y lo que se nos ocurra. Esto permite una interacción mucho más natural con nuestra centralita Asterisk que la típica marcación para navegar un menú.
Supondremos Verbio instalado y configurado ya en nuestro servidor por lo que no hablaremos de la configuración de Verbio. Eso sería material de otro artículo.
Un ejemplo sencillo: La centralita da un mensaje de bienvenida a una llamada entrante. Pide el nombre de Juan o de Pepe para transferir a la extensión adecuada o se disculpa y pide de nuevo el nombre si no ha entendido lo dicho.
DIALPLAN:
exten => 888,1,NoOp(Llamada entrante)
exten => 888,n,Playback(bienvenido_diga_nombre)
exten => 888,n,Goto(889,1)
exten => 889,1,AGI(ASR.agi|nombres.txt|ISOLATED|2|5000)
exten => 889,n,GotoIf($[$[${VASR_RESULT} != ERROR] & $[${VASR_SCORE}>${UMBRAL}]]?400,1:401,1)
;
;Si no hay error en el reconocimiento
;si juan vete a juan y si no vete a pepe
exten => 400,1,n,GotoIf($[${VASR_RESULT} = JUAN]?200,1:201,1)
;
;Si hay error en el reconocimiento disculpas y vuelve al ASR
exten => 401,1,Playback(no_he_entendido_repita)
exten => 401,n,Goto(889,1)
;
exten => 200,1,NoOp(Extension de Juan)
exten => 201,1,NoOp(Extension de Pepe)
;
;si queremos tts
exten => xxx,1,AGI(TTS.agi|es|laura|Hola mundo hoy es ${DIA_DE_LA SEMANA})
El ASR.agi es un script que recibe como parámetro el tipo de gramática así como el fichero de gramática que vamos a usar. De esta forma, podemos usar el mismo AGI para interpretar nombres, números…
Su funcionamiento es muy simple: Graba lo que el usuario ha dicho, ejecuta el cliente de verbio para ASR y devuelve el valor reconocido así como una puntuación que nos indica lo fiable que ha sido el reconocimiento. Estos valores son los que utilizamos en el dialplan para saltar a una u otra extensión.
ASR.agi:
-
#!/usr/bin/perl
-
use strict;
-
#
-
$|=1;
-
#
-
# Setup some variables
-
my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;
-
#
-
#
-
#Recogemos las cosas que nos pasa asterisk
-
while() {
-
$AGI{$1} = $2;
-
}
-
}
-
#
-
#Ahora unas cuantas variables mas
-
my $uid = "$AGI{uniqueid}";
-
my $asr_cfg = "es";
-
my $lang = "es";
-
my $voc_file = $ARGV[0];
-
my $gram_type = $ARGV[1];
-
my $rectime = $ARGV[3];
-
my $vf2t_cmd = "verbiof2t";
-
my $result = 0;
-
my $basedir = "/var/lib/asterisk/verbio";
-
my $vf2tpath = "/usr/bin";
-
my $verbiowavedir = "audio";
-
my $myrecpath = "$basedir/$verbiowavedir";
-
my $voc_path = "$basedir/gram";
-
my $myrecfile = "verbio-rec-$ruid";
-
my $codec = "alaw";
-
my $skip = "0";
-
my $silence = $ARGV[3]
-
my $offset = "0";
-
my $voxserver = "127.0.0.1";
-
#
-
#
-
#Vamos a grabar lo que se dice
-
print "RECORD FILE $myrecpath/$myrecfile $codec $stoprec $rectime $offset $playbeep s=$silence n";
-
my $result = <STDIN> ;
-
#
-
#
-
# Creamos el comando de reconocimiento
-
my $comando = "/usr/bin/verbiof2t -l $lang -g $voc_path/$voc_file -t $gram_type -f $myrecpath/$myrecfile.$codec -c $codec -d $ruid -s $voxserver -k $skip";
-
#ahora ejecutamos el comando
-
my $result = <STDIN> ;
-
#
-
my $data = ;
-
close VF2T;
-
#
-
my $exit_value=$? >>8;
-
if( $exit_value != 1)
-
{
-
print "SET VARIABLE VASR_RESULT \"ERROR\"n";
-
exit;
-
}
-
#
-
#
-
#Quitar espacios de las variables
-
#
-
#Redondeo del score
-
#
-
#Seteamos las variables de asterisk
-
print "SET VARIABLE VASR_INDEX $datax[0]n";
-
print "SET VARIABLE VASR_RESULT $datax[1]n";
-
print "SET VARIABLE VASR_SCORE $datax[2]n";
-
#
-
#
-
#
-
#borramos ficheros temporales y salimos
-
exit;
Se puede ver que el script setea las variables VASR_RESULT con el resultado del ASR y VASR_SCORE con la puntuación obtenida. En el dialplan se comprueba que el resultado no sea ERROR y que la puntuación supere un cierto umbral de fiabilidad para que el ASR se considere correcto.
En este ejemplo hemos usado el tipo de gramática ISOLATED y un fichero de gramática nombres.txt. EL fichero de gramática es muy sencillo: Es un fichero de texto con las salidas del ASR asociadas a las entradas esperadas y separadas mediante un tabulador:
NOMBRES.TXT:
JUAN juan
PEPE pepe
Es importante observar, que sea cual sea la entrada del usuario, Verbio lo interpretará como una de las entradas esperadas y por lo tanto, aunque se diga patata, Verbio nos devolverá JUAN o PEPE. Naturalmente, la puntuación del reconocimiento será menor y podemos dar por inválido el reconocimiento en el dialplan al no haber superado ${UMBRAL}.
El valor de UMBRAL es algo que se ha de estimar después de hacer pruebas, pero un valor de 25-30 para una gramática ISOLATED de este ejemplo es una buena aproximación.
La parte del TTS es casi idéntica a la de ASR: Un script que genera un fichero de audio a partir del texto que se le pasa como parámetro y que lo reproduce.
TTS.agi:
-
#!/usr/bin/perl
-
use strict;
-
#
-
$|=1;
-
my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;
-
#
-
#
-
#Recogemos las cosas que nos pasa asterisk
-
while() {
-
$AGI{$1} = $2;
-
}
-
}
-
#
-
#Ahora unas cuantas variables
-
my $uid = "$AGI{uniqueid}";
-
my $language = $ARGV[0];
-
my $speaker = $ARGV[1];
-
my $text = $ARGV[2];
-
my $textfile = "verbio-tts-$ruid.txt";
-
my $wavefile = "verbio-tts-$ruid";
-
my $result = 0;
-
my $basedir = "/var/lib/asterisk/verbio";
-
my $verbiowavedir = "audio";
-
my $verbiotextdir = "text";
-
my $text2filedir = "/usr/bin";
-
my $vt2f_cmd = "verbiot2f";
-
my $voxserver = "127.0.0.1";
-
my $codec = "alaw";
-
my $sounddir = "$basedir/$verbiowavedir";
-
my $textfiledir = "$basedir/$verbiotextdir";
-
#
-
#
-
# Vamos a crear un fichero de texto con los parametros que nos pasa el asr por medio de asterisk
-
print fileOUT "$text";
-
#
-
#Generamos el fichero audio para poder reproducirlo
-
my $comando = $text2filedir."/$vt2f_cmd -l $language -k $speaker -t $textfiledir/$textfile -f $sounddir/$wavefile -c $codec -d $ruid -s $voxserver";
-
#
-
#
-
my $filetoplay = $sounddir."/".$wavefile;
-
print "STREAM FILE $filetoplay \"#\"n";
-
#
-
exit;
Con esto ya tenemos una implementación sencilla de Verbio integrado en Asterisk. Hacer un menú personalizado, mejorar los TTS con el uso de variables y usar diferentes gramáticas es trivial a partir de este punto.
Para terminar con este post sólo queda comentar lo bueno y lo malo de mis primeras experiencias con Verbio y Asterisk.
LO BUENO:
- Verbio es independiente del locutor y no requiere entrenamiento previo para reconocer voces en un ASR.
- El reconocimiento tiene muy buen desempeño en ficheros de gramática pequeños.
- El servicio técnico de Verbio ha sido sencillamente genial en cada llamada que le hemos hecho con dudas y problemas.
- Desarrollado por empresa catalana, verbio ofrece gramáticas para castellano, euskera, gallego y catalán entre otras.
LO MALO:
- Las gramáticas buit-in de Verbio no se han comportado tan bien como la ISOLATED. En concreto, la de telefonía, aunque reconoce muy bien el número dado, no devuelve un score fiable.
- La documentación que viene con Verbio es insuficiente y anticuada.
- Los paquetes debian que hemos usado eran rpm “alienizados”. Faltaba una librería que hubo que pedir al servicio técnico de Verbio.
- Verbio no es software libre.
CONCLUSIONES
Por las pruebas que hemos hecho, se puede usar verbio para un IVR controlado por voz o para recoger datos de clientes que llamen para dejarlos (un concurso o una reserva de billetes por ejemplo) siempre y cuando haya una extensión con un operador humano que coja las llamadas fallidas.
Hemos comprobado que muy por encima del error técnico (fallos de reconocimiento o de la centralita) esta el error social: Mucha gente no se siente cómoda hablando con un operador artificial y no hace caso de las instrucciones, por muy sencillas que estas sean; esta gente ha de tener el recurso de poder acceder a un operador humano. Aún no se puede dejar todo en manos de la máquina.
ACTUALIZACIÓN: Ahora ya hay una forma de usar verbio directamente desde dialplan sin necesidad de usar AGIs. En este mismo blog se puede encontrar una entrada al respecto.
