Skip to content
· 18 min read

11 Truques Para Tornar a Sua Aplicação de IA Rápida

Técnicas práticas para reduzir latência e melhorar a performance percebida em aplicações de IA — desde a escolha do modelo até padrões de UI.

Jan Schulte
Jan Schulte

Founder, Betalyra

ai performance latency llm ux
11 Truques Para Tornar a Sua Aplicação de IA Rápida

tl;dr: A maior parte da latência em IA vem da escolha do modelo, do número de output tokens e dos round-trips de tools. Resolva isso primeiro — depois otimize caching, budgets de thinking e tamanho do contexto. Os ganhos acumulam-se.

Principais Conclusões

  • Escolha do modelo + limites de output têm o maior rácio impacto/esforço
  • Faça streaming de tudo — respostas, resultados de tools, dados estruturados — o utilizador nunca deve ficar a olhar para um ecrã em branco
  • Cada tool call interrompe a geração e arrisca um cache miss — desenhe tools orientadas ao caso de uso, não wrappers CRUD
  • A estrutura do prompt determina a taxa de cache hit — estático no topo, dinâmico no fundo, 80–95% de cache hits alcançáveis
  • Compacte agressivamente, falhe rápido — resuma o histórico a cada turno, valide structured output em mid-stream, empurre todo o pós-processamento para background queues

Nos últimos dois anos temos vindo a construir interfaces conversacionais de IA para os nossos clientes — e recentemente lançámos o Cuttlekit, a nossa visão para o futuro da generative UI. Fazer a IA parecer rápida tem sido uma prioridade de topo. Aqui está o que aprendemos.


1. Escolha um Modelo Rápido

A escolha do modelo continua a ser a maior alavanca de latência: comece com o modelo mais rápido que faz o trabalho de forma fiável e só escale para cima quando a qualidade o exigir.

Os modelos frontier costumam dar os melhores resultados, mas são geralmente os mais lentos. Modelos mais pequenos são muito mais baratos, muito mais rápidos e frequentemente suficientes para formatação, extração, classificação, respostas curtas e muitas tarefas que alimentam a UI. O nosso modelo de referência atual é o Gemini Flash — boa qualidade a uma fração da latência. Aqui fica uma visão geral do que existe.

Modelos pequenos

Variantes de foundation models

Todos os grandes fornecedores oferecem variantes mais pequenas e rápidas dos seus modelos flagship. Trocam alguma profundidade de raciocínio por latência dramaticamente inferior:

  • Gemini Flash / Flash Lite — excelente rácio qualidade/velocidade, um dos melhores modelos que testámos para aplicações de alta performance
  • OpenAI Mini & Nano models — modelos leves otimizados para velocidade e custo, fortes em structured outputs
  • Anthropic Haiku — o modelo mais rápido da família Claude, ideal para pipelines de alto throughput

Modelos OSS rápidos

Os modelos open source são frequentemente uma boa opção para aplicações sensíveis à latência. Pode fazer self-host para latência mínima, usar as APIs oferecidas pelos próprios criadores, ou executá-los através de inference providers especializados (ver abaixo). Os modelos chineses em particular obtêm frequentemente pontuações altas em benchmarks:

  • Deepseek — raciocínio forte com poucos parâmetros
  • Qwen — família de modelos da Alibaba, competitiva em código e tarefas multilingues
  • Hermes da NousResearch — fine-tuned para instruction following e function calling
  • Minimax — modelos multimodais rápidos
  • GLM da Zhipu AI — modelos multilingues com forte suporte para chinês
  • Mistral — modelos europeus open-weight, excelentes para deployments alojados na UE

Fornecedores focados em performance

Se não quer fazer self-host, estes fornecedores especializam-se em inference de baixa latência para modelos open source:

  • Groq — silício custom (LPUs) construído de raiz para inference; oferece modelos Llama, Qwen e Kimi com TPS excecional
  • TogetherAI — catálogo amplo de modelos OSS com throughput competitivo e endpoints serverless
  • Fireworks.ai — plataforma de inference otimizada com serving de baixa latência e suporte para fine-tuning
  • OpenRouter — meta-router para comparar latência e custo entre fornecedores sem alterar código

Modelos de text diffusion

