Qué es
Sinte es un asistente de voz que conversa de verdad. Lo saludás, te contesta, te recuerda cosas y puede ejecutar acciones (crear un recordatorio, buscar algo, responder preguntas).
La diferencia con un altavoz inteligente: todo corre en tu propia máquina y el código es tuyo. Sin que te escuchen de fondo empresas de las que no sabés nada.
La cadena de voz
Un asistente de voz tiene tres momentos, y cada uno es un problema distinto:
- Escuchar — convertir audio a texto (STT).
- Pensar — generar una respuesta (LLM).
- Hablar — convertir texto a voz (TTS).
1. Escuchar — Whisper local
Uso faster-whisper, la versión optimizada de Whisper de OpenAI que corre en CPU sin problema:
# stt.py (resumido)
from faster_whisper import WhisperModel
modelo = WhisperModel("small", device="cpu", compute_type="int8")
def escuchar(audio_path: str) -> str:
segmentos, _ = modelo.transcribe(audio_path, language="es")
return " ".join(s.text for s in segmentos).strip()
El audio se graba con una detección de silencio propia: arranca a grabar cuando hay ruido y corta cuando hay silencio, así no se llena de aire muerto.
2. Pensar — LLM con contexto
La respuesta la genera un modelo de lenguaje con un system prompt que define la personalidad y las capacidades:
SYSTEM = """
Sos Sinte, un asistente de voz en español.
Respondé corto, natural y sin alardes (es una conversación hablada).
Podés crear recordatorios, buscar en el calendario y contestar preguntas.
Si algo no sabés, decilo directo.
"""
Tiene memoria: cada conversación se guarda y se inyecta como contexto en la siguiente. Hablás con él hoy y se acuerda de ayer.
3. Hablar — TTS con control
La síntesis de voz elige el motor según lo que haya disponible (coqui TTS para la voz local, o un servicio de TTS de alta calidad si hace falta). El audio resultante se reproduce de inmediato, y se aplica ducking: baja la música mientras el asistente habla y la sube cuando termina.
Wake word
Nada de botones. Escucha pasiva con Porcupine (on-device): decís “hey Sinte” y se activa. El resto del tiempo el micrófono se procesa localmente y no se guarda nada.
Habilidades
El asistente detecta intenciones y delega a funciones:
SKILLS = {
"recordatorio": crear_recordatorio, # agenda + aviso
"alarma": crear_alarma,
"buscar": buscar_en_web,
"clima": consultar_clima,
"default": chatear_normal,
}
Cada habilidad es un módulo independiente. Agregar una nueva es escribir una función y registrarla. Así crece sin tocar la cadena de voz.
Arquitectura
audio → wake word → STT (whisper) → LLM (con memoria) → TTS → audio
│
intent → SKILLS → acción + respuesta
Todo orquestado con FastAPI + WebSocket: el frontend (una web minimalista o el micrófono del sistema) manda audio y recibe audio, sin instalaciones raras.
Lo que aprendí
- La latencia importa muchísimo: una conversación natural se arruina con 1 segundo de espera. Optimizar STT/TTS local fue el desafío real.
- El prompt del system determina el 80% de la “personalidad”.
- Pensar en intenciones y habilidades desde el día uno hace que sumar features sea trivial.
Siguiente paso
Conectarlo al sistema de automatizaciones de la casa y que sea la interfaz de voz de todo: “Sinte, poné el modo cine” y que apague luces y baje el volumen. Todo desde la misma cadena de voz.