Reduzir Custos de LLM: Estratégias de Otimização de Tokens

Reduza em 80% os custos de LLM com otimização inteligente de tokens

Conteúdo da página

A otimização de tokens é a habilidade crítica que separa aplicações de LLM economicamente viáveis de experimentos que esvaziam o orçamento.

Como os custos de API escalam linearmente com o uso de tokens, compreender e implementar estratégias de otimização pode reduzir despesas em 60-80%, mantendo a qualidade.

arquitetura inteligente

Compreendendo a Economia de Tokens

Antes de otimizar, você precisa entender como tokens e preços funcionam entre diferentes provedores de LLM.

Noções Básicas de Tokens

Tokens são as unidades fundamentais que os LLMs processam - equivalentes a aproximadamente 4 caracteres ou 0,75 palavras em inglês. A string “Hello, world!” contém aproximadamente 4 tokens. Diferentes modelos usam tokenizadores diferentes (GPT usa tiktoken, Claude usa o próprio), então as contagens de tokens variam ligeiramente entre provedores.

Comparação de Modelos de Preço

Preços da OpenAI (em 2025):

  • GPT-4 Turbo: $0,01 de entrada / $0,03 de saída por 1K tokens
  • GPT-3.5 Turbo: $0,0005 de entrada / $0,0015 de saída por 1K tokens
  • GPT-4o: $0,005 de entrada / $0,015 de saída por 1K tokens

Preços da Anthropic:

  • Claude 3 Opus: $0,015 de entrada / $0,075 de saída por 1K tokens
  • Claude 3 Sonnet: $0,003 de entrada / $0,015 de saída por 1K tokens
  • Claude 3 Haiku: $0,00025 de entrada / $0,00125 de saída por 1K tokens

Para uma comparação completa de Provedores de LLM na Nuvem, incluindo preços detalhados, recursos e casos de uso, confira nosso guia dedicado.

Insight Chave: Tokens de saída custam 2-5x mais que tokens de entrada. Limitar o comprimento da saída tem um impacto desproporcional nos custos.

Engenharia de Prompts para Eficiência

A engenharia de prompts eficaz reduz drasticamente o consumo de tokens sem sacrificar a qualidade.

1. Eliminar Redundâncias

Exemplo Ruim (127 tokens):

Você é um assistente útil. Por favor, ajude-me com a seguinte tarefa.
Gostaria que você analisasse o seguinte texto e me fornecesse
um resumo. Aqui está o texto que gostaria que resumisse:
[texto]
Por favor, forneça um resumo conciso dos principais pontos.

Otimizado (38 tokens):

Resuma os pontos principais:
[texto]

Economias: Redução de 70% de tokens, com qualidade de saída idêntica.

2. Usar Formatos Estruturados

JSON e saídas estruturadas reduzem o desperdício de tokens proveniente de linguagem natural verbosa.

Em vez de:

Por favor, extraia o nome, idade e ocupação da pessoa deste texto
e formate sua resposta de forma clara.

Use:

Extraia para JSON: {name, age, occupation}
Texto: [input]

3. Otimização de Aprendizado Pouco-Shot (Few-Shot)

Exemplos few-shot são poderosos, mas caros. Otimize:

  • Use o número mínimo de exemplos necessários (1-3 geralmente são suficientes)
  • Mantenha os exemplos concisos - remova palavras desnecessárias
  • Compartilhe prefixos comuns - reduza instruções repetidas
# Prompt few-shot otimizado
prompt = """Classifique o sentimento (pos/neg):
Texto: "Produto ótimo!" -> pos
Texto: "Decepcionado" -> neg
Texto: "{user_input}" ->"""

Para mais padrões de otimização em Python e atalhos de sintaxe, veja nossa Lista de Referência do Python.

Estratégias de Cache de Contexto

O cache de contexto é a otimização mais eficaz para aplicações com conteúdo estático repetido.

Como o Cache de Contexto Funciona

Provedores como OpenAI e Anthropic armazenam em cache prefixos de prompts que aparecem em múltiplas solicitações. As partes em cache custam 50-90% menos que tokens regulares.

Requisitos:

  • Conteúdo mínimo armazenável em cache: 1024 tokens (OpenAI) ou 2048 tokens (Anthropic)
  • TTL do cache: 5-60 minutos, dependendo do provedor
  • O conteúdo deve ser idêntico e aparecer no início do prompt

Exemplo de Implementação

from openai import OpenAI

client = OpenAI()

# Mensagem do sistema armazenada em cache entre solicitações
SYSTEM_PROMPT = """Você é uma IA de atendimento ao cliente da TechCorp.
Políticas da empresa:
[Documento de política grande - 2000 tokens]
"""

# Isso é armazenado em cache automaticamente
response = client.chat.completions.create(
    model="gpt-4-turbo",
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": "Como devolvo um item?"}
    ]
)

# Chamadas subsequentas dentro do TTL do cache usam o prompt do sistema em cache
# Pagando apenas pela mensagem do usuário + saída