Uma nova classe de modelos que gera o output completo de uma vez em vez de token a token, tornando-os inerentemente mais rápidos que transformers autorregressivos. Ainda em fase inicial, mas vale a pena acompanhar:

Métrica: Tokens per second (TPS) — a velocidade a que o modelo produz output. Compare entre modelos e fornecedores para encontrar o seu sweet spot de velocidade/qualidade.

Model Routing

Não se comprometa com um único modelo. Encaminhe pedidos por complexidade da tarefa: use um modelo rápido e barato para queries simples e reserve o modelo frontier para tarefas que realmente necessitam de raciocínio profundo. Isto reduz significativamente a latência média sem sacrificar qualidade onde ela importa.

Model Router
live
What's the weather?
SIMPLE
Fast Model
~50ms TTFT
routed
Frontier
~800ms TTFT
routed

Há várias formas de implementar routing, do simples ao sofisticado:

Simples: Classificação baseada em LLM

Use um modelo pequeno e rápido com um prompt de classificação para decidir que modelo deve tratar o pedido:

System: Classify the user message as either SIMPLE or COMPLEX.
SIMPLE: greetings, factual lookups, short answers, formatting.
COMPLEX: multi-step reasoning, code generation, analysis, creative writing.
Respond with a single word: SIMPLE or COMPLEX.

Isto adiciona uma chamada LLM rápida antes do pedido real — mas essa chamada usa um modelo minúsculo com output tokens mínimos, portanto o overhead é baixo.

Mais inteligente: Classificação baseada em logprobs

Alguns fornecedores (nomeadamente a OpenAI) expõem logprobs — a log-probabilidade que o modelo atribui a cada output token. Em vez de gerar uma resposta completa, peça um único token com max_tokens: 1 e logprobs: true, depois compare diretamente as probabilidades dos seus tokens de classificação:

// Response with logprobs
{
  "token": "SIMPLE",
  "logprob": -0.12
}

Os logprobs são sempre logaritmos naturais (base e) de probabilidades. Para converter de volta: e^(-0.12) ≈ 0.89, logo o modelo tem 89% de confiança que a resposta é SIMPLE. Se estiver acima do seu threshold, encaminhe para o modelo rápido. Caso contrário, use o modelo frontier.

Isto é mais rápido e barato do que gerar uma resposta de classificação completa porque só produz um único token e toma a decisão a partir da distribuição de probabilidades.

Avançado: Classificação baseada em embeddings

Use um encoder model para calcular o embedding do prompt de entrada e compare-o usando cosine similarity com embeddings pré-calculados das suas categorias de classificação. Nenhuma chamada LLM generativa necessária em tempo de inferência — apenas um passo de embedding mais uma comparação vetorial rápida.

  1. Pré-calcule embeddings para prompts representativos de cada categoria
  2. Em runtime, calcule o embedding do prompt recebido
  3. Compare com os seus embeddings de referência usando cosine similarity
  4. Encaminhe com base na correspondência mais próxima

Isto é extremamente rápido porque os embedding models são muito mais baratos e rápidos que modelos generativos, e a comparação por cosine similarity em si é essencialmente gratuita.

Fornecedores como a Jina AI já oferecem isto como solução chave-na-mão — classificação zero-shot e few-shot sem treinar um modelo.

Mais sofisticado: Classificador fine-tuned

Para máxima precisão, faça fine-tune de um pequeno modelo de classificação empilhando uma camada densa sobre um encoder model pré-treinado. Treina com exemplos rotulados do seu tráfego real, para que o classificador aprenda os seus padrões de routing específicos.

Bons modelos base para isto:

  • EmbeddingGemma — modelo de embeddings da Google baseado no Gemma 3
  • Jina AI Embeddings — modelos de embeddings multilingues construídos de raiz para classificação e retrieval
  • Mixedbread Embeddings — modelos de embeddings de alta qualidade com resultados fortes em benchmarks

Isto dá-lhe um classificador sub-milissegundo que corre em CPU com precisão quase perfeita no seu workload específico — mas requer dados de treino rotulados e um passo de treino inicial.


2. Minimize os Output Tokens

