Resposta de IA cortada? Corrija finish_reason "length" e max_tokens
Sua resposta da API para no meio da frase ou retorna JSON quebrado? Verifique finish_reason, aumente max_tokens dentro do limite e adicione um passo de continuação.

Nesta página
Seu script rodou, o modelo respondeu e a função termina no meio de uma linha. Ou o parser JSON lança erro em uma resposta que parece perfeitamente normal. Na maioria das vezes o modelo não falhou: ele atingiu o limite max_tokens que você definiu (ou um padrão que você nunca viu) e a API o interrompeu no meio da palavra.
A correção rápida: leia finish_reason na resposta. Se for "length" (API compatível com OpenAI) ou stop_reason for "max_tokens" (Anthropic Messages), a resposta foi cortada. Aumente max_tokens até o limite de saída do modelo, ou peça ao modelo para continuar. O restante desta página mostra os dois em código que você pode colar.
Se você quer a versão em linguagem simples de por que isso acontece, comece por por que uma resposta de IA para no meio da frase. Esta página é a versão de depuração.
Como uma resposta cortada aparece na tela#
Os sintomas variam conforme o que você pediu, mas a causa é a mesma. Tente associar estes aos que você já viu:
Emparelhar os pares
Associe o sintoma à sua causa provável
Toque num item à esquerda, depois no seu par
- Uma função termina com
return resuA resposta de código atingiu max_tokens no meio da linha json.loadsfalha com "Unterminated string" ou "Expecting ',' delimiter"O JSON foi cortado no meio- Uma tradução para depois da primeira metade do textoO limite de saída é menor que a tradução
- A resposta está completa e o campo diz
stopO modelo terminou sozinho; procure em outro lugar
Essa última linha importa. Se finish_reason for stop, o limite não é o seu problema, e aumentar max_tokens não mudará nada.
Passo 1: leia o campo que te informa#
Toda resposta diz por que a geração terminou. Em uma resposta compatível com OpenAI é choices[0].: "stop" quando o modelo terminou, "length" quando ficou sem tokens. Na API Anthropic Messages o campo é stop_reason, e o valor de corte é "max_tokens". O guia de stop-reason da Anthropic (verificado em 28 de outubro de 2026) recomenda exatamente as duas correções abaixo: aumentar max_tokens ou continuar a resposta.
Aqui está a mesma verificação em três formas. A URL base é https:/ para o SDK da OpenAI e https:/ (sem /v1) para o SDK da Anthropic. O max_tokens=200 é deliberadamente pequeno, para você ver o corte por conta própria.
Uma verificação, três formas
Python (SDK da OpenAI)
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.cheaptokens.dev/v1",
api_key=os.environ["CHEAPTOKENS_API_KEY"],
)
resp = client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Flash-0731",
max_tokens=200,
messages=[{"role": "user", "content": "Write a Python class for a todo list with tests."}],
)
choice = resp.choices[0]
if choice.finish_reason == "length":
print("Cut off at the token limit")
print(choice.message.content)
print(resp.usage.completion_tokens)Python (SDK da Anthropic)
import os
import anthropic
client = anthropic.Anthropic(
base_url="https://api.cheaptokens.dev",
api_key=os.environ["CHEAPTOKENS_API_KEY"],
)
msg = client.messages.create(
model="deepseek-ai/DeepSeek-V4-Flash-0731",
max_tokens=200,
messages=[{"role": "user", "content": "Write a Python class for a todo list with tests."}],
)
if msg.stop_reason == "max_tokens":
print("Cut off at the token limit")
print(msg.content[0].text)curl
curl https://api.cheaptokens.dev/v1/chat/completions \
-H "Authorization: Bearer $CHEAPTOKENS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-ai/DeepSeek-V4-Flash-0731",
"max_tokens": 200,
"messages": [{"role": "user", "content": "Write a Python class for a todo list with tests."}]
}'Procure "finish_ no JSON que retorna.
Quando funciona como diagnóstico, você verá este par: um limite baixo dá length, um limite folgado dá stop.

