Un cirujano con oficio te lo dirá sin dramatismo: lo peligroso casi nunca es la herida que ves. Es la que sangra por debajo, callada, mientras tú coses la de arriba y te felicitas por el trabajo bien hecho.
Hace dos días, el Día Mundial de la Enfermedad Inflamatoria Intestinal, publicamos un benchmark honesto de nuestro asistente de IA médica. Hoy te cuento por qué estuvimos a punto de publicarlo mal, y qué encontramos cuando decidimos abrir en canal el único número que no nos cuadraba.
Esto es un post mortem. Y como todo buen post mortem, empieza con un cuerpo sobre la mesa.
El paciente que no encajaba
El examen era sencillo de enunciar: 27 preguntas sobre EII extraídas de MIRAGE, un banco de pruebas para IA médica. Una mezcla de viñetas clínicas tipo examen de licencia (esas de «un paciente acude a consulta con…»), literatura biomédica de PubMedQA y un set curado de farmacología específica de la EII.
Para puntuar usamos RAGAS answer_correctness: una métrica de 0 a 1 en la que otro modelo actúa de juez y compara nuestra respuesta con la respuesta correcta de referencia. Y aquí va un detalle que importará luego: es una métrica de precisión. No premia escribir mucho ni demostrar que sabes. Premia decir lo correcto sin rellenar.
Casi todo iba razonablemente bien. Hasta que apareció un escenario que se nos quedó clavado.
Una mujer de 38 años, con una resección ileal previa por enfermedad de Crohn, llega con un cólico biliar. La respuesta correcta es coledocolitiasis: una piedra atascada en el conducto biliar. No es una pregunta tramposa; de hecho tiene una lógica biomecánica preciosa, porque quitarle a alguien una parte del íleon estropea la reabsorción de sales biliares y lo predispone justamente a fabricar cálculos. El cuerpo, otra vez, contando su propia historia.
Nuestro sistema sacó un 0,382. Un GPT-4o desnudo —el modelo crudo, sin nuestro RAG, sin nuestra tubería de agentes, solo él— sacó un 0,892. Una brecha de 0,510 puntos. En un solo escenario.
Conviene parar aquí, porque esto es incómodo. Habíamos construido toda una arquitectura alrededor del modelo —recuperación de documentos, orquestación, personas— y en esa pregunta el modelo a pelo nos barría. Habíamos puesto andamios y el andamio pesaba más que el edificio.
La tentación de publicar igual
Podríamos haber publicado el benchmark tal cual. Un escenario flojo entre 27 no hunde una media. Se redondea, se acompaña de una nota a pie de página y nadie pregunta.
No lo hicimos. Y no por orgullo, sino por una regla que es casi anatómica: un número que no sabes defender es un bulto que no has palpado. Puede no ser nada. O puede ser lo que te mate seis meses después, en producción, con un usuario real delante.
Así que abrimos. Dos días de análisis forense de causa raíz. Y lo que encontramos no fue un bug. Fueron cuatro. En serie. Y, como las capas de un tejido, cada uno tapaba al de debajo.
Cuatro bugs, en serie, tapándose unos a otros
Esta es la parte que merece detalle, porque el patrón es más interesante que cualquiera de los fallos por separado.
Bug 1 — Mojibake en la zona de uso privado
Una tubería RAG empieza por leer documentos. Nosotros le damos de comer un corpus médico en PDF, lo troceamos en fragmentos y guardamos cada fragmento como un vector —una huella numérica de su significado— para poder buscar por similitud.
Dos de esos PDF estaban envenenados. Su texto venía codificado en la Private Use Area de Unicode: un rincón del estándar deliberadamente vacío, pensado para que cada cual meta ahí sus propios símbolos. Una fuente con un cmap personalizado había mapeado las letras a esa zona. Para un humano abriendo el PDF, se leía perfecto. Para nuestro extractor de texto, era mojibake: ristras de caracteres basura sin ningún significado.
Lo venenoso no fue la basura en sí. Fue que nuestro embedder —el componente que convierte texto en vectores— no se quejó. Le diste galimatías y, tan contento, lo colocó en el espacio vectorial y empezó a puntuarlo como «parecido» a las preguntas. Imagina un sistema inmune que, en lugar de marcar un tejido extraño, lo abraza y lo integra. El cuerpo no detecta el problema; lo adopta.
El arreglo: un decodificador heurístico que detecta el desplazamiento de la zona de uso privado y revierte el mapeo, con docling como red de seguridad cuando la heurística no llega.
Bug 2 — El efecto distractor del RAG
Arreglado el primer bug, esperábamos que la herida cerrara. No cerró. Y aquí apareció algo más sutil.
La búsqueda por similitud densa —comparar vectores— de vez en cuando devolvía un fragmento con una puntuación alta, un 0,75, que sin embargo no compartía ni una sola palabra sustantiva con la pregunta. El vector decía «esto es relevante». El texto, leído por un humano, no tenía nada que ver.
Es el equivalente a un reflejo mal calibrado: el estímulo no era el correcto, pero el arco reflejo se dispara igual. Y un fragmento irrelevante metido en el contexto no es neutro. Distrae al modelo. Le da material plausible para construir una respuesta elegante y equivocada.
El arreglo: una compuerta de relevancia, activable por variable de entorno, que descarta el contexto cuando la puntuación de similitud y el solapamiento léxico caen por debajo de sus umbrales —o cuando el solapamiento baja de un suelo de veto, da igual lo alta que sea la puntuación del vector. Si las dos señales no se confirman, no entra.
Bug 3 — La persona equivocada en la sala equivocada
Este es mi favorito, porque no es un fallo de código. Es un fallo de identidad.
Nuestra persona por defecto se llama Matucha: una compañera para personas con enfermedad crónica. Está diseñada para hablar con un paciente real —con calidez, con cuidado, recordándole que consulte con su equipo médico—. Para esa misión, es exactamente lo que debe ser.
El problema es que Matucha también estaba respondiendo las viñetas tipo examen. Y a un tribunal de licencia médica le estaba contestando con preámbulos empáticos y avisos de «consulta a tu profesional sanitario», enterrando el diagnóstico bajo capas de amabilidad. La respuesta correcta estaba ahí dentro. Solo que sepultada.
Era el animal correcto en el hábitat equivocado. Un pez extraordinario al que habíamos pedido escalar un árbol.
El arreglo: despacho según el modo. Las preguntas en tercera persona —»Una mujer de 38 años acude a consulta…»— se reconocen como registro académico y se enrutan por un canal clínico, directo y sin preámbulos. Las preguntas de un paciente de verdad siguen llegando a Matucha, intacta.
Bug 4 — La verborrea que diluye
Con el canal académico ya funcionando, quedaba un último goteo. El prompt académico producía respuestas de 8 o 9 frases, mientras que el GPT-4o desnudo despachaba en 4 o 5.
Y aquí vuelve el detalle del principio. RAGAS answer_correctness es una métrica de precisión. Cada frase de fisiopatología correcta pero irrelevante que añades no suma: diluye. Es como una analítica con demasiados marcadores pedidos «por si acaso» —cada valor de más no aporta señal, solo ruido que enmascara el dato que importa.
El arreglo: apretar el prompt a 3 o 4 frases como máximo. Decir lo correcto, y callarse.
El quinto problema no era un bug del producto
Hay un quinto hallazgo que merece una mención aparte, porque es el más traicionero de todos.
Nuestro orquestador de evaluación tenía un timeout de 30 segundos. Y estaba cortando 8 de los 9 escenarios de tipo examen antes de que se pudieran medir. Es decir: durante parte del proceso estuvimos arreglando bugs sin poder ver siquiera el efecto de los arreglos, porque el banco de pruebas censuraba las respuestas antes de puntuarlas.
Lo importante: la experiencia del usuario real estuvo bien todo el tiempo. El producto respondía. Lo que estaba roto era el instrumento de medida, no el paciente. Y eso da escalofríos, porque es el error que más se parece a un termómetro estropeado: no te enferma, pero te hace tomar todas las decisiones a ciegas.
Dónde quedamos
Dos días. Ocho pull requests. La misma tanda del juez RAGAS sobre el mismo subconjunto de 27 escenarios de EII.
El resultado: 0,310 de RAGAS answer_correctness para SynapseFlow, 0,310 para el GPT-4o desnudo. Paridad. Y dentro de esa paridad global, ganamos justo en los cubos donde la recuperación de documentos importa de verdad: +0,056 en farmacología de la EII y +0,049 en literatura de PubMedQA.
Quiero ser claro con lo que esto significa y con lo que no. No significa que seamos mejores. Significa que, después de depurar cuatro bugs en serie, una arquitectura RAG con agentes está a la altura del modelo crudo, y empieza a despuntar exactamente donde se supone que debe aportar: cuando hay que ir a buscar un dato a un documento. Esa es la posición honesta. Ni «estado del arte» ni superlativos. Paridad ganada a pulso.
¿Dónde seguimos por detrás? En 3 de las 9 viñetas tipo examen, donde nuestra respuesta académica era correcta pero estaba formulada de manera distinta a la de referencia. Sospechamos que es varianza del juez, no un fallo del producto. Lo estamos investigando, y lo diremos cuando lo sepamos.
Lo que aprendimos
Si te dedicas a construir IA médica con agentes, la lección se resume en una frase: las tuberías de agentes apilan modos de fallo.
Un único punto de answer_correctness fuera de sitio escondía cuatro bugs en serie, y cada uno enmascaraba al siguiente. Arreglas el mojibake y aparece el distractor. Arreglas el distractor y aparece la persona. Arreglas la persona y aparece la verborrea. Es la diferencia entre un organismo y una pieza suelta: en un sistema con muchas capas, ningún síntoma apunta limpiamente a una sola causa. Hay que disecar.
Y la disciplina forense de negarse a publicar un número que no puedes defender no es una formalidad. Es el juego entero.
El informe completo —con el detalle escenario a escenario, todos los JSON de la línea base y el rastro de auditoría de las 8 PR— está aquí: github.com/DEUS-AI/SynapseFlow → docs/benchmarks/eje1-ibd-baseline.md.
Lo siguiente: los mismos 27 escenarios contra KAG (Liang et al., 2024). Esa es la comparación que toda esta autopsia nos estaba comprando el derecho a hacer con credibilidad. La contaremos cuando tengamos los números. No antes.
Próximo post: SynapseFlow contra KAG — la comparación que esta autopsia hizo posible.
Deja una respuesta