← Voltar ao curso
Nível 3 — Automação e escala · Módulo 3.5 — Automação: routines, headless e CI

3.5.3 · Saída estruturada e sessões multi-etapa

5 min de vídeo TEC BASIS

Objetivo: ao final, o consultor obtém JSON conforme um schema para alimentar outro sistema, e divide um trabalho longo em dois scripts que compartilham a mesma sessão.

O que você precisa levar desta aula

  1. --output-format json devolve result, session_id e o custo da chamada; com --json-schema, o objeto que obedece ao schema vem num campo separado, structured_output — não no result.
  2. Capture session_id da primeira chamada e retome com --resume "$session_id" na segunda: a segunda passada tem o contexto inteiro da primeira. Ambas precisam rodar do mesmo diretório.
  3. Para CI, --bare garante o mesmo resultado em toda máquina e --max-turns põe teto no loop, encerrando com erro ao bater o limite.

Os três formatos de saída

Formato O que entrega
text (padrão) Texto puro
json JSON com result (o texto), session_id, uso e custo (total_cost_usd, com quebra por modelo)
stream-json Uma linha JSON por evento, para consumo em tempo real. Combine com --verbose e --include-partial-messages; a última linha é a mensagem result

Saída conforme schema

claude -p "leia a pasta de controle e liste o status de cada RICEFW do Meridiano" \
  --bare \
  --output-format json \
  --json-schema '{"type":"object","properties":{"ricefw":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"tipo":{"type":"string"},"status_transporte":{"type":"string"},"pendencia":{"type":"string"}},"required":["id","status_transporte"]}}},"required":["ricefw"]}' \
  --allowedTools "Read,Glob,Grep" \
  | jq '.structured_output.ricefw'
Ponto Detalhe
Onde o objeto cai Em structured_output, ao lado dos metadados. O result continua sendo o texto
Schema inválido Error: --json-schema is not a valid JSON Schema, seguido do diagnóstico do validador, e encerra com erro. Em versões anteriores à 2.1.205, um schema inválido era ignorado silenciosamente e você recebia texto solto
A palavra format Aceita, mas tratada como anotação: "format": "email" não é validado por você
Só em print mode --json-schema funciona apenas com -p

Daí para a planilha de RICEFW é um passo: jq extrai o array, e qualquer conversor de JSON para CSV monta as colunas. O valor aqui não é o Claude "gerar uma planilha" — é a saída ter forma garantida, para que o passo seguinte do processo não precise adivinhar.

Sessão em duas passadas: plano e execução

O padrão que resolve trabalho longo com revisão humana no meio:

# 01-planejar.sh — primeira passada: produz o plano, não executa
session_id=$(claude -p "leia as 3 especificações novas da Fase 2 e proponha um plano de ajuste na documentação de integração. Não altere nenhum arquivo ainda." \
  --bare \
  --output-format json \
  --allowedTools "Read,Glob,Grep" \
  | tee plano.json | jq -r '.session_id')

echo "$session_id" > .sessao-atual
jq -r '.result' plano.json > plano.md
# 02-executar.sh — segunda passada: retoma com o contexto inteiro
session_id=$(cat .sessao-atual)

claude -p "o plano foi aprovado com os comentários em plano-revisado.md. Execute-o." \
  --resume "$session_id" \
  --bare \
  --max-turns 15 \
  --permission-mode dontAsk
Regra Por quê
Mesmo diretório nas duas chamadas A busca por session_id é limitada ao diretório do projeto e às suas worktrees
--resume "$session_id" vs --continue --resume escolhe uma sessão específica; --continue pega a mais recente, sem precisar guardar identificador. Com mais de uma conversa em andamento, use --resume
A segunda passada não reexplica a tarefa Ela já tem o contexto da primeira — inclusive o que foi lido e concluído. Reexplicar gasta contexto e cria a chance de contradizer a primeira passada

Os dois freios de CI

Flag O que faz
--bare Pula a descoberta do ambiente local (aula 3.5.2): mesmo resultado em toda máquina, porque as fontes locais nunca são lidas
--max-turns N Teto de turnos agênticos, só em print mode. Encerra com erro ao bater o limite — sem limite por padrão

Junto com --output-format json, esses dois dão a um passo de pipeline as três coisas que um passo de pipeline precisa: resultado previsível, teto de execução e custo visível por chamada.

