johnsmithCA-sta/health-report-trend-analysis

Análisis de tendencias de exámenes de salud de múltiples años: normaliza informes en series temporales, genera análisis de tendencias y un panel de control interactivo offline. Totalmente local.

¿Qué es health-report-trend-analysis?

Este skill permite a un agente de IA (como Claude Code, Cursor o Codex) analizar informes de exámenes físicos de múltiples años en diversos formatos (PDF electrónicos, escaneos, fotos) y transformarlos en una serie temporal estandarizada de indicadores de salud. El flujo de trabajo identifica automáticamente el tipo de entrada, extrae los datos usando técnicas de extracción de PDF o OCR, normaliza nombres y unidades, y genera un análisis de tendencias que detecta cambios significativos (≥20% o ≥30% del rango de referencia) y anomalías. Los entregables incluyen un informe en Markdown con interpretaciones detalladas y un dashboard HTML interactivo y autónomo (sin dependencias externas) que se ejecuta completamente offline. Una característica crítica es la privacidad: todo el procesamiento es local, y el skill fuerza la creación de un conjunto de datos anonimizado (sin nombres, IDs, teléfonos, direcciones) en un directorio separado con permisos de solo lectura (444) para garantizar que solo se comparta la versión segura. Es ideal para desarrolladores o usuarios avanzados que desean un análisis de salud longitudinal automatizado, seguro y totalmente controlado por el usuario.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add johnsmithCA-sta/health-report-trend-analysis

Installed? Explore more Investigación y análisis de datos skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Sistema de Análisis de Tendencias de Indicadores de Exámenes de Salud

Propósito

Unifica la interpretación de informes de exámenes de salud de múltiples años y diversos formatos (PDF electrónico, escaneos, fotos) en una serie temporal estandarizada de indicadores, produciendo un informe de análisis de tendencias y un panel de control interactivo de salud. Procesamiento completamente local, anonimización automática y extensibilidad dinámica (al agregar un nuevo informe, basta con re-ejecutar el pipeline).

Palabras Clave de Activación

  • Informes de exámenes de salud históricos / de múltiples años
  • Digitalización de datos de exámenes de salud / interpretación de exámenes
  • Tendencias de indicadores de salud / análisis de tendencias de indicadores
  • Comparación de indicadores de exámenes a lo largo de los años / cambios anuales
  • Análisis de análisis clínicos / interpretación de análisis / análisis de informes de laboratorio
  • Escaneos de informes de exámenes de salud / OCR de escaneos
  • Fotos de informes de exámenes de salud / informes tomados con teléfono móvil
  • Panel de control de salud / tablero de salud / visualización de salud
  • Tendencia de glucosa / cambio de glucosa / ácido úrico elevado / tendencia de lípidos / tendencia de presión arterial
  • Indicadores anormales en exámenes de salud / interpretación de anomalías
  • Agregar nuevo informe de examen / incorporar nuevo año
  • Anonimización de datos de exámenes de salud / conjunto de datos anonimizado / datos compartibles

Preparación del Entorno

# Dependencias (omitir si ya instaladas): pymupdf es obligatorio; Pillow (para fotos), pyobjc-framework-Vision/Quartz (OCR, solo macOS) son opcionales
export REPORT_DIR=/ruta/al/directorio/de/informes      # Directorio donde se almacenan los informes (PDF o carpetas por año + JPG)
export WORK_DIR=/ruta/al/directorio/de/trabajo        # Directorio para los datos generados (crea automáticamente data/ y output/)
export PY=/ruta/a/python                               # Se recomienda usar un intérprete de Python con las dependencias instaladas

Paso 0 (obligatorio al inicio de cada nueva sesión):

$PY scripts/check_deps.py            # Verificación rápida: qué falta, qué scripts afecta, cómo instalarlo
$PY scripts/check_deps.py --json     # Salida legible por máquina para automatización

Código de salida 0 = dependencias obligatorias completas, listo para trabajar; 1 = faltan dependencias obligatorias (el flujo principal no funcionará, seguir instrucciones para instalar); la falta de dependencias opcionales solo afecta al tipo de entrada correspondiente, sin bloquear la ruta principal de PDF electrónico.

Flujo de Ejecución

