Trabajo / 2025

Medifé Medical Pipeline OCR

Un sistema de procesamiento documental construido en tres etapas: un primer workflow funcional en n8n, su migración a una API modular en Python para el MVP y una tercera versión con recuperación sobre catálogos CSV mediante RAG. El pipeline combina visión multimodal, extracción estructurada, normalización, clasificación y reglas de confianza para no esconder la incertidumbre detrás de una respuesta aparentemente precisa.

  1. 1Extraer
  2. 2Normalizar
  3. 3Revisar

Receta

Documento de ejemplo
Prescription
Rx

Extracción estructurada

Información extraída del documento mediante OCR e IA.

PacienteOculto
MedicamentoRequiere revisión
DiagnósticoNo disponible
En esta página

EN BREVE

Un pipeline documental que transforma recetas médicas en datos estructurados y listos para revisión sin ocultar la incertidumbre.

Mi contribución

Arquitectura del pipeline · extracción estructurada · validación · migración de n8n a Python · RAG · diseño human-in-the-loop.

Datos clave

n8nFastAPILangGraphPydanticGemini VisionCatálogos CSVRAGRevisión humana

Decisiones de ingeniería

  1. Mantener visible la incertidumbre

    Usar confianza, alternativas y caminos de revisión en vez de presentar una extracción estructurada como una respuesta segura.

  2. Preservar el workflow visual antes de migrar

    Llevar el flujo validado en n8n a FastAPI, LangGraph y Pydantic sin descartar sus reglas de negocio y bifurcaciones.

  3. Entregar el documento al modelo

    Hacer que la imagen o el PDF sean una entrada multimodal real para reproducir la etapa de lectura documental esperada.

  4. Recuperar desde catálogos controlados

    Usar candidatos respaldados por CSV para normalización y clasificación, manteniendo las opciones de fuente revisables y reemplazables.

Evolución del proyecto

  1. Workflow en n8n
  2. Extracción estructurada y validación
  3. Migración a API en Python
  4. Caminos de revisión humana
  5. Catálogos CSV y RAG

Leer no alcanza

En Argentina, muchas recetas médicas todavía son manuscritas. Nombres, números de credencial, diagnósticos, fechas, indicaciones y medicamentos pueden convivir en un mismo documento, entre abreviaturas y caligrafías ambiguas. Un OCR convencional puede devolver fragmentos de texto, pero no puede determinar si interpretó correctamente un medicamento, si el resultado tiene coherencia clínica o si los datos extraídos son suficientemente confiables para continuar.

Este trabajo suele resolverse mediante revisión administrativa: una persona lee el documento, identifica los campos relevantes, los transcribe en otro sistema y decide cómo proceder cuando algo no es claro. Por eso, el proyecto cambió de dirección: dejó de ser únicamente un experimento de OCR y pasó a buscar la automatización de un flujo humano de procesamiento documental. El objetivo no era eliminar el criterio de las personas, sino reducir la transcripción repetitiva y dirigir la atención humana según el riesgo.

Las lecturas ambiguas y las recetas con medicamentos de alto costo se derivaban a una persona. Las recetas de menor prioridad y costo podían continuar sin intervención humana cuando la confianza del OCR superaba el umbral requerido; una extracción con baja confianza igualmente activaba el reprocesamiento o la revisión. El desafío pasó a ser diseñar ese recorrido conservando la receta original como evidencia y transformando su contenido en un contrato estructurado e inspeccionable.

Del workflow visual a un servicio mantenible

Trabajé sobre la arquitectura del pipeline, el contrato de datos y sus tres implementaciones sucesivas. El workflow inicial en n8n funcionaba correctamente y permitió diseñar y validar rápidamente la lógica de negocio. La migración a Python no fue una corrección de ese primer paso: fue la forma de convertirlo en el MVP, con mayor control sobre el código, los contratos y las pruebas.

