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.
Founder, Betalyra
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:
- InceptionLabs Mercury — primeiro modelo de text diffusion production-grade
- Google Gemini Diffusion — a entrada da Google na geração paralela de texto
- Bytedance Seed Diffusion — modelo de text diffusion da Bytedance, atualmente em beta
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.
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.
- Pré-calcule embeddings para prompts representativos de cada categoria
- Em runtime, calcule o embedding do prompt recebido
- Compare com os seus embeddings de referência usando cosine similarity
- 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:
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
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:
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.
Suporte dos fornecedores
Nem todos os fornecedores tratam o caching da mesma forma:
- OpenAI — automático, sem necessidade de opt-in. Mínimo de 1.024 tokens de prefixo.
- Anthropic — opt-in via breakpoints
cache_controlno pedido da API. Mínimo de 1.024 tokens (Sonnet/Haiku), 2.048 (Opus). - Google Gemini — opt-in via recursos explícitos de “cached content”. Threshold mais alto: mínimo de 32.768 tokens.
- Groq — automá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.
- System prompt (estático) — instruções, formato de output, definições de tools. Nunca muda entre pedidos e deve estar sempre no topo.
- Documentos (semi-dinâmico) — knowledge base, dados de referência, contexto obtido por retrieval. Muda ocasionalmente.
- Histórico (semi-dinâmico) — turnos de conversa. Cresce mas o prefixo mantém-se estável.
- 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.
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 comolowou desative para tarefas simples. Também suportamax_completion_tokenspara limitar o output total incluindo raciocínio. - Anthropic — parâmetro
thinkingcombudget_tokensconfigurável. Definatype: "disabled"para desligar, ou defina um budget baixo (ex. 1024 tokens) para raciocínio ligeiro. - Google Gemini —
thinking_configcomthinking_budget. Defina como0para 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.
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.
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.
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.
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.
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.