Cada año aparecen más dispositivos centrados en la salud: relojes inteligentes que monitorean el ritmo cardíaco, básculas que miden composición corporal, monitores de glucosa y apps que registran el sueño. La cantidad de información que podemos recolectar sobre nuestro propio cuerpo es enorme. Pero ¿realmente estamos aprovechando todos estos datos?

Este artículo presenta un proyecto que combina Apple Health, Python y Gemini para transformar exportaciones de datos de salud en informes clínicos estructurados. El pipeline procesa los datos de forma determinista, calcula indicadores, genera visualizaciones y utiliza un LLM únicamente para construir la narrativa del reporte.

Importante: Este es un prototipo educativo construido con datos simulados. No reemplaza el juicio médico ni está listo para producción clínica.

La arquitectura del pipeline

El proyecto sigue una arquitectura modular donde cada clase es responsable de una etapa:

HealthDataReader → HealthChartBuilder → HealthSummaryGenerator (Gemini) → HealthReportPDF
  1. Lectura y procesamiento: extrae y normaliza registros del XML exportado por Apple Health.
  2. Cálculo de métricas: produce indicadores de movilidad, cardiovasculares y sueño.
  3. Visualizaciones: genera gráficos con zonas de referencia configurables.
  4. Narrativa con IA: Gemini transforma métricas precalculadas en texto estructurado.
  5. PDF final: combina todo en un reporte profesional con ReportLab.

HealthKit: el framework detrás de los datos

HealthKit es el framework de Apple que funciona como un repositorio central donde el iPhone y Apple Watch almacenan datos de salud y fitness. Con el permiso explícito del usuario, las aplicaciones autorizadas pueden leer y escribir información a través de una API unificada.

Una de las decisiones de diseño más interesantes de HealthKit es su catálogo extenso de clases predefinidas para métricas estandarizadas. Esto asegura que el ritmo cardíaco, la glucosa o el peso siempre usen las mismas unidades, independientemente del dispositivo o aplicación que generó el registro.

Fuentes de datos comunes

  • iPhone: pasos, distancia, datos de movilidad.
  • Apple Watch: ritmo cardíaco, ECG, SpO₂, temperatura, sueño, VO₂ Max.
  • Apps de terceros: nutrición, salud mental, hidratación, medicación.
  • Dispositivos médicos BLE: glucómetros, monitores de presión arterial.

Compatibilidad con HL7 FHIR

Desde 2018, Apple permite importar registros clínicos estructurados de instituciones de salud mediante el estándar HL7 FHIR (Fast Healthcare Interoperability Resources). FHIR organiza la información en recursos modulares como Patient, Observation, Condition y MedicationRequest.

En HealthKit, estos registros se representan como objetos HKClinicalRecord de solo lectura que preservan el recurso FHIR original. El acceso requiere autorización explícita del usuario y está sujeto a la revisión de Apple.

Construyendo el pipeline paso a paso

1. Lectura de datos con HealthDataReader

La clase recibe la ruta del archivo XML exportado desde Apple Health y el período de análisis:

reader = HealthDataReader(
    xml_path="patients/alex_28m.xml",
    months=6,
).load()

El método load() ejecuta dos operaciones principales:

  • _parse_xml(): parsea el archivo y crea un DataFrame de Pandas.
  • _compute_metrics(): calcula métricas agrupadas en tres categorías:
# Métricas de movilidad y actividad
steps = self._daily_sum("StepCount")
speed = self._daily_mean("WalkingSpeed")

# Métricas cardiovasculares
hr = self._daily_mean("RestingHeartRate")
hrv = self._daily_mean("HeartRateVariabilitySDNN")
spo2 = self._daily_mean("OxygenSaturation")

# Métricas de sueño
sleep = self._daily_sum("SleepAnalysis")

Los umbrales de referencia no están hardcodeados. Se cargan desde config/params_health.yml, permitiendo actualizar los valores sin modificar el código:

threshold_steps_goal: 7000
threshold_speed_goal: 4.5
threshold_spo2_low: 95.0
threshold_sleep_goal: 7.0
threshold_hrv: 25.0

2. Preparación de datos para el LLM

En lugar de enviar todas las series temporales a Gemini, Python genera un resumen compacto y determinista que incluye:

  • Media y desviación estándar
  • Valores mínimo y máximo
  • Tendencia en el período analizado
  • Mejor y peor promedio semanal
  • Variabilidad semanal
  • Racha más larga por debajo del umbral

Esta decisión tiene dos beneficios clave:

  1. Reduce tokens y costos al evitar enviar miles de registros individuales.
  2. Mantiene los cálculos en Python —el LLM solo recibe valores verificables y los convierte en lenguaje natural.

