R
Interview Deckreact · next.js · senior/staff
0·0·122
IA Básico

Custos e Otimização de LLMs

Calcular e reduzir custos de API: caching, modelos menores, batching e prompt compression.

APIs de LLM cobram por token (input + output). GPT-4o: ~$2.50/1M tokens input, $10/1M output. GPT-4o-mini: $0.15/1M input, $0.60/1M output. Claude Haiku 3.5: ~$0.80/1M input. Estratégias de redução: usar modelo menor quando qualidade for suficiente, context caching (Anthropic/Google), prompt compression (remover tokens desnecessários), caching de respostas determinísticas, e semantic caching (cache por similaridade de query).

Problema
App que faz 10k chamadas/dia ao GPT-4o com prompts de 2000 tokens = $50/dia = $1500/mês. Sem estratégia de custo, escala linear com uso.
Solução
Model routing: GPT-4o-mini para queries simples (classificação, extração), GPT-4o para raciocínio complexo. Context caching para system prompts longos. Semantic caching: se a pergunta é similar a uma anterior (>95% similarity), retornar o cache em vez de chamar o LLM. Prompt compression: remover texto redundante, usar abreviações no system prompt.
Tip
A maior alavanca de custo geralmente é a escolha do modelo. GPT-4o-mini tem 90%+ da qualidade do GPT-4o para tasks comuns a 17x menor custo. Testar GPT-4o-mini primeiro, só usar GPT-4o quando a qualidade não for suficiente. Implementar fallback: tenta mini, se confidence baixa, retenta com o modelo grande.
// Model routing por complexidade
async function smartLLMCall(query: string, context?: string) {
  const isComplex = query.length > 200
    || /\b(analise|compare|implemente|arquitetura|trade-off)\b/i.test(query)
    || context && context.length > 2000

  const model = isComplex ? 'gpt-4o' : 'gpt-4o-mini'
  const cost = isComplex ? 'high' : 'low'
  console.log(`Using ${model} (complexity: ${cost})`)

  return openai.chat.completions.create({ model, messages: [...] })
}

// Semantic caching com embeddings
class SemanticCache {
  private cache = new Map<string, { embedding: number[]; response: string }>()

  async get(query: string): Promise<string | null> {
    const queryEmb = await embed(query)
    for (const [, entry] of this.cache) {
      if (cosineSimilarity(queryEmb, entry.embedding) > 0.95) {
        return entry.response // cache hit!
      }
    }
    return null // cache miss
  }

  async set(query: string, response: string) {
    const embedding = await embed(query)
    this.cache.set(query, { embedding, response })
  }
}

// Context caching Anthropic
const response = await anthropic.messages.create({
  model: 'claude-opus-4-5',
  system: [
    { type: 'text', text: LONG_SYSTEM_PROMPT,
      cache_control: { type: 'ephemeral' } // cachear este prefixo
    }
  ],
  messages: [{ role: 'user', content: userQuery }]
})
Q.O que é semantic caching para LLMs?
A.Cache por similaridade semântica: gerar embedding da query, verificar se existe query similar em cache (threshold ~95% similarity), retornar resposta cacheada se sim. Diferente de cache exato (string match), semantic cache encontra "Como fazer login JWT" como cache hit de "Tutorial de autenticação com token". Reduz custos em 40-60% em apps de Q&A com queries repetitivas. GPTCache, Langchain semantic cache.
Q.Como fazer model routing baseado em complexidade?
A.Classificar a query antes de chamar o modelo principal: query simples (extração, formatação, classificação) → modelo barato. Query complexa (raciocínio, código, análise) → modelo caro. A classificação pode ser feita com um modelo muito barato (GPT-4o-mini) ou com regras simples (tamanho do input, palavras-chave). RouteLLM é uma lib open-source para isso.
Q.Context caching da Anthropic — como funciona?
A.Prefixo do prompt (system prompt + documentos) pode ser cacheado por 5 minutos na Anthropic. Chamadas subsequentes que usam o mesmo prefixo pagam ~10% do custo para os tokens cacheados. Para apps com system prompts longos (1000+ tokens) ou RAG context inserido no prompt, o saving pode ser de 70-80%. Marcar com `cache_control: { type: "ephemeral" }`.
96/122← →