Todos los scripts soportan --help; los parámetros tienen prioridad sobre las variables de entorno; ejecutar sin parámetros = usar el comportamiento predeterminado de las variables de entorno.

  1. Identificar el tipo de entrada: Recorrer REPORT_DIR
    • Archivos *.pdf en el directorio raíz con capa de texto → Electrónico (procesado por parse_reports.py)
    • Archivos *.pdf en el directorio raíz sin capa de texto → Escaneo (vision_ocr.py + extract.py)
    • Subdirectorios por año YYYYinformes/*.JPG → Versión foto (make_year_pdfs.py para convertir → OCR → extract.py)
  2. Interpretar PDF electrónico (método de ubicación por coordenadas, límites de columnas en references/Interpretación_y_calibre.md):
    $PY scripts/parse_reports.py                        # → data/reports_raw.json
    $PY scripts/parse_reports.py --year 2027 --dry-run  # Prueba para un solo año, sin escribir en disco
    
  3. Convertir fotos a PDF + OCR + extracción (si existen directorios JPG / escaneos):
    $PY scripts/make_year_pdfs.py --year 2015-2020      # Varias JPG de un año → un único PDF (corrección automática de rotación para fotos horizontales)
    $PY scripts/vision_ocr.py <pdf> data/ocr_2022.json  # OCR de escaneo/foto → JSON con coordenadas
    $PY scripts/extract.py --year 2022                  # Resultado OCR → indicadores (estrategia automática)
    $PY scripts/extract.py --years 2015-2020            # OCR tipo dict multianual (abreviatura + rango de referencia para deducción)
    
    extract.py se parametriza por año, no necesita modificación de código para años nuevos: colocar data/ocr_<año>.json y ejecutar directamente --year <año>. La estrategia por defecto es auto (la parte superior del JSON de entrada es dict → abbr, es list → row); se puede forzar con --strategy.
  4. Normalización + construcción del conjunto de datos (mapeo de nombres/unidades, filtrado de datos sucios, inyección automática de OCR, generación de versión anonimizada):
    $PY scripts/build_dataset.py
    
    Produce data/dataset_std.json (versión completa, control local) + data/anonymized/anonymized_dataset_anon_shareable.json (versión anonimizada, subdirectorio separado + solo lectura 444 + compartible)
  5. Análisis de tendencias (determinación de anomalías según el rango del año, cambios significativos ≥20% o ≥30% del ancho de referencia, mejora/empeoramiento, enfoque en los últimos tres años):
    $PY scripts/trend_analysis.py                        # Por defecto, últimos tres años
    $PY scripts/trend_analysis.py --focus-years 2020,2023,2026
    
  6. Generar entregables:
    $PY scripts/report_generator.py    # output/Informe_de_análisis_de_tendencias_de_salud.md (por defecto **con** anonimización en el cuerpo)
    $PY scripts/build_dashboard.py     # output/health_dashboard.html (archivo único offline)
    

Guía para Incorporar Nuevos Informes

Al agregar un informe de un nuevo año, seguir la rama correspondiente según el tipo de entrada (ver references/Guía_para_incorporar_nuevos_informes.md para más detalles):

  1. Colocar el informe: Poner *.pdf en la raíz de REPORT_DIR, o crear un subdirectorio YYYYinformes/ con las JPG
  2. Identificar el tipo: Verificar la capa de texto del PDF (get_text() longitud >0 = electrónico)
    • Electrónico → ejecutar directamente parse_reports.py; si hay anomalías en los límites de columnas, imprimir primero una muestra de coordenadas de 1 página
    • Escaneo/foto → make_year_pdfs.py → vision_ocr.py → extract.py --year <año> (no crear un script por año)
  3. Actualizar diccionario (si hay indicadores no cubiertos): Agregar una línea en NAME_MAP de indicator_dict.py (el registro se encuentra en data/unrecognized)
    $PY scripts/indicator_dict.py --search ácido úrico      # Verificar si ya está cubierto (incluye alias)
    $PY scripts/indicator_dict.py --validate                # Autoverificar integridad del diccionario (alias huérfanos, claves duplicadas)
    $PY scripts/indicator_dict.py --count                   # Contar el total de indicadores estándar actuales
    
  4. Re-ejecutar el pipeline: build_dataset → trend_analysis → report_generator → build_dashboard
  5. Verificación: Confirmar que el nuevo año aparece en trend_analysis.json["years"] y en la línea de tiempo del dashboard; verificar aleatoriamente 3 indicadores clave para que coincidan con el informe; generar y validar la versión anonimizada

Reglas Clave

  • Restricción de privacidad estricta (tolerancia cero): Todo el proceso es local, el skill no contiene ninguna llamada de red externa; al completar la tarea, se debe generar y verificar la versión anonimizada (sin nombres, números de identificación, teléfonos, direcciones, hospitales); para compartir, usar solo data/anonymized/anonymized_dataset_anon_shareable.json (aislamiento estricto en directorios separados del dataset_std.json completo, solo lectura 444, para evitar compartir accidentalmente la versión completa)
  • Verificación de anonimización antes de escribir en disco: _write_anon_verified() en build_dataset.py es la única salida para escribir la versión anonimizada en disco: primero verifica en memoria, y solo escribe en disco si pasa la verificación. Una vez escrita, se establece como solo lectura 444. Si la verificación ocurriera después de escribir, cuando se detectara información de identificación personal (PII), el archivo con PII ya estaría en el disco y no se podría modificar, y [FAIL] sería solo una advertencia posterior. Está prohibido omitir esta salida y llamar directamente a _write_anon(); --skip-verify es solo para depuración, el producto no se puede compartir
  • Anonimización del cuerpo del informe: mask_identity_text en report_generator.py está activado por defecto (enmascara nombres de instituciones, nombres de médicos, números de teléfono, números de identificación); solo se desactiva con --no-mask, y es únicamente para verificación local del texto original; el producto generado no debe compartirse
  • Nuevos informes anuales: Colocar en REPORT_DIR → re-ejecutar los pasos 2→6; los indicadores no cubiertos en el diccionario se registran en data/unrecognized, agregar una línea en NAME_MAP de indicator_dict.py
  • Ubicación de datos OCR: Los indicadores extraídos por OCR se usan solo para visualización en gráficos (marcados con Ⓞ gris), no participan en la determinación de cambios significativos, para evitar contaminar las estadísticas
  • Enfoque de tendencias: La tendencia general y la comparación del primer y último año se basan únicamente en los años de enfoque (por defecto, los últimos tres años, se puede anular con --focus-years); los datos históricos solo sirven como fondo de visualización
  • Consistencia de calibre: La determinación de anomalías utiliza el rango de referencia del propio informe de ese año (se adapta automáticamente a cambios de reactivo, por ejemplo, bilirrubina directa de 0.0–4.0 a 1.7–6.8 a partir de 2025)

Entregables

  • output/Informe_de_análisis_de_tendencias_de_salud.md — Tabla resumen de indicadores, resaltado de anomalías, interpretación autorizada, recomendaciones estratificadas (estilo de vida/dieta/ejercicio/cuándo consultar al médico), metodología
  • output/health_dashboard.html — Resumen de salud, filtros de mejora/empeoramiento, gráficos de líneas con bandas de referencia, cambio de escala de tiempo (archivo único, sin dependencias externas)
  • data/anonymized/anonymized_dataset_anon_shareable.json — Conjunto de datos anonimizado compartible

Lista de Scripts

ScriptPropósitoParámetros Principales
check_deps.pyAutoverificación de dependencias (Paso 0)--json --quiet
parse_reports.pyInterpretación de PDF electrónico--report-dir --data-dir --year --out --dry-run
make_year_pdfs.pyConversión de JPG anual a PDF--report-dir --year --out-dir --dry-run
vision_ocr.pyOCR de escaneos/fotospdf out (argumentos posicionales) --dpi --quiet
extract.pyResultado OCR → indicadores (parametrizado)--year --strategy --ocr-json --out --data-dir --quiet
build_dataset.pyNormalización + versión anonimizada--work-dir --data-dir --out --skip-verify --dry-run
trend_analysis.pyDeterminación de tendencias--work-dir --focus-years --out --dry-run
report_generator.pyInforme Markdown--work-dir --out --no-mask --dry-run
build_dashboard.pyDashboard HTML--work-dir --data-dir --out --quiet
indicator_dict.pyDiccionario de indicadores (importado)--list --search --count --validate --category (solo cuando se ejecuta directamente)

El código de salida es de tres estados: 0 éxito / 1 fallo en tiempo de ejecución / 2 parámetros o condiciones previas insatisfechas.

Documentos de Referencia

DocumentoContenido
references/Guía_para_incorporar_nuevos_informes.mdPasos completos y solución de problemas para incorporar informes de nuevos tipos/años
references/Interpretación_y_calibre.mdCoordenadas de límites de columnas de PDF electrónico, definiciones de calibre
references/Metodología_OCR.mdEstrategias de OCR para escaneos/fotos, mantenimiento de tabla de mapeo de abreviaturas
evals/8 pruebas de regresión (incluyendo 3 líneas de defensa de privacidad), se pueden ejecutar con eval_loop.py --run

Ejemplo de Uso (Sesión Completa)

Usuario: «Agrega el informe del examen de salud de 2027 y actualiza el análisis de tendencias.»

  1. Paso 0: python3 scripts/check_deps.py → Dependencias obligatorias completas
  2. Verificar REPORT_DIR: encontrar nuevo archivo Informe_270510004567.pdf (electrónico, capa de texto completa)
  3. Confirmar límites de columnas con una muestra pequeña: imprimir coordenadas de 1 página, coinciden con references/Interpretación_y_calibre.md → no requiere ajuste
  4. Ejecutar pipeline:
    export REPORT_DIR=informes_de_salud WORK_DIR=/ruta/a/trabajo
    python3 scripts/parse_reports.py
    python3 scripts/build_dataset.py
    python3 scripts/trend_analysis.py
    python3 scripts/report_generator.py
    python3 scripts/build_dashboard.py
    
  5. Los registros de interpretación muestran: nuevo año con 98 indicadores, 1 nombre no reconocido → indicator_dict.py --search confirma que no está cubierto, agregar 1 línea en NAME_MAP y re-ejecutar build_dataset
  6. Verificación: trend_analysis.json["years"] contiene 2027; aparece 2027 en la línea de tiempo del dashboard; verificar aleatoriamente valores de glucosa/lípidos/IMC para que coincidan con el informe; grep en la versión anonimizada no muestra información de identidad
  7. Entrega: Informar al usuario la ruta del informe y del dashboard; explicar los cambios y recomendaciones para los indicadores anormales de 2027

Disciplina de Reducción de Costos (Obligatorio durante la Ejecución)

  1. Primero la muestra pequeña: Antes de interpretar un nuevo formato, imprimir primero una muestra de coordenadas de 1 página para confirmar los límites de columnas, luego procesar por completo (evitar volcar todo el archivo)
  2. Compresión de salida: Los comandos de depuración deben usar | head -N / python -c para extraer con precisión; está prohibido hacer cat de archivos grandes JSON
  3. Aislamiento de sub-agentes: La lectura de archivos grandes / la detección de formatos debe delegarse al sub-agente Explore; el hilo principal solo recibe la conclusión
  4. La verificación se realiza solo con una captura de pantalla final; las iteraciones intermedias se verifican con DOM/JS

Historial de Cambios

VersiónFechaCambios
1.1.02026-08-29Reforma de ingeniería concentrada: ① Los 10 scripts ahora soportan --help + argparse + código de salida de tres estados (antes 0/10, el peor); ② Nuevo check_deps.py para autoverificación de dependencias y se coloca como Paso 0; ③ Los scripts extract_2015_2020.py / extract_2022.py codificados por año se fusionan en extract.py --year parametrizado (la incorporación de nuevos años ya no requiere modificar código, el formato de salida coincide campo por campo con los scripts antiguos); ④ Nuevo capítulo ## Palabras Clave de Activación con 12 entradas + evals/ con 8 pruebas de regresión (incluyendo 3 casos de uso de líneas de defensa de privacidad); ⑤ Corrección de privacidad: La versión anonimizada ahora se «verifica primero en memoria, y solo se escribe en disco si pasa» (antes se escribía primero y luego se verificaba, cuando se detectaba PII, el archivo con información de identidad ya estaba en el disco y era de solo lectura, [FAIL] era solo una advertencia posterior); ⑥ Se corrigió código muerto en trend_analysis.py que perdía elementos de medición (measurement_items se reiniciaba después de agregar, ahora se desduplica por clave)
1.0.32026-08-23Corrección P2 M-1 (Seguridad del skill): Aislamiento estricto de la versión anonimizada — anonymized_dataset.json → data/anonymized/anonymized_dataset_anon_shareable.json (subdirectorio separado + solo lectura 444 + marcado de nombre _anon_shareable), para evitar mezclar y compartir accidentalmente la versión completa; build_dataset.py añadió _write_anon() (escritura atómica tmp+replace + chmod 444); actualización de la ruta de la declaración de privacidad en report_generator
1.0.22026-08-17Corrección P1: build_dataset.py añadió verify_anonymized al final (escaneo con regex de ID/teléfono/correo/nombre de hospital, error de salida si se detecta)
1.0.12026-08-17Corrección P0: report_generator.py añadió función de anonimización mask_identity_text (enmascaramiento de teléfono/ID/firma del médico + generalización de institución), anonimización de la capa de visualización del resumen/conclusión; alineación de la declaración de privacidad con la salida real
1.0.02026-08-16Versión inicial: Sistema de análisis de tendencias de indicadores de exámenes de salud

Skills relacionados