Leve seus embeddings para o cliente: um playbook de CTO para busca privada e rápida

Por Diogo Hudson Dias
Engineer testing an offline search feature on a laptop and smartphone in a São Paulo office, network cable unplugged.

Você ainda está fazendo POST de texto de usuário para uma API de embeddings de terceiros. Isso funcionou em 2024. Em 2026, é preguiçoso, lento, caro e cada vez menos compatível. A comunidade acabou de lançar um modelo de embeddings de 7 MB que roda no navegador (WASM). Modelos pequenos e locais estão ganhando tração exatamente onde a rede é pouco confiável. O recado é claro: uma fatia grande da busca semântica e do pré-processamento de RAG pertence ao cliente.

Isso não é purismo. É um redesenho pragmático que reduz o gasto com inferência, fortalece a postura de privacidade e derruba a latência para “parece instantâneo”. Se você lidera um time de engenharia em uma startup ou scale‑up, precisa de um framework de decisão claro sobre quando mover embeddings para a borda e como fazer isso com segurança.

O que mudou desde 2024

  • Os modelos encolheram. Uma nova leva de modelos minúsculos de embeddings (por exemplo, um modelo WASM de ~7 MB destacado no Hacker News) agora roda totalmente offline no navegador. Você não precisa mais de um download de 200–500 MB para obter vetores aceitáveis.
  • Maturidade do runtime. WebAssembly SIMD, threads e WebGPU elevaram os limites. Em laptops intermediários, gerar embeddings de um parágrafo não parece mais compilar o Chromium.
  • Offline voltou a ser normal. Você viu isso com mapas offline FOSS e a tendência mais ampla de “modelos pequenos em redes pouco confiáveis”. Usuários esperam que funcionalidades centrais funcionem com o Wi‑Fi desligado.
  • A pressão por privacidade aumentou. IDs de dispositivo, telemetria silenciosa e rastreamento entre apps estão nos holofotes. Enviar texto bruto para endpoints de embeddings está cada vez mais difícil de justificar para o jurídico, auditores e clientes enterprise.

Quando embeddings no cliente fazem sentido

Nem toda recuperação é igual. Mova os 60% certos para o cliente e deixe o resto como está.

Bons candidatos

  • Busca e RAG com escopo por usuário. Notas, tickets, documentos, chats, trechos de CRM, trechos de código. Pense em 1–50 mil itens por usuário, não um corpus global.
  • Dados com zero‑knowledge ou criptografia de ponta a ponta. Se seus servidores não devem ler o conteúdo, não peça a eles para gerar os embeddings.
  • Domínios sensíveis à privacidade. Saúde, finanças, RH. Mesmo que você tenha base legal, minimizar a exposição é poderoso em vendas para enterprise.
  • UX sensível à latência. Sugestões enquanto digita, sugestões “ao colar”, quick‑open. Ganhos sub‑100 ms são óbvios para o usuário final.
  • Conectividade intermitente. Trabalho de campo, transporte público, viagens aéreas, mercados emergentes. “Funciona offline” rende pontos de NPS.

Maus candidatos (mantenha no servidor)

  • Busca global entre usuários/tenants. Agregações, sinais de popularidade e defesas contra abuso geralmente precisam de centralização.
  • Requisitos rígidos de auditoria centralizada. Se toda consulta e atualização de índice precisa ser registrada e reproduzível centralmente, fluxos apenas no cliente complicam a vida.
  • Corpora muito grandes por usuário. Se um único usuário pesquisa rotineiramente 1M+ itens, você vai bater em limites de armazenamento e memória do navegador.

A matemática de custo e latência (com números redondos)

