HealthQuery

Especificación del Agente

Spec Driven Development — HealthQuery v0.3

v0.3 16/05/2026 7 herramientas 6 intents 18 reglas
Descripción General

Agente de consulta a un dataset de salud mediante lenguaje natural. El usuario hace una pregunta en portugués, español o inglés — el agente interpreta, genera SQL SELECT, ejecuta en la base de datos conectada y devuelve la respuesta en texto con el razonamiento expuesto.

Opera sobre 5 tablas: pacientes, consultas, diagnosticos, medicamentos, exames. Límite de 30 consultas por sesión. Ningún dato es modificado.

Capacidades

Qué hace el agente

  1. Acepta preguntas en lenguaje natural en PT, ES e EN
  2. Clasifica la intención mediante el modelo Haiku antes de cualquier otra llamada
  3. Genera SQL SELECT compatible con la base de datos conectada (SQLite en preparación, Teradata en el evento)
  4. Ejecuta la consulta y procesa el resultado — filas devueltas, resultado vacío, error de SQL
  5. Devuelve respuesta en 3 partes: respuesta directa + SQL generado (siempre expuesto) + razonamiento
  6. Soporta preguntas multi-paso: descompone en sub-consultas, informa cuántas usará antes de ejecutar
  7. Gestiona contador de consultas: avisa cuando restan 5, finaliza cuando llega a 30
  8. Registra cada interacción con intención clasificada, SQL, tiempo de ejecución, tokens
  9. Memoria conversacional con ventana deslizante de 30 mensajes — soporta refinamientos anafóricos
  10. Sugerencias de siguiente pregunta post-respuesta, en el idioma del usuario
  11. Modo reporte — sintetiza historial de la sesión sin incrementar el contador

Qué no hace el agente

  1. Sin escritura — sin INSERT, UPDATE, DELETE, DROP, CREATE, ALTER (bloqueo programático)
  2. No responde preguntas fuera del dominio del dataset
  3. No formula diagnósticos médicos ni da consejos clínicos
  4. No ejecuta SQL enviado directamente por el usuario
  5. No referencia tablas fuera de las 5 definidas en el schema (bloqueo programático)
  6. No continúa después del límite de 30 consultas
  7. No inventa datos — si no encontró en la base, lo dice
7 Herramientas
Herramienta Función
execute_sql NL→SQL principal con guard rails multicapa
detect_anomalies Compara resultado_valor con referencia_min/max, calcula desvío %, clasifica alterado/crítico
compare_periods 2 consultas de agregación, diff absoluto + variación porcentual por columna
rank_patients CTE con 4 factores ponderados, top N con puntaje y justificación
patient_profile 4 consultas internas, síntesis en prosa clínica por Sonnet
trend_analysis Divide registros en 2 mitades, compara promedios, interpreta relativo al rango de referencia
calculate Evaluador AST seguro para crecimiento compuesto, exponencial, fórmulas multi-paso
Guard Rails

Los guard rails son validaciones programáticas en el código, no en el prompt. El modelo no decide qué está permitido — el código lo decide antes.

Guard Rail Tipo Trigger Acción
Escritura bloqueada Programático Haiku clasifica como write_attempt Bloquea, responde sin llamar a la BD
Límite de consultas Programático Contador ≥ 30 Cierra sesión
Schema enforcement Programático SQL referencia tabla fuera de las 5 definidas Rechaza antes de ejecutar
PII + diagnóstico sensible Programático Query devolvería nombre + condición sin agrupación Fuerza agregación o rechaza
check_pii_result Programático Resultado real contiene columna nombre + columnas clínicas Bloquea — captura SELECT * y split-queries
Comportamiento por Situación
1

Pregunta clara, consulta directa

Clasifica como data_query, genera SELECT, ejecuta, devuelve resultado con SQL y razonamiento.

2

Pregunta ambigua

Hace 1 pregunta de aclaración por turno. Si sigue ambigua, elige la interpretación más común e informa cuál eligió.

3

Pregunta fuera del dominio

Clasifica como out_of_scope e informa que opera exclusivamente sobre el dataset de salud.

4

Intento de escritura o modificación

Haiku clasifica como write_attempt → bloqueo programático antes de llegar al modelo principal o a la BD.

5

Consulta devuelve vacío

No inventa datos, no especula. Informa que no se encontraron resultados para la condición consultada.

6

Error de SQL

Captura el error, intenta auto-corregir una vez (reenvía error + SQL al modelo). Si falla de nuevo, informa al usuario. El intento cuenta en el límite de 30.

7

Pregunta multi-paso

Descompone explícitamente antes de ejecutar: informa cuántas consultas usará y qué resuelve cada una.

8

Acercándose al límite

Avisa al llegar a 5 restantes. Cierra con mensaje claro al llegar a 30. Orienta a iniciar nueva sesión.

9

PII + condición sensible

Bloquea retorno de identificadores combinados con diagnóstico específico. Ofrece conteo o agregación como alternativa. Estándar production-safe incluso con datos ficticios.

10

Input no es una pregunta (saludo)

