Como monitorar o GPT-6 Astra em produção: o que registrar em log desde o primeiro dia

painel de logs para monitorar GPT-6 Astra em produção
Resposta rápida

Para monitorar GPT-6 Astra em produção, o mínimo é gravar de cada chamada: o snapshot do modelo, a versão do prompt, o seu X-Client-Request-Id, o _request_id da resposta, o tempo medido na sua aplicação, o objeto usage inteiro (com cached_tokens e reasoning_tokens), o reasoning.effort enviado e, em caso de falha, status mais headers de rate limit. Com esses campos você compara janelas e descobre se a queda veio de troca de snapshot, de prompt novo ou de cache perdido. As respostas armazenadas na OpenAI ficam 30 dias por padrão, então o log próprio é o que sobra depois 🙂

Ninguém percebe que a qualidade caiu no momento em que ela cai

A conta chega depois: o suporte reclama, alguém abre o painel, e a pergunta que ninguém consegue responder é "o que mudou?"

E o GPT-6 Astra é exatamente o cenário perfeito pra esse tipo de dor agora. Ele foi lançado pela OpenAI em 3 de setembro de 2026, com rollout gradual: primeiro um conjunto limitado de organizações, depois ChatGPT Plus, Pro, Business e Enterprise, além da API, Microsoft Azure e AWS Bedrock. Em 7 de setembro o catálogo do Microsoft Foundry já marcava o gpt-6-astra como generally available

Ou seja: tem MUITA gente saindo do teste e entrando em produção nesta semana, sem uma linha sequer de histórico de operação acumulado

Então bora fazer o certo desde o dia um, beleza?

O que você precisa antes de instrumentar

Nada de PC da Nasa aqui, é tudo decisão de configuração. Mas são decisões que doem depois se você deixar pra pensar em produção

  • Acesso à API OpenAI com o modelo gpt-6-astra, que é o identificador do modelo na API
  • SDK oficial, porque ele já entrega duas coisas de graça: a propriedade _request_id em toda resposta (preenchida com o header x-request-id, e sim, é pública apesar do underline) e o retry automático de erros elegíveis de rate limit, respeitando o Retry-After
  • Uma decisão consciente sobre store: por padrão as respostas ficam armazenadas por 30 dias e aparecem na página de logs em https://platform.openai.com/logs, ou podem ser recuperadas via API. Você desliga isso com store: false nos endpoints /v1/responses e /v1/chat/completions
  • Saber se a sua organização usa Zero Data Retention. Com ZDR habilitado o store é sempre tratado como false, mesmo que a sua requisição peça true. Se ninguém te avisou disso, o log "que existe no painel" simplesmente não existe
  • Admin API key separada, se você quiser puxar uso e custo pelos endpoints administrativos (falo deles lá embaixo)

Tome cuidado com o terceiro e o quarto item juntos: é o combo clássico de time que acha que tem histórico e descobre no pior dia possível que não tem

Formação Claude Code
Formação Recomendada

Formação Claude Code

Domine Claude Code do absoluto zero até o avançado

  • 114 aulas
  • 4 projetos
  • 9h 18min

Passo a passo: montando o log de cada chamada do GPT-6 Astra

A regra mental é simples: o log tem que permitir reconstruir a chamada sem ela na frente

Se o campo não te ajuda a responder "o que era diferente ontem?", ele é enfeite

  1. Fixe um snapshot em vez de alias, e grave o identificador que você usou

A OpenAI oferece snapshots de modelo justamente pra travar uma versão específica e manter comportamento e desempenho consistentes. A lista de snapshots e aliases fica na página do modelo, e é de lá que você tira o valor exato

import os

MODEL = os.environ["ASTRA_SNAPSHOT"]  # snapshot fixo, copiado da página do modelo

log["model_requested"] = MODEL

O erro comum deste passo: chamar o alias, gravar a string genérica no log e depois não ter como provar qual versão respondeu naquela terça

  1. Grave a versão do prompt, e grave também como metadata na chamada