Regra Wayon Passo de pipeline que alimenta planilha, ticket ou relatório de cliente usa --json-schema obrigatoriamente. Parser de texto livre quebra em silêncio no dia em que a redação muda, e a quebra só aparece no relatório errado que chega ao cliente. E todo -p de CI leva --max-turns: sem teto, um loop que não converge consome orçamento até alguém notar.

📖 Get structured output · Continue conversations · CLI reference

Quiz — 4 questões

1.Você rodou claude -p com --output-format json e --json-schema, e o script seguinte quebrou ao tentar ler o objeto estruturado em .result.
  • a)O objeto conforme o schema vem em structured_output; .result continua sendo o texto

    Correto. São dois campos distintos, e é o erro mais comum de quem usa schema pela primeira vez.

  • b)--json-schema não funciona junto com --output-format json

    Funcionam juntos — é justamente a combinação exigida.

  • c)O objeto vem em .result, mas como string escapada, que precisa de um segundo fromjson

    Não é o caso: existe um campo próprio para o objeto estruturado.

Ver resposta e por quê
a) Correto. São dois campos distintos, e é o erro mais comum de quem usa schema pela primeira vez.
b) Funcionam juntos — é justamente a combinação exigida.
c) Não é o caso: existe um campo próprio para o objeto estruturado.
2.Um consultor precisa que a saída alimente a planilha de RICEFW e escreveu no prompt: "responda sempre no formato: ID, tipo, status, separados por ponto e vírgula". Funciona nos testes. Qual o risco em produção?
  • a)Nenhum, se o prompt for suficientemente explícito sobre o formato

    O formato pedido em prosa é uma tendência forte, não uma garantia — e a quebra é silenciosa.

  • b)O risco é de custo: pedir formato no prompt consome mais tokens

    A diferença de custo é irrelevante; o risco real é de outra natureza.

  • c)O parser quebra em silêncio no dia em que a redação variar; --json-schema amarra a forma de verdade

    Correto. É a diferença entre pedir um formato e restringir a saída a um schema.

Ver resposta e por quê
a) O formato pedido em prosa é uma tendência forte, não uma garantia — e a quebra é silenciosa.
b) A diferença de custo é irrelevante; o risco real é de outra natureza.
c) Correto. É a diferença entre pedir um formato e restringir a saída a um schema.
3.Um script gera o plano de ajuste de documentação e um segundo script deve executá-lo depois da aprovação, com todo o contexto da primeira passada. O segundo script roda a partir do diretório home do usuário, e não do diretório do projeto.
  • a)Funciona: --resume busca a sessão pelo identificador em qualquer diretório

    A busca por identificador de sessão é limitada ao diretório do projeto e às suas worktrees.

  • b)Não vai encontrar a sessão — rode as duas chamadas do mesmo diretório

    Correto. É a pegadinha mais comum do padrão de duas passadas.

  • c)Funciona, mas perde o contexto da primeira passada, retomando só o último turno

    Quando encontra a sessão, --resume traz o contexto inteiro; o problema aqui é não encontrar.

Ver resposta e por quê
a) A busca por identificador de sessão é limitada ao diretório do projeto e às suas worktrees.
b) Correto. É a pegadinha mais comum do padrão de duas passadas.
c) Quando encontra a sessão, --resume traz o contexto inteiro; o problema aqui é não encontrar.
4.Num pipeline de CI, você quer que uma execução que não converge seja interrompida em vez de girar consumindo orçamento. ---
  • a)--max-turns N, que encerra com erro ao bater o limite

    Correto. Sem essa flag não há limite por padrão.

  • b)--bare, que reduz o escopo do que o Claude pode fazer

    --bare resolve reprodutibilidade e tempo de partida, não põe teto no número de turnos.

  • c)--output-format json, que expõe o custo e permite abortar

    O custo aparece ao final da chamada, o que é útil para acompanhar gasto, mas não interrompe uma execução em andamento.

Ver resposta e por quê
a) Correto. Sem essa flag não há limite por padrão.
b) --bare resolve reprodutibilidade e tempo de partida, não põe teto no número de turnos.
c) O custo aparece ao final da chamada, o que é útil para acompanhar gasto, mas não interrompe uma execução em andamento.