Tutorial de IA
Construye tu primer asistente de voz con OpenAI y Python: Tutorial para desarrolladores
Un tutorial práctico de Python para construir un asistente de voz con las API de Whisper, ChatGPT y texto a voz de OpenAI: grabación de audio, transcripción, generación de una respuesta hablada y conversión de vuelta a audio.

Un asistente de voz suena como un gran proyecto de ingeniería, pero el bucle principal son solo tres llamadas a la API encadenadas: transcribir el habla a texto, enviar ese texto a un modelo de lenguaje y luego convertir la respuesta de vuelta a habla. Este tutorial construye una versión funcional de línea de comandos de ese bucle utilizando Whisper de OpenAI para la transcripción, ChatGPT para la respuesta y el endpoint de texto a voz de OpenAI para la salida de audio.
Qué necesitarás
- Python 3.9 o posterior instalado
- Una clave de API de OpenAI con facturación habilitada (este proyecto usa tres endpoints separados, cada uno facturado por uso)
- Un micrófono y una forma de reproducir audio desde tu máquina
Paso 1: Configurar el entorno
Crea una carpeta de proyecto e instala los paquetes necesarios:
pip install openai sounddevice scipy python-dotenv
Almacena tu clave de API en un archivo .env en lugar de codificarla directamente en el script, esto es más importante de lo que parece: las claves de API comprometidas en el código terminan filtrándose en repositorios de git más a menudo de lo que los desarrolladores esperan.
OPENAI_API_KEY=tu-clave-aqui
Paso 2: Grabar y transcribir audio con Whisper
El paso de grabación captura unos segundos de entrada del micrófono y lo guarda como un archivo WAV, que luego se envía al endpoint de transcripción de Whisper:
import sounddevice as sd, scipy.io.wavfile as wav, os
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI()
def record_audio(filename="input.wav", duration=5, fs=44100):
print("Grabando...")
audio = sd.rec(int(duration * fs), samplerate=fs, channels=1)
sd.wait()
wav.write(filename, fs, audio)
def transcribe(filename="input.wav"):
with open(filename, "rb") as f:
result = client.audio.transcriptions.create(model="whisper-1", file=f)
return result.text
Cinco segundos son suficientes para una pregunta corta. Para una entrada más larga, aumenta la duración o, para una versión de producción, reemplaza la grabación de duración fija con detección de silencio para que se detenga automáticamente una vez que termines de hablar.
Paso 3: Enviar la transcripción a ChatGPT
Con el texto en mano, la llamada de finalización de chat es sencilla. Mantén el mensaje del sistema breve, ya que las respuestas de voz deben ser más cortas y conversacionales que la salida de chat típica destinada a la lectura en pantalla:
def get_response(user_text):
completion = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "Eres un asistente de voz. Mantén las respuestas en menos de 3 oraciones, conversacionales, sin markdown."},
{"role": "user", "content": user_text}
]
)
return completion.choices[0].message.content
La instrucción "sin markdown" importa aquí específicamente porque una lista con viñetas no tiene sentido al ser leída en voz alta, este es un caso donde el mensaje debe tener en cuenta el medio de salida, no solo el contenido.
Paso 4: Convertir la respuesta a voz
El endpoint de texto a voz de OpenAI toma ese texto de respuesta y devuelve audio directamente:
def speak(text, filename="output.mp3"):
response = client.audio.speech.create(model="tts-1", voice="alloy", input=text)
response.stream_to_file(filename)
os.system(f"start {filename}" if os.name == "nt" else f"afplay {filename}")
El parámetro voice acepta varias opciones predefinidas: alloy, echo, fable, onyx, nova y shimmer, cada una con un tono distinto. Prueba algunas para tu caso de uso; un asistente orientado al cliente y una herramienta personal para tomar notas no necesitan la misma voz.
Paso 5: Conectarlo todo
if __name__ == "__main__":
record_audio()
text = transcribe()
print(f"Dijiste: {text}")
reply = get_response(text)
print(f"Asistente: {reply}")
speak(reply)
Ejecuta el script, habla una pregunta cuando se te solicite, y el bucle completo (grabar, transcribir, responder, hablar) se completa en unos segundos.
Dónde falla esto y cómo solucionarlo
El problema más común es el audio recortado: si la ventana fija de 5 segundos se corta antes de que termines de hablar, la transcripción será incompleta y la respuesta responderá a la pregunta incorrecta. Aumentar la duración es la solución rápida; agregar una biblioteca de detección de actividad de voz como webrtcvad es la correcta. La latencia es la otra restricción que vale la pena planificar: tres llamadas secuenciales a la API suelen sumar 2-4 segundos de tiempo de ida y vuelta, notable pero generalmente aceptable para una herramienta personal, menos para algo que pretenda ser verdaderamente en tiempo real.