
Compartir:
Guillaume es desarrollador senior de .Net en Vonage. Ha estado trabajando en .Net durante casi 15 años, mientras que en los últimos años se ha centrado en la defensa de Software Craftsmanship. Sus temas favoritos son la calidad del código, la automatización de pruebas, el mobbing y las katas de código. Fuera del trabajo, le gusta pasar tiempo con su mujer y su hija, hacer ejercicio o jugar.
Cómo me hice millonario con las API de Vonage
Tiempo de lectura: 7 minutos
Spoiler: En realidad no soy millonario.
Todos hemos soñado con ello: sentarnos en la silla caliente de 'Quién quiere ser millonariomirando fijamente la pregunta final, con el presentador esperando tu respuesta. Pero, ¿y si, en un mundo de multiversos y realidades alternativas, me fuera con un buen cheque en la mano?
¿Y si te dijera que he descubierto una forma de ganar? Cada. Cada. Time.
En este post, nos adentraremos por un momento en este universo alternativo, en el que las API de Vonage me hicieron millonario y nadie sospechó nada.
El atraco perfecto
En este universo, no soy sólo un concursante de un concurso: soy el cerebro del atraco perfecto. Una última pregunta me separa del gran premio. He guardado cuidadosamente mi último salvavidas, "Llama a un amigo", para este preciso momento. Lo que está en juego no podría ser mayor, pero estoy tranquilo. Tengo el control.
¿Por qué? Porque esta no es una llamada ordinaria.
Tengo un as en la manga: un amigo que sabe todo. En lugar de llamar a una persona real, he preparado algo un poco... poco convencional. El número que he dado al programa es un número de teléfono virtual que he comprado a Vonage.
En cuanto el presentador marca el número, comienza mi operación meticulosamente planificada. Nadie del público, ni siquiera el presentador, tiene ni idea de lo que ocurre entre bastidores. Una cadena de procesos automatizados, todos impulsados por las API de Vonage, cobra vida para proporcionarme la respuesta correcta.
El atraco perfecto no consiste sólo en salirse con la suya, sino en llevarlo a cabo con tanta facilidad que nadie se dé cuenta de que ha ocurrido algo inusual.
Permítanme explicarles cómo lo conseguí.
Insertar "risa malvada" aquí
Paso 1: Necesitamos un Numbers
Todo atraco empieza con las herramientas adecuadas; en este caso, necesitamos un número, uno virtual. ¿Por qué un número virtual? Porque es la clave para controlar el flujo de información, nos permite interceptar la llamada y manipularla a nuestro antojo. Admite tanto llamadas entrantes como salientes y mensajes. No se necesita ningún dispositivo ni intervención manual: basta con un número virtual y un webhook.
Un número virtual le permite recibir llamadas y desviarlas a cualquier lugar, incluso a un sistema automatizado. En este caso, la llamada desencadenará una serie de interacciones sin que nadie se dé cuenta de que es algo distinto a una llamada telefónica normal. Puede obtener más información sobre los Numbers virtuales aquí.
Más concretamente con Vonage, el proceso es relativamente sencillo. Puedes comenzar con la Voice API de Vonage para comprar un número y configurarlo para que apunte a un webhook de tu elección; en este caso, el webhook que manejará la llamada.
Cuando el anfitrión marque el número, la llamada se desviará automáticamente a nuestro webhook. A partir de ahí, empieza la verdadera diversión.
Paso 2: Nuestro hombre interior
Cuando el anfitrión marca el número, alguien tiene que coger el teléfono, ¿verdad? Pero al otro lado de la línea no está cualquiera. No, aquí es donde presentamos a nuestro hombre de adentro: Adam. Es un amigo de 40 años que vive en Londres, muy bien informado y dispuesto a ayudar con las preguntas más difíciles.
Pero aquí está el giro - Adam en realidad no existe. Es completamente sintético, y cobra vida gracias a la tecnología función de texto a voz (TTS) (TTS). Cuando el anfitrión llama, la voz de Adam se genera en tiempo real, y es tan suave y convincente que nadie sospecharía que no está hablando con una persona real.
Su voz relajada y natural y su acento londinense lo convierten en el cómplice perfecto.
// Our webhook
[HttpPost("answer")]
public IActionResult Answer()
{
// Creating a Talk action with Adam's greeting message
var talkAction = VoiceAdapter.MakeAdamTalk(GreetingsMessage);
...
// Return a call control object to define the call flow
return this.Ok(new Ncco(talkAction, ...));
}
public static TalkAction MakeAdamTalk(string text) =>
new TalkAction
{
Text = text,
Language = "en-GB",
Style = 6,
Premium = true, // Provides a more natural voice
};
private const string GreetingsMessage = "Adam here. What can I do for you?";Como se muestra en el fragmento de código, devolvemos un Objeto de Control de Llamada (NCCO) con un Hablar para que Adán hable. Cuando reciba la llamada, saludará al anfitrión con un mensaje, para que la conversación parezca auténtica desde la primera palabra.
Paso 3: Transcripción del texto
Nuestro infiltrado nos ha dado la bienvenida; es hora de compartir con él nuestra última pregunta. El siguiente paso en nuestro atraco es crítico: convertir mi pregunta hablada en texto. Para ello, utilizaremos la función conversión de voz a texto de la Voice API de Vonage.
En nuestro webhook, después de Adamtenemos que añadir un Voz para capturar mi pregunta.
[HttpPost("answer")]
public IActionResult Answer()
{
var talkAction = VoiceAdapter.MakeAdamTalk(GreetingsMessage);
var inputAction = new MultiInputAction
{
Type = [NccoInputType.Speech],
// Url where the transcription will be sent
EventUrl = apiUrl + "/Webhooks/asr"],
Speech = new SpeechSettings
{
Language = "en-GB",
MaxDuration = 20,
EndOnSilence = 2,
},
};
return this.Ok(new Ncco(talkAction, inputAction));
}
// Webhook that will receive the text transcription
[HttpPost("asr")]
public async Task<IActionResult> Speech(MultiInput speechResponse)
{
...
}Nuestro Objeto de Control de Llamada contiene ahora dos acciones que se ejecutarán en secuencia: Adam saludará al anfitrión y, a continuación, el sistema escuchará mi pregunta. Una vez que el sistema detecte que mi discurso ha terminado, ya sea por un periodo de silencio o por alcanzar la duración máxima, la transcripción se enviará al webhook que hemos configurado.
Aquí está la transcripción de mi pregunta:
¡Hola Adam! Mira, actualmente estoy en el juego "¿Quién quiere ser millonario?" con Jeremy Clarkson, y te estoy llamando como parte de mi último comodín "Llama a un amigo". Necesito tu ayuda con la pregunta final.
Aquí está: "Durante la Guerra Fría, ¿el gobierno de EE.UU. construyó un búnker para alojar al Congreso bajo qué campo de golf?".
A: TheBreakers B: TheGreenbrier C: Pinehurst D: TheBroadmoor
Este paso es absolutamente esencial. El texto son datos y, en este atraco, los datos lo son todo. Se pueden manipular, analizar y, lo que es más importante, pasar a la siguiente fase de nuestro plan.
Paso 4: El oráculo
Ahora que tenemos la transcripción textual de la pregunta, es hora de consultar a nuestra entidad omnisciente: GPT4. En este atraco, es nuestro oráculo, el que tiene todas las respuestas.
Una vez que la transcripción llega a nuestro webhook, enviamos el texto, junto con un mensaje personalizado, a GPT4. Este mensaje garantiza que la IA ofrezca la respuesta precisa que necesitamos para ganar, ya que Adam.
Contexto:
Estamos en el juego "Quién quiere ser millonario", y te llamo como parte de mi último comodín "Llama a un amigo".
Eres Adam, un hombre de 40 años que utiliza el lenguaje en-UK.
Tu respuesta debe parecer que realmente has cogido el teléfono para darme una respuesta, y fingir que piensas la respuesta.
Tu respuesta se transcribirá mediante texto a voz, así que evita todo lo que no diría una persona.
No hace falta que me saludes, y deséame luch por el partido al final de tu respuesta.
[HttpPost("asr")]
public async Task<IActionResult> Speech(MultiInput speechResponse) =>
await FetchQuestion(speechResponse.Speech.SpeechResults)
.MapAsync(aiAdapter.AskAsync)
.Map(VoiceAdapter.MakeAdamTalk)
.Map(this.Ok)
.IfNone(this.Ok(VoiceAdapter.MakeAdamTalk(FailedToUnderstandQuestion)));
private static Maybe<string> FetchQuestion(SpeechRecognitionResult[] results) =>
results.Length != 0 ? results.First().Text : Maybe<string>.None;
public Task<string> AskAsync(string question)
{
var client = new ChatGpt(
configuration["openai-key"] ?? throw new InvalidOperationException("Missing OpenAI key."),
new ChatGptOptions { Model = "gpt-4-turbo" });
return client.Ask(configuration["prompt"] + "\n" + question);
}
Gracias a nuestro prompt personalizado, el Oracle generará una respuesta de texto donde Adam parece estar reflexionando sobre la respuesta. Tanto si se trata de un hecho histórico complejo como de un trivial complicado, generará la respuesta perfecta, lista para ser entregada en AdamVoice.
He aquí la respuesta a mi pregunta:
Hmm... eso es difícil. Déjame pensar...
Recuerdo haber leído sobre esto hace un tiempo.
No creo que sea The Breakers o Pinehurst, esos no me parecen bien.
Me inclino por The Greenbrier, si no me equivoco.
Sí, estoy bastante seguro de que es B: The Greenbrier.
Es el que usaban para el Congreso durante la Guerra Fría.
Buena suerte, ¡espero que lo consigas!
Sin embargo, hay una advertencia: estas cosas no suceden tan rápido como chasquear los dedos. Consideremos nuestro escenario:
Entrego mi pregunta.
Tras dos segundos de silencio, la transmisión de voz se transcribe en texto.
La pregunta se envía a GPT, que genera la respuesta.
Nos enfrentamos a una latencia potencial de entre cinco y diez segundos antes de recibir la respuesta. Es un tiempo precioso que puede poner en peligro todo mi plan.
Una posible solución técnica sería recurrir a API en tiempo real de OpenAIque se ha publicado recientemente. Pero, por desgracia, eso es un lujo de tiempo que no tengo.
En su lugar, he pensado en una solución inteligente: charla trivial. Sé que a Jeremy Clarkson le encanta su Ford GT40, y si saco el tema a colación, puedo conseguir que hable. Su entusiasmo por los coches me dará los segundos que necesito para que la IA genere la respuesta.
¿Y cuando esté listo? Enviamos un Talk con la respuesta como respuesta a nuestro endpoint, y Adam entregará con confianza la respuesta correcta al host.
Paso 5: La victoria
Con la respuesta en la mano, repito Adam"B: The Greenbrier" - de vuelta al anfitrión, tranquilo como siempre. Y así de fácil, ¡he ganado!
Desde fuera, nadie sospecha nada. Para el público, parece como si hubiera llamado a un ser humano que vive y respira y que casualmente conoce todas las respuestas. Lo que no saben es que todo ha sido posible gracias a las API de Vonage, un poco de IA y, lo más importante, creatividad.
El atraco perfecto no tenía que ver con las herramientas, sino con cómo las usaba.
Resumen
Volviendo a la realidad, obviamente no soy millonario, ni un cerebro criminal.
En realidad, mi plan tiene muchos agujeros. Para empezar, tendría que asegurarme de que el anfitrión no le hace a Adam ninguna pregunta de seguimiento o, peor aún, de que llama al número antes del momento final. El flujo de trabajo que he establecido también es bastante rígido: Saludo → Pregunta → Respuesta. Si nos desviamos de eso, todo el plan se viene abajo.
Y, por supuesto, ¡está la pequeña cuestión de llegar a la pregunta final! No tengo los conocimientos necesarios para responder a 14 preguntas en "Quién quiere ser millonario"; quizá alguna de mis variantes multiversales sí, pero desde luego yo no.
Desde el punto de vista técnico, puede que Speech-to-text y Text-to-speech no sean tecnologías nuevas, pero siguen siendo increíblemente útiles. Sin embargo, lo realmente importante de este artículo es la automatización: conectar plataformas como Vonage y OpenAI para crear un flujo de trabajo específico. No se trata solo de utilizar herramientas de vanguardia, sino de cómo combinarlas para crear algo único.
Como siempre, no dudes en ponerte en contacto conmigo en mi cuenta de LinkedIn o únete a nosotros en Slack para desarrolladores de Vonage. También puedes enviarnos un mensaje en @VonageDev en X.
Feliz codificación, ¡y hasta luego!
Compartir:
Guillaume es desarrollador senior de .Net en Vonage. Ha estado trabajando en .Net durante casi 15 años, mientras que en los últimos años se ha centrado en la defensa de Software Craftsmanship. Sus temas favoritos son la calidad del código, la automatización de pruebas, el mobbing y las katas de código. Fuera del trabajo, le gusta pasar tiempo con su mujer y su hija, hacer ejercicio o jugar.