MedPrompt
Voltar ao catálogo
Metaprompting

Prompt de Extração Estruturada com JSON Schema

Template para extração estruturada de dados de texto não estruturado, validado com JSON Schema


Prompt

Você é prompt engineer especializado em structured outputs, autor de pipelines em produção que extraem dados clínicos com >95% acurácia. Domina OpenAI Structured Outputs, Anthropic tool use, Gemini schema grounding e validação com JSON Schema (Draft 2020-12).

<contexto> - TIPO DE INPUT: [EX: laudo de exame, evolução clínica, paper, prontuário] - DADOS A EXTRAIR: [campos] - CARDINALIDADE: [um por input, lista, hierárquico] - LÍNGUA: [PT-BR, EN] - VOLUME: [...] - VALIDAÇÃO PÓS-EXTRAÇÃO: [necessária] </contexto>

Estrutura do prompt

Você é extrator de dados estruturados.

Receberá: {tipo de input}. Sua tarefa: extrair os campos definidos no schema abaixo.

REGRAS:

  1. Extraia APENAS o que está explicitamente no texto.
  2. Para campos ausentes, retorne null.
  3. NÃO invente valores.
  4. Se ambíguo, retorne null e adicione a "uncertainty_flags".
  5. Padronize unidades (SI quando aplicável).
  6. Datas em ISO 8601.

JSON SCHEMA: {schema}

INPUT: {input}

OUTPUT (JSON válido apenas, sem prosa):

JSON Schema (template Draft 2020-12)

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "ExtractedClinicalData",
  "type": "object",
  "required": ["patient_token", "extraction_metadata"],
  "additionalProperties": false,
  "properties": {
    "patient_token": {
      "type": "string",
      "description": "token pseudonimizado"
    },
    "vitals": {
      "type": "object",
      "properties": {
        "blood_pressure_systolic": {"type": ["number", "null"], "minimum": 50, "maximum": 250},
        "blood_pressure_diastolic": {"type": ["number", "null"]},
        "heart_rate": {"type": ["number", "null"]},
        "temperature_celsius": {"type": ["number", "null"]},
        "spo2": {"type": ["number", "null"], "minimum": 50, "maximum": 100},
        "respiratory_rate": {"type": ["number", "null"]}
      }
    },
    "medications": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": {"type": "string"},
          "dose": {"type": ["string", "null"]},
          "frequency": {"type": ["string", "null"]},
          "route": {"type": ["string", "null"]}
        }
      }
    },
    "diagnoses": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {"type": "string"},
          "icd10": {"type": ["string", "null"], "pattern": "^[A-Z][0-9]{2}(\\.[0-9]+)?$"},
          "primary": {"type": "boolean"}
        }
      }
    },
    "uncertainty_flags": {
      "type": "array",
      "items": {"type": "string"}
    },
    "extraction_metadata": {
      "type": "object",
      "required": ["model", "timestamp"],
      "properties": {
        "model": {"type": "string"},
        "timestamp": {"type": "string", "format": "date-time"},
        "confidence_score": {"type": "number", "minimum": 0, "maximum": 1}
      }
    }
  }
}

Implementação por modelo

OpenAI (Structured Outputs):

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": prompt}],
    response_format={"type": "json_schema", "json_schema": schema, "strict": True}
)

Anthropic (Tool Use):

tools = [{"name": "extract", "input_schema": schema}]
response = client.messages.create(model="claude-opus-4-7", tools=tools, ...)

Gemini (Schema Grounding):

response = model.generate_content(prompt, generation_config={"response_schema": schema, "response_mime_type": "application/json"})

Validação pós-extração

import jsonschema
try:
    jsonschema.validate(instance=extracted, schema=schema)
except jsonschema.ValidationError as e:
    # log erro, retentar ou flag para humano

Métricas de qualidade

  • Validity rate: % outputs JSON válidos
  • Field-level accuracy vs gold standard
  • Hallucination rate (campos inventados)
  • Coverage (campos extraídos quando presentes)

Requisitos de estilo

  • Schema explícito e estrito
  • Sem em-dashes ou en-dashes
  • Permitir null em campos opcionais
  • Padronizar unidades
  • Validar sempre

Input necessário

Este prompt combina paste de amostra dos documentos e schema-alvo com entrevista breve.

Cole abaixo algumas amostras dos documentos de input (receitas, relatórios, formulários). ANTES de colar dados reais, REMOVA PII, PHI e qualquer identificador (nomes, CPF, telefones, prontuários). Use apenas dados sintéticos ou pseudonimizados.

[COLE AQUI AMOSTRAS DEIDENTIFICADAS]

Em paralelo, responda em até 8 perguntas por rodada:

  • Tipo de documento de origem
  • Schema-alvo (campos obrigatórios, tipos, enums)
  • Volume (documentos/dia)
  • Modelo alvo e tolerância a custo
  • Campos opcionais vs obrigatórios
  • Padronização de unidades (SI, custom)
  • Validação automática pós-extração
  • Gold standard disponível para avaliação

Como usar

  1. Defina schema antes de prompt
  2. Use structured outputs nativo do modelo
  3. Valide com jsonschema lib
  4. Trate erros (retry com schema reforçado)
  5. Avalie campo a campo vs gold standard

Exemplo

Entrada:

  • Input: evolução clínica em texto livre
  • Dados: sinais vitais, medicamentos, diagnósticos

Saída esperada: Schema completo Draft 2020-12, prompt com regras explícitas e schema embutido, OpenAI structured outputs strict mode, validação jsonschema, métricas em eval set 100 evoluções: validity 100%, field accuracy 94%, hallucination <2%, coverage 91%. Retry automático em caso de validation error.

Variações

  • Extração de paper científico (PICO + outcomes): schema com population, intervention, comparator, outcomes, results
  • Extração de receita médica: schema com prescriber, patient, medications array, signatures
  • Extração para data warehouse: schema com tipos SQL-compatíveis, foreign keys