Clasifica como greeting, responde brevemente. No decrementa el contador de consultas.

Schema — 5 tablas

pacientes

Columna Tipo Descripción
id INTEGER PK Identificador
nome TEXT Nombre completo
data_nascimento DATE Para calcular edad
sexo TEXT 'M' o 'F'
cidade TEXT Ciudad de residencia
estado TEXT UF (estado)
plano_saude TEXT Ej: "Unimed", "SUS", "Bradesco"

consultas

Columna Tipo Descripción
id INTEGER PK Identificador
paciente_id INTEGER FK → pacientes
data_consulta DATE Fecha de la consulta
medico TEXT Nombre del médico
especialidade TEXT Ej: "Cardiología"
tipo TEXT 'electiva', 'emergencia', 'retorno'
duracao_min INTEGER Duración en minutos

diagnosticos

Columna Tipo Descripción
id INTEGER PK Identificador
paciente_id INTEGER FK → pacientes
consulta_id INTEGER FK → consultas
cid TEXT Código CIE (ej: E11.9, I10)
descricao TEXT Ej: "Diabetes tipo 2"
data_diagnostico DATE Fecha del diagnóstico
status TEXT 'activo', 'crónico', 'resuelto'

medicamentos

Columna Tipo Descripción
id INTEGER PK Identificador
paciente_id INTEGER FK → pacientes
consulta_id INTEGER FK → consultas (nullable)
nome_comercial TEXT Ej: "Losartán"
principio_ativo TEXT Principio activo
dosagem TEXT Ej: "500mg"
frequencia TEXT Ej: "2 veces al día"
data_inicio DATE Inicio del tratamiento
data_fim DATE Fin (NULL = en uso)
status TEXT 'activo', 'suspendido', 'concluido'

exames

Columna Tipo Descripción
id INTEGER PK Identificador
paciente_id INTEGER FK → pacientes
consulta_id INTEGER FK → consultas (nullable)
tipo_exame TEXT 'laboratorial', 'imagen', 'funcional'
nome_exame TEXT Ej: "Glucemia en ayunas"
resultado_valor REAL Para resultados numéricos (nullable)
resultado_texto TEXT Para resultados textuales
unidade TEXT Ej: "mg/dL"
referencia_min REAL Valor mínimo normal
referencia_max REAL Valor máximo normal
data_coleta DATE Fecha de recolección
status TEXT 'normal', 'alterado', 'crítico'
Decisiones de Diseño
Decisión Elección Razón
Clasificador de intención Haiku (modelo) Más robusto que regex para edge cases; costo despreciable
Guard rails Programático, no via prompt El prompt puede ser evadido; el código no
Auto-corrección de SQL Máximo 1 retry Los loops son costosos; 2 fallos señalan ambigüedad en el input
Conteo de consultas Incluye intentos con error Se alinea con el límite de 30 del hackathon
SQL siempre expuesto Observabilidad y credibilidad
SELECT * Nunca permitido Agujero de PII via wildcard
EXISTS para múltiples condiciones EXISTS separado, no AND en la misma fila Un registro de diagnóstico solo tiene un CID; AND devolvería vacío
tool_choice="none" en final_response Forzado Evita BadRequestError 400 cuando el modelo intenta generar una segunda herramienta
Idioma PT, ES y EN Patrick trabaja en PT; el hackathon es global
Observabilidad — Estructura del Log

Cada interacción es registrada en logs/session_<id>.jsonl. Un registro por línea.

{
  "session_id": "uuid",
  "query_number": 3,
  "timestamp": "ISO8601",
  "user_input": "...",
  "intent_classified": "data_query",
  "sql_generated": "SELECT ...",
  "execution_time_ms": 120,
  "rows_returned": 47,
  "error": null,
  "model_used": "claude-sonnet-4-6",
  "input_tokens": 340,
  "output_tokens": 85
}
Changelog
v0.3 — 16/05/2026
  • 7 herramientas: +detect_anomalies, +compare_periods, +rank_patients, +patient_profile, +trend_analysis, +calculate
  • 6 intents: +greeting, +report_request
  • Memoria conversacional con ventana deslizante de 30 mensajes
  • Sugerencias de siguiente pregunta post-respuesta
  • Modo reporte sin incrementar query_count
  • Multilingüe PT/ES/EN — clasificador detecta idioma
v0.2 — 16/05/2026
  • 12 reglas en SYSTEM_PROMPT (vs. 5 originales) — 7 nuevas surgidas de bugs en pruebas
  • check_pii_result: analiza columnas del resultado real, no solo el SQL
  • Soporte a múltiples bloques tool_use en paralelo
  • tool_choice="none" en final_response — corrige BadRequestError 400
  • Calibración del clasificador Haiku: ejemplos de clarification_needed vs. data_query
v0.1 — 15/05/2026
  • Spec inicial: descripción general, capacidades, 4 guard rails, schema 5 tablas
  • 10 situaciones de comportamiento documentadas
  • Estructura del log JSONL definida

HealthQuery — AI Agent Hackathon Pilot — Teradata Global Services — Junio 2026