Destaques
- Embeddings multimodais gerados com
Gemini Embeddings 2(liberado em março de 2026), capaz de vetorizar texto, imagem, vídeo, áudio e PDF no mesmo espaço vetorial. - Vetores armazenados numa tabela dedicada
post_embeddingsno PostgreSQL, com a extensãopgvectorgarantida via migration (ensureVectorExtensionExists) e dimensão fixa de 1536, o padrão de mercado adotado por OpenAI e Gemini. - Indexação
HNSW(Hierarchical Navigable Small World) criada viaDB::statement, baseada em grafos de proximidade entre pontos, reduzindo a complexidade de busca de O(n) para O(log n). - Operador de distância por cosseno (
<=>) escolhido em vez da distância euclidiana (<->) por captar a direção semântica do vetor e por dispensar normalização prévia dos embeddings. - Geração de embedding por post feita por um
GeminiEmbedService, disparada por umPostObserverque implementaShouldHandleEventsAfterCommit, garantindo que a transação e as mídias do post já estejam salvas antes de vetorizar o conteúdo. - Centroide do usuário calculado inteiramente em PHP, sem nova chamada à API: é a média, dimensão a dimensão, dos embeddings dos posts curtidos — uma regra de negócio que hoje considera só o "like", sem levar em conta o que o usuário publica.
- Feed reordenado com uma query com
JOINempost_embeddingseORDER BYpelo operador de cosseno, com fallback para ordenação cronológica quando o usuário ainda não tem centroide calculado. - Discussão em profundidade sobre a evolução do modelo básico para uma arquitetura de dois estágios: candidate generation (vizinhos próximos, trending e quem o usuário segue) seguida de ranking, com vetores separados de gosto de longo prazo, curto prazo e "avoid", incorporando sinais negativos e diversidade de conteúdo.
Profundidade técnica
O pipeline construído ao vivo segue três etapas: primeiro, todo post criado dispara a geração de um embedding único via Gemini (tarefa retrieval_document), armazenado em coluna vector com índice HNSW; segundo, cada ação de "like" do usuário aciona o recálculo de um centroide — a média aritmética das 1536 dimensões dos embeddings de todos os posts curtidos — sem custo adicional de API, já que reaproveita os vetores já gerados; terceiro, o feed é montado ordenando os posts pela proximidade de cosseno entre o embedding do post e o centroide do usuário. Os principais trade-offs discutidos: coluna vector não pode ser emulada com JSON (falta o operador de cálculo de proximidade), a indexação tradicional de árvore binária não funciona sobre colunas vetoriais, a dimensão do embedding não pode ser alterada após a criação do banco sem invalidar todos os vetores existentes, e a troca de provedor de embeddings (por exemplo, de Gemini para OpenAI) quebra a comparação, pois cada modelo treina seu próprio espaço semântico. Recalcular o centroide a cada like tem complexidade O(n) sobre o histórico de curtidas — didático para a aula, mas sinalizado como ponto de otimização (soma incremental) para produção — e tanto a geração de embeddings quanto o recálculo de centroide foram apontados como candidatos naturais a fila (Redis/Horizon). Como fechamento, o workshop detalhou a evolução planejada do centroide único para uma representação multivetor (long-term, short-term e avoid) com camada de candidate generation e reranking, superando as limitações do modelo básico: ausência de sinais negativos, de temporalidade e de diversidade no feed.
Faça parte do Clã
Quer aprender a construir sistemas de recomendação, IA aplicada e engenharia de IA na prática, com quem já implementa isso em produção? Entre no Clã Beer and Code.
Engenharia de IA virou profissão, e se aprende construindo, não assistindo. O Clã Beer and Code é o ambiente onde isso acontece ao vivo, toda semana: RAG, agentes, observabilidade e LLMOps em projetos reais, ao lado de quem já está em produção. É pago, é assinatura, e é exatamente o ambiente que estes encontros dão uma amostra.
Entrar no Clã