Domínio 4 — Prompt Engineering & Structured Output · Lição 6 de 7

Extended thinking, effort e Batch API

Objetivos de aprendizagem

Extended thinking nos modelos atuais: adaptativo

Extended thinking é o raciocínio interno do modelo antes da resposta. Nos modelos atuais a configuração é o thinking adaptativo: thinking={"type": "adaptive"} — o modelo decide quanto raciocinar conforme a dificuldade da tarefa. O antigo budget_tokens (thinking={"type": "enabled", "budget_tokens": N}) foi removido nos modelos atuais: enviá-lo retorna erro 400 (ele permanece apenas em modelos antigos). Em claude-opus-5, o thinking já é ativo por padrão — omitir thinking equivale a adaptativo.

output_config.effort: o controle de custo/profundidade

A profundidade (e o custo) do raciocínio é controlada por output_config={"effort": ...} com os níveis low | medium | high | xhigh | max:

EffortQuando usar
lowTarefas mecânicas de alto volume: classificação simples, extração de campos diretos, reformatação.
mediumTarefas rotineiras com algum julgamento.
highAnálise não trivial: revisão de código, extração com reconciliação de valores.
xhigh / maxProblemas difíceis de raciocínio profundo: arquitetura, depuração complexa, matemática/provas. Custo e latência máximos.

Regra de decisão: ligue effort alto quando a tarefa envolve julgamento multi-etapas cujo erro custa caro; mantenha baixo em tarefas mecânicas de volume — pagar raciocínio profundo para extrair um CNPJ é desperdício. Detalhe de API no claude-opus-5: thinking={"type": "disabled"} só é aceito com effort high ou menor — combiná-lo com xhigh/max retorna 400.

import anthropic

client = anthropic.Anthropic()

# Tarefa difícil: raciocínio adaptativo com esforço alto
response = client.messages.create(
    model="claude-opus-5",
    max_tokens=16000,
    thinking={"type": "adaptive"},
    output_config={"effort": "high"},
    messages=[{
        "role": "user",
        "content": "Reconcilie as divergências entre estes dois balancetes e explique cada ajuste.",
    }],
)

for block in response.content:
    if block.type == "thinking":
        print("[thinking]", block.thinking)
    elif block.type == "text":
        print(block.text)

Message Batches API

A Batches API processa requisições da Messages API de forma assíncrona com 50% de desconto em todos os tokens. Os fatos que caem na prova:

Janela de submissão vs SLA

Se o negócio promete resultado em até N horas e o batch pode levar até 24h, os documentos não podem "envelhecer" na fila de entrada mais do que N − 24 horas. Exemplo do exam guide: com SLA de 30h, submeter batches a cada 4 horas garante que um documento espere no máximo 4h + 24h = 28h < 30h (com folga de 2h para retries e pós-processamento). Submeter uma vez por dia (janela de 24h) estouraria: 24h + 24h = 48h.

Outra prática cobrada: em falhas parciais, reprocessar apenas os requests que falharam — identificados pelo custom_id — com as correções necessárias (ex.: dividir em chunks documentos que estouraram o contexto), em vez de reenviar o lote inteiro.

Refine antes do lote: antes de processar 50.000 documentos, rode o prompt em uma amostra representativa na API síncrona, meça a taxa de sucesso e refine. Descobrir um defeito de prompt depois de um batch de 24h custa um ciclo inteiro (e o retrabalho é cobrado). Maximizar o acerto de primeira passada é a forma de reduzir custo de resubmissão iterativa.

import time
import anthropic
from anthropic.types.message_create_params import MessageCreateParamsNonStreaming
from anthropic.types.messages.batch_create_params import Request

client = anthropic.Anthropic()

documents = {
    "doc-001": "Relatório trimestral Q3...",
    "doc-002": "Ata de reunião de 12/09...",
}

batch = client.messages.batches.create(
    requests=[
        Request(
            custom_id=doc_id,  # correlaciona resultado (pode vir fora de ordem)
            params=MessageCreateParamsNonStreaming(
                model="claude-opus-5",
                max_tokens=2048,
                messages=[{"role": "user", "content": "Resuma em 3 bullets:\n" + text}],
            ),
        )
        for doc_id, text in documents.items()
    ]
)

while True:
    status = client.messages.batches.retrieve(batch.id)
    if status.processing_status == "ended":
        break
    time.sleep(60)

failed_ids = []
for result in client.messages.batches.results(batch.id):
    if result.result.type == "succeeded":
        msg = result.result.message
        text = next((b.text for b in msg.content if b.type == "text"), "")
        print(result.custom_id, "->", text[:80])
    else:
        failed_ids.append(result.custom_id)  # só estes serão resubmetidos

print("Reprocessar apenas:", failed_ids)
flowchart TD
    A[Amostra na API síncrona] --> B{Taxa de sucesso OK?}
    B -->|Não| C[Refinar prompt/schema] --> A
    B -->|Sim| D[Submeter batch - janela compatível com SLA]
    D --> E[Poll até processing_status == ended]
    E --> F[Correlacionar resultados por custom_id]
    F --> G{Falhas parciais?}
    G -->|Sim| H[Resubmeter só os custom_ids falhos, com correções]
    G -->|Não| I[Pipeline downstream]
  

Pegadinhas da prova

Resumo em 5 linhas

  1. Modelos atuais: thinking={"type": "adaptive"}; budget_tokens foi removido (erro 400).
  2. Profundidade/custo do raciocínio: output_config.effort = low | medium | high | xhigh | max — alto só quando o julgamento difícil justifica.
  3. Batch API: 50% de desconto, até 24h, sem SLA de latência, custom_id para correlação, resultados fora de ordem, sem multi-turn tool calling.
  4. Batch para workloads tolerantes a latência (relatórios noturnos, auditorias); síncrona para fluxos bloqueantes (pré-merge).
  5. Janela de submissão = SLA − 24h (com folga); refine o prompt em amostra antes do lote e resubmeta só os falhos.

Documentação oficial

Questões de fixação

1. Código legado envia thinking={"type": "enabled", "budget_tokens": 6000} para claude-opus-5 e recebe erro 400. Qual é a correção?

2. Para reduzir custos, um gerente propõe migrar para a Batch API dois fluxos: (1) análise de risco pré-merge que bloqueia o botão de merge até concluir, e (2) auditoria semanal de contratos gerada aos domingos. Qual avaliação está correta?

3. Um contrato prevê que documentos recebidos sejam processados em até 30 horas. Usando a Batch API (janela de até 24h), qual frequência de submissão respeita o SLA?

4. (escolha duas) Num batch de 10.000 extrações, 200 falharam — parte por documentos maiores que o contexto, parte por erro de servidor. Quais ações estão corretas?