HealthQuery

Especificação do Agente

Spec Driven Development — HealthQuery v0.3

v0.3 16/05/2026 7 ferramentas 6 intents 18 regras
Visão Geral

Agente de consulta a dataset de saúde via linguagem natural. O usuário faz uma pergunta em português, espanhol ou inglês — o agente interpreta, gera SQL SELECT, executa no banco conectado e devolve a resposta em texto com o raciocínio exposto.

Opera sobre 5 tabelas: pacientes, consultas, diagnosticos, medicamentos, exames. Limite de 30 queries por sessão. Nenhum dado é modificado.

Capacidades

O que o agente faz

  1. Aceita perguntas em linguagem natural em PT, ES e EN
  2. Classifica a intenção via modelo Haiku antes de qualquer outra chamada
  3. Gera SQL SELECT compatível com o banco conectado (SQLite em prep, Teradata no evento)
  4. Executa a query e trata o resultado — linhas retornadas, resultado vazio, erro de SQL
  5. Devolve resposta em 3 partes: resposta direta + SQL gerado (sempre exposto) + raciocínio
  6. Suporta perguntas multi-step: decompõe em sub-queries, informa quantas vai usar antes de executar
  7. Gerencia contador de queries: avisa quando restam 5, encerra quando chega a 30
  8. Loga cada interação com intenção classificada, SQL, tempo de execução, tokens
  9. Memória conversacional com sliding window de 30 mensagens — suporta refinamentos anafóricos
  10. Sugestões de próxima pergunta pós-resposta, no idioma do usuário
  11. Modo relatório — sintetiza histórico da sessão sem incrementar o contador

O que o agente não faz

  1. Nenhuma escrita — sem INSERT, UPDATE, DELETE, DROP, CREATE, ALTER (bloqueio programático)
  2. Não responde perguntas fora do domínio do dataset
  3. Não formula diagnósticos médicos nem dá conselhos clínicos
  4. Não executa SQL passado diretamente pelo usuário
  5. Não referencia tabelas fora das 5 definidas no schema (bloqueio programático)
  6. Não continua após o limite de 30 queries
  7. Não inventa dados — se não encontrou no banco, diz que não encontrou
7 Ferramentas
Ferramenta Função
execute_sql NL→SQL principal com guard rails multicamada
detect_anomalies Compara resultado_valor com referencia_min/max, calcula desvio %, classifica alterado/crítico
compare_periods 2 queries de agregação, diff absoluto + variação percentual por coluna
rank_patients CTE com 4 fatores ponderados, top N com score e justificativa
patient_profile 4 queries internas, síntese em prosa clínica pelo Sonnet
trend_analysis Divide registros em 2 metades, compara médias, interpreta relativo à faixa de referência
calculate Evaluador AST seguro para crescimento composto, exponencial, fórmulas multi-passo
Guard Rails

Guard rails são validações programáticas no código, não no prompt. O modelo não decide o que é permitido — o código decide antes.

Guard Rail Tipo Trigger Ação
Escrita bloqueada Programático Haiku classifica como write_attempt Bloqueia, responde sem chamar banco
Query limit Programático Contador ≥ 30 Encerra sessão
Schema enforcement Programático SQL referencia tabela fora das 5 definidas Rejeita antes de executar
PII + diagnóstico sensível Programático Query retornaria nome + condição sem agrupamento Força agregação ou recusa
check_pii_result Programático Resultado real contém coluna nome + colunas clínicas Bloqueia — captura SELECT * e split-queries
Comportamento por Situação
1

Pergunta clara, query direta

Classifica como data_query, gera SELECT, executa, devolve resultado com SQL e raciocínio.

2

Pergunta ambígua

Faz 1 pergunta de clarificação por turno. Se ainda ambígua, escolhe a interpretação mais comum e informa qual escolheu.

3

Pergunta fora do domínio

Classifica como out_of_scope e informa que opera exclusivamente sobre o dataset de saúde.

4

Tentativa de escrita ou modificação

Haiku classifica como write_attempt → bloqueio programático antes de chegar no modelo principal ou no banco.

5

Query retorna vazio

Não inventa dados, não especula. Informa que nenhum resultado foi encontrado para a condição consultada.

6

Erro de SQL

Captura o erro, tenta auto-corrigir uma vez (re-envia erro + SQL ao modelo). Se falhar de novo, informa o usuário. A tentativa conta no limite de 30.

7

Pergunta multi-step

Decompõe explicitamente antes de executar: informa quantas queries vai usar e o que cada uma resolve.

8

Chegando no limite

Avisa ao chegar em 5 restantes. Encerra com mensagem clara ao atingir 30. Orienta a iniciar nova sessão.

9