Os output tokens são a parte computacionalmente mais cara da inferência. É por isso que a maioria dos fornecedores cobra 2–4x mais por output tokens do que por input tokens. Cada token que o modelo não gera é tempo poupado, dinheiro poupado e latência reduzida.

Structured output: otimize o seu schema

Para structured output (JSON, function calls), o seu output schema determina diretamente a contagem de tokens. Nomes de atributos mais curtos e valores compactos significam menos tokens. Use o Tokenizer Playground para verificar como o seu schema é tokenizado — a diferença pode ser significativa:

Token Comparison (GPT-4 tokenizer)
Verbose schema33 tokens
{"task_title":"Review quarterly report","assigned_to":"marketing","due_date":"2026-04-15","is_completed":false,"priority_level":"high"}
Compact schema28 tokens
{"t":"Review quarterly report","to":"marketing","due":"2026-04-15","done":false,"p":"h"}
Saved:5 tokens (−15%)× 1000 items = 5000 tokens saved

15% menos tokens por item — e isso acumula-se rapidamente quando está a fazer streaming de centenas de resultados. Pode sempre mapear o output compacto do LLM para o seu schema de domínio completo num passo de pós-processamento. O modelo não precisa de chaves legíveis por humanos — o seu código precisa. Cada token não gerado é um bom token.

Geração de texto: instrua para brevidade

Para respostas de texto, seja explícito no system prompt:

Answer in 1–2 sentences max. No preamble, no filler, no "Sure! Here's...".
Skip summaries and recaps. Lead with the answer.
If a list, use short bullet points, not paragraphs.

Métrica: Number of output tokens (NOT) — total de tokens gerados por resposta. Monitorize isto nos seus prompts e otimize os piores casos primeiro.


3. Faça Streaming de Tudo

JSONL Streaming vs Blocking
Streaming JSONL
0/5 items
Blocking JSON
Generating full list...
same time, worse UX

Streaming é o standard da indústria — os utilizadores esperam-no. Não reduz o tempo total de geração, mas melhora dramaticamente a velocidade percebida porque os utilizadores começam a ler enquanto o modelo gera. Um TTFT de 200–400ms parece instantâneo; 3 segundos de espera em branco parece avariado.

Para structured output, use JSONL — um item por linha em vez de um array JSON completo. Items de todo, linhas de tabela, resultados de pesquisa — cada um é renderizado assim que é gerado, sem esperar pelo bracket de fecho.

Faça streaming dos outputs de tool calls também. Quando o seu agente invoca outro LLM — um summariser, um sub-agente — essa chamada interna deve fazer streaming de volta para o utilizador. Caso contrário: streaming inicial rápido, pausa morta durante a execução da tool, depois mais texto. Faça streaming de toda a cadeia, não só do modelo exterior.

Métrica: Time to first token (TTFT) — quanto tempo até o utilizador ver o primeiro output. Streaming não altera o tempo total, mas reduz o TTFT para quase zero.


4. Mantenha a Superfície de Tools Pequena

Cada tool call interrompe a geração — o AI SDK trata a chamada, executa a tool e alimenta o resultado de volta na próxima chamada LLM. Cada round-trip adiciona latência, e se houver um prompt cache miss (máquina diferente, cache expirado), todo o contexto é recalculado. Minimize o número de tool calls.

Desenhe tools para casos de uso, não CRUD

Não exponha a sua REST API tal como está ao modelo. Desenhe tools em torno do que a IA precisa de realizar, não da sua estrutura de dados:

Tool Design: CRUD vs Use-Case
3 CRUD-style calls — 3 round-trips700ms + 3× cache recompute
getUser(id: 42)200ms
getOrders(userId: 42)350ms
getPreferences(userId: 42)150ms
1 use-case call — 1 round-trip180ms
getUserDashboard(id: 42)180ms
Returns only what the AI needs — pre-formatted, paginated
Overhead saved2 fewer round-trips + 520ms less tool execution

Regras para output de tools:

  • Devolva apenas os dados que a IA precisa para a tarefa atual — nunca dumps de API em bruto
  • Pagine resultados — não devolva 500 items quando a IA precisa de 5
  • Pré-formate dados na tool — valores monetários, datas, traduções — para que a IA não desperdice tokens a convertê-los

MCP: atenção ao token budget

