Curso
API de audio de OpenAI: Una guía con proyecto de demostración
OpenAI ha presentado su próxima generación de modelos de audio centrados en mejorar las capacidades de voz a texto y de texto a voz. Estos últimos modelos prometen una mayor precisión, especialmente en situaciones complejas como acentos o entornos ruidosos, y ofrecen interacciones de voz más personalizables.
En este tutorial, te explicaré paso a paso cómo utilizar estos nuevos modelos de audio de OpenAI para construir un asistente de IA de voz a voz. Nuestro objetivo es desarrollar un asistente de inteligencia artificial capaz de comprender la voz hablada y responder con una voz sintetizada de forma natural y adaptada a necesidades específicas.
Desarrollar aplicaciones de IA
La API de audio de OpenAI
Esta nueva versión de OpenAI incluye tres modelos:
gpt-4o-mini-tts
: Un modelo de texto a audio capaz de generar audio a partir de texto con varios tonos y voces. Una característica interesante de este modelo de texto a voz es que podemos guiar cómo suena la voz dando instrucciones de texto específicas. Esto aporta un alto nivel de personalización, permitiendo la creación de experiencias de voz únicas y a medida. Puedes probarlo en OpenAI.fm.-
gpt-4o-transcribe
ygpt-4o-mini-transcribe
: Dos modelos audio-texto diseñados para convertir el lenguaje hablado en texto escrito. Su función principal es proporcionar transcripciones de audio muy precisas y fiables. Estos modelos demuestran una tasa de error de palabra (WER) más baja, lo que significa que cometen menos errores al reconocer palabras habladas en comparación con las soluciones anteriores.
Estos nuevos modelos tienen los siguientes precios:
Proyecto Asistente de Voz
En este tutorial, te guiaré en la creación de un asistente de voz con IA directamente en tu terminal. Este asistente de voz imitará esencialmente un popular modelo de IA basado en texto, pero interactuará totalmente a través del lenguaje hablado. Imagina poder hablar directamente a tu ordenador, hacer cualquier pregunta que tengas y recibir una respuesta vocal casi al instante.
Nuestro proyecto utilizará una arquitectura sencilla pero eficaz. Empezaremos utilizando tu micrófono para captar tu mensaje hablado. Una vez grabada, convertiremos esta entrada de audio en texto con la ayuda de modelos avanzados de conversión de voz a texto.
A continuación, este texto se introduce en un gran modelo lingüístico para generar una respuesta adecuada. Por último, convertiremos la respuesta de texto en audio, para que el asistente te "diga" la respuesta. Cada paso de este proceso está diseñado para garantizar que nuestro asistente de voz sea preciso y atractivo.
Aunque OpenAI ofrece una API en tiempo real que puede mejorar las interacciones agilizando todo el proceso, optaremos por un enfoque diferente. La API en tiempo real, aunque es impresionante y perfecta para los desarrolladores que buscan integraciones rápidas, suele ser más costosa y ofrece menos flexibilidad.
Al elegir construir nuestro proyecto utilizando componentes separados para cada paso, obtenemos un mayor control sobre la personalización de nuestro asistente de IA. Este enfoque nos permite decidir los modelos que queremos utilizar, optimizando así para necesidades específicas, ya sea la precisión, la velocidad o la preferencia en el tono de respuesta. De este modo, nuestro asistente de voz se convierte no sólo en una potente herramienta, sino también en una herramienta muy personalizada, capaz de adaptarse a los requisitos únicos de cada proyecto.
Todo el código que desarrollamos aquí está disponible en este repositorio de GitHub.
Configuración de Python
Para empezar, primero configuraremos un nuevo entorno Anaconda llamado audio-demo
. Los entornos de Anaconda nos permiten crear espacios aislados para cada proyecto en los que podemos instalar versiones específicas de paquetes sin conflictos. Ejecuta los siguientes comandos en tu interfaz de línea de comandos:
conda create -n audio-demo -y python=3.9
conda activate audio-demo
pip install openai
pip install numpy
pip install dotenv
pip install sounddevice
pip install scipy
Veamos qué hace cada comando y cada paquete:
- Crear el entorno:
conda create -n audio-demo -y python=3.9
: Este comando crea un nuevo entorno llamadoaudio-demo
con la versión 3.9 de Python. La bandera-y
acepta automáticamente la instalación de paquetes sin preguntar.
- Activar el entorno:
conda activate audio-demo
: Activa el entornoaudio-demo
recién creado, para que podamos trabajar en él.
- Instalar paquetes:
pip install openai
: OpenAI es una biblioteca que facilita el acceso a los modelos y API de OpenAI.pip install numpy
: NumPy es una biblioteca esencial para la computación numérica.pip install dotenv
: Dotenv ayuda a cargar variables de entorno desde un archivo.env
, facilitando y haciendo más segura la gestión de la configuración.pip install sounddevice
: Sounddevice nos permite grabar y reproducir sonido mediante funciones sencillas, lo que es ideal para manejar la entrada y salida de audio en Python.pip install scipy
: SciPy se basa en NumPy y proporciona funciones adicionales para la informática científica y técnica, como el procesamiento de señales. En nuestro caso, lo utilizaremos para almacenar el archivo de audio.
Con nuestro entorno audio-demo
configurado, estamos listos para empezar a trabajar en nuestro asistente de IA que puede procesar entradas de audio. Esta configuración estructurada nos ayuda a mantener un espacio de desarrollo limpio, asegurándonos de que todas las dependencias están en su sitio para nuestro proyecto.
Configuración de la clave API de IA Abierta
Para utilizar la API de OpenAI, necesitamos una clave API. Ir a su página de clave API y genera una clave API haciendo clic en el botón "Generar nueva clave secreta". Copia la clave, crea un archivo llamado .env
, y pégala allí con el siguiente formato:
OPENAI_API_KEY=<paste_your_api_key_here>
Ejemplo de conversión de texto a audio
Vamos a recorrer los pasos para crear un script en Python que utilice las capacidades de conversión de texto a audio de OpenAI, transformando el texto en voz con un toque personalizado. Escribimos nuestro código en un archivo llamado text_to_audio.py
en la misma carpeta que el archivo .env.
.
Importa las bibliotecas necesarias
En primer lugar, tenemos que importar las bibliotecas necesarias que compondrán nuestro script:
import asyncio
from openai import AsyncOpenAI
from openai.helpers import LocalAudioPlayer
from dotenv import load_dotenv
Veamos rápidamente qué hace cada una de estas importaciones:
asyncio
: Esta biblioteca es necesaria para escribir código asíncrono en Python, que es esencial para trabajar con APIs de streaming.AsyncOpenAI
: Forma parte de la biblioteca OpenAI y proporciona herramientas para interactuar con las API de OpenAI de forma asíncrona.LocalAudioPlayer
: Este ayudante de OpenAI nos permite reproducir audio localmente en nuestra máquina.load_dotenv
: Carga variables de entorno del archivo.env
, que es donde almacenamos información sensible como nuestras claves API.
Cargar variables de entorno
A continuación, cargamos nuestra clave API desde el archivo .env
utilizando la función load_dotenv
:
load_dotenv()
Esto garantiza que nuestro script tenga acceso seguro a la clave API.
Inicializar OpenAI
Creamos una instancia de AsyncOpenAI
para empezar a interactuar con la API de OpenAI:
openai = AsyncOpenAI()
Escribe la función principal
Ahora definimos nuestra función principal, text_to_audio()
, que utilizará la función de conversión de texto en audio de OpenAI para procesar la entrada y reproducir el audio resultante:
async def text_to_audio(text, tone_and_style_instructions):
async with openai.audio.speech.with_streaming_response.create(
model="gpt-4o-mini-tts",
voice="coral",
input=text,
instructions=tone_and_style_instructions,
response_format="pcm",
) as response:
await LocalAudioPlayer().play(response)
Vamos a explicar rápidamente lo que hicimos arriba:
- Especificamos los parámetros
model
yvoice
para controlar la síntesis del habla. Elmodel
utilizado esgpt-4o-mini-tts
y la voz seleccionada es "coral". - El
response_format
está ajustado a"pcm"
, adecuado para el procesamiento de audio. - A continuación,
LocalAudioPlayer
reproduce la respuesta de audio generada por la API.
Ejecuta la función
Completamos el script con las siguientes líneas para asegurarnos de que la función text_to_audio()
se ejecuta cuando ejecutamos el script:
if __name__ == "__main__":
asyncio.run(text_to_audio("Hello world!", "Enthusiastic voice."))
Este bloque de código comprueba si el script es el módulo principal que se está ejecutando y ejecuta la función text_to_audio()
utilizando asyncio.run()
para manejar la lógica asíncrona.
Con estos pasos, nuestro script está listo para convertir la entrada de texto en voz utilizando el servicio de conversión de texto a audio de OpenAI. Esta configuración nos permite experimentar con diferentes entradas y estilos, dando vida al texto a través del sonido.
Podemos ejecutar el script utilizando el comando
python text_to_audio.py
Puedes encontrar el código completo aquí.
Transcripción de audio de un archivo
En esta sección, vamos a explorar cómo transcribir un archivo de audio a texto utilizando la herramienta de transcripción de audio de OpenAI. Nuestro script está diseñado para manejar archivos de audio de forma asíncrona para que el proceso sea eficaz y rápido. Implementaremos este script en un archivo llamado audio_to_text.py
.
Las importaciones y la configuración inicial son las mismas que antes, salvo que aquí no necesitamos importar el LocalAudioPlayer
. Así es como podemos escribir una función que transcriba un archivo de audio:
async def transcribe_audio(audio_filename = "audio.wav"):
audio_file = await asyncio.to_thread(open, audio_filename, "rb")
stream = await openai.audio.transcriptions.create(
model="gpt-4o-mini-transcribe",
file=audio_file,
response_format="text",
stream=True,
)
transcript = ""
async for event in stream:
if event.type == "transcript.text.delta":
print(event.delta, end="", flush=True)
transcript += event.delta
print()
audio_file.close()
return transcript
Vamos a desglosar lo que ocurre aquí:
- Abrir el archivo de audio:
audio_file = await asyncio.to_thread(open, audio_filename, "rb")
: Esta línea abre el archivo de audio en modo de lectura binario ("rb"
). El métodoasyncio.to_thread()
permite que esta operación de apertura de archivos se ejecute en un hilo independiente, evitando que bloquee otras partes del programa.
- Crear un flujo de transcripción:
stream = await openai.audio.transcriptions.create(...)
: Esta línea llama a la API de transcripción.- Especificamos el parámetro
model
comogpt-4o-mini-transcribe
, diseñado específicamente para tareas de transcripción. - El parámetro
file
contiene nuestro archivo de audio abierto. response_format="text"
indica a la API que devuelva la transcripción como texto.stream=True
se utiliza para transmitir la transcripción en tiempo real, lo que significa que en cuanto se procesa una parte del audio, se devuelve inmediatamente, acelerando la respuesta.
- Procesar el flujo de transcripción:
async for event in stream
: Inicia un bucle para leer los eventos del flujo de transcripción a medida que se producen.if event.type == "transcript.text.delta":
: Comprueba cada tipo de evento y procésalo si es del tipotranscript.text.delta
, que indica que una parte de la transcripción está lista.print(event.delta, end="", flush=True)
: Imprime la transcripción incremental a medida que esté disponible, garantizando que nuestra salida sea en tiempo real.
- Cerrar el archivo de audio:
audio_file.close()
: Cuando terminemos la transcripción, es una buena práctica cerrar el archivo de audio para liberar recursos del sistema.
Ejecutando la función main()
, podemos convertir un archivo de audio en texto de forma eficaz y procesarlo en flujo para obtener una respuesta inmediata. Esta configuración es ideal para aplicaciones que necesitan una transcripción rápida o que implican archivos de audio largos.
Puedes probarlo colocando un archivo de audio en la misma carpeta que el script, sustituyendo audio.wav
por el nombre de tu archivo de audio y ejecutando el comando:
python audio_to_text.py
Puedes encontrar el código completo aquí.
Transcripción de audio desde el micrófono
Como nuestro objetivo es crear un asistente de voz, necesitamos grabar la petición de audio del usuario en un archivo de audio.
Crearemos un nuevo archivo llamado record.py
con una función llamada record_audio
. Esta función captura el sonido del micrófono y lo guarda como un archivo de audio. No entraremos en muchos detalles sobre su funcionamiento porque no es el tema principal de este artículo:
import sounddevice as sd
import numpy as np
import scipy.io.wavfile as wavfile
SAMPLE_RATE = 44100 # Sample rate in Hz
def record_audio():
print("[INFO: Recording... Press <Enter> to stop]")
audio_data = [] # Initialize a list to store audio frames
def callback(indata, frames, time, status):
audio_data.append(indata.copy())
with sd.InputStream(samplerate=SAMPLE_RATE, channels=1, callback=callback, dtype='int16'):
input() # Wait for the user to press Enter to stop recording
print("[INFO: Recording complete]")
print()
audio_data = np.concatenate(audio_data) # Concatenate the list into a single array
filename = "output.wav"
wavfile.write(filename, SAMPLE_RATE, audio_data)
return audio_data
Cuando llamemos a esta función, empezará a grabar desde el micrófono del usuario. Espera a que el usuario pulse "Intro" y luego guarda el audio en un archivo con el nombre de archivo dado.
Para probarlo, podemos combinar esta función con la función de transcripción anterior para transcribir un mensaje hablado por el usuario. Así es como podemos crear un nuevo archivo llamado record_and_transcribe.py
para ponerlo en práctica:
import asyncio
from audio_to_text import transcribe_audio
from audio_recorder import record_audio
async def main():
record_audio("prompt.wav")
await transcribe_audio("prompt.wav")
if __name__ == "__main__":
asyncio.run(main())
Puedes intentar ejecutarlo utilizando el comando python record_and_transcribe.py
. El guión grabará lo que digas hasta que pulses "Intro" y luego transcribirá lo que has dicho.
Construir un asistente de audio
En esta sección, lo unimos todo para construir un asistente de audio. Lo implementamos en un nuevo archivo llamado audio_assistant.py
siguiendo estos pasos:
- Graba la indicación de audio del usuario utilizando la función
record_audio()
. - Convierte la indicación de audio en texto con la función
transcribe_audio()
. - Utiliza un modelo normal de texto a texto como
gpt-4o
para generar una respuesta. - Por último, convierte la respuesta textual en audio utilizando la función
text_to_audio()
. - Repítelo hasta que el usuario salga.
El siguiente diagrama lo ilustra:
Te animo a que intentes construirlo tú mismo antes de seguir leyendo.
En primer lugar, importamos las funciones que implementamos antes e inicializamos el cliente OpenAI.
# Import the functions we created
from text_to_audio import text_to_audio
from audio_to_text import transcribe_audio
from audio_recorder import record_audio
# Import other dependencies and initialize OpenAI
import asyncio
from openai import AsyncOpenAI
from dotenv import load_dotenv
load_dotenv()
openai = AsyncOpenAI()
Entonces, necesitamos una función que genere la respuesta. Esto utiliza la API GPT normal de OpenAI con un modelo como gpt-4o
o cualquier otro modelo de texto a texto. Si eres nuevo en esto, quizás quieras consultar este tutorial de la API GPT-4o.
Aquí tienes una implementación asíncrona de esta función:
async def get_answer(prompt):
stream = await openai.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user", "content": prompt}
],
stream=True,
)
answer = ""
async for chunk in stream:
content = chunk.choices[0].delta.content
if content is not None:
answer += content
print(content, end="", flush=True)
print("\n\n")
return answer
Para ejecutar el bucle principal, seguimos los pasos descritos anteriormente:
async def main(tone_and_style_instructions):
await text_to_audio("Hello, how can I help you today?", tone_and_style_instructions)
while True:
record_audio("prompt.wav")
prompt = await transcribe_audio("prompt.wav")
print()
answer = await get_answer(prompt)
await text_to_audio(answer, tone_and_style_instructions)
Por último, ejecutamos el bucle principal cuando se ejecuta el script:
if __name__ == "__main__":
tone_and_style_instructions = "Enthusiastic voice."
asyncio.run(main(tone_and_style_instructions))
Aquí tienes una demostración en acción:
Puedes encontrar el código completo aquí.
Nuevas mejoras
Si intentamos utilizar el asistente con instrucciones complejas de tono y estilo, podemos notar una disociación entre las palabras y el tono. Por ejemplo, considera las siguientes instrucciones para una voz de "Adolescente Emo" tomadas del sitio web de OpenAI:
tone_and_style_instructions = """
Tone: Sarcastic, disinterested, and melancholic, with a hint of passive-aggressiveness.
Emotion: Apathy mixed with reluctant engagement.
Delivery: Monotone with occasional sighs, drawn-out words, and subtle disdain, evoking a classic emo teenager attitude.
"""
El tono de voz del audio coincidirá con este estilo, pero el contenido del texto de la respuesta generado por la función get_answer()
no lo tendrá en cuenta, lo que puede dar lugar a un poco de incoherencia. He aquí un ejemplo:
Para superar esto, podemos emparejar el mensaje del usuario en la función get_answer()
con una indicación del sistema que indique que el texto generado debe seguir las instrucciones de tono y estilo.
Para ello, proporcionamos el tone_and_style_instructions
como segundo argumento de la función get_answer()
y modificamos la petición de chat añadiendo un mensaje del sistema:
async def get_answer(prompt, tone_and_style_instructions):
stream = await openai.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content":
f"""
The text you generate is being used in a text-to-voice model.
Make sure your answer matches the guidelines {tone_and_style_instructions}
"""
},
{"role": "user", "content": prompt}
],
stream=True,
)
answer = ""
async for chunk in stream:
content = chunk.choices[0].delta.content
if content is not None:
answer += content
print(content, end="", flush=True)
print("\n\n")
return answer
Así es como responde ahora el modelo:
Como puedes ver, el texto que genera ahora coincide con las instrucciones de tono. Puedes encontrar el código completo aquí.
Construir un Asistente con la API de Agentes
En el ejemplo anterior, solicitamos manualmente los modelos de voz a texto y de texto a voz para construir un asistente de voz. Al hacerlo, aprendimos a utilizar explícitamente los nuevos modelos de la API de voz de OpenAI.
Sin embargo, si el objetivo es crear un asistente de voz, hay una forma más sencilla de utilizar la API del agente. Esta API se ha actualizado para poder gestionar automáticamente el flujo de trabajo voz-a-texto-a-voz que hemos implementado aquí.
Si es la primera vez que utilizas la API del agente, tal vez quieras echar un vistazo a este tutorial sobre SDK de Agentes OpenAI.
Antes de empezar, tenemos que instalar una dependencia más:
pip install 'openai-agents[voice]'
Con eso fuera del camino, empezamos importando todo lo que necesitamos para ejecutar un agente con una canalización de voz:
from dotenv import load_dotenv
load_dotenv()
import asyncio
from agents import Agent
from agents.voice import (
AudioInput,
SingleAgentVoiceWorkflow,
VoicePipeline,
VoicePipelineConfig,
TTSModelSettings,
)
from audio_recorder import record_audio
from audio_player import AudioPlayer
El AudioPlayer
no pertenece a ningún paquete. Se importa desde un archivo local y contiene una clase sencilla que nos ayuda a reproducir el audio en tiempo real. Esto es necesario porque con el VoicePipeline
, obtendremos el audio trozo a trozo, y reproduciremos cada trozo a medida que lo recibamos. Este es el contenido del audio_player.py
archivo:
import numpy as np
import sounddevice as sd
class AudioPlayer:
def __enter__(self):
self.stream = sd.OutputStream(samplerate=24000, channels=1, dtype=np.int16)
self.stream.start()
return self
def __exit__(self, tp, val, tb):
self.stream.close()
def add_audio(self, audio_data):
self.stream.write(audio_data)
El siguiente paso es crear un agente:
agent = Agent(
name="Voice Assistant",
instructions="You’re a helpful assistant speaking to a human.",
model="gpt-4o-mini",
)
Aquí tienes una descripción de los parámetros que utilizamos:
name
: Puede ser lo que queramos.instructions
: Estas instrucciones definen lo que debe ser el agente. Funciona como el indicador del sistema.model
: El modelo que se utiliza para generar respuestas.
El agente funciona como la función get_answer()
que implementamos anteriormente. Piensa en ella como la parte de la cadena que proporciona una respuesta a un mensaje de texto.
A continuación, definimos la tubería. Aquí es donde especificamos todas las configuraciones relacionadas con la voz:
pipeline = VoicePipeline(
workflow=SingleAgentVoiceWorkflow(agent),
stt_model="gpt-4o-mini-transcribe",
tts_model="gpt-4o-mini-tts",
config=VoicePipelineConfig(
tts_settings=TTSModelSettings(
voice="coral",
instructions="""
Speak in an enthusiastic voice.
"""
)
)
)
Aquí tienes un desglose de algunos de los parámetros:
stt_model
: El modelo a utilizar para convertir la voz en texto.tts_model
: El modelo utilizado para convertir el texto en voz.config
: Proporciona la configuración de la tubería. Aquí lo utilizamos para especificar la voz que queremos que utilice eltts_model
, así como las instrucciones de voz.
Por último, ejecutamos el bucle principal, de forma similar a lo que hicimos antes:
async def main():
while True:
audio_input = AudioInput(buffer=record_audio())
result = await pipeline.run(audio_input)
with AudioPlayer() as player:
async for event in result.stream():
if event.type == "voice_stream_event_audio":
player.add_audio(event.data)
if __name__ == "__main__":
asyncio.run(main())
Puedes encontrar una implementación completa aquí.
Añadir herramientas
Ten en cuenta que este bucle se ejecutará eternamente, ya que no hemos especificado una condición de parada. Al ejecutarlo, tendrás que matar el proceso manualmente para detenerlo. Una forma de impedirlo es proporcionar una herramienta al agente.
Las herramientas son funciones que proporcionamos al agente para que las ejecute por nosotros. En este caso, podríamos proporcionar una función que detuviera el script. El agente utiliza el nombre de la función y el comentario para decidir si debe llamarla.
from agents import function_tool
@function_tool
def stop_conversation():
"""Stop the conversation."""
exit()
Después, proporcionamos la herramienta al agente:
agent = Agent(
…
tools=[stop_conversation], # Add this line when creating the agent
)
Con esta implementación, si decimos: "Me gustaría detener la conversación", el agente entenderá que tiene que llamar a la función stop_conversation()
. Ten en cuenta que esta implementación no saldrá correctamente debido a la forma en que está implementada la función stop_conversation()
.
Consulta este archivo si quieres un guión completo.
Utilizar varios agentes
Una característica interesante de la API de agentes es que podemos configurar varios agentes para que trabajen juntos. He aquí un ejemplo extraído de la documentación de OpenAI:
from agents.extensions.handoff_prompt import prompt_with_handoff_instructions
spanish_agent = Agent(
name="Spanish voice assistant",
handoff_description="A spanish speaking agent.",
instructions=prompt_with_handoff_instructions(
"You're speaking to a human, so be polite and concise. Speak in Spanish.",
),
model="gpt-4o-mini",
)
agent = Agent(
name="Voice Assistant",
instructions=prompt_with_handoff_instructions("""
You're speaking to a human, so be polite and concise.
If the user speaks in Spanish, handoff to the spanish agent.
"""),
model="gpt-4o-mini",
)
En este ejemplo, definimos un segundo agente diseñado para hablar español y modificamos al primer agente proporcionándole una indicación con un traspaso. Cuando se verifiquen las instrucciones de traspaso, el segundo agente entrará en acción y continuará la conversación.
El guión completo está disponible aquí.
Conclusión
Utilizando las capacidades avanzadas de los últimos modelos de audio de OpenAI, hemos creado un sistema que puede transcribir eficazmente el lenguaje hablado a texto y generar un habla similar a la humana a partir de respuestas textuales. Este proyecto demuestra no sólo el potencial de la tecnología actual, sino también lo accesibles que se han vuelto estas herramientas para los desarrolladores interesados en crear soluciones de IA personalizadas.
Aprende IA con estos cursos
Curso
Understanding the EU AI Act
Programa
Developing AI Applications

blog
Cinco proyectos que puedes crear con modelos de IA generativa (con ejemplos)

Tutorial
Cómo utilizar la API de conversión de texto a voz de OpenAI

Tutorial
Tutorial de la API de OpenAI Assistants

Tutorial
Guía para principiantes de la API de OpenAI: Tutorial práctico y prácticas recomendadas

Tutorial
Convertir voz en texto con la API Whisper de OpenAI
Tutorial