CTOs se importam com dólares e milissegundos. Eis o modelo mental rápido:

  • Custo de API de embeddings. Grandes provedores precificam embeddings por tokens processados. Mesmo a alguns dólares por milhão de tokens, indexar conteúdo de usuário soma. Um único kilobyte dá algumas centenas de tokens, em média. Milhões de itens na sua base viram cinco a seis dígitos anuais — e isso antes de re‑embedar por upgrade de modelo.
  • Latência de ida e volta. Uma chamada de rede mais a inferência do provedor tipicamente dá 200–800 ms no caminho feliz; pior no mobile. Embeddings locais costumam executar em 10–70 ms para um parágrafo curto em um laptop 2023–2025, mais tempo em celulares de entrada. Mas é previsível e funciona offline.
  • Pegada de armazenamento no dispositivo. Um vetor de 384 dimensões em int8 tem ~384 bytes. Para 10 mil itens, vetores brutos são ~3,8 MB. Some um índice de vizinhos aproximados (HNSW/IVF) e algum metadata e você ainda fica nas dezenas de megabytes, o que é ok para navegadores modernos e apps mobile se você gerenciar cache e cotas.
  • Egress do servidor. Ao parar de enviar texto do usuário para gerar embeddings, você corta egress em cada evento de ingestão. Se seus clientes estão fora da sua região, isso não é trivial.

O ganho não é só unit economics. É poder gerar embeddings a cada tecla, a cada colagem, a cada edição, porque você removeu o imposto da rede.

Um framework de decisão aplicável neste trimestre

1) Delimite o conteúdo e a meta de qualidade

  • Tamanho do corpus por usuário: 1k, 10k, 100k, 1M itens. Navegador e mobile ficam felizes até dezenas de milhares se você for cuidadoso. Seis dígitos já força sem sharding.
  • Comprimento do texto: títulos curtos vs. corpos de vários parágrafos. Modelos locais pequenos se saem melhor em textos curtos a médios. Para documentos longos, gere embeddings de chunks no cliente e costure no servidor se necessário.
  • Barra de qualidade: defina metas de recall@K e MRR em um conjunto de teste representativo. Se vetores no servidor dão recall@10 de 0,90, aceite 0,85 local com re‑rank no cliente? Decida agora.

2) Selecione modelo e runtime por classe de dispositivo

  • Navegadores: comece com um modelo de embeddings minúsculo em WASM (classe de 7 MB) para cobertura universal. Onde houver WebGPU, ofereça opcionalmente um modelo maior de 100–200 MB atrás de um toggle “High Accuracy” para power users.
  • Android: direcione ao NNAPI com um modelo quantizado via TensorFlow Lite/ONNX; a pilha de IA on‑device do Android 17 finalmente está confiável para essa carga.
  • iOS: entregue uma versão em Core ML e rode no Neural Engine quando disponível; faça fallback para CPU para indexação em segundo plano.

Congele a dimensão do vetor e o esquema de normalização. Dimensões incompatíveis ou erros de cosseno vs. dot vão queimar um sprint depois.

3) Escolha uma estratégia de indexação

  • Corpora pequenos (<10k itens): cosseno ou L2 por força bruta em arrays otimizados é suficiente. Use Web Workers e SIMD.
  • Corpora médios (10k–200k): HNSW (grafos hierárquicos) ou IVF (inverted file) construídos no cliente ou enviados como shard pré‑construído. hnswlib tem ports para WASM; meça o overhead de memória.
  • Híbrido: o servidor faz filtro grosseiro (por metadata/tempo) e o cliente faz rerank exato ou baseado em grafo em alguns milhares de candidatos. Isso preserva privacidade mantendo as consultas ágeis.

4) Inclua privacidade e governança desde o início

  • Não envie texto bruto. Telemetria deve ser tempos e contadores, não conteúdo. Se você precisar de analytics de busca, agregue no dispositivo e reporte resumos com privacidade diferencial.
  • Trate vetores como sensíveis. Vetores podem vazar semântica. Criptografe em repouso no dispositivo quando possível; com namespaces por tenant. Se você sincroniza vetores, criptografe de ponta a ponta ou rotacione ao atualizar o modelo.
  • Versionamento de modelo. Marque cada vetor com um model_id e normalize_version. Nunca misture vetores entre modelos incompatíveis. Faça roll‑forward com re‑embedding em segundo plano.

5) Entregue fallbacks por capacidade

  • Detecção de capacidade: no boot, meça compute, memória e cota de armazenamento disponíveis. Coloque o usuário em uma de três bandas: Local‑Fast, Local‑Okay ou Remote.
  • Fallback remoto: mantenha vivo o caminho de embeddings no servidor para dispositivos de entrada e navegadores travados. Torne isso configurável por tenant.
  • Degradação graciosa: se um dispositivo esquentar ou estiver com pouca bateria, reduza a indexação em segundo plano e confie em filtros por metadata mais os últimos vetores conhecidos.