Impacto no Mundo Real: Aplicações com bases de conhecimento ou instruções extensas veem uma redução de custos de 60-80%.

Estratégia de Seleção de Modelo

Usar o modelo certo para cada tarefa é crucial para a otimização de custos.

A Escada de Modelos

  1. GPT-4 / Claude Opus - Raciocínio complexo, tarefas criativas, precisão crítica
  2. GPT-4o / Claude Sonnet - Equilíbrio desempenho/custo, uso geral
  3. GPT-3.5 / Claude Haiku - Tarefas simples, classificação, extração
  4. Modelos menores ajustados (fine-tuned) - Tarefas repetitivas especializadas

Padrão de Roteamento

def route_request(task_complexity, user_query):
    """Roteia para o modelo apropriado com base na complexidade"""
    
    # Classificação simples - use Haiku
    if task_complexity == "simple":
        return call_llm("claude-3-haiku", user_query)
    
    # Moderado - use Sonnet
    elif task_complexity == "moderate":
        return call_llm("claude-3-sonnet", user_query)
    
    # Raciocínio complexo - use Opus
    else:
        return call_llm("claude-3-opus", user_query)

Estudo de Caso: Um chatbot de atendimento ao cliente que roteia 80% das consultas para GPT-3.5 e 20% para GPT-4 reduziu os custos em 75% em comparação com o uso do GPT-4 para tudo.

Processamento em Lote (Batch)

Para cargas de trabalho não sensíveis ao tempo, o processamento em lote oferece descontos de 50% da maioria dos provedores.

API de Lote da OpenAI

from openai import OpenAI
client = OpenAI()

# Criar arquivo de lote
batch_requests = [
    {"custom_id": f"request-{i}", 
     "method": "POST",
     "url": "/v1/chat/completions",
     "body": {
         "model": "gpt-3.5-turbo",
         "messages": [{"role": "user", "content": query}]
     }}
    for i, query in enumerate(queries)
]

# Enviar lote (50% de desconto, processamento de 24h)
batch = client.batches.create(
    input_file_id=upload_batch_file(batch_requests),
    endpoint="/v1/chat/completions",
    completion_window="24h"
)

Casos de Uso:

  • Rotulagem e anotação de dados
  • Geração de conteúdo para blogs/SEO
  • Geração de relatórios
  • Traduções em lote
  • Geração sintética de conjuntos de dados

Técnicas de Controle de Saída

Como os tokens de saída custam 2-5x mais, controlar o comprimento da saída é crítico.

1. Definir Tokens Máximos

response = client.chat.completions.create(
    model="gpt-4",
    messages=messages,
    max_tokens=150  # Limite rígido evita custos descontrolados
)

2. Usar Sequências de Parada

response = client.chat.completions.create(
    model="gpt-4",
    messages=messages,
    stop=["END", "\n\n\n"]  # Para em marcadores
)

3. Solicitar Formatos Concisos

Adicione instruções como:

  • “Responda com menos de 50 palavras”
  • “Forneça apenas tópicos”
  • “Retorne apenas JSON, sem explicação”

Streaming para Melhor UX

Embora o streaming não reduza custos, ele melhora a performance percebida e permite terminação antecipada.