La versión con FastAPI y LangGraph mantuvo las decisiones del workflow original —validar, extraer, normalizar, clasificar, decidir y consolidar— y las hizo explícitas como nodos y transiciones. Swagger funcionó como interfaz técnica, Pydantic definió límites verificables entre etapas y la integración con Gemini quedó aislada detrás de un cliente. En una tercera etapa incorporé recuperación sobre catálogos CSV para apoyar la normalización y la clasificación con candidatos controlados.

Tres etapas del sistema

  1. 1. Workflow en n8n

    La primera versión implementó el recorrido completo como un flujo visual: ingreso por webhook, validación documental, OCR, normalización, clasificación, bifurcaciones y respuesta estructurada. En la primera demo con el cliente, n8n permitió ejecutar el proceso en vivo y recorrerlo nodo por nodo, mostrando cómo cambiaba el documento en cada etapa antes de consolidar el flujo en Python. Esa demostración visual convirtió requisitos todavía cambiantes en algo concreto: las etapas, excepciones y campos de salida podían discutirse y ajustarse directamente sobre un proceso funcionando.

  2. 2. MVP en Python

    El flujo se migró a FastAPI, LangGraph y Pydantic para ganar modularidad, tipado, manejo de errores y capacidad de prueba, preservando el comportamiento definido en n8n.

  3. 3. CSV y RAG

    La tercera implementación agregó recuperación sobre catálogos controlados. El sistema buscaba candidatos relevantes antes de normalizar medicamentos o asignar la jerarquía de tipo, subtipo y práctica.

Un pipeline con puntos de control

Arquitectura simplificada

El documento avanza como estado tipado. Cada etapa produce información inspeccionable y la validación decide si el flujo puede continuar.

01

Ingreso

Recibir imagen o PDF junto con metadata opcional del paciente y su afiliación.

02

Validación documental

Comprobar que el archivo sea procesable y corresponda al tipo esperado.

03

Visión y extracción

Enviar el archivo real al modelo multimodal y mapear la lectura a un schema.

04

Normalización

Corregir candidatos de medicamentos usando receta, diagnóstico y especialidad como contexto.

05

Clasificación y control

Asignar categorías y evaluar consistencia, confianza y necesidad de reintento.

06

Enrutamiento por riesgo

Continuar automáticamente los casos confiables y de menor costo; derivar las recetas ambiguas, de baja confianza o alto costo a revisión humana.

El contrato de salida también es producto

La extracción se diseñó alrededor de campos como validez de la receta, credencial, paciente, obra social, diagnóstico, fecha, área médica, prescripción completa y lista de medicamentos. Los datos ausentes debían permanecer nulos: completar silenciosamente un campo era peor que reconocer que no estaba disponible.

La normalización agregaba otra capa de evidencia por medicamento: texto original, corrección propuesta, concentración, frecuencia, candidatos alternativos, correspondencia con el diagnóstico, confianza seleccionada y una acción sugerida. Así, un consumidor podía distinguir entre un dato leído, una hipótesis normalizada y un caso todavía incierto.

El contexto se convierte en evidencia

Decisión
Calcular la confianza a partir del documento completo, combinando la calidad del OCR con metadata del paciente y señales contextuales de la receta.
Motivo
Los detalles que rodean una lectura dudosa pueden ayudar a desambiguarla. Los datos conocidos del paciente permiten contrastar la identidad extraída, mientras que la institución emisora, el diagnóstico y la especialidad aportan indicios sobre el medicamento. Por ejemplo, el encabezado de una clínica oftalmológica vuelve más plausible un medicamento relacionado con el cuidado ocular que otro candidato no relacionado pero con un nombre manuscrito similar.
Compromiso
El contexto es evidencia de apoyo, no una prueba. Una clínica puede cubrir varias especialidades, la metadata puede estar incompleta y un medicamento plausible igualmente puede estar mal leído. Estas señales pueden ajustar la confianza, pero no deben imponerse sobre evidencia contradictoria del documento.
Resultado
El puntaje de confianza refleja la concordancia entre calidad del OCR, datos del paciente, contexto clínico y candidatos del catálogo. Las señales débiles o contradictorias reducen la confianza y acercan la receta al reprocesamiento o la revisión humana.

El archivo debía llegar al modelo