O MCP (Model Context Protocol) pode ser um enorme sumidouro de tokens. O custo acumula-se de vários ângulos:

  • Tamanho do schema — cada definição de tool é injetada no prompt
  • Contagem de tools — uma única ligação MCP carrega todas as suas tools, não apenas as que precisa
  • Overhead de serialização — o MCP adiciona wrapping ao nível do protocolo em cada chamada e resultado
  • Tamanho do payload de resultado — as tools MCP frequentemente devolvem mais dados do que o modelo precisa

Múltiplos fornecedores MCP podem facilmente adicionar dezenas de milhares de tokens a cada pedido. Para produção, prefira integrações diretas de tools onde controla exatamente que tools são expostas e quantos dados devolvem. Use MCP para desenvolvimento e prototipagem.

Execução de código em sandboxes

A indústria está a migrar de arquiteturas pesadas em tools para deixar o LLM escrever e executar código num ambiente sandbox. Em vez de 10 tools especializadas, dê ao modelo um code sandbox e alguns SDKs — ele escreve a integração sozinho. A Anthropic foi pioneira nesta abordagem e demonstrou até 98.7% de redução de tokens comparado com cadeias equivalentes de tools MCP.

Fornecedores SaaS de sandboxes:

  • E2B — microVMs Firecracker com ~150ms de boot, SDKs Python/JS
  • Daytona — sandboxes baseadas em Docker com ~90ms de startup
  • Vercel Sandbox — microVMs efémeras integradas com o Vercel AI SDK
  • Cloudflare Workers — sandboxing baseado em V8 isolates, cold starts extremamente rápidos

Self-hosted / OSS:

  • Boxlite — sandbox micro-VM local-first, sem daemon necessário
  • Microsandbox — sandbox microVM self-hosted construída em Rust, startup sub-200ms

Mantenha-se em Python ou TypeScript — os LLMs conhecem-nos bem e não requerem passos de compilação que abrandariam o ciclo de interação.

Métrica: Tool call overhead — número de round-trips e total de tokens consumidos por definições e resultados de tools por pedido. Menos tools, resultados mais magros, respostas mais rápidas.


5. Otimize para Prompt Caching

O prompt caching é uma das otimizações de latência com maior alavancagem. Os fornecedores fazem cache do KV state (os cálculos internos) do prefixo do seu prompt. No pedido seguinte, se o prefixo corresponder, esses cálculos são saltados por completo. Tokens em cache são processados a uma fração do custo e latência de tokens frescos.

Prompt Caching — KV Computation
System
You are a financial analyst. Answer concisely...
Docs
Q3 Report: Revenue €4.2M, EBITDA €1.1M...
History
User: Show Q3 results / AI: Revenue grew 12%...
User
Break down by region
KV cached
Computed
All 22 tokens computed

Suporte dos fornecedores

Nem todos os fornecedores tratam o caching da mesma forma:

  • OpenAIautomático, sem necessidade de opt-in. Mínimo de 1.024 tokens de prefixo.
  • Anthropicopt-in via breakpoints cache_control no pedido da API. Mínimo de 1.024 tokens (Sonnet/Haiku), 2.048 (Opus).
  • Google Geminiopt-in via recursos explícitos de “cached content”. Threshold mais alto: mínimo de 32.768 tokens.
  • Groqautomático, aplica-se a prefixos repetidos. Boa documentação introdutória.

Como maximizar a taxa de cache hit

Estruture o seu prompt do mais estático para o mais dinâmico. O cache faz matching a partir do topo — no momento em que algo muda, tudo o que vem depois é cache miss.

  1. System prompt (estático) — instruções, formato de output, definições de tools. Nunca muda entre pedidos e deve estar sempre no topo.
  2. Documentos (semi-dinâmico) — knowledge base, dados de referência, contexto obtido por retrieval. Muda ocasionalmente.
  3. Histórico (semi-dinâmico) — turnos de conversa. Cresce mas o prefixo mantém-se estável.
  4. Mensagem do utilizador (dinâmico) — o pedido atual. Sempre no fundo.

Evite colocar conteúdo dinâmico no system prompt. Um erro comum: injetar um timestamp como "Current time: 2026-04-01T19:45:00Z" na mensagem de sistema. Isto invalida todo o cache a cada pedido porque o prefixo muda. Se precisa da hora atual, coloque-a na mensagem do utilizador no fim.