3. Generación de gráficos clínicos

HealthChartBuilder recibe las métricas y produce visualizaciones profesionales:

  • Pasos diarios con zonas de color basadas en umbrales
  • Velocidad al caminar con línea de referencia
  • Variabilidad cardíaca (HRV) con valor mínimo
  • Saturación de oxígeno con zonas crítica, baja y normal
  • Duración de sueño con zonas de color por umbral

Cada gráfico es independiente, por lo que se puede modificar sin afectar el resto del pipeline.

4. Narrativa con Gemini

HealthSummaryGenerator utiliza tres archivos de entrada:

  • json_path: resumen compacto del paciente con métricas calculadas.
  • yml_path: umbrales de referencia desde params_health.yml.
  • prompt_path: template del prompt con instrucciones para el modelo.

El prompt se construye reemplazando placeholders con los datos reales:

prompt = self._build_prompt()
response = self.client.models.generate_content(
    model=self.model_id,
    contents=prompt,
    config=types.GenerateContentConfig(
        max_output_tokens=self.max_tokens,
    ),
)

Las instrucciones del prompt son críticas: el modelo no debe diagnosticar ni usar términos como “saludable” o “preocupante”. Solo debe describir si cada valor está por encima, dentro o por debajo del umbral configurado. La narrativa generada siempre incluye un descargo de responsabilidad visible.

5. Generación del PDF final

HealthReportPDF combina métricas, gráficos y la narrativa de Gemini en un documento estructurado con cuatro secciones:

  1. Movilidad: KPIs de pasos, velocidad, estabilidad y actividad.
  2. Cardiovascular: ritmo cardíaco en reposo, HRV, SpO₂, VO₂ Max.
  3. Sueño: duración promedio, noches bajo el mínimo y noches que cumplen la meta.
  4. Resumen generado por IA: narrativa estructurada con perfil del paciente y evaluación general.

Lecciones y consideraciones

Separar el cálculo de la interpretación

La decisión de diseño más importante fue mantener los cálculos deterministas en Python y usar Gemini solo para la narrativa. Esto proporciona:

  • Control total sobre la información que usa el modelo.
  • Reproducibilidad: cualquier persona puede verificar los mismos datos y obtener los mismos indicadores.
  • Menor costo: al resumir los datos antes de enviarlos al LLM, se reduce drásticamente el uso de tokens.

Calidad de datos

Los datos de dispositivos de consumo pueden verse afectados por:

  • Registros incompletos por batería baja o falta de sincronización.
  • Mediciones duplicadas o valores atípicos.
  • Períodos sin uso del dispositivo.

El pipeline debe validar, limpiar y normalizar los datos antes de generar cualquier análisis.

Privacidad y regulación

La información de salud es uno de los tipos de datos más sensibles. Dependiendo del país, puede estar sujeta a HIPAA (EE.UU.) o GDPR (Unión Europea). Cualquier implementación real debe incluir:

  • Consentimiento del usuario
  • Gestión de acceso
  • Minimización de datos
  • Anonimización
  • Cifrado y almacenamiento seguro

Configuración sobre personalización

Los mismos umbrales no sirven para todos los pacientes. Hacerlos configurables permite adaptar el análisis al perfil del paciente y al objetivo del monitoreo. Pero la configuración por sí sola no garantiza resultados confiables —los métodos estadísticos también deben validarse, y el pipeline debe medir la completitud de los datos.

Código y recursos

El proyecto completo, incluyendo datos simulados de tres pacientes, archivos de configuración, template de prompt y dependencias, está disponible en el repositorio:

github.com/RominaElenaMendezEscobar/apple-health-data

Para ejecutarlo localmente necesitas:

  1. Clonar el repositorio e instalar dependencias.
  2. Una exportación XML de Apple Health (o usar los datos simulados incluidos).
  3. Una API key de Gemini desde Google AI Studio.

Conclusiones

Este proyecto demuestra cómo los datos continuos de salud, el procesamiento determinista, las visualizaciones y un modelo de lenguaje pueden combinarse en un pipeline modular para transformar datos crudos en información útil.

El LLM ayuda a comunicar los resultados, pero los cálculos, las reglas de validación y los controles de calidad de datos deben seguir siendo reproducibles y verificables. La tecnología no reemplaza la supervisión humana —la potencia, y ese es precisamente su valor más importante.


Sigue explorando estos temas en el blog de DojoFullStack. Si te interesa la inteligencia artificial aplicada al desarrollo de software, la automatización de pipelines y la creación de sistemas modulares escalables, tenemos contenido diseñado para desarrolladores y emprendedores LATAM que quieren llevar sus habilidades al siguiente nivel.