Quería dictar como trabajo: mantener una tecla, hablar, soltar, y que el texto aparezca donde está el cursor, en alemán, español o inglés. Una herramienta con tantas piezas móviles solo es de fiar si puedes decir por qué está cada una. Así que construí una para mi propio Mac y fui anotando cada decisión en el momento de tomarla.
Es una pequeña app de barra de menús llamada Flabbeo. No vende nada, así que esta página trata de cómo se decidió y se comprobó.
Primero, una regla
Todo se ejecuta en el Mac. El reconocimiento de voz es el modelo Parakeet de NVIDIA, y de ordenar el texto se encarga un modelo de lenguaje pequeño, Qwen3.5-4B, a través de llama.cpp. El único código de red de todo el proyecto es una descarga única de esos dos modelos desde Hugging Face, fijada a versiones exactas y comprobada con sumas de verificación. No hay telemetría ni canal de actualizaciones. Una nota al pie, porque es verdad: el texto que escribe va adonde lo envíe la app en la que escribes.
Decisiones, y en qué se apoyaron
No di por buenos tres informes de investigación hechos con IA. Los puntué contra fuentes primarias. El resultado más útil fue un hallazgo lateral: un proyecto mejor del que aprender.
El código ajeno exige comprobar la licencia y llevar una cabecera. 26 archivos fuente llevan una cabecera que nombra el proyecto del que derivan (Pindrop y FreeFlow, ambos MIT). Un proyecto de referencia sin licencia solo sirvió de modelo de comportamiento, y mis avisos no recogen código suyo.
Elegí el modelo de lenguaje por benchmark. Cuatro modelos, 23 casos de prueba en tres idiomas, 20 de ellos para el paso de limpieza. Qwen3.5-4B resolvió bien 19 de esos 20. Un competidor que sacó 16 propuso dos cambios peligrosos: quitó el “nicht” de “nicht an meine private Adresse” y cambió 450 por 540. Las reglas que describo a continuación rechazaron ambos, para eso están.
El modelo nunca tiene vía libre. En el nivel de limpieza solo puede devolver una lista de supresiones, en un formato que impone una gramática, y una regla rechaza cualquier cambio que añada, reordene o quite palabras que yo no haya marcado. En el nivel de reformulación, que trabaja sobre el texto ya limpio, un vigilante determinista comprueba cifras, una negación perdida, direcciones de correo y enlaces, el trato (du o Sie) y el idioma. Si una comprobación falla, se inserta la versión anterior. El vigilante no comprueba nombres, y el texto de ayuda de la app ya lo dice.
Probé con voz. El audio hablado sacó a la luz fallos que el texto escrito de prueba no había mostrado: el reconocedor omite las comas alrededor de una corrección dicha en voz alta, escribe los números con letras, y una vez el modelo convirtió “quinientos cuarenta” en 450. Cuatro clases de fallo, todas corregidas desde entonces.
Meter texto en otra app es una escalera de comprobaciones. La app recuerda el campo en el que dictaste, se asegura de que no has cambiado de app ni has caído en un campo de contraseña, pega y vuelve a leer el campo para ver si el texto llegó. Cuando no puede saberlo, lo dice. Incorporé a la app una función de medición en lugar de adivinar qué apps permiten qué.
Aprender de las correcciones, solo con tu permiso. Si corriges una palabra justo después de dictar, la app se ofrece a añadirla al diccionario. Nunca añade nada por su cuenta.
Tres idiomas desde el primer día. 213 textos de interfaz por idioma, con una comprobación en la compilación de textos que faltan y del tono.
Al final hice menos a propósito. Firmada para mis propios Mac, sin notarización, sin actualizaciones automáticas. Una herramienta para una persona no necesita una maquinaria de distribución.
Lo que salió mal
El texto de la interfaz decía que la IA protege los nombres. El vigilante no lo hace. Lo vi al contrastar cada texto con el código y corregí el texto. La primera redacción de las líneas de estilo por app omitía contenido: en tres de los estilos, “no la pequeña” desaparecía de una frase en español. Medí, reescribí la instrucción y volví a medir. El texto que quedaba en el portapapeles tras una inserción fallida, por ejemplo desde un campo de contraseña, no estaba marcado como transitorio, así que los gestores del portapapeles podían registrarlo. Lo vi al documentar el proyecto y ahora tiene una prueba.
El nombre
Empezó como Zefiro, un nombre de trabajo. Una comprobación previa encontró una app con ese nombre en el App Store y ningún dominio libre, así que busqué otro: unos 300 candidatos en tres rondas. La mayoría la pronunciaron nueve voces sintéticas en alemán, español e inglés, y a los preseleccionados los revisé por significado, colisiones y motivos para descartarlos. La prueba mostró que los nombres inventados de sonido suave vuelven escritos de forma distinta cada vez. Elegí Flabbeo igualmente, contra el resultado, porque la herramienta es para mí. Con mi propia voz la app escribió el nombre bien en 5 de 18 intentos, los cinco en alemán; en español escribe “flaveo”. Para eso está el diccionario que aprende. El nombre no ha pasado por una búsqueda de marca.
Lo que todavía no sabe hacer
Se ha probado en un Mac. El mío. La instalación en un segundo Mac está por hacer.
Puede confirmar que el texto llegó en tres de ocho apps. En las otras cinco no puede leer el campo y te lo dice, en lugar de pegar dos veces.
Algunas partes no tienen pruebas automáticas. 347 pruebas en 54 suites cubren la lógica que las rodea. El reconocimiento de voz en sí y las ventanas de la app las compruebo a mano, y nada ejecuta las pruebas automáticamente con cada cambio.
No hay una cifra de precisión del reconocimiento de voz. Solo muestras con voces sintéticas y mi propio uso.
El estilo por app apenas se nota en dictados cortos. Falta una prueba con dictados largos.
Unas 13.900 líneas de Swift en 13 módulos. Se queda en mi Mac y no está a la venta.
Cada decisión aquí tiene una razón, y la mayoría una medición o una prueba. La página dice dónde no es así.
¿Tienes un proyecto parecido?
Cuéntame qué tienes en mente. Te diré con honestidad si puedo ayudarte y qué haría falta.
Cuéntame tu proyecto →Tratarás directamente conmigo, desde la primera llamada hasta la entrega final.