Pré-aqueça o cache — envie um pedido de priming no início da sessão (por exemplo, com uma mensagem de utilizador vazia) para que a primeira interação real do utilizador já encontre um cache quente.

Métrica: Cache hit rate — percentagem de input tokens servidos a partir do cache. Monitorize isto no dashboard do seu fornecedor. Um prompt bem estruturado pode atingir 80–95% de cache hit rates em aplicações conversacionais.


6. Desative (ou Reduza) o Thinking

O extended thinking pode melhorar bastante a qualidade do output — mas à custa de latência. O thinking está agora ativado por defeito na maioria dos foundation models principais — se não o configurou, está a pagar esta taxa de latência em cada pedido.

Thinking Latency Calculator
Model speed100 tok/s
501002005001000
Thinking budget2.048k tokens
off5122.048k8.192k32.768k
Added latency before first token+20.5s

Desative o thinking para tarefas simples, ou defina um token budget apertado para tarefas que beneficiam de algum raciocínio. Note que alguns modelos (ex. Gemini 2.5 Pro) não permitem desativar o thinking completamente — só pode reduzir o budget. Teste onde a qualidade cai abaixo do aceitável para o seu caso de uso. Pode também combinar isto com a técnica de model routing da secção 1 — use um classificador para ajustar dinamicamente o thinking budget por pedido, encaminhando queries simples com thinking desativado e complexas com budget mais alto.

Configuração por fornecedor

  • OpenAI — parâmetro reasoning_effort: low, medium, high. Defina como low ou desative para tarefas simples. Também suporta max_completion_tokens para limitar o output total incluindo raciocínio.
  • Anthropic — parâmetro thinking com budget_tokens configurável. Defina type: "disabled" para desligar, ou defina um budget baixo (ex. 1024 tokens) para raciocínio ligeiro.
  • Google Geminithinking_config com thinking_budget. Defina como 0 para desativar, ou limite a contagem de tokens.

Métrica: Number of thinking tokens (NTT) — tokens gastos em raciocínio antes do primeiro output token. Monitorize isto — é frequentemente o maior contribuidor para o TTFT em modelos modernos.


7. Compactação Agressiva de Memória

Não precisa de guardar o histórico exato da conversa — um resumo compacto é frequentemente suficiente. Os LLMs tendem a gerar respostas longas, e essas respostas tornam-se parte do contexto para cada pedido subsequente. Uma conversa de 6 turnos pode facilmente atingir mais de 1.000 tokens de histórico, a maioria redundante.

Memory Compaction
YouWhat were Q3 results?
45t
AIRevenue grew 12% YoY driven by...
320t
YouCompare to Q2
38t
AIQ2 showed 8% growth, so Q3...
280t
YouBreak down by region
52t
AIEU +18%, US +6%, APAC +14%...
410t
Context size
1145 tokens

Compacte a conversa após cada interação — resuma a troca e substitua o histórico completo. Execute a compactação assincronamente após a resposta para não bloquear o utilizador, usando um modelo rápido e barato. Os resultados de tool calls são frequentemente os piores ofensores — trunce-os agressivamente.

O que deve sobreviver à compactação: objetivos do utilizador, restrições ativas, entidades referenciadas, tarefas por resolver e preferências. Sumarização lossy que perca estes elementos vai degradar silenciosamente a qualidade. O seu prompt de compactação deve preservá-los explicitamente.

Alguns fornecedores suportam isto out of the box — veja a API de compactação da Anthropic e o seu cookbook de memória de sessão.

Isto pode reduzir as taxas de prompt cache hit, mas processar menos tokens geralmente compensa o cache miss — especialmente quando alterar o histórico da conversa causaria um miss de qualquer forma.

Métrica: Average context length (ACL) — contagem média de tokens do prompt completo entre pedidos. Se cresce ao longo do tempo, compacte mais agressivamente.


8. Seja um Homem das Cavernas

Menos input tokens = menos processamento = resposta mais rápida. Isto aplica-se ao system prompt (onde vive a maior parte do bloat) e às partes do prompt visíveis ao utilizador. Remova filler words, linguagem florida, exemplos excessivos e instruções duplicadas. Os LLMs são surpreendentemente bons a compreender prompts comprimidos.

