Pular para o conteúdo principal

Máximo de tokens e sequências de parada

Definição

Máximo de tokens, sequências de parada e penalidades de repetição são parâmetros de controle de geração que determinam quando o modelo para de gerar e como ele lida com conteúdo repetido. Enquanto parâmetros de amostragem como temperatura moldam o que o modelo diz, parâmetros de controle de geração moldam quanto ele diz, onde ele para e quão variado ele permanece durante uma resposta longa. Toda API de LLM expõe uma versão desses controles, e entendê-los é essencial para construir pipelines confiáveis e econômicos.

O máximo de tokens define um limite superior estrito sobre quantos tokens o modelo pode gerar em uma única resposta. Age como um teto de segurança: o modelo para assim que emitiria um token que ultrapasse esse orçamento. Não é um alvo de comprimento — o modelo pode parar mais cedo se gerar naturalmente um token de fim de sequência. Escolher um valor adequado de máximo de tokens é importante tanto para o custo (você geralmente é cobrado por token de saída) quanto para a correção (uma resposta truncada pode deixar objetos JSON abertos, interromper uma cadeia de raciocínio ou entregar resultados parciais a sistemas downstream).

Sequências de parada fornecem condições de parada semânticas: uma ou mais strings que, uma vez geradas, fazem o modelo parar imediatamente (a string de parada em si é excluída da saída). São indispensáveis para geração estruturada — envolver a saída do LLM em um delimitador conhecido e usar o delimitador de fechamento como sequência de parada torna a extração trivial e robusta. Penalidades de repetição (penalidade de frequência e penalidade de presença no OpenAI; não expostas nativamente na API de mensagens do Anthropic) reduzem a probabilidade de regenerar tokens que já apareceram, desencorajando loops e texto de preenchimento que podem emergir em gerações longas.

Como funciona

Cada token gerado passa por três pontos de verificação em sequência: detecção de fim de sequência, aplicação do orçamento máximo de tokens e correspondência de sequências de parada. Se nenhuma das condições de parada for acionada, a penalidade de repetição é aplicada aos logits do próximo token antes que a amostragem continue.

Máximo de tokens

O parâmetro max_tokens (chamado max_tokens_to_sample em SDKs mais antigos do Anthropic, agora max_tokens) é um campo obrigatório ou fortemente recomendado na maioria das APIs de LLM. Definir muito baixo arrisca truncar a saída; definir desnecessariamente alto desperdiça computação e aumenta a latência em endpoints de streaming. Uma heurística prática: estimar o comprimento de saída esperado, então definir max_tokens como 1,5–2× dessa estimativa como teto de segurança. Para saídas estruturadas como JSON, fazer o perfil da contagem de tokens do pior caso do seu esquema e adicionar uma margem de 20%.

Sequências de parada

Sequências de parada são definidas como uma lista de strings. O modelo verifica sua saída após cada token e para assim que o texto gerado terminar com uma entrada da lista. Padrões comuns incluem ["###", "\n\n", "</answer>", "```"] para templates de prompts estruturados, ["\nHuman:", "\nUser:"] para simuladores de chat que não devem gerar o próximo turno do usuário, e delimitadores de fechamento como ["</json>"] para extração com tags. Sequências de parada são comparadas ao texto bruto gerado, não aos limites tokenizados, então strings de múltiplos tokens funcionam corretamente. Um ponto importante: a sequência de parada não está incluída no texto retornado, então sua lógica de análise precisa considerar sua ausência.

Penalidades de repetição

A API do OpenAI expõe dois parâmetros de penalidade distintos. A penalidade de frequência (frequency_penalty, intervalo −2,0 a 2,0) reduz o logit de um token proporcionalmente ao número de vezes que ele já apareceu no texto gerado — desencorajando a repetição de palavras usadas com frequência. A penalidade de presença (presence_penalty, intervalo −2,0 a 2,0) aplica uma redução fixa de logit a qualquer token que apareceu pelo menos uma vez, independentemente da frequência — desencorajando a reutilização de qualquer token já visto. Valores positivos reduzem a repetição; valores negativos a encorajam. Valores no intervalo 0,1–0,5 são geralmente suficientes para suprimir loops sem degradar significativamente a qualidade da saída. Valores acima de 1,0 podem fazer o modelo evitar palavras de ligação úteis e degradar a coerência.

Quando usar / Quando NÃO usar