Esse é o campo que transforma "acho que mexemos no prompt" em filtro. Dá pra criar avaliações a partir das completions armazenadas usando data source do tipo stored_completions com filtros de metadata, por exemplo usecase e prompt-version

resp = client.chat.completions.create(
    model=MODEL,
    messages=messages,
    store=True,
    metadata={"usecase": "suporte-triagem", "prompt-version": "2026-09-08-a"},
)

O erro comum: versionar o prompt no Git e não mandar a versão junto da chamada. O Git sabe o que mudou, mas não sabe qual chamada usou o quê

  1. Gere o seu próprio ID antes da chamada e guarde o da resposta depois

O cliente pode enviar um identificador por requisição no header X-Client-Request-Id, que NÃO é adicionado automaticamente: você define na mão. E a resposta traz o _request_id, que vem do x-request-id. A própria OpenAI recomenda registrar esses IDs em produção pra facilitar o suporte

import uuid

client_request_id = str(uuid.uuid4())
log["client_request_id"] = client_request_id

resp = client.responses.create(
    model=MODEL,
    input=payload,
    extra_headers={"X-Client-Request-Id": client_request_id},
)

log["request_id"] = resp._request_id

O erro comum: guardar só o _request_id. Se a chamada morrer no timeout, o x-request-id nunca chega até você, e aí o único fio que sobra é o ID que VOCÊ gerou

  1. Meça o tempo do lado da aplicação, do envio ao fim da resposta
import time

t0 = time.perf_counter()
resp = client.responses.create(model=MODEL, input=payload)
log["latency_ms"] = round((time.perf_counter() - t0) * 1000)

O erro comum: assumir que alguém guarda essa métrica por você. Tempo percebido pelo seu usuário é o tempo medido no seu código, incluindo fila, rede e retry

  1. Persista o objeto usage inteiro, não só o total

O usage da Responses API traz input_tokens, output_tokens, total_tokens, input_tokens_details.cached_tokens e output_tokens_details.reasoning_tokens

u = resp.usage
log["input_tokens"] = u.input_tokens
log["output_tokens"] = u.output_tokens
log["total_tokens"] = u.total_tokens
log["cached_tokens"] = u.input_tokens_details.cached_tokens
log["reasoning_tokens"] = u.output_tokens_details.reasoning_tokens

O erro comum: salvar total_tokens e achar que resolveu. Entrada, saída e entrada em cache têm preços diferentes, e o token de raciocínio some dentro do total se você não separar

  1. Registre o esforço de raciocínio que você pediu

O controle é reasoning.effort na Responses API e reasoning_effort na Chat Completions. Os valores possíveis dependem do modelo e incluem none, minimal, low, medium, high, xhigh e max

effort = "medium"
resp = client.responses.create(
    model=MODEL,
    input=payload,
    reasoning={"effort": effort},
)
log["reasoning_effort"] = effort

O erro comum deste passo é bem concreto: no GPT-6 Astra, definir none retorna HTTP 400. Se você copiou config de outro modelo, é aqui que quebra

  1. Registre o erro com status, corpo e headers de rate limit

A API retorna headers de limite em cada resposta: x-ratelimit-limit-tokens, x-ratelimit-remaining-requests, x-ratelimit-remaining-tokens, x-ratelimit-reset-requests e x-ratelimit-reset-tokens. Ao estourar o limite vem um 429, que pode incluir Retry-After (segundos) e retry-after-ms (milissegundos)

try:
    resp = client.responses.create(model=MODEL, input=payload)
except Exception as e:
    err_resp = getattr(e, "response", None)
    headers = err_resp.headers if err_resp is not None else {}
    log["status"] = getattr(e, "status_code", None)
    log["error_body"] = str(e)
    log["rl_limit_tokens"] = headers.get("x-ratelimit-limit-tokens")
    log["rl_remaining_tokens"] = headers.get("x-ratelimit-remaining-tokens")
    log["rl_remaining_requests"] = headers.get("x-ratelimit-remaining-requests")
    log["rl_reset_tokens"] = headers.get("x-ratelimit-reset-tokens")
    log["rl_reset_requests"] = headers.get("x-ratelimit-reset-requests")
    log["retry_after"] = headers.get("retry-after")
    raise