PII + condição sensível

Bloqueia retorno de identificadores combinados com diagnóstico específico. Oferece contagem ou agregação como alternativa. Padrão production-safe mesmo com dados fake.

10

Input não é pergunta (saudação)

Classifica como greeting, responde brevemente. Não decrementa o contador de queries.

Schema — 5 tabelas

pacientes

Coluna Tipo Descrição
id INTEGER PK Identificador
nome TEXT Nome completo
data_nascimento DATE Para calcular idade
sexo TEXT 'M' ou 'F'
cidade TEXT Cidade de residência
estado TEXT UF
plano_saude TEXT Ex: "Unimed", "SUS", "Bradesco"

consultas

Coluna Tipo Descrição
id INTEGER PK Identificador
paciente_id INTEGER FK → pacientes
data_consulta DATE Data da consulta
medico TEXT Nome do médico
especialidade TEXT Ex: "Cardiologia"
tipo TEXT 'eletiva', 'emergencia', 'retorno'
duracao_min INTEGER Duração em minutos

diagnosticos

Coluna Tipo Descrição
id INTEGER PK Identificador
paciente_id INTEGER FK → pacientes
consulta_id INTEGER FK → consultas
cid TEXT Código CID (ex: E11.9, I10)
descricao TEXT Ex: "Diabetes tipo 2"
data_diagnostico DATE Data do diagnóstico
status TEXT 'ativo', 'cronico', 'resolvido'

medicamentos

Coluna Tipo Descrição
id INTEGER PK Identificador
paciente_id INTEGER FK → pacientes
consulta_id INTEGER FK → consultas (nullable)
nome_comercial TEXT Ex: "Losartana"
principio_ativo TEXT Substância ativa
dosagem TEXT Ex: "500mg"
frequencia TEXT Ex: "2x ao dia"
data_inicio DATE Início do tratamento
data_fim DATE Fim (NULL = em uso)
status TEXT 'ativo', 'suspenso', 'concluido'

exames

Coluna Tipo Descrição
id INTEGER PK Identificador
paciente_id INTEGER FK → pacientes
consulta_id INTEGER FK → consultas (nullable)
tipo_exame TEXT 'laboratorial', 'imagem', 'funcional'
nome_exame TEXT Ex: "Glicemia em jejum"
resultado_valor REAL Para resultados numéricos (nullable)
resultado_texto TEXT Para resultados textuais
unidade TEXT Ex: "mg/dL"
referencia_min REAL Valor mínimo normal
referencia_max REAL Valor máximo normal
data_coleta DATE Data da coleta
status TEXT 'normal', 'alterado', 'critico'
Decisões de Design
Decisão Escolha Razão
Classificador de intenção Haiku (modelo) Mais robusto que regex para edge cases; custo desprezível
Guard rails Programático, não via prompt Prompt pode ser contornado; código não
Auto-correção de SQL Máximo 1 retry Loops são caros; 2 falhas sinalizam ambiguidade no input
Contagem de queries Inclui tentativas com erro Alinha com limite de 30 do hackathon
SQL sempre exposto Sim Observabilidade e credibilidade
SELECT * Nunca permitido Buraco de PII via wildcard
EXISTS para múltiplas condições EXISTS separado, não AND na mesma row Um registro de diagnóstico só tem um CID; AND retornaria vazio
tool_choice="none" na final_response Forçado Evita BadRequestError 400 quando modelo tenta gerar segunda ferramenta
Idioma PT, ES e EN Patrick trabalha em PT; hackathon é global
Observabilidade — Estrutura do Log

Cada interação é logada em logs/session_<id>.jsonl. Um registro por linha.

{
  "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 ferramentas: +detect_anomalies, +compare_periods, +rank_patients, +patient_profile, +trend_analysis, +calculate
  • 6 intents: +greeting, +report_request
  • Memória conversacional com sliding window de 30 mensagens
  • Sugestões de próxima pergunta pós-resposta
  • Modo relatório sem incrementar query_count
  • Multilíngue PT/ES/EN — classifier detecta idioma
v0.2 — 16/05/2026
  • 12 regras no SYSTEM_PROMPT (vs. 5 originais) — 7 novas surgidas de bugs em testes
  • check_pii_result: analisa colunas do resultado real, não só o SQL
  • Suporte a múltiplos tool_use blocks em paralelo
  • tool_choice="none" na final_response — corrige BadRequestError 400
  • Calibração do classifier Haiku: exemplos de clarification_needed vs. data_query
v0.1 — 15/05/2026
  • Spec inicial: visão geral, capacidades, 4 guard rails, schema 5 tabelas
  • 10 situações de comportamento documentadas
  • Estrutura do log JSONL definida

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