stream = client.chat.completions.create(
    model="gpt-4",
    messages=messages,
    stream=True
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        token = chunk.choices[0].delta.content
        print(token, end="")
        
        # Terminação antecipada se a resposta se desviar do caminho
        if undesired_pattern(token):
            break

Otimização RAG

A Geração Aumentada por Recuperação (RAG) adiciona contexto, mas um RAG não otimizado desperdiça tokens.

Padrão RAG Eficiente

def optimized_rag(query, vector_db):
    # 1. Recuperar trechos relevantes
    chunks = vector_db.search(query, top_k=3)  # Não muitos
    
    # 2. Comprimir trechos - remover redundâncias
    compressed = compress_chunks(chunks)  # Compressão personalizada
    
    # 3. Truncar para limite de tokens
    context = truncate_to_tokens(compressed, max_tokens=2000)
    
    # 4. Prompt estruturado
    prompt = f"Contexto:\n{context}\n\nP: {query}\nR:"
    
    return call_llm(prompt)

Técnicas de Otimização:

  • Usar fragmentação semântica (não tamanho fixo)
  • Remover formatação de markdown dos trechos recuperados
  • Implementar reclassificação (re-ranking) para obter o conteúdo mais relevante
  • Considerar sumário de trechos para documentos grandes

Cache de Respostas

Armazene em cache solicitações idênticas ou similares para evitar chamadas de API inteiramente.

Implementação com Redis

import redis
import hashlib
import json

redis_client = redis.Redis()

def cached_llm_call(prompt, model="gpt-4", ttl=3600):
    # Criar chave de cache a partir do prompt + modelo
    cache_key = hashlib.md5(
        f"{model}:{prompt}".encode()
    ).hexdigest()
    
    # Verificar cache
    cached = redis_client.get(cache_key)
    if cached:
        return json.loads(cached)
    
    # Chamar LLM
    response = call_llm(model, prompt)
    
    # Armazenar resultado em cache
    redis_client.setex(
        cache_key, 
        ttl, 
        json.dumps(response)
    )
    
    return response

Cache Semântico: Para consultas similares (não idênticas), use embeddings vetoriais para encontrar respostas em cache.

Monitoramento e Análise

Rastreie o uso de tokens para identificar oportunidades de otimização.

Métricas Essenciais

class TokenTracker:
    def __init__(self):
        self.metrics = {
            'total_tokens': 0,
            'input_tokens': 0,
            'output_tokens': 0,
            'cost': 0.0,
            'requests': 0
        }
    
    def track_request(self, response, model):
        usage = response.usage
        self.metrics['input_tokens'] += usage.prompt_tokens
        self.metrics['output_tokens'] += usage.completion_tokens
        self.metrics['total_tokens'] += usage.total_tokens
        self.metrics['cost'] += calculate_cost(usage, model)
        self.metrics['requests'] += 1
    
    def report(self):
        return {
            'avg_tokens_per_request': 
                self.metrics['total_tokens'] / self.metrics['requests'],
            'total_cost': self.metrics['cost'],
            'input_output_ratio': 
                self.metrics['input_tokens'] / self.metrics['output_tokens']
        }

Alertas de Custo

Configure alertas quando o uso exceder limites:

def check_cost_threshold(daily_cost, threshold=100):
    if daily_cost > threshold:
        send_alert(f"Custo diário ${daily_cost} excedeu ${threshold}")

Técnicas Avançadas

1. Modelos de Compressão de Prompts

Use modelos dedicados para comprimir prompts:

  • LongLLMLingua
  • AutoCompressors
  • Tokens de compressão aprendidos

Estes podem alcançar razões de compressão de 10x mantendo 90%+ de desempenho na tarefa.

2. Decodificação Especulativa

Execute um modelo pequeno ao lado de um modelo grande para prever tokens, reduzindo chamadas ao modelo grande. Tipicamente acelera 2-3x e reduz custos para qualidade similar.

3. Quantização

Para modelos auto-hospedados, a quantização (4-bit, 8-bit) reduz memória e computação:

  • 4-bit: ~75% de redução de memória, perda mínima de qualidade
  • 8-bit: ~50% de redução de memória, perda de qualidade negligenciável

Se você estiver executando LLMs localmente, o Ollama oferece uma plataforma excelente para implantar modelos quantizados com configuração mínima. Para seleção de hardware e benchmarks de desempenho, nossa comparação NVIDIA DGX Spark vs Mac Studio vs RTX-4080 mostra desempenho no mundo real em diferentes configurações de hardware executando modelos quantizados grandes.

Checklist de Otimização de Custos

  • Perfil de uso atual de tokens e custos por endpoint
  • Auditoria de prompts para redundâncias - remover palavras desnecessárias
  • Implementar cache de contexto para conteúdo estático > 1K tokens
  • Configurar roteamento de modelos (pequeno para simples, grande para complexo)
  • Adicionar limites max_tokens a todas as solicitações
  • Implementar cache de respostas para consultas idênticas
  • Usar API de lote para cargas de trabalho não urgentes
  • Habilitar streaming para melhor UX
  • Otimizar RAG: menos trechos, melhor ranking
  • Monitorar com rastreamento de tokens e alertas de custo
  • Considerar ajuste (fine-tuning) para tarefas repetitivas
  • Avaliar modelos menores (Haiku, GPT-3.5) para classificação

Estudo de Caso no Mundo Real

Cenário: Chatbot de suporte ao cliente, 100K solicitações/mês

Antes da Otimização:

  • Modelo: GPT-4 para todas as solicitações
  • Tokens de entrada médios: 800
  • Tokens de saída médios: 300
  • Custo: 100K × (800 × 0,00003 + 300 × 0,00006) = $4.200/mês

Após a Otimização:

  • Roteamento de modelo: 80% GPT-3.5, 20% GPT-4
  • Cache de contexto: 70% dos prompts em cache
  • Compressão de prompt: 40% de redução
  • Cache de resposta: 15% de taxa de acerto

Resultados:

  • 85% das solicitações evitaram o GPT-4
  • 70% beneficiam-se do desconto de cache de contexto
  • 40% menos tokens de entrada
  • Custo efetivo: $780/mês
  • Economias: 81% ($3.420/mês)

Conclusão

A otimização de tokens transforma a economia dos LLM de proibitivamente cara para sustentavelmente escalável. Ao implementar compressão de prompts, cache de contexto, seleção inteligente de modelos e cache de respostas, a maioria das aplicações alcança uma redução de custos de 60-80% sem comprometer a qualidade.

Comece com as vitórias rápidas: audite seus prompts, habilita o cache de contexto e roteie tarefas simples para modelos menores. Monitore seu uso de tokens religiosamente - o que é medido é otimizado. A diferença entre uma aplicação de LLM economicamente viável e uma cara não é a tecnologia—é a estratégia de otimização.

Artigos Relacionados

Assinar

Receba novos artigos sobre sistemas, infraestrutura e engenharia de IA.