Antes da busca híbrida, eu precisei confiar no pipeline
No primeiro fim de semana de maio, eu construí uma POC privada chamada nexus-stash.
A proposta parecia pequena demais para esconder qualquer complexidade séria.
Salvar um link.
Extrair o conteúdo legível.
Gerar resumo e tags com IA.
Transformar esse conteúdo em algo pesquisável.
Buscar depois.
Na superfície, era isso.
Na prática, o ponto de virada apareceu bem antes da busca híbrida.
O problema real começou quando eu percebi que o fluxo ainda não merecia confiança.
O happy path era convincente demais
Quando uma POC funciona no caminho principal, é muito fácil achar que o sistema já está "pronto o suficiente".
No caso do nexus-stash, o demo inicial era sedutor:
- o usuário autenticado salva uma URL
- o sistema normaliza e deduplica o link
- o conteúdo é extraído
- enrichment gera resumo e tags
- o sistema prepara o conteúdo para busca por texto e por significado
Isso parece uma pipeline simples.
Mas esse tipo de fluxo só é simples enquanto nada precisa falhar, repetir, ser interrompido ou reprocessado.
Vale traduzir esses termos de forma mais amigável.
Quando eu falo em "embedding", estou falando de uma representação vetorial do conteúdo. Na prática, é uma forma de o sistema comparar proximidade de significado, e não só palavras idênticas.
E quando eu falo em "busca híbrida", o ponto não é o nome bonito. O ponto é combinar duas leituras diferentes:
- busca léxica, que encontra palavras e termos literalmente presentes no conteúdo
- busca semântica, que tenta encontrar conteúdo parecido em sentido, mesmo com palavras diferentes
No nexus-stash, a ideia era justamente misturar essas duas leituras sem perder clareza sobre o pipeline que extrai, enriquece e prepara esse conteúdo para busca.
Onde a confiança começou a pedir garantias reais
O primeiro aprendizado útil não foi sobre relevância de busca.
Foi sobre integridade do fluxo.
Rapidamente ficou claro que eu precisava responder perguntas bem menos glamourosas:
- o que acontece se a mesma URL entrar duas vezes?
- como eu separo reaproveitamento legítimo de duplicação acidental?
- se enrichment falhar, eu consigo explicar em que etapa o fluxo parou?
- se a etapa que prepara o conteúdo para busca falhar depois, eu ainda sei o que já foi persistido com segurança?
- quando faz sentido reprocessar tudo e quando isso só aumenta custo e ruído?
Foi aí que a POC pediu quatro coisas que aparecem cedo em qualquer sistema minimamente sério:
- ingestão determinística
- deduplicação por URL canônica
- trilha de tentativas por processamento
- reprocessamento manual com guardrails
O fluxo deixou de ser só uma sequência e virou um sistema de estados
Uma das decisões mais úteis no nexus-stash foi parar de tratar o processamento como um bloco só.
Enrichment e a etapa de preparação para busca passaram a ter estados explícitos e independentes.
Isso parece detalhe de implementação, mas muda completamente a capacidade de confiar no sistema.
Sem isso, a leitura do operador fica pobre demais:
- deu certo
- deu errado
Com estados separados, a leitura vira algo muito mais útil:
- extração terminou
- enrichment falhou
- a etapa de busca nem chegou a rodar
- ou enrichment passou, a etapa de busca falhou, e o item precisa de outra ação
Reprocessar não é conserto mágico
Outro ponto que apareceu cedo: reprocessamento não pode ser só um botão otimista de "tentar de novo".
Quando um fluxo depende de fetch externo, extração, provider de IA e persistência, reprocessar sem critério vira duas coisas ao mesmo tempo:
- custo desnecessário
- perda de clareza sobre o que realmente aconteceu no histórico daquele item
Por isso a POC acabou pedindo trilha de tentativas e guardrails bem explícitos:
- cooldown para reprocess manual
- limite diário por usuário
- uma linha de auditoria por tentativa
- motivo de falha preservado por etapa
O ganho não foi só "evitar abuso".
O ganho foi preservar leitura operacional.
Sem isso, o sistema até pode continuar funcionando, mas ninguém consegue dizer com segurança o que falhou, o que foi repetido e o que ainda merece confiança.
O problema continuou o mesmo quando a busca por texto e significado entrou
A fase seguinte da POC foi melhorar a recuperação de conteúdo com busca léxica, comparação semântica e ranking híbrido.
De forma simples, a lógica era esta:
- se o usuário procura uma palavra exata, a busca por texto precisa funcionar bem
- se ele procura uma ideia parecida, mesmo com outras palavras, a busca semântica precisa ajudar
- e o ranking final precisa equilibrar as duas coisas sem produzir resultado "bom na média" e ruim na prática
No nível de implementação, isso acabou passando por chunk embeddings, ou seja, dividir o conteúdo em partes menores e gerar representação vetorial por trecho, não só pelo documento inteiro.
Mas esse detalhe só ficou interessante porque a base do fluxo já estava mais confiável.
Se eu tivesse invertido a ordem, o sistema teria ganhado uma busca mais sofisticada em cima de um pipeline ainda ambíguo.
Isso é um padrão recorrente em produto:
o time avança para a próxima feature visível enquanto o fluxo anterior ainda não tem garantias suficientes para merecer confiança operacional.
O incidente de produção reforçou a mesma tese
Mesmo sendo uma POC privada, o nexus-stash teve um lembrete útil em produção: o ambiente público deixou de responder quando o projeto Supabase foi pausado por inatividade.
Não foi um bug clássico de aplicação.
O código continuava lá. O deploy continuava lá. O produto parecia pronto o suficiente.
Mas a dependência operacional crítica não estava ativa.
Hoje o app público já voltou a responder em nexus-stash.vercel.app depois da reativação do Supabase.
Mesmo assim, o incidente continua relevante porque a mitigação permanente contra a próxima pausa ainda é uma preocupação operacional real, e não um detalhe cosmético.
Esse tipo de incidente é útil porque mostra uma coisa importante:
confiabilidade não depende só de lógica correta.
Ela também depende de fornecedor, estado do ambiente, mecanismo de detecção e operação mínima para manter o fluxo vivo.
É o mesmo padrão em outra escala:
na superfície, o sistema ainda parece existir.
Na prática, ele já deixou de merecer confiança plena.
O que essa POC me relembrou sobre sistemas maiores
O aprendizado mais valioso do nexus-stash não foi sobre IA, representação vetorial ou UX de busca.
Foi este:
antes de otimizar capacidade de encontrar informação, eu precisei confiar na integridade do caminho que cria, atualiza e reprocessa essa informação.
Em produto transacional maior, a tradução é direta.
O nome das peças muda, mas a pergunta continua parecida:
- dá para confiar no retry?
- dá para confiar na reconciliação?
- dá para confiar no estado que ficou persistido?
- dá para explicar onde a falha nasceu e o que foi feito depois?
Quando essas respostas ainda são vagas, o sistema pode até parecer saudável no fluxo principal.
Mas a confiança operacional já começou a ficar mais frágil do que o dashboard sugere.
Fechamento
Foi por isso que eu acabei olhando para o nexus-stash menos como "uma POC de busca com IA" e mais como um lembrete prático de algo que aparece o tempo todo em sistemas reais:
o problema mais caro quase nunca começa onde a feature está brilhando.
Ele começa onde o fluxo ainda não tem garantias suficientes para merecer confiança.
Se você quiser ver o app restaurado, ele está aqui:
Se esse tipo de leitura conversa com o teu contexto, o ponto de entrada principal continua aqui:
eliasfeijo.dev/br
E, se fizer mais sentido começar por uma autoavaliação prática:
Diagnóstico inicial de resiliência transacional