System Prompt Compression
Original46 tokens
You are a helpful assistant that specializes in analyzing financial data. When the user asks you a question, you should provide a clear, concise, and well-structured response. Always make sure to include relevant numbers and percentages where applicable.
Savings46t16t(−65%)

Caveman compression é um framework prático para isto. A ideia central: elimine artigos, conectivos e qualificadores redundantes — mantenha apenas as palavras que carregam significado. “You are a helpful assistant that should always provide” torna-se “Provide”. Feio, eficaz.

Não faça isto às cegas: compressão agressiva funciona melhor para scaffolding de instruções repetitivas, mas tenha cuidado com regras de segurança, tratamento de edge cases e tudo onde a precisão da formulação importa.

Verifique com embeddings

Como sabe que o seu prompt comprimido ainda transmite a mesma informação? Use um embedding model para comparar a similaridade semântica entre as versões original e comprimida. Calcule o embedding de ambos os prompts (ou frases/parágrafos individuais) e compute cosine similarity — se estiver acima de 0.95, não perdeu significado. Isto permite comprimir agressivamente com confiança.

Métrica: Number of input tokens (NIT) — total de input tokens por pedido. Audite o seu system prompt regularmente — tende a crescer ao longo do tempo à medida que instruções se acumulam.


9. Empurre Trabalho Pesado para Background Queues

Mantenha o loop de interação principal curto. Apenas a resposta em si deve bloquear o utilizador. Tool calls demoradas e qualquer pós-processamento devem ser empurrados para fora do loop principal para uma background queue.

Sync vs Background
Main loop
Generate responsewaiting
User sees response immediately
Background queue
Compact memoryqueued
Update embeddingsqueued
Log analyticsqueued

Se uma tool executa uma operação com side effects (escrita em BD, chamada de API), torne-a async — confirme imediatamente, execute em background. Pós-processamento como compactação de memória, atualização de embeddings, analytics e logging vão todos para a queue. Dispare tarefas independentes em paralelo, não sequencialmente.


10. Falhe Rápido e Tente de Novo

Quando gera structured output para alimentar uma UI — conversacional, agêntica ou generativa — o LLM pode produzir dados inválidos que quebram as coisas. Não espere até a resposta completa estar gerada para validar. Valide cada chunk estruturado assim que chega no stream. No momento em que algo inválido aparece, pare o stream imediatamente e tente de novo. Não faz sentido gerar mais centenas de output tokens a partir de uma resposta quebrada.

Fail Fast — Validate While Streaming
Attempt 1streaming...
Retrywaiting
Validating each chunk as it arrives...

Na prática: faça parse de cada linha JSONL ou chunk estruturado assim que chega e valide contra o seu schema. No momento em que um chunk falha, aborte o stream, adicione o erro ao prompt (para o modelo aprender com o erro) e tente de novo. Isto é mais rápido do que gerar uma resposta completa quebrada e regenerar do zero.


11. Buffer de Pedidos Rápidos

Isto é mais relevante para IDE copilots, editores em tempo real e UIs que mudam rapidamente onde os utilizadores disparam múltiplos inputs em sucessão rápida. Menos aplicável a chat standard ou fluxos transacionais.

Coloque pedidos recebidos em buffer numa queue e agrupe-os numa única chamada LLM em vez de processar cada um sequencialmente.

Request Buffering
Message queueempty
LLM
Idle — waiting for queue

Se um novo pedido substitui o atual, considere cancelar a geração em curso — pode não valer a pena terminar uma resposta desatualizada. Avançado: use interrupções de tool calls como checkpoints — cada tool call pausa a geração, dando-lhe um momento natural para verificar a queue por novas mensagens. Este é o padrão que o Cursor usa.


Todos estes onze são aplicáveis hoje, e a maioria pode ser adotada incrementalmente. Não os aplique todos de uma vez: identifique a parte mais lenta do seu loop de interação e resolva essa primeiro.

Se está a construir interfaces de IA e quer discutir algum destes tradeoffs — entre em contacto.

Queres saber mais sobre como a IA pode transformar o teu negócio?

Marcar chamada