Traducción simultánea bidireccional en videollamada sin romper la cadencia
Traducción simultánea bidireccional en videollamada: dos sesiones en paralelo, streaming continuo y enrutado de audio que hace imposible el bucle.
- tiempo real
- webrtc
- audio
- traduccion
- arquitectura
- traductor live
Veinticinco minutos en un idioma que no domino
Tenía que sostener una conversación técnica de veinticinco minutos en un idioma que no domino. No leerlo: sostenerlo en voz, con turnos rápidos, sin que la otra persona tuviera que esperarme.
Lo que hay disponible resuelve medio problema. Los subtítulos automáticos dan comprensión parcial y cero expresión. Los traductores por turnos cubren las dos direcciones y rompen el ritmo hasta hacer la conversación inviable: hablas, esperas, escuchas, esperas. A los tres minutos se ha muerto, no por falta de traducción, sino porque nadie aguanta ese protocolo.
Así que el problema de diseño no era traducir. Traducir, hoy, es una llamada a una API. Era traducir sin destruir la cadencia de una conversación humana, en las dos direcciones a la vez, sobre un canal de audio que no controlo: la aplicación de videollamada es de un tercero y solo me deja elegir qué dispositivo del sistema es el micrófono y cuál el altavoz. Todo el diseño tiene que caber en esas dos elecciones y en el margen que un humano tolera antes de pensar que la línea se ha caído: por debajo de 1,5 segundos por dirección.
Seis decisiones con la cadencia como restricción principal
Dos sesiones independientes, no una bidireccional
Una sesión con idioma de salida A y otra con idioma de salida B, en paralelo sobre la misma llamada. Cada una con su fuente de audio, su destino y su ciclo de vida.
La alternativa obvia era una sola sesión que detectase el idioma entrante y conmutase. Es más elegante, consume la mitad y mete una decisión de conmutación en el camino crítico, que es exactamente donde no puedes permitirte pensar. Una detección que dude 400 milisegundos se come un tercio del presupuesto de latencia; y cuando falla, no llega tarde: llega al oído equivocado.
Trade-off aceptado: pago el doble de sesiones y de ancho de banda a cambio de que en el camino crítico no haya ni una decisión que tomar.
Streaming continuo frente a ciclo de turnos
El sistema no espera al final de la frase: empieza a emitir con el contexto mínimo necesario mientras el hablante sigue hablando. Es la diferencia entre un intérprete simultáneo y un traductor por turnos, y define todo lo demás. No hay evento de "fin de turno" del que colgar la lógica, y el buffer no se corta nunca, ni en los silencios entre frases.
Eso obliga a renunciar a la mayor comodidad de arquitectura que hay aquí: el punto de sincronización limpio del ciclo de turnos, y con él los reintentos triviales.
Trade-off aceptado: convivo con traducciones que se reajustan a mitad de frase cuando el contexto posterior cambia el sentido, a cambio de que la latencia percibida no acumule la duración de la frase completa. Un intérprete humano hace lo mismo.
El enrutado de audio es el 80% de la ingeniería y el 0% de lo que se ve
La traducción entrante sale solo por auriculares. Si sale por altavoz, el micrófono la recoge y el sistema se traduce a sí mismo en bucle. La traducción saliente no va a los altavoces: va a un cable de audio virtual, y ese cable es lo que la videollamada tiene seleccionado como micrófono. El micrófono físico —el que me escucha— nunca es el que la llamada tiene seleccionado. Dicho como propiedad: el bucle no está mitigado, es imposible; no hay ningún camino en el grafo de dispositivos que devuelva la salida del sistema a su entrada.
Trade-off aceptado: introduzco una dependencia de instalación (un dispositivo de audio virtual) y una obligación de uso no negociable (auriculares siempre) a cambio de no depender de supresión de eco. La supresión de eco es una promesa estadística; la separación de dispositivos es una propiedad estructural. Donde el fallo se manifiesta como un chillido de realimentación en mitad de una conversación, prefiero la propiedad.
Credenciales efímeras desde un servidor local mínimo
La clave permanente del proveedor del modelo no llega nunca al navegador: el cliente pide un secreto de un solo uso a un servidor en localhost. El resto corre entero en mi máquina, sin backend en la nube y sin tránsito del audio por ningún servicio mío. Trade-off aceptado: un proceso más que levantar antes de cada uso a cambio de reducir a un token de un solo uso lo expuesto en el cliente.
Subtítulos en pantalla como respaldo, no como producto
El canal principal es el audio. El texto existe para que, cuando el audio falle, lo note y pueda seguir leyendo. Con él, indicadores de estado: conectado, traduciendo, caído. Trade-off aceptado: parte de mi atención se va a la pantalla a cambio de que un fallo sea visible cuando ocurre y no tres frases después.
La decisión que define el producto: la IA traduce, nunca responde
Esta no es una limitación técnica: es la decisión de diseño de la que cuelga el sentido del producto.
El sistema no genera contenido, no sugiere respuestas, no completa frases, no mejora lo que digo. Traslada mis palabras a otro idioma y nada más. Técnicamente, añadir sugerencias habría sido la función más barata —el modelo ya está ahí, el contexto en memoria, la interfaz ya muestra texto— y también la más fácil de vender. Y en el momento en que cruzas esa línea, la herramienta deja de ser una prótesis y se convierte en una suplantación: si el sistema responde, la persona al otro lado ya no está hablando conmigo. Por eso la línea está en la arquitectura y no en una casilla de configuración: lo que no existe no se puede activar sin querer.
Trade-off aceptado: renuncio a la función más vendible a cambio de poder declarar en voz alta que lo estoy usando sin que eso cambie nada de lo que la otra persona esperaba de la conversación.
Los dos canales, dibujados
En el diagrama hay que mirar una cosa: los dos canales son caminos separados que no se cruzan en ningún punto, con los dispositivos de audio explícitos en cada extremo. Debe verse por qué no puede haber bucle.
Canal 1 · entrante
Canal 2 · saliente
Qué descarté y por qué
Una sesión bidireccional con detección de idioma. Mete una conmutación en el camino crítico y convierte un error de detección en audio enviado al destinatario equivocado.
El ciclo de turnos. Suma la duración de la frase al presupuesto de latencia, y con eso la conversación deja de ser una conversación.
Salida por altavoz con cancelación de eco. Cambia una propiedad estructural por una promesa estadística en el único punto donde el fallo es catastrófico y público.
La clave del proveedor en el cliente. Un secreto permanente en la capa que el usuario puede inspeccionar no es un secreto.
Subtítulos como canal principal. Resuelven comprensión y no expresión.
Sugerencia de respuestas. Por diseño, no por dificultad.
Infraestructura propia en la nube. El audio no pasa por un sistema mío.
Estado real
Traductor Live funciona: corre entero en local y lo he usado.
- Pruebas de extremo a extremo con voz real: 3 de 3 superadas.
- Latencia objetivo cumplida: por debajo de 1,5 segundos por dirección.
- Grado de acabado: ~95%. Lo que falta es pulido de operación —arranque en un paso, recuperación automática si una sesión cae—, no arquitectura.
- Usado en una conversación real, declarando su uso en voz alta al empezar. Una herramienta así se declara siempre; usar algo que no declaras no es usar una herramienta.
Lecciones transferibles
La ingeniería difícil casi nunca está donde parece. El modelo de traducción es una llamada a una API y me costó una tarde. El enrutado de audio y evitar la realimentación se llevaron el 80% del trabajo, y son el 0% de lo que se ve en una demo.
Prefiere propiedades estructurales a promesas de política. "El bucle es imposible porque no existe la ruta" es distinto de "el bucle está suprimido por software". Si puedes convertir una garantía en una propiedad del grafo, hazlo.
Saca las decisiones del camino crítico, aunque el diseño quede menos bonito. Duplicar sesiones es feo y funcionó. La elegancia de la sesión única se pagaba en el único recurso que no tenía: tiempo dentro de la frase.
La lección incómoda. La barrera del idioma me ha costado oportunidades reales durante años y la traté como un hecho consumado en vez de como un problema técnico. Cuando por fin la traté como problema técnico, tardé menos en resolverla que cualquiera de los años que pasé asumiéndola. Y la decisión más importante tampoco fue técnica: fue dónde poner el límite entre asistir y suplantar. Esa no la toma el modelo.
Versión corta en LinkedIn: Voy a una conversación técnica en inglés y mi inglés no llega, así que me construí un intérprete (linkedin.com/in/carlosdelatorre-ai)