Passo 2: aumente max_tokens, mas não além do teto#
A correção óbvia é um número maior. O detalhe: cada modelo tem seu próprio limite para a resposta. Não defina um valor acima dele: o limite é por modelo, então confira a tabela abaixo primeiro. Estes são os limites por resposta na CheapTokens (fatos verificados em 28 de outubro de 2026):
Role a tabela para a direita →
| Modelo | Saída máxima por resposta | Contexto |
|---|---|---|
| DeepSeek-V4-Flash | 32.768 tokens | 380K |
| GLM-5.3-Flash | 8.192 tokens | 390K |
| MiniMax-M2.7 | 8.192 tokens | 180K |
Uma tradução de 9.000 tokens precisa de um modelo com limite por resposta maior — o DeepSeek-V4-Flash aceita até 32.768 tokens por resposta. Para código longo, JSON longo ou um documento inteiro, deepseek- tem mais espaço: até 32.768 tokens por resposta, um preço a qualquer hora do dia. Pegue os ids exatos dos modelos na documentação da CheapTokens e na página de modelos, já que os provedores os nomeiam de forma diferente.
Uma regra prática: defina max_tokens como a resposta mais longa que você aceitaria, não como o máximo. Você paga pelos tokens que o modelo realmente escreve, então um teto alto não custa nada quando as respostas são curtas.
Passo 3: JSON que para no meio#
Uma resposta JSON cortada é o caso mais chato, porque o texto parece certo até o parser chegar ao fim. Digamos que você extraia campos de 40 notas fiscais em uma chamada e peça um array. O modelo escreve 31 objetos, atinge o limite e o array nunca fecha.

Não tente reparar a string adicionando ]}. Você obterá JSON válido com registros faltando, o que é pior que um erro. Verifique finish_reason primeiro; se for length, aumente o limite e execute a chamada de novo, ou divida a entrada em lotes menores. Para forçar o formato em si, veja JSON válido de uma API de LLM.
Passo 4: deixe o modelo continuar#
Às vezes a resposta é genuinamente maior que qualquer limite: um capítulo de livro, uma refatoração grande. Então devolva o que você tem e peça ao modelo para continuar. O loop abaixo mantém o texto obtido até agora, pede o restante e desiste após algumas rodadas para que um bug não gire para sempre.
def complete(base_messages, model, max_tokens=4096, rounds=4):
text = ""
for _ in range(rounds):
messages = list(base_messages)
if text:
messages += [
{"role": "assistant", "content": text},
{"role": "user", "content": "Continue exactly where you stopped. Do not repeat anything."},
]
r = client.chat.completions.create(model=model, max_tokens=max_tokens, messages=messages)
choice = r.choices[0]
text += choice.message.content or ""
if choice.finish_reason != "length":
return text, True # finished on its own
return text, False # still cut after all roundsDois hábitos mantêm isso honesto. Retorne o flag True/False e mostre um aviso ao usuário em False, em vez de apresentar meio documento como concluído. E lembre-se de que cada rodada reenvia o texto anterior como entrada, então uma resposta continuada custa mais que uma resposta grande única. Para dados estruturados, prefira um limite maior ou lotes menores a continuar.
Quanto custa uma resposta longa#
Digamos que uma resposta longa tenha 2.000 tokens de entrada e 8.000 tokens de saída. No DeepSeek-V4-Flash essa requisição custa $0.00083 pelo preço de hoje, e no total, com entrada e saída contadas juntas, sai mais barato que na OpenRouter. Troque os números pela sua própria carga:
Calculadora de custos
Um dia de 50 respostas longas
Tokens de entrada por solicitação: 2.000 · Tokens de saída por solicitação: 8.000 · Solicitações por dia: 50
| Modelo | Por dia | Por mês |
|---|---|---|
| GLM-5.3-Flash$0.02$0.04 | $0.018 | $0.54 |
| DeepSeek-V4-Flash$0.015$0.10 | $0.0415 | $1.25 |
| MiniMax-M2.7$0.05$0.15 | $0.065 | $1.95 |
A conclusão: o lado da saída domina neste cenário, então folga em max_tokens é um seguro barato contra uma nova execução. Uma resposta cortada que você precisa regenerar é paga duas vezes. Contexto sobre os dois lados da conta está em tokens de entrada vs saída, e a lista completa de modelos com preços está na página de preços.
Antes de publicar: uma checklist curta#
Lista de verificação
Checklist de truncamento para o seu código