Decisión
Tratar la imagen o el PDF como entrada multimodal real, no como un adjunto reducido a nombre y metadata.
Motivo
Una primera integración podía leer los bytes en FastAPI pero luego construir el prompt solo con el nombre del archivo y el contexto textual. Eso mantenía el endpoint funcionando sin reproducir el OCR original: el modelo nunca veía el documento.
Compromiso
Enviar contenido multimodal exige validar MIME, tamaño, multipart y límites del proveedor. También vuelve más importante registrar errores sin conservar información médica sensible.
Resultado
La arquitectura dejó explícito el transporte del binario hasta Gemini Vision y separó los problemas de carga, inferencia y parsing para poder probarlos de forma independiente.

Diseñar para la incertidumbre

  1. Conservar la lectura original

    Mantener el texto detectado junto con cualquier corrección propuesta para no borrar la evidencia del OCR.

  2. Usar contexto clínico

    Contrastar el medicamento con la metadata del paciente, la prescripción completa, el diagnóstico, el área médica y la institución emisora antes de seleccionar una normalización.

  3. Medir consistencia

    Exponer confianza, alternativas y correspondencia con el diagnóstico en lugar de devolver una única respuesta opaca.

  4. Elegir una acción

    Continuar automáticamente las recetas confiables, de menor prioridad o costo; reprocesar cuando la confianza del OCR es insuficiente; o solicitar revisión humana ante ambigüedad y medicamentos de alto costo.

Tercera etapa: catálogo controlado

Decisión
Incorporar recuperación sobre catálogos CSV curados para apoyar la normalización y la clasificación.
Motivo
Depender solo del conocimiento paramétrico del modelo limitaba la trazabilidad. La tercera versión recuperaba candidatos de medicamento o de una jerarquía tipo, subtipo y práctica; el modelo elegía y estructuraba la respuesta usando ese conjunto acotado.
Compromiso
La recuperación agrega versionado del catálogo, búsqueda semántica y criterios de ranking. A cambio, las opciones pueden rastrearse hasta una fuente administrada y actualizarse sin reentrenar el modelo.
Resultado
La separación entre OCR, normalización, recuperación y validación permitió sumar RAG sin reemplazar la API ni el grafo completo. El catálogo pasó a funcionar como una fuente controlada de candidatos dentro del pipeline; el caso no afirma por eso que la solución haya alcanzado validación productiva.

Una superficie técnica pequeña

El prototipo expuso un endpoint de carga para ejecutar el grafo, un health check y la especificación OpenAPI generada por FastAPI. Swagger permitió probar el recorrido con documentos y metadata sin construir antes una interfaz específica.

El manejo de errores diferenció fallas del modelo, respuestas no parseables, problemas de multipart y excepciones internas. Ese detalle convirtió un error 500 genérico en información accionable durante la integración, sin confundir que el servidor estuviera disponible con que el pipeline completo hubiese sido validado.

Resultado del prototipo

El trabajo produjo tres versiones conectadas del sistema: un workflow funcional en n8n para definir y probar el recorrido, un MVP modular en Python con API y documentación interactiva, y una etapa posterior con CSV/RAG para recuperar candidatos desde fuentes controladas.

El caso no publica métricas de precisión ni presenta el sistema como productivo porque todavía faltan resultados revisados sobre un conjunto representativo. Su valor está en mostrar cómo una automatización visual válida pudo convertirse en un servicio verificable y luego incorporar recuperación sin rehacer el pipeline desde cero.

Aprendizajes

En procesamiento documental, una respuesta estructurada no es sinónimo de una respuesta correcta. Los schemas mejoran el contrato; la confianza, los candidatos y la revisión humana mejoran la decisión.

La migración también mostró que copiar nodos uno a uno no es suficiente. La paridad real depende de preservar el binario, las bifurcaciones, los reintentos y la semántica de cada campo. La siguiente etapa natural sería construir un dataset anonimizado, evaluar por campo y por tipo de documento, y recién entonces ajustar umbrales o afirmar calidad operativa.

CONSTRUYAMOS ALGO ÚTIL

Un problema complejo. Un buen punto de partida.

Hablemos