Repare que os cinco headers entram no log, os dois de remaining e os dois de reset, mais o teto de tokens. É esse conjunto que deixa a resposta óbvia depois

O erro comum: logar só a mensagem de erro. Sem os headers você não distingue "bati no teto de tokens" de "bati no teto de requisições", que são reações completamente diferentes

  1. Registre safety_identifier e prompt_cache_key, sem confundir os dois

O antigo campo user foi separado em dois: safety_identifier é o identificador estável de usuário final, usado pra detecção de abuso, com no máximo 64 caracteres. O prompt_cache_key influencia o roteamento pro cache de prompt

resp = client.responses.create(
    model=MODEL,
    input=payload,
    safety_identifier=user_hash,          # estável por usuário final
    prompt_cache_key="suporte-triagem-v3",  # roteamento de cache
)
log["safety_identifier"] = user_hash
log["prompt_cache_key"] = "suporte-triagem-v3"

O erro comum: tratar prompt_cache_key como promessa. Ele influencia o roteamento, não fixa a requisição numa máquina nem garante acerto de cache. Quem confirma o acerto é o cached_tokens do passo 5

O resumo dos campos:

Campo no seu log De onde vem Responde qual pergunta
model_requested snapshot que você fixou mudou a versão do modelo?
prompt-version seu código e o metadata mudou o prompt?
client_request_id header X-Client-Request-Id qual chamada foi essa, mesmo sem resposta?
request_id _request_id / x-request-id o que levar pro suporte
latency_ms medido na aplicação ficou lento pra quem?
usage completo usage da resposta por que ficou caro?
reasoning_effort o que você enviou pediu mais raciocínio sem querer?
status + headers de limite erro da API é teto de tokens ou de requisições?

Como padronizar os campos com as convenções GenAI do OpenTelemetry

Antes de inventar nome de campo, olha o que já existe. As convenções semânticas GenAI do OpenTelemetry padronizam os atributos de cada chamada de modelo dentro do namespace gen_ai.*

Os que você vai usar todo dia:

  • gen_ai.provider.name
  • gen_ai.operation.name
  • gen_ai.request.model
  • gen_ai.usage.input_tokens
  • gen_ai.usage.output_tokens

Um aviso operacional importante: os atributos de chat e embeddings já estão estáveis o bastante pra dashboard de produção, enquanto as convenções de agentes e orquestração de ferramentas ainda estão se acomodando. Trate essa segunda parte como provisória e não construa alerta crítico em cima dela ainda

O erro comum aqui é aquele que parece inofensivo: batizar tudo de tokens_in e tokens_out porque é mais curto. Aí seis meses depois você quer plugar uma ferramenta que fala gen_ai.* e tem que reescrever dashboard, alerta e query. Chato demais

Do log ao diagnóstico: como achar a causa quando a qualidade cai

Agora a parte que justifica todo o trabalho acima. Cada cenário abaixo é um campo virando conclusão

"A resposta piorou e ninguém fez deploy":

Compare model_requested e prompt-version entre a janela boa e a janela ruim

Se o snapshot gravado é o mesmo nas duas janelas, você acabou de eliminar a hipótese mais assustadora sem discussão. Se você gravou só o alias, essa comparação é impossível, e o time vai passar o dia chutando

"Ficou lento e ficou caro do nada":

Olhe reasoning_tokens e cached_tokens lado a lado

Subida de reasoning_tokens com reasoning_effort igual é um sinal. Queda de cached_tokens é outro, e esse pesa direto no bolso: entrada em cache custa US$ 1,00 por 1 milhão de tokens, contra US$ 10 por 1 milhão de entrada sem cache, ou seja, 90% mais barato. Um prefixo de prompt que mudou de lugar transforma chamada barata em chamada cara sem alterar uma vírgula da resposta

