Usa Milvus y Airbyte para la búsqueda por similitud en todos tus datos
Milvus es una popular base de datos vectorial de código abierto. Los vectores son arreglos de números de alta dimensionalidad. Al trabajar con modelos de lenguaje grandes (LLMs), "embeddings" se refiere específicamente a la última capa oculta dentro del componente Encoder de una red neuronal profunda basada en transformers. Esta capa de embedding es un conjunto de vectores que representan el significado semántico de palabras o píxeles (para texto o imágenes).
Dada la gran cantidad de información en la capa de embedding de un LLM entrenado, el almacenamiento y la recuperación eficientes de vectores se han vuelto cruciales. Milvus es una base de datos vectorial diseñada específicamente para almacenar, indexar y buscar eficientemente datos vectoriales de alta dimensionalidad. Las bases de datos vectoriales se utilizan normalmente para búsquedas de similitud en datos no estructurados, lo que permite mejoras en las respuestas de chat generativas, recomendaciones de productos y otras aplicaciones.
Al usar Airbyte, es sencillo transferir datos desde muchas fuentes diferentes a Milvus, calculando embeddings vectoriales de textos en el proceso.
El poder de los embeddings es poder buscar fragmentos de información relevantes, incluso si conceptos similares se expresan de manera diferente. Este artículo utilizará esta funcionalidad para hacer que un formulario de soporte de un sitio web sea más inteligente al buscar información relevante sobre la marcha. Esto se utilizará para informar al usuario sobre tickets similares que ya están procesados y destacar artículos relevantes de la base de conocimientos que podrían ayudar a resolver el problema sin la ayuda de un agente de soporte.
Usaremos Zilliz Cloud como nuestro almacén vectorial, Airbyte para extraer y cargar los datos, la API de embeddings de OpenAI para calcular embeddings y Streamlit para crear un formulario de envío inteligente que muestre datos relevantes.
Necesitarás:
Cuenta de Zendesk (u otra fuente de datos desde la que quieras sincronizar datos)
Cuenta de Airbyte o instancia local
Clave API de OpenAI
Cuenta de Zilliz Cloud o clúster local de Milvus
Python 3.10 instalado localmente
Paso 1: Configurar el clúster de Milvus
En cloud.zilliz.com, puedes registrarte para obtener un clúster gratuito para almacenar tus embeddings vectores para la búsqueda de similitud. Una vez que hayas creado una cuenta, debes configurar un nuevo clúster.
Las entidades individuales (en nuestro caso, tickets de soporte y artículos de la base de conocimientos) se almacenan en una “colección”; después de configurar tu clúster, debes crear una colección. Elige un nombre adecuado y establece la Dimensión en 1536 para que coincida con la dimensionalidad vectorial generada por el servicio de embeddings de OpenAI:
Después de la creación, Zilliz te mostrará el endpoint y la clave API; anótalos, ya que los necesitaremos en el siguiente paso.
Paso 2: Configurar la conexión en Airbyte
Nuestra base de datos está lista, ¡movamos algunos datos! Para hacer esto, necesitamos configurar una conexión en Airbyte. Regístrate para obtener una cuenta de Airbyte cloud en cloud.airbyte.com o inicia una instancia local como se describe en la documentación.
Una vez que tu instancia esté en ejecución, debemos configurar la conexión: haz clic en “New connection” y elige el conector “Zendesk Support” como fuente.
En Airbyte cloud, puedes autenticarte fácilmente haciendo clic en el botón Authenticate. Cuando uses una instancia local de Airbyte, sigue las instrucciones descritas en la página de documentación.
Info::
Si quieres usar otra fuente de datos, el resto de este artículo es aplicable a todo tipo de fuentes basadas en texto
::
Después de hacer clic en el botón “Test and Save”, Airbyte comprobará si se puede establecer la conexión. Si todo funciona correctamente, el siguiente paso es configurar el destino al que mover los datos. Aquí, elige el conector “Milvus”.
El conector de Milvus hace tres cosas:
- Fragmentación y formato - Divide los registros de Zendesk en texto y metadatos. Si el texto es más grande que el tamaño de fragmento especificado, los registros se dividen en varias partes que se cargan en la colección individualmente. La división del texto (o fragmentación) puede ocurrir, por ejemplo, en el caso de tickets de soporte grandes o artículos de conocimiento. Al dividir el texto, puedes asegurarte de que las búsquedas siempre produzcan resultados útiles.
Vayamos con un tamaño de fragmento de 1000 tokens y campos de texto de body, title, description y subject, ya que estarán presentes en los datos que recibiremos de Zendesk.
Incrustación - El uso de modelos de Machine Learning transforma los fragmentos de texto producidos por la parte de procesamiento en incrustaciones vectoriales que luego puedes buscar por similitud semántica. Para crear las incrustaciones, debes proporcionar la clave de la API de OpenAI. Airbyte enviará cada fragmento a OpenAI y añadirá el vector resultante a las entidades cargadas en tu clúster de Milvus.
Indexación - Una vez que hayas vectorizado los fragmentos, puedes cargarlos en la base de datos. Para hacerlo, inserta la información que obtuviste al configurar tu clúster y colección en Zilliz cloud.
Al hacer clic en “Test and save” se comprobará si todo está alineado correctamente (credenciales válidas, la colección existe y tiene la misma dimensionalidad vectorial que la incrustación configurada, etc.)
El último paso antes de que los datos estén listos para fluir es seleccionar qué “streams” sincronizar. Un stream es una colección de registros en la fuente. Como Zendesk admite una gran cantidad de streams que no son relevantes para nuestro caso de uso, seleccionemos solo “tickets” y “articles” y deshabilitemos todos los demás para ahorrar ancho de banda y asegurarnos de que solo la información relevante aparezca en las búsquedas:
Puedes seleccionar qué campos extraer de la fuente haciendo clic en el nombre del stream. El modo de sincronización “Incremental | Append + Deduped” significa que las ejecuciones posteriores de la conexión mantienen Zendesk y Milvus sincronizados mientras transfieren datos mínimos (solo los artículos y tickets que han cambiado desde la última ejecución).
Tan pronto como se configure la conexión, Airbyte comenzará a sincronizar datos. Puede tardar unos minutos en aparecer en tu colección de Milvus.
Si seleccionas una frecuencia de replicación, Airbyte se ejecutará regularmente para mantener tu colección de Milvus actualizada con los cambios en los artículos de Zendesk y los problemas recién creados.
Puedes comprobar en la interfaz de usuario de Zilliz cloud cómo están estructurados los datos en la colección navegando al playground y ejecutando una consulta “Query Data” con un filtro establecido en “_ab_stream == \”tickets\””
Como puedes ver en la vista Result, cada registro que proviene de Zendesk se almacena como entidades separadas en Milvus con todos los metadatos especificados. El fragmento de texto en el que se basa la incrustación se muestra como la propiedad “text”; este es el texto que se incrustó usando OpenAI y será aquello sobre lo que buscaremos.
Step 3: Crear una aplicación de Streamlit que consulte la colección
Nuestros datos están listos; ahora necesitamos construir la aplicación para usarlos. En este caso, la aplicación será un formulario de soporte simple para que los usuarios envíen casos de soporte. Cuando el usuario pulse enviar, haremos dos cosas:
Buscar tickets similares enviados por usuarios de la misma organización
Buscar artículos de la base de conocimiento que puedan ser relevantes para el usuario
En ambos casos, aprovecharemos la búsqueda semántica usando embeddings de OpenAI. Para hacer esto, la descripción del problema que ingresó el usuario también se convierte en un embedding y se usa para recuperar entidades similares del clúster de Milvus. Si hay resultados relevantes, se muestran debajo del formulario.
Necesitarás una instalación local de Python, ya que usaremos Streamlit para implementar la aplicación.
Primero, instala Streamlit, la biblioteca cliente de Milvus y la biblioteca cliente de OpenAI localmente:
pip install streamlit pymilvus openai
Para renderizar un formulario básico de soporte, crea un archivo de 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 ejecutar tu aplicación, usa Streamlit run:
streamlit run app.py
Esto renderizará un formulario básico:
El código de este ejemplo también se puede encontrar en GitHub.
A continuación, comprobemos si hay tickets abiertos existentes que puedan ser relevantes. Para hacer esto, convertimos en embedding el texto que ingresó el usuario usando OpenAI, y luego hicimos una búsqueda de similitud en nuestra colección, filtrando por tickets aún abiertos. Si hay uno con una distancia muy baja entre el ticket proporcionado y el ticket existente, avisa al usuario y no lo envíes:
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!")
Aquí están sucediendo varias cosas:
Se configura la conexión al clúster de Milvus.
El servicio de OpenAI se usa para generar un embedding de la descripción que ingresó el usuario.
Se realiza una búsqueda de similitud, filtrando los resultados por el estado del ticket y el id de la organización (ya que solo son relevantes los tickets abiertos de la misma organización).
Si hay resultados y la distancia entre los vectores de embedding del ticket existente y el texto recién ingresado está por debajo de cierto umbral, se señala este hecho.
Para ejecutar la nueva aplicación, primero debes configurar las variables de entorno para OpenAI y Milvus:
export MILVUS_TOKEN=...
export MILVUS_URL=https://...
export OPENAI_API_KEY=sk-...
streamlit run app.py
Al intentar enviar un ticket que ya existe, así es como se verá el resultado:
El código de este ejemplo también se puede encontrar en GitHub.
Como puedes ver en la salida de depuración verde oculta en la versión final, dos tickets coincidieron con nuestra búsqueda (en estado new, de la organización actual y cerca del vector de embedding). Sin embargo, el primero (relevante) se clasificó más alto que el segundo (irrelevante en esta situación), lo que se refleja en el valor de distancia más bajo. Esta relación se captura en los vectores de embedding sin coincidir directamente con palabras, como en una búsqueda normal de texto completo.
Para finalizar, mostremos información útil después de que se envíe el ticket para darle al usuario la mayor cantidad de información relevante por adelantado posible.
Para hacer esto, vamos a realizar una segunda búsqueda después de que se envíe el ticket para obtener los artículos de la base de conocimientos con mayor coincidencia:
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')})")
Si no hay ningún ticket de soporte abierto con una puntuación de similitud alta, se envía el nuevo ticket y se muestran artículos de conocimiento relevantes a continuación:
El código de este ejemplo también se puede encontrar en Github.
Si bien la interfaz de usuario que se muestra aquí no es un formulario de soporte real, sino un ejemplo para ilustrar el caso de uso, la combinación de Airbyte y Milvus es muy potente: facilita cargar texto desde una amplia variedad de fuentes (desde bases de datos como Postgres, pasando por API como Zendesk o GitHub, hasta fuentes completamente personalizadas creadas con el SDK de Airbyte o el generador visual de conectores) e indexarlo en forma embebida en Milvus, un potente motor de búsqueda vectorial capaz de escalar a enormes cantidades de datos.
Airbyte y Milvus son de código abierto y completamente gratuitos para usar en tu infraestructura, con ofertas en la nube para descargar las operaciones si se desea.
Más allá del caso de uso clásico de búsqueda semántica ilustrado en este artículo, la configuración general también se puede usar para crear un bot de chat de preguntas y respuestas usando el método RAG (Retrieval Augmented Generation), sistemas de recomendación o ayudar a que la publicidad sea más relevante y eficiente.
Sigue leyendo

Zilliz Cloud Enterprise Vector Search Powers High-Performance AI on AWS
Zilliz Cloud on AWS powers secure, scalable, ultra-fast vector search for enterprise AI apps, with BYOC, sub-10ms latency, and zero-DevOps simplicity.

Zilliz Cloud Introduces Advanced BYOC-I Solution for Ultimate Enterprise Data Sovereignty
Explore Zilliz Cloud BYOC-I, the solution that balances AI innovation with data control, enabling secure deployments in finance, healthcare, and education sectors.

Introducing DeepSearcher: A Local Open Source Deep Research
In contrast to OpenAI’s Deep Research, this example ran locally, using only open-source models and tools like Milvus and LangChain.