Três arquiteturas de referência

1) Somente cliente, sincronize metadados

Use quando: posicionamento de zero‑knowledge, cofres de dados pessoais, requisitos altos de privacidade.

  • Todo o texto permanece local. O cliente calcula vetores, constrói um índice ANN local e persiste em IndexedDB/SQLite (mobile).
  • O servidor sincroniza apenas IDs de itens, timestamps e blobs criptografados opcionais. A busca roda inteiramente no dispositivo.
  • Trade‑off: sem busca entre dispositivos sem sincronizar vetores criptografados; download inicial maior do modelo.

2) Rerank híbrido

Use quando: corpora médios, UX multi‑dispositivo, compliance exige trilha no servidor.

  • O cliente gera embeddings de consultas e itens. O servidor armazena vetores criptografados para sync e faz seleção grosseira de candidatos por consulta (ex.: por projeto/tempo/dono).
  • O cliente baixa os vetores dos top N candidatos, executa rerank por cosseno exato e renderiza resultados. Texto bruto não precisa sair do dispositivo.
  • Trade‑off: você precisa operar um serviço de sincronização de vetores e criptografar bem os metadados.

3) Filtro grosseiro no servidor + embeddings no cliente

Use quando: você tem infraestrutura de busca no servidor que não consegue substituir neste trimestre.

  • O servidor responde rápido a consultas apenas de metadata (keyword, filtros). O cliente gera embeddings só do contexto e da consulta do usuário, fazendo rerank local dos top N retornos do servidor.
  • Trade‑off: a qualidade depende do recall do servidor; risco de vazamento de meta permanece se os filtros forem grosseiros demais.

Armadilhas de qualidade e como evitá‑las

  • Desalinhamento de domínio. Modelos gerais minúsculos podem ter desempenho inferior em código, textos médicos ou jurídicos. Considere adaptação leve ao domínio ou um dicionário curado de sinônimos no cliente.
  • Estratégia de chunking. Para documentos longos, tamanho de chunk, stride e reforço de títulos importam mais do que espremer mais 1% do modelo. Padronize e teste.
  • Deriva do índice. Edições em segundo plano devem re‑embedar e atualizar o grafo ANN de forma atômica. Use write‑ahead log e segmentos de índice versionados.
  • Alucinações em RAG. Não deixe a recuperação local alimentar lixo silenciosamente no gerador. Anexe proveniência e imponha checagens de “respondível pelo contexto” antes das chamadas ao modelo.

Armazenamento e engenharia de performance no navegador

  • Onde armazenar: IndexedDB para blobs estruturados, OPFS (Origin Private File System) para shards binários grandes em navegadores modernos baseados em Chromium, SQLite via WASM para performance previsível em Electron/Tauri ou mobile.
  • Compressão: vetores int8 cortam memória em 4x vs. float32 com impacto pequeno em recall. Quantização de produto pode trazer mais 2–4x se você tolerar pequena perda de acurácia.
  • Memória do ANN: HNSW carrega arestas em memória; planeje overhead de 2–3x o tamanho dos vetores quando totalmente residente. Limite concorrência e aqueça subconjuntos por namespace.
  • Workers: sempre mova geração de embeddings e trabalho de ANN para Web Workers. Mantenha a thread de UI dentro do budget de 16 ms por frame.
  • Térmica: controle a indexação em segundo plano por bateria e temperatura de CPU quando disponível. No mobile, indexe ao carregar ou logo após uso ativo.

Conformidade, contratos e habilitação de vendas

Se você vende para enterprises, embeddings no cliente são um presente para o fluxo de questionários de segurança.

  • Residência de dados: “Nenhum conteúdo de usuário sai do dispositivo para busca” antecipa metade do debate de residência.
  • DPIAs e DSRs: minimizar o processamento de dados pessoais no servidor reduz sua exposição em avaliações de impacto de privacidade e solicitações de titulares de dados.
  • Risco de fornecedor: você remove um provedor de embeddings de terceiros da lista de “sub‑processadores” para esse recurso. Isso desbloqueia a compra mais rápido.

Plano de rollout: 30 / 60 / 90 dias