"Falha intermitente, mas só às vezes":

Olhe os 429 e os headers de limite que você guardou no passo 7

Lembre que os SDKs oficiais já repetem erros elegíveis de rate limit e respeitam o Retry-After. Então parte do que o usuário viu como "lentidão" é retry silencioso funcionando. Sem log de status e sem latency_ms medido na aplicação, esse comportamento fica invisível

"A chamada sumiu":

Timeout ou falha de rede, nenhum x-request-id de volta, nada no seu lado

É literalmente o caso pro qual o X-Client-Request-Id existe: é o identificador que você definiu ANTES de mandar, então ele sobrevive mesmo quando a resposta não volta

Custo e consumo: o que os endpoints administrativos entregam

Tem hora que o log da aplicação não fecha a conta, principalmente quando existem vários projetos e várias chaves girando

Aí você cruza com os endpoints administrativos da organização, que exigem Admin API key:

curl "https://api.openai.com/v1/organization/usage/completions?bucket_width=1h&group_by=model" \
  -H "Authorization: Bearer $OPENAI_ADMIN_KEY"

curl "https://api.openai.com/v1/organization/costs" \
  -H "Authorization: Bearer $OPENAI_ADMIN_KEY"

O endpoint de uso aceita bucket_width de 1m, 1h ou 1d (padrão 1d) e group_by por project_id, user_id, api_key_id, model, batch e service_tier. Já o de custos agrupa por project_id, line_item e api_key_id

E é aqui que separar entrada, saída e cache no seu log muda a conversa. Na API OpenAI o GPT-6 Astra custa US$ 10 por 1 milhão de tokens de entrada e US$ 50 por 1 milhão de tokens de saída

Saída é cinco vezes a entrada. Uma feature que ficou verbosa não aparece como "bug", aparece como fatura. Se você ainda está decidindo se o Astra compensa no seu projeto, é essa separação de campos que dá a resposta em número em vez de opinião

Vale lembrar do tamanho do brinquedo também: janela de contexto de 1.050.000 tokens, máximo de 128.000 tokens de saída e corte de conhecimento em 30 de abril de 2026. Contexto gigante é ótimo, e é justamente por isso que a linha de entrada da conta merece vigilância 😀

O que o log da OpenAI não guarda por você

Essa seção existe porque muita gente monta a operação inteira em cima de uma memória que não é dela

Sintoma: você quer investigar um incidente de dois meses atrás e não acha a resposta original

Causa: a retenção padrão das respostas armazenadas é de 30 dias

Como prevenir: o dado sai pro SEU armazenamento no momento da chamada, não depois. Log de produção que depende de janela alheia é log emprestado

Sintoma: a página de logs está vazia e ninguém mexeu em nada

Causa: com Zero Data Retention habilitado, o store é sempre tratado como false, mesmo que a requisição peça true

Como prevenir: descubra isso ANTES de escrever o runbook. Se a sua organização usa ZDR, o seu log local não é redundância, é a única fonte

Sintoma: você precisa auditar quem mudou o quê e a trilha não está mais lá

Causa: os logs de auditoria da API Platform não têm período de retenção fixo nem TTL configurado, a OpenAI os mantém em regime de melhor esforço, sem garantia de disponibilidade permanente

Como prevenir: trate como fonte de apoio, nunca como registro oficial do seu processo

E tem um ponto de prazo que muda planejamento: dá pra criar avaliações a partir das completions armazenadas, com filtros de metadata como usecase e prompt-version, usando as variáveis {{item.input}} e {{sample.output_text}}. Só que a plataforma de Evals da OpenAI está sendo descontinuada: fica somente leitura pra usuários existentes em 31 de outubro de 2026 e é desligada em 30 de novembro de 2026

