Usa Milvus e Airbyte per la ricerca di similarità su tutti i tuoi dati
Milvus è un popolare database vettoriale open-source. I vettori sono array di numeri ad alta dimensionalità. Quando si lavora con i Large Language Models (LLM), gli "embedding" si riferiscono specificamente all'ultimo strato nascosto all'interno del componente Encoder di una Deep Neural Network basata su transformer. Questo strato di embedding è un insieme di vettori che rappresentano il significato semantico di parole o pixel (per testo o immagini).
Data la ricchezza di informazioni nello strato di embedding di un LLM addestrato, l'archiviazione e il recupero efficienti dei vettori sono diventati cruciali. Milvus è un database vettoriale progettato appositamente per archiviare, indicizzare e cercare in modo efficiente dati vettoriali ad alta dimensionalità. I database vettoriali sono tipicamente utilizzati per ricerche di similarità su dati non strutturati, consentendo miglioramenti nelle risposte delle chat generative, nelle raccomandazioni di prodotti e in altre applicazioni.
Utilizzando Airbyte, è semplice trasferire dati da molte fonti diverse in Milvus, calcolando lungo il percorso gli embedding vettoriali dei testi.
Il potere degli embedding consiste nel poter cercare informazioni pertinenti, anche se concetti simili sono formulati in modo diverso. Questo articolo userà questa funzionalità per rendere più intelligente un modulo di supporto di un sito web, cercando informazioni pertinenti al volo. Ciò verrà utilizzato per informare l'utente su ticket simili già elaborati e per evidenziare articoli pertinenti della knowledge base che potrebbero aiutare a risolvere il problema senza l'aiuto di un agente di supporto.
Useremo Zilliz Cloud come nostro archivio vettoriale, Airbyte per estrarre e caricare i dati, l'API di embedding di OpenAI per calcolare gli embedding e Streamlit per creare un modulo di invio intelligente che mostri dati pertinenti.
Avrai bisogno di:
Account Zendesk (o un'altra fonte dati da cui vuoi sincronizzare i dati)
Account Airbyte o istanza locale
Chiave API OpenAI
Account Zilliz Cloud o cluster Milvus locale
Python 3.10 installato localmente
Passaggio 1: Configurare il cluster Milvus
Su cloud.zilliz.com, puoi registrarti per un cluster gratuito per archiviare i tuoi embedding vettori per la ricerca di similarità. Una volta creato un account, devi configurare un nuovo cluster.
Le singole entità (nel nostro caso, ticket di supporto e articoli della knowledge base) sono archiviate in una “collection” — dopo aver configurato il cluster, devi creare una collection. Scegli un nome adatto e imposta la Dimension a 1536 per corrispondere alla dimensionalità vettoriale generata dal servizio di embedding di OpenAI:
Dopo la creazione, Zilliz ti mostrerà l'endpoint e la chiave API — annotali perché ne avremo bisogno nel passaggio successivo.
Passaggio 2: Configurare la connessione in Airbyte
Il nostro database è pronto, trasferiamo un po' di dati! Per farlo, dobbiamo configurare una connessione in Airbyte. Registrati per un account Airbyte cloud su cloud.airbyte.com oppure avvia un'istanza locale come descritto nella documentazione.
Una volta che la tua istanza è in esecuzione, dobbiamo configurare la connessione — fai clic su “New connection” e scegli il connettore “Zendesk Support” come fonte.
Su Airbyte cloud, puoi autenticarti facilmente facendo clic sul pulsante Authenticate. Quando usi un'istanza Airbyte locale, segui le indicazioni riportate nella pagina della documentazione.
Info::
Se vuoi utilizzare un'altra fonte dati — il resto di questo articolo è applicabile a tutti i tipi di fonti basate su testo
::
Dopo aver fatto clic sul pulsante “Test and Save”, Airbyte verificherà se la connessione può essere stabilita. Se tutto funziona correttamente, il passo successivo è configurare la destinazione in cui spostare i dati. Qui, scegli il connector “Milvus”.
Il connector Milvus fa tre cose:
- Chunking e formattazione - Divide i record Zendesk in testo e metadati. Se il testo è più grande della dimensione del chunk specificata, i record vengono suddivisi in più parti che vengono caricate nella collection individualmente. La suddivisione del testo (o chunking) può, per esempio, avvenire nel caso di ticket di supporto o articoli della knowledge base di grandi dimensioni. Suddividendo il testo, puoi assicurarti che le ricerche producano sempre risultati utili.
Procediamo con una dimensione del chunk di 1000 token e campi di testo body, title, description e subject, poiché questi saranno presenti nei dati che riceveremo da Zendesk.
Embedding - Utilizzando modelli di Machine Learning trasforma i chunk di testo prodotti dalla parte di elaborazione in vector embeddings che puoi poi cercare per similarità semantica. Per creare gli embeddings, devi fornire la chiave API OpenAI. Airbyte invierà ogni chunk a OpenAI e aggiungerà il vettore risultante alle entità caricate nel tuo cluster Milvus.
Indicizzazione - Una volta vettorializzati i chunk, puoi caricarli nel database. Per farlo, inserisci le informazioni ottenute durante la configurazione del tuo cluster e della tua collection in Zilliz cloud.
Facendo clic su “Test and save” verrà verificato se tutto è allineato correttamente (credenziali valide, la collection esiste e ha la stessa dimensionalità vettoriale dell'embedding configurato, ecc.)
L'ultimo passaggio prima che i dati siano pronti a fluire è selezionare quali “stream” sincronizzare. Uno stream è una raccolta di record nella sorgente. Poiché Zendesk supporta un gran numero di stream che non sono rilevanti per il nostro caso d'uso, selezioniamo solo “tickets” e “articles” e disabilitiamo tutti gli altri per risparmiare larghezza di banda e assicurarci che solo le informazioni rilevanti vengano visualizzate nelle ricerche:
Puoi selezionare quali campi estrarre dalla sorgente facendo clic sul nome dello stream. La modalità di sincronizzazione “Incremental | Append + Deduped” significa che le successive esecuzioni della connessione mantengono Zendesk e Milvus sincronizzati trasferendo una quantità minima di dati (solo gli articoli e i ticket che sono cambiati dall'ultima esecuzione).
Non appena la connessione è configurata, Airbyte inizierà a sincronizzare i dati. Potrebbero volerci alcuni minuti prima che appaiano nella tua collection Milvus.
Se selezioni una frequenza di replica, Airbyte verrà eseguito regolarmente per mantenere la tua collection Milvus aggiornata con le modifiche agli articoli Zendesk e ai nuovi problemi creati.
Puoi verificare nell'interfaccia utente di Zilliz cloud come sono strutturati i dati nella collection navigando nel playground ed eseguendo una query “Query Data” con un filtro impostato su “_ab_stream == \”tickets\””
Come puoi vedere nella vista Result, ogni record proveniente da Zendesk è memorizzato come entità separate in Milvus con tutti i metadati specificati. Il chunk di testo su cui si basa l'embedding è mostrato come proprietà “text” — questo è il testo che è stato incorporato usando OpenAI e sarà ciò su cui effettueremo la ricerca.
Passaggio 3: Crea l'app Streamlit che interroga la collection
I nostri dati sono pronti — ora dobbiamo creare l'applicazione per usarli. In questo caso, l'applicazione sarà un semplice modulo di supporto per consentire agli utenti di inviare casi di supporto. Quando l'utente preme submit, faremo due cose:
Cercare ticket simili inviati dagli utenti della stessa organizzazione
Cercare articoli della knowledge base che potrebbero essere rilevanti per l'utente
In entrambi i casi, sfrutteremo la ricerca semantica utilizzando gli embedding di OpenAI. Per farlo, anche la descrizione del problema inserita dall’utente viene trasformata in embedding e utilizzata per recuperare entità simili dal cluster Milvus. Se ci sono risultati pertinenti, vengono mostrati sotto il modulo.
Avrai bisogno di un’installazione locale di Python, poiché useremo Streamlit per implementare l’applicazione.
Per prima cosa, installa localmente Streamlit, la libreria client di Milvus e la libreria client di OpenAI:
pip install streamlit pymilvus openai
Per visualizzare un modulo di supporto di base, crea un file 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!")
Per eseguire la tua applicazione, usa Streamlit run:
streamlit run app.py
Questo visualizzerà un modulo di base:
Il codice di questo esempio si trova anche su GitHub.
Poi, verifichiamo la presenza di ticket aperti esistenti che potrebbero essere pertinenti. Per farlo, trasformiamo in embedding il testo inserito dall’utente utilizzando OpenAI, quindi eseguiamo una ricerca di similarità sulla nostra collection, filtrando per i ticket ancora aperti. Se ce n’è uno con una distanza molto bassa tra il ticket fornito e il ticket esistente, informa l’utente e non inviare:
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!")
Qui stanno accadendo diverse cose:
Viene configurata la connessione al cluster Milvus.
Il servizio OpenAI viene utilizzato per generare un embedding della descrizione inserita dall’utente.
Viene eseguita una ricerca di similarità, filtrando i risultati in base allo stato del ticket e all’id dell’organizzazione (poiché sono rilevanti solo i ticket aperti della stessa organizzazione).
Se ci sono risultati e la distanza tra i vettori di embedding del ticket esistente e del testo appena inserito è inferiore a una certa soglia, segnala questo fatto.
Per eseguire la nuova app, devi prima impostare le variabili d’ambiente per OpenAI e Milvus:
export MILVUS_TOKEN=...
export MILVUS_URL=https://...
export OPENAI_API_KEY=sk-...
streamlit run app.py
Quando provi a inviare un ticket che esiste già, il risultato apparirà così:
Il codice di questo esempio si trova anche su GitHub.
Come puoi vedere nell’output di debug verde nascosto nella versione finale, due ticket corrispondevano alla nostra ricerca (con stato new, dell’organizzazione corrente e vicini al vettore di embedding). Tuttavia, il primo (pertinente) si è classificato più in alto del secondo (non pertinente in questa situazione), cosa che si riflette nel valore di distanza più basso. Questa relazione viene catturata nei vettori di embedding senza una corrispondenza diretta delle parole, come in una normale ricerca full-text.
Per concludere, mostriamo informazioni utili dopo l’invio del ticket per fornire all’utente quante più informazioni pertinenti possibile fin da subito.
Per farlo, eseguiremo una seconda ricerca dopo l’invio del ticket per recuperare gli articoli della knowledge base con la migliore corrispondenza:
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 non esiste alcun ticket di supporto aperto con un punteggio di similarità elevato, il nuovo ticket viene inviato e gli articoli pertinenti della knowledge base vengono mostrati sotto:
Il codice per questo esempio è disponibile anche su Github.
Sebbene l’interfaccia utente mostrata qui non sia un vero modulo di supporto ma un esempio per illustrare il caso d’uso, la combinazione di Airbyte e Milvus è molto potente: consente di caricare facilmente testo da un’ampia varietà di fonti (da database come Postgres ad API come Zendesk o GitHub, fino a fonti completamente personalizzate create usando l’SDK di Airbyte o il visual connector builder) e indicizzarlo in forma embedded in Milvus, un potente motore di ricerca vettoriale in grado di scalare fino a enormi quantità di dati.
Airbyte e Milvus sono open source e completamente gratuiti da usare sulla propria infrastruttura, con offerte cloud per esternalizzare le operazioni se lo si desidera.
Oltre al classico caso d’uso della ricerca semantica illustrato in questo articolo, la configurazione generale può essere usata anche per creare un chat bot di domande e risposte usando il metodo RAG (Retrieval Augmented Generation), sistemi di raccomandazione o contribuire a rendere la pubblicità più pertinente ed efficiente.
Continua a leggere

Vector Lakebase: End the AI Data Silo
Learn how Vector Lakebase unifies vector search, data lakes, and AI data operations so teams can serve RAG and agents without copy-and-sync pipelines.

Introducing Customer-Managed Encryption Keys (CMEK) on Zilliz Cloud
We're announcing the general availability of Customer-Managed Encryption Keys (CMEK) on Zilliz Cloud.

Why I’m Against Claude Code’s Grep-Only Retrieval? It Just Burns Too Many Tokens
Learn how vector-based code retrieval cuts Claude Code token consumption by 40%. Open-source solution with easy MCP integration. Try claude-context today.