Dia 0–30: Comprove

  • Escolha um recurso com escopo por usuário (por exemplo, busca no workspace) e implemente um caminho somente no cliente atrás de um feature flag.
  • Integre um modelo minúsculo em WASM e meça cold start, tempo de embedding por parágrafo e recall@10 vs. seu baseline no servidor em um conjunto de teste de 1k consultas.
  • Defina as bandas de capacidade e implemente um kill switch remoto e fallback no servidor.
  • >

Dia 31–60: Produtize

  • Adicione ANN local para corpora acima de 10k itens. Persista em OPFS/IndexedDB com segmentos versionados.
  • Instrumente telemetria sem conteúdo: tempos, códigos de falha, versão do modelo, banda do dispositivo. Direcione para um sink governado por privacidade separado.
  • Escreva a nota de segurança: vetores são sensíveis, versões de modelo são fixadas, criptografia em repouso onde suportado e E2EE se você sincroniza vetores.

Dia 61–90: Escalone

  • Faça rollout para 25–50% dos usuários em dispositivos capazes. Observe taxas de crash, cold starts e deltas de recall por tenant.
  • Ofereça um modelo opcional “High Accuracy” para desktops com WebGPU. Mantenha o modelo pequeno como padrão.
  • Planeje sua próxima migração: rerank no cliente para sua busca global ou sumarização on‑device para os principais resultados.

Trade‑offs que você deve reconhecer na sala

  • Acurácia: um modelo de 7 MB não vai igualar um embedder de 500 MB de ponta em domínios de nicho. Mas com bom chunking e rerank, os usuários podem nem notar. Teste com seus dados, não com os do Twitter.
  • Complexidade: você está introduzindo uma segunda pilha de recuperação e detecção de capacidade. Mantenha isso atrás de uma abstração fina e seja fanático por versionamento de modelo.
  • Cotas de armazenamento: navegadores estão melhores do que antes, mas cotas e políticas de despejo variam. Projete para índices parciais e reconstruções rápidas.
  • Diversidade de dispositivos: espere uma variação de 10x em throughput. Seu produto precisa ser agradável tanto em um Android de dois anos quanto em um Mac com chip M de última geração.

Por que isso importa para times nearshore (e para o seu roadmap)

Embeddings no cliente permitem que times distribuídos entreguem velocidade perceptível ao usuário sem mudanças caras de infraestrutura. Para orgs de produto EUA‑LATAM, há um bônus: construir pipelines Rust‑to‑WASM robustos, índices on‑device e camadas de recuperação híbrida é o tipo de trabalho de sistemas em que engenheiros nearshore seniores brilham, com 6–8 horas de overlap para iteração apertada. Você vai gastar tempo em UX de produto, não em mais um cluster de vetores.

Em resumo

Você não precisa mover toda a recuperação para o cliente. Mas se não está movendo nenhuma parte, você está pagando mais do que precisa, esperando mais do que os usuários toleram e carregando mais risco de privacidade do que sua equipe de vendas consegue defender. Comece com um recurso com escopo por usuário. Envie um modelo minúsculo. Meça. Depois expanda.

Principais pontos

  • Modelos de embeddings pequenos agora rodam no navegador; um modelo WASM de ~7 MB é suficiente para muitas buscas com escopo por usuário.
  • Mova embeddings para o cliente para recursos com escopo por usuário, sensíveis à privacidade e críticos de latência; mantenha a busca global no servidor.
  • Espere vetores em torno de 384 bytes por item em int8; 10k itens cabem confortavelmente no dispositivo com um índice ANN modesto.
  • Marque todo vetor com uma versão de modelo; nunca misture embeddings incompatíveis; criptografe vetores em repouso e durante a sincronização.
  • Use detecção de capacidade para classificar dispositivos e mantenha um fallback no servidor; instrumente telemetria sem conteúdo.
  • Arquiteturas híbridas (filtro no servidor, rerank no cliente) preservam privacidade evitando quedas bruscas de qualidade.
  • Planeje um rollout de 90 dias: comprove, produtize e depois escale com modelos opcionais de maior acurácia em hardware capaz.

Ready to scale your engineering team?

Tell us about your project and we'll get back to you within 24 hours.

Start a conversation