Use Milvus e Airbyte para busca por similaridade em todos os seus dados
Milvus é um popular banco de dados vetorial de código aberto. Vetores são arrays de números de alta dimensionalidade. Ao trabalhar com Modelos de Linguagem Grandes (LLMs), "embeddings" referem-se especificamente à última camada oculta dentro do componente Encoder de uma Rede Neural Profunda baseada em transformers. Essa camada de embedding é um conjunto de vetores que representa o significado semântico de palavras ou pixels (para texto ou imagens).
Dada a riqueza de informações na camada de embedding de um LLM treinado, o armazenamento e a recuperação eficientes de vetores tornaram-se cruciais. Milvus é um banco de dados vetorial criado especificamente para armazenar, indexar e pesquisar com eficiência dados vetoriais de alta dimensionalidade. Bancos de dados vetoriais são normalmente usados para buscas por similaridade em dados não estruturados, possibilitando melhorias em respostas de Chat Generativo, recomendações de produtos e outras aplicações.
Ao usar o Airbyte, é simples transferir dados de muitas fontes diferentes para o Milvus, calculando embeddings vetoriais de textos ao longo do caminho.
O poder dos embeddings está em conseguir pesquisar partes relevantes de informações, mesmo que conceitos semelhantes sejam expressos de formas diferentes. Este artigo usará essa funcionalidade para tornar um formulário de suporte de site mais inteligente, consultando informações relevantes em tempo real. Isso será usado para informar o usuário sobre tickets semelhantes que já foram processados e destacar artigos relevantes da base de conhecimento que poderiam ajudar a resolver o problema sem a ajuda de um agente de suporte.
Usaremos o Zilliz Cloud como nosso armazenamento vetorial, o Airbyte para extrair e carregar os dados, a API de embeddings da OpenAI para calcular embeddings e o Streamlit para criar um formulário de envio inteligente que exibe dados relevantes.
Você precisará de:
Conta do Zendesk (ou outra fonte de dados da qual você deseja sincronizar dados)
Conta do Airbyte ou instância local
Chave de API da OpenAI
Conta do Zilliz Cloud ou cluster Milvus local
Python 3.10 instalado localmente
Etapa 1: Configurar o cluster Milvus
Em cloud.zilliz.com, você pode se cadastrar para obter um cluster gratuito para armazenar seus embeddings vetores para a busca por similaridade. Depois de criar uma conta, você precisa configurar um novo cluster.
Entidades individuais (no nosso caso, tickets de suporte e artigos da base de conhecimento) são armazenadas em uma “collection” — depois que seu cluster estiver configurado, você precisa criar uma collection. Escolha um nome adequado e defina a Dimension como 1536 para corresponder à dimensionalidade vetorial gerada pelo serviço de embeddings da OpenAI:
Após a criação, o Zilliz mostrará o endpoint e a chave de API — anote-os, pois precisaremos deles na próxima etapa.
Etapa 2: Configurar a conexão no Airbyte
Nosso banco de dados está pronto, vamos mover alguns dados para lá! Para fazer isso, precisamos configurar uma conexão no Airbyte. Cadastre-se em uma conta do Airbyte cloud em cloud.airbyte.com ou inicialize uma instância local conforme descrito na documentação.
Quando sua instância estiver em execução, precisamos configurar a conexão — clique em “New connection” e escolha o conector “Zendesk Support” como a fonte.
No Airbyte cloud, você pode se autenticar facilmente clicando no botão Authenticate. Ao usar uma instância local do Airbyte, siga as instruções descritas na página de documentação.
Info::
Se você quiser usar outra fonte de dados — o restante deste artigo é aplicável a todos os tipos de fontes baseadas em texto
::
Depois de clicar no botão “Test and Save”, o Airbyte verificará se a conexão pode ser estabelecida. Se tudo estiver funcionando corretamente, o próximo passo é configurar o destino para o qual mover os dados. Aqui, escolha o conector “Milvus”.
O conector Milvus faz três coisas:
- Fragmentação e formatação - Divide os registros do Zendesk em texto e metadados. Se o texto for maior do que o tamanho de fragmento especificado, os registros são divididos em várias partes que são carregadas individualmente na coleção. A divisão do texto (ou fragmentação) pode, por exemplo, ocorrer no caso de tickets de suporte grandes ou artigos de conhecimento extensos. Ao dividir o texto, você pode garantir que as pesquisas sempre produzam resultados úteis.
Vamos usar um tamanho de fragmento de 1000 tokens e campos de texto de body, title, description e subject, pois estes estarão presentes nos dados que receberemos do Zendesk.
Embedding - O uso de modelos de Machine Learning transforma os fragmentos de texto produzidos pela parte de processamento em embeddings vetoriais, que você pode então pesquisar por similaridade semântica. Para criar os embeddings, você deve fornecer a chave da API da OpenAI. O Airbyte enviará cada fragmento para a OpenAI e adicionará o vetor resultante às entidades carregadas no seu cluster Milvus.
Indexação - Depois de vetorizar os fragmentos, você pode carregá-los no banco de dados. Para fazer isso, insira as informações que você obteve ao configurar seu cluster e sua coleção na Zilliz cloud.
Clicar em “Test and save” verificará se tudo está alinhado corretamente (credenciais válidas, a coleção existe e tem a mesma dimensionalidade vetorial que o embedding configurado etc.)
O último passo antes de os dados estarem prontos para fluir é selecionar quais “streams” sincronizar. Uma stream é uma coleção de registros na origem. Como o Zendesk oferece suporte a um grande número de streams que não são relevantes para o nosso caso de uso, vamos selecionar apenas “tickets” e “articles” e desabilitar todas as outras para economizar largura de banda e garantir que apenas as informações relevantes apareçam nas pesquisas:
Você pode selecionar quais campos extrair da origem clicando no nome da stream. O modo de sincronização “Incremental | Append + Deduped” significa que as execuções subsequentes da conexão mantêm o Zendesk e o Milvus sincronizados enquanto transferem o mínimo de dados (apenas os artigos e tickets que mudaram desde a última execução).
Assim que a conexão for configurada, o Airbyte começará a sincronizar os dados. Pode levar alguns minutos para aparecerem na sua coleção Milvus.
Se você selecionar uma frequência de replicação, o Airbyte será executado regularmente para manter sua coleção Milvus atualizada com alterações em artigos do Zendesk e problemas recém-criados.
Você pode verificar na interface da Zilliz cloud como os dados estão estruturados na coleção navegando até o playground e executando uma consulta “Query Data” com um filtro definido como “_ab_stream == \”tickets\””
Como você pode ver na visualização de Result, cada registro vindo do Zendesk é armazenado como entidades separadas no Milvus com todos os metadados especificados. O fragmento de texto no qual o embedding se baseia é mostrado como a propriedade “text” — este é o texto que foi incorporado usando a OpenAI e será o que pesquisaremos.
Etapa 3: Criar aplicativo Streamlit consultando a coleção
Nossos dados estão prontos — agora precisamos criar a aplicação para usá-los. Neste caso, a aplicação será um formulário de suporte simples para os usuários enviarem casos de suporte. Quando o usuário clicar em enviar, faremos duas coisas:
Pesquisar tickets semelhantes enviados por usuários da mesma organização
Pesquisar artigos da base de conhecimento que possam ser relevantes para o usuário
Em ambos os casos, aproveitaremos a busca semântica usando embeddings da OpenAI. Para fazer isso, a descrição do problema inserida pelo usuário também é incorporada e usada para recuperar entidades semelhantes do cluster Milvus. Se houver resultados relevantes, eles serão mostrados abaixo do formulário.
Você precisará de uma instalação local do Python, pois usaremos o Streamlit para implementar a aplicação.
Primeiro, instale localmente o Streamlit, a biblioteca cliente do Milvus e a biblioteca cliente da OpenAI:
pip install streamlit pymilvus openai
Para renderizar um formulário básico de suporte, crie um arquivo Python app.py:
import streamlit as st
with st.form("my_form"):
st.write("Submit a support case")
text_val = st.text_area("Describe your problem")
submitted = st.form_submit_button("Submit")
if submitted:
# TODO check for related support cases and articles
st.write("Submitted!")
Para executar sua aplicação, use Streamlit run:
streamlit run app.py
Isso renderizará um formulário básico:
O código deste exemplo também pode ser encontrado no GitHub.
Em seguida, vamos verificar tickets abertos existentes que possam ser relevantes. Para fazer isso, incorporamos o texto inserido pelo usuário usando a OpenAI e, em seguida, fizemos uma busca por similaridade em nossa coleção, filtrando por tickets ainda abertos. Se houver um com uma distância muito baixa entre o ticket fornecido e o ticket existente, informe o usuário e não envie:
import os
import pymilvus
import openai
org_id = 360033549136 # TODO Load from customer login data
pymilvus.connections.connect(uri=os.environ["MILVUS_URL"], token=os.environ["MILVUS_TOKEN"])
collection = pymilvus.Collection("zendesk")
embedding = openai.Embedding.create(input=text_val, model="text-embedding-ada-002")['data'][0]['embedding']
results = collection.search(data=[embedding], anns_field="vector", param={}, limit=5, output_fields=["_id", "subject", "description"], expr=f'status == "new" and organization_id == {org_id}')
st.write(results[0]) # debug output just for now
if len(results[0]) > 0 and results[0].distances[0] < 0.35:
matching_ticket = results[0][0].entity
st.write(f"This case seems very similar to {matching_ticket.get('subject')} (id #{matching_ticket.get('_id')}). Make sure it has not been submitted before")
else:
st.write("Submitted!")
Várias coisas estão acontecendo aqui:
A conexão com o cluster Milvus é configurada.
O serviço OpenAI é usado para gerar um embedding da descrição inserida pelo usuário.
Uma busca por similaridade é realizada, filtrando os resultados pelo status do ticket e pelo ID da organização (pois apenas tickets abertos da mesma organização são relevantes).
Se houver resultados e a distância entre os vetores de embedding do ticket existente e do texto recém-inserido estiver abaixo de um determinado limite, destaque esse fato.
Para executar a nova aplicação, primeiro você precisa definir as variáveis de ambiente para OpenAI e Milvus:
export MILVUS_TOKEN=...
export MILVUS_URL=https://...
export OPENAI_API_KEY=sk-...
streamlit run app.py
Ao tentar enviar um ticket que já existe, é assim que o resultado será exibido:
O código deste exemplo também pode ser encontrado no GitHub.
Como você pode ver na saída de depuração verde, oculta na versão final, dois tickets corresponderam à nossa busca (com status new, da organização atual e próximos ao vetor de embedding). No entanto, o primeiro (relevante) ficou ranqueado acima do segundo (irrelevante nesta situação), o que se reflete no valor de distância menor. Essa relação é capturada nos vetores de embedding sem correspondência direta de palavras, como em uma busca de texto completo comum.
Para concluir, vamos mostrar informações úteis depois que o ticket for enviado para fornecer ao usuário o máximo possível de informações relevantes logo de início.
Para fazer isso, vamos realizar uma segunda busca depois que o ticket for enviado para obter os artigos da base de conhecimento com maior correspondência:
article_results = collection.search(data=[embedding], anns_field="vector", param={}, limit=5, output_fields=["title", "html_url"], expr=f'_ab_stream == "articles"')
st.write(article_results[0])
if len(article_results[0]) > 0:
st.write("We also found some articles that might help you:")
for hit in article_results[0]:
st.write(f"* [{hit.entity.get('title')}]({hit.entity.get('html_url')})")
Se não houver nenhum ticket de suporte aberto com uma pontuação de similaridade alta, o novo ticket será enviado e artigos de conhecimento relevantes serão exibidos abaixo:
O código deste exemplo também pode ser encontrado no Github.
Embora a UI mostrada aqui não seja um formulário de suporte real, mas um exemplo para ilustrar o caso de uso, a combinação de Airbyte e Milvus é muito poderosa — ela facilita carregar texto de uma ampla variedade de fontes (desde bancos de dados como Postgres, passando por APIs como Zendesk ou GitHub, até fontes totalmente personalizadas criadas usando o SDK da Airbyte ou o construtor visual de conectores) e indexá-lo em forma de embeddings no Milvus, um poderoso mecanismo de busca vetorial capaz de escalar para enormes quantidades de dados.
Airbyte e Milvus são open source e totalmente gratuitos para usar na sua infraestrutura, com ofertas em cloud para terceirizar as operações, se desejado.
Além do caso de uso clássico de busca semântica ilustrado neste artigo, a configuração geral também pode ser usada para criar um chat bot de perguntas e respostas usando o método RAG (Retrieval Augmented Generation), sistemas de recomendação ou ajudar a tornar a publicidade mais relevante e eficiente.
Continue lendo

Why We Built Vector Lakebase: Rethinking Unstructured Data Architecture for AI
Vector Lakebase: a unified, lake-native data foundation for AI workloads — and an answer to what happens after vector databases succeed.

How to Choose the Best Embedding Model for RAG in 2026: 10 Models Benchmarked
We benchmarked 10 embedding models on cross-modal, cross-lingual, long-document, and dimension compression tasks. See which one fits your RAG pipeline.

How to Install and Run OpenClaw (Previously Clawdbot/Moltbot) on Mac
Turn your Mac into an AI gateway for WhatsApp, Telegram, Discord, iMessage, and more — in under 5 minutes.



