Todos os artigos

// Knowledge.log — 技術記事

Coding agent com teto de custo: token budget e circuit breaker por tarefa

Defina limite mensal, encerre tarefas longas e leve tokens e custo por PR ao CI sem expor prompts nem esperar a fatura chegar.

Um coding agent recebe a tarefa de corrigir um teste. Ele lê metade do repositório, tenta um refactor, desfaz o refactor, compacta o contexto e continua. O PR ainda não existe, mas a tarefa já consumiu o que deveria sustentar várias correções pequenas. Um agente desgovernado tem uma habilidade peculiar para comer o orçamento do mês antes de encontrar o if errado.

O resultado que queremos é verificável: cada tarefa termina dentro de um limite de turnos e tempo, grava tokens e custo num usage.json, e o CI recusa o artefato que ultrapassa a política do repositório. Acima disso, o provedor mantém um teto financeiro mensal para impedir que uma chave ou projeto comprometa a organização inteira.

São três camadas diferentes. Confundi-las deixa um buraco justamente onde o time esperava proteção:

  1. Backstop financeiro do provedor: limita o dano mensal quando o provedor oferece essa função.
  2. Kill switch da tarefa: encerra uma execução antes que ela vire o orçamento inteiro.
  3. Gasto observável: atribui tokens e dólares à tarefa ou ao PR e permite um gate no CI.

Se o repositório ainda não definiu permissões, revisão e isolamento do agente, vale fechar primeiro os gates antes do primeiro PR. Controle de custo não compensa credencial ampla.

Camada 1: o teto mensal não substitui o teto da tarefa

A OpenAI oferece alertas e hard spend limits mensais no nível da organização e do projeto. O alerta envia e-mail, mas mantém o tráfego. O hard limit passa a responder 429 com organization_spend_limit_exceeded ou project_spend_limit_exceeded. A documentação de spend limits avisa que a aplicação não é instantânea, então pode haver pequena ultrapassagem.

Um limite por projeto isola o ambiente do agente; o limite da organização é o último anteparo da conta. Com uma Admin key, o teto organizacional de US$ 100 mensais pode ser configurado assim — threshold_amount usa centavos:

curl -X POST https://api.openai.com/v1/organization/spend_limit \
  -H "Authorization: Bearer ***" \
  -H "Content-Type: application/json" \
  -d '{"threshold_amount":10000,"currency":"USD","interval":"month"}'

A correção concreta é criar um projeto dedicado ao agente, usar chaves desse projeto e aplicar limites no projeto e na organização. Em produção, acompanhe os erros project_spend_limit_exceeded e organization_spend_limit_exceeded, além do painel de uso. Não trate x-ratelimit-remaining-tokens como saldo: esse header mede capacidade de requisição, não a fatura. É um engano compreensível; o header tem números e a fatura também.

O cenário muda nos outros provedores. A xAI documenta RPS e TPM por tier, mas não um kill switch financeiro em dólares equivalente ao hard limit da OpenAI. A MiniMax oferece alerta de saldo no console; ele notifica quando o saldo cai abaixo do limiar, mas não encerra uma tarefa. Portanto:

  • OpenAI: hard limit mensal por projeto e organização, mais alertas.
  • MiniMax: alerta de saldo; o harness ainda precisa impor o limite da tarefa.
  • xAI: RPS/TPM controlam vazão, não dólares; o harness é responsável pelo teto financeiro por execução.

A observação segura é manter o projeto isolado e comparar diariamente os agregados do provedor com os artefatos das tarefas. RPM e TPM são úteis para estabilidade, mas não são orçamento.

Camada 2: circuit breaker por tarefa

O limite mensal pode deixar uma única execução consumir todo o mês antes de agir. A tarefa precisa de limites locais independentes: turnos, duração e custo acumulado.

No OpenAI Agents SDK, max_turns encerra o loop com MaxTurnsExceeded. Nas ferramentas agentic da xAI, max_turns conta turnos de assistente e chamadas de ferramentas; ferramentas paralelas pertencem ao mesmo turno. No Hermes, a configuração pode combinar turnos e tempo:

agent:
  max_turns: 40
  run_budget_seconds: 900
compression:
  enabled: true
  threshold: 0.50
  threshold_tokens: 120000

Os valores são uma política inicial, não um padrão universal. Calibre-os com tarefas pequenas e conhecidas, depois ajuste por classe de trabalho. Quando o limite dispara, preserve o estado, o motivo da parada e o último teste executado. Essa é a observação de produção: um término por orçamento deve ser distinguível de falha do modelo, timeout externo e teste vermelho.

Compactação também merece um rótulo correto. Ela resume ou reduz o contexto para a execução continuar; não é circuit breaker de dólares. O Codex oferece compactação e model_auto_compact_token_limit, enquanto codex exec --json emite eventos de uso. Compactar sem limitar turnos pode apenas deixar o agente gastar por mais tempo, agora com a mesa organizada.

Uma política local pode ainda abortar após três patches ou falhas de teste idênticos, comparando hashes no harness. Isso não é uma função oficial de OpenAI, xAI, MiniMax, Codex ou Hermes; é uma regra editorial do time. Observe o hash e o motivo no log, sem guardar prompt ou conteúdo sensível.

Camada 3: um usage.json que o CI consegue entender

GitHub Actions não enxerga tokens de LLM nativamente e não calcula “gasto por arquivo” a partir do diff. O agente ou seu harness precisa somar o usage de cada resposta e produzir um artefato por tarefa ou PR.