CenárioParâmetros recomendadosEvitar
Respostas factuais curtas ou classificaçõesmax_tokens=50–150; sem necessidade de sequências de paradamax_tokens muito alto; desperdiça orçamento e pode convidar ao preenchimento
Extração JSON estruturada ou com tagsParar no delimitador de fechamento (ex. ["</json>"]); max_tokens dimensionado ao esquema do pior casoOmitir sequências de parada; o modelo pode adicionar prosa após a chave de fechamento
Simulação de chat multi-turnoSequências de parada ["\nHuman:", "\nUser:"] para impedir o modelo de gerar o próximo turno do usuárioSem sequências de parada; o modelo irá alucinar o próximo turno da conversa
Geração de formato longo (ensaios, relatórios)max_tokens alto (2048–4096+); frequency_penalty=0,2 leve para evitar fraseado repetitivofrequency_penalty > 1,0; quebra a coerência estilística e evita termos repetidos legítimos
Geração de códigoParar em delimitadores apropriados ao idioma (ex. triple backtick); max_tokens dimensionado ao comprimento da funçãopresence_penalty > 0,5; nomes de variáveis e palavras-chave devem se repetir — penalidades prejudicam a correção
Inferência em lote sensível a custosDefinir max_tokens mais próximo do percentil 95 do comprimento de saída esperadoDeixar max_tokens no máximo da API (ex. 4096) quando a saída típica tem 100 tokens

Exemplos de código

OpenAI — max_tokens, stop e frequency_penalty

# OpenAI SDK: max_tokens, stop sequences, and repetition penalties
# pip install openai

import os
from openai import OpenAI

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])


def extract_with_controls(
text: str,
max_tokens: int = 512,
stop: list[str] | None = None,
frequency_penalty: float = 0.0,
presence_penalty: float = 0.0,
) -> str:
"""Call the chat API with full generation-control parameters."""
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": (
"You are a structured data extractor. "
"Output only valid JSON between <json> and </json> tags."
),
},
{"role": "user", "content": f"Extract key facts from:\n\n{text}"},
],
max_tokens=max_tokens,
stop=stop or ["</json>"],
frequency_penalty=frequency_penalty,
presence_penalty=presence_penalty,
temperature=0,
)
raw = response.choices[0].message.content
# Strip the opening tag; closing tag was consumed by stop sequence
return raw.replace("<json>", "").strip()


if __name__ == "__main__":
article = (
"SpaceX launched its Starship rocket on March 14, 2024. "
"The vehicle reached an altitude of 210 km before completing a controlled reentry. "
"It was the third integrated flight test of the system."
)

# Tight budget extraction
result = extract_with_controls(
article,
max_tokens=256,
stop=["</json>"],
frequency_penalty=0.1,
)
print(result)

# Long-form summary with anti-repetition penalty
summary_resp = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": f"Write a 3-paragraph summary of: {article}"}],
max_tokens=600,
frequency_penalty=0.4,
presence_penalty=0.1,
temperature=0.6,
)
print(summary_resp.choices[0].message.content)

Anthropic — max_tokens e stop_sequences

# Anthropic SDK: max_tokens and stop_sequences
# pip install anthropic

import os
import anthropic

client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])


def generate_with_controls(
prompt: str,
max_tokens: int = 512,
stop_sequences: list[str] | None = None,
) -> tuple[str, str]:
"""
Returns (text_content, stop_reason).
stop_reason is 'end_turn', 'max_tokens', or 'stop_sequence'.
"""
message = client.messages.create(
model="claude-opus-4-5",
max_tokens=max_tokens,
stop_sequences=stop_sequences or [],
messages=[{"role": "user", "content": prompt}],
temperature=0,
)
text = "".join(block.text for block in message.content if hasattr(block, "text"))
return text, message.stop_reason


if __name__ == "__main__":
# JSON extraction with stop sequence on closing delimiter
json_prompt = (
"Extract the event name, date, and location from the following text as JSON "
"between <json> and </json> tags:\n\n"
"The annual PyCon US conference will be held in Pittsburgh, PA on May 14-22, 2025."
)
output, reason = generate_with_controls(
json_prompt,
max_tokens=256,
stop_sequences=["</json>"],
)
print(f"Stop reason: {reason}")
print(output)

# Constrained generation — stop before model generates a second answer
answer_prompt = "Answer in one sentence: What is gradient descent?"
answer, reason = generate_with_controls(
answer_prompt,
max_tokens=100,
stop_sequences=["\n\n"],
)
print(f"Stop reason: {reason}")
print(answer)

Recursos práticos

Veja também