Ou seja: use enquanto ajuda, mas não aposte nela como memória de longo prazo. O que é seu, guarde você

Conclusão

Instrumentar no primeiro dia é o que separa duas frases muito diferentes

"A qualidade caiu" é pânico

"A qualidade caiu porque o snapshot mudou na terça" é tarefa

O próximo passo é bem concreto: escolha o snapshot na página do modelo e fixe, suba o log com os campos daquela tabela do resumo, e deixe rodar uma semana antes do volume crescer. Essa semana chata vira a sua linha de base, e linha de base é o que faz o alerta significar alguma coisa

Se você ainda está na etapa anterior, comparando saídas antes de escolher, vale registrar os resultados do teste com a mesma disciplina: o campo que você não gravou é sempre o que faltou

Bora instrumentar antes do incidente, e não durante ele… até o próximo post!

Perguntas frequentes

Como saber se os logs do GPT-6 Astra continuam existindo quando a organização usa Zero Data Retention?

Com Zero Data Retention habilitado, o parâmetro store é sempre tratado como false em /v1/responses e /v1/chat/completions, mesmo que a requisição peça true. Ou seja, a página de logs em https://platform.openai.com/logs não vai ter o histórico dessa chamada. Por isso vale confirmar com quem administra a conta se o ZDR está ativo antes de contar com esse painel como fonte de verdade.

Qual a diferença entre reasoning.effort e reasoning_effort ao configurar o GPT-6 Astra?

reasoning.effort é o campo usado na Responses API, enquanto reasoning_effort é o equivalente na Chat Completions API. Os dois aceitam os mesmos valores possíveis (none, minimal, low, medium, high, xhigh e max), mas no GPT-6 Astra especificamente o valor none não é aceito e retorna HTTP 400. O restante dos valores varia conforme o modelo.

O prompt_cache_key garante que a chamada vai acertar o cache?

Não. O prompt_cache_key influencia o roteamento para o cache de prompt, mas não fixa a requisição a uma máquina específica nem garante o acerto de cache. Vale registrar esse campo no log mesmo assim, já que ele ajuda a explicar variações de cached_tokens entre chamadas parecidas.

O que a API do GPT-6 Astra retorna quando estoura o limite de requisições?

A API responde com HTTP 429, podendo incluir os headers Retry-After (em segundos) e retry-after-ms (em milissegundos). Os SDKs oficiais já repetem automaticamente os erros elegíveis de rate limit respeitando o Retry-After, então grave nos logs também os headers x-ratelimit-remaining-requests e x-ratelimit-remaining-tokens pra enxergar o limite chegando antes do 429.

Como consultar o custo e o uso do GPT-6 Astra separado por projeto ou por modelo?

A OpenAI expõe os endpoints administrativos GET /v1/organization/usage/completions e GET /v1/organization/costs, que exigem uma Admin API key no header Authorization. O endpoint de uso aceita agrupamento por project_id, user_id, api_key_id, model, batch e service_tier, com bucket_width configurável em 1m, 1h ou 1d (padrão 1d), enquanto o de custos agrupa por project_id, line_item e api_key_id.

Por quanto tempo ficam guardados os logs de auditoria e as respostas armazenadas do GPT-6 Astra?

As respostas armazenadas por padrão ficam disponíveis por 30 dias na página de logs ou via API, salvo se store: false ou ZDR estiverem em uso. Já os logs de auditoria da API Platform não têm período de retenção fixo nem TTL configurado: a OpenAI os mantém em regime de melhor esforço, sem garantia de disponibilidade permanente.



Escrito por | Matheus Battisti

Matheus Battisti
Fundador da Hora de Codar

Programador apaixonado pelo mundo das tecnologias, sempre buscando em aprender e se aprofundar em linguagens, frameworks e o que mais for necessário para executar um bom trabalho. Agora tem uma nova missão que é de passar seu conhecimento adiante para formar novos programadores e especializar mais os que já são.

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 27min

Blog | Mais populares