Com o Codex em modo não interativo, o JSONL fornece os contadores de cada turno:

codex exec --json "implemente apenas o teste que está falhando" > /tmp/codex.jsonl

jq -s '
  reduce (.[] | select(.type == "turn.completed") | .usage) as $u
    ({input_tokens: 0, cached_tokens: 0, output_tokens: 0};
     .input_tokens += ($u.input_tokens // 0) |
     .cached_tokens += ($u.cached_input_tokens // 0) |
     .output_tokens += ($u.output_tokens // 0))
' /tmp/codex.jsonl > usage.json

Para xAI, o rastreamento oficial de custo inclui input_tokens, output_tokens, total_tokens e cost_in_usd_ticks em cada resposta; US$ 1 corresponde a 10^10 ticks. Some todas as respostas da conversa — o campo é por requisição. Em streaming, habilite stream_options: {"include_usage": true} para receber o uso no último chunk. Para MiniMax, persista prompt_tokens, completion_tokens e prompt_tokens_details.cached_tokens de cada resposta.

Um contrato interno útil, que não é schema de nenhum fornecedor, fica assim:

{
  "task_id": "pr-184",
  "provider": "xai",
  "model": "grok-4.6",
  "input_tokens": 23000,
  "cached_tokens": 8000,
  "output_tokens": 4100,
  "usd": 0.0586
}

Esses valores são apenas um exemplo de formato. O arquivo real deve ser produzido a partir das respostas, nunca preenchido manualmente. Não inclua prompt, completion, diff ou saída de ferramenta. O identificador da tarefa e do PR já permite agregar custo sem mandar código para o dashboard.

O gate usa a política do repositório e o artefato, não alguma telepatia do GitHub:

- name: Validar orçamento da tarefa
  shell: bash
  run: |
    jq -e '
      (.input_tokens + .output_tokens) <= 120000 and
      (.usd == null or .usd <= 1.50)
    ' usage.json

- name: Publicar medição
  uses: actions/upload-artifact@v4
  with:
    name: agent-usage
    path: usage.json

O upload de artifacts do GitHub Actions conserva a evidência da decisão. A remediação para um gate excedido é reduzir o escopo e abrir uma nova tarefa com orçamento próprio, não aumentar o limite no mesmo job. Para observar em produção, agregue task_id, provider, model, tokens e usd num dashboard; nunca exponha uma Admin key a um workflow que executa código de PR não confiável.

Na OpenAI, o dashboard pode ser reconciliado sem prompts pelas Usage e Costs Admin APIs. GET /v1/organization/usage/completions agrega tokens e requisições por projeto, chave ou modelo; GET /v1/organization/costs retorna valores em USD. A Admin key fica num coletor separado do runner do PR.

Quanto cada token custa em 29 de agosto de 2026

As páginas oficiais publicam preços por 1 milhão de tokens. A tabela abaixo divide esses valores por mil; ela não mistura créditos de planos ChatGPT ou Codex com cobrança da API.

Modelo e faixaEntrada / 1kCache / 1kSaída / 1k
gpt-5.6-sol, standard shortUS$ 0,00400US$ 0,00040US$ 0,02000
grok-4.6, prompt abaixo de 200kUS$ 0,00200US$ 0,00050US$ 0,00600
MiniMax-M3, PAYG standard até 512k faturadosUS$ 0,00030US$ 0,00006 cache readUS$ 0,00120

Para gpt-5.6-sol, a tabela oficial também cobra cache write a US$ 5 por milhão; o preço promocional informado vale pelo menos até 21 de novembro de 2026. No Grok 4.6, requisições com prompt a partir de 200k dobram todos os preços da requisição. Na MiniMax M3 PAYG, os números acima são os valores faturados com o desconto permanente de 50% informado na data; acima de 512k, as taxas dobram.

Preço de tabela ajuda a definir o orçamento, mas o gate deve preferir custo faturado quando o provedor o entrega. Cache, ferramentas server-side e tiers de serviço tornam uma multiplicação ingênua insuficiente.

Verifique antes de confiar no teto

Faça uma execução barata e confirme o caminho inteiro:

  1. Verifique se cada resposta contém usage; em xAI, confirme que a soma de cost_in_usd_ticks / 10^10 coincide com o painel dentro do arredondamento.
  2. Compare o bucket diário da OpenAI Usage API com o dashboard e com a soma dos usage.json do mesmo projeto.
  3. Em um projeto descartável, configure um hard limit pequeno e confirme o 429 com project_spend_limit_exceeded. Não use a organização principal para esse ensaio.
  4. Force max_turns e run_budget_seconds em uma tarefa controlada e confirme motivo de parada, artefato e log.
  5. Valide que o workflow falha com um usage.json acima do limite e publica o artefato quando fica abaixo.

A DevDojo adotaria esse desenho quando agentes puderem executar tarefas autônomas no CI ou abrir PRs com cobrança por API. A equipe recuaria para execução manual e escopo menor se o provedor não expuser uso confiável por resposta, se o harness não conseguir interromper a tarefa ou se a reconciliação entre artefatos e fatura divergir de forma recorrente.

O próximo passo é simples: escolha uma tarefa curta, aplique limites de turno e tempo, gere o primeiro usage.json e faça o CI recusá-lo de propósito. Um circuit breaker só merece o nome depois que alguém prova que ele abre.

ai-agentsgithubdevex

// Continue.training — 次のステップ

Conhecimento só conta quando vira prática.

Volte ao artigo, execute os exemplos e compartilhe o que aprendeu.

Explorar mais artigos