Concepto clave
En los sistemas RAG (Retrieval Augmented Generation), la optimización de consultas es crucial para recuperar los fragmentos de texto más relevantes de tu base de datos vectorial. Chroma, como base de datos vectorial local, ofrece dos herramientas principales para esta tarea: filtros y métricas de similitud.
Los filtros te permiten restringir la búsqueda a un subconjunto de documentos basado en metadatos. Imagina que tienes una biblioteca digital con miles de artículos técnicos. Sin filtros, buscar "optimización de consultas" podría devolver artículos de cualquier año o autor. Con filtros, puedes limitar la búsqueda a artículos publicados después de 2020 y escritos por expertos en bases de datos, reduciendo el ruido y mejorando la precisión.
Las métricas de similitud determinan cómo se compara el vector de tu consulta con los vectores almacenados. Chroma soporta varias, como cosine similarity, Euclidean distance, y dot product. Cada métrica tiene sus características: cosine similarity es ideal para textos donde la magnitud no importa, mientras que Euclidean distance mide la distancia directa en el espacio vectorial. Elegir la métrica correcta puede impactar significativamente la calidad de los resultados recuperados.
Cómo funciona en la práctica
Vamos a implementar una consulta optimizada en Chroma paso a paso. Supongamos que tenemos una colección de documentos técnicos sobre bases de datos, con metadatos como 'año', 'autor', y 'categoría'.
- Configuración inicial: Primero, importa Chroma y carga tu colección existente.
- Definir la consulta: Convierte tu pregunta en un vector usando el mismo modelo de embeddings que usaste para indexar los documentos.
- Aplicar filtros: Usa un diccionario para especificar condiciones. Por ejemplo, para filtrar documentos del año 2022 o posterior y de la categoría 'optimización':
filtros = {"año": {"$gte": 2022}, "categoría": "optimización"}. - Especificar métrica de similitud: Al realizar la consulta, pasa el parámetro 'metric'. Por defecto es 'cosine', pero puedes cambiarlo a 'euclidean' o 'ip' (producto punto).
- Ejecutar la consulta: Llama al método 'query' con el vector de consulta, número de resultados, filtros y métrica.
Ejemplo de código:
from chromadb import Client
client = Client()
collection = client.get_collection("documentos_tecnicos")
query_vector = [0.1, 0.2, ...] # Vector de tu consulta
resultados = collection.query(
query_embeddings=[query_vector],
n_results=5,
where={"año": {"$gte": 2022}, "categoría": "optimización"},
metric="cosine"
)Caso de estudio
Una empresa de análisis financiero usa Chroma para construir un sistema RAG que responde preguntas sobre reportes anuales. Tienen documentos de múltiples años y sectores. Inicialmente, las consultas como "tendencias de crecimiento" devolvían resultados mixtos, incluyendo datos obsoletos.
Problema: Recuperación de información irrelevante debido a falta de filtrado por año y sector.
Solución implementada:
- Indexaron documentos con metadatos: 'año' (entero), 'sector' (texto, e.g., 'tecnología', 'salud').
- Para cada consulta del usuario, extrajeron el contexto (e.g., si el usuario menciona "en 2023", filtran por año 2023).
- Usaron cosine similarity como métrica, ya que los embeddings de texto capturan similitud semántica independiente de la longitud.
Resultado: Precisión mejorada en un 40%, con respuestas más relevantes y actualizadas. Por ejemplo, una consulta sobre "crecimiento en tecnología en 2023" ahora recupera solo documentos de ese año y sector, evitando confusiones con datos antiguos.
Errores comunes
- Usar filtros demasiado restrictivos: Aplicar muchos filtros puede devolver pocos o ningún resultado. Solución: Comienza con filtros amplios y ajústalos gradualmente basado en el feedback.
- Ignorar la normalización de embeddings: Al cambiar entre métricas como cosine y Euclidean, no normalizar los vectores puede llevar a resultados inconsistentes. Solución: Asegúrate de que los embeddings estén normalizados si usas Euclidean distance, ya que es sensible a la magnitud.
- No probar diferentes métricas: Asumir que 'cosine' siempre es la mejor opción. Solución: Experimenta con al menos dos métricas en tu dataset específico y evalúa la calidad de los resultados con métricas como precisión@k.
- Filtrar por metadatos incorrectos: Usar nombres de campos de metadatos que no existen en la colección. Solución: Verifica la estructura de metadatos con
collection.peek()antes de aplicar filtros. - Olvidar el impacto en performance: Filtros complejos pueden ralentizar consultas en colecciones grandes. Solución: Indexa metadatos frecuentemente filtrados y monitorea los tiempos de respuesta.
Checklist de dominio
- Puedo explicar la diferencia entre filtros por metadatos y métricas de similitud en Chroma.
- He implementado una consulta en Chroma usando al menos un filtro y una métrica no predeterminada.
- Sé cómo normalizar embeddings cuando cambio entre métricas de similitud.
- Puedo diagnosticar y resolver errores comunes como consultas sin resultados debido a filtros excesivos.
- He evaluado el impacto de diferentes métricas (cosine vs. Euclidean) en la relevancia de los resultados para mi caso de uso.
- Entiendo cómo los filtros afectan la performance y cuándo indexar metadatos.
- Puedo integrar consultas optimizadas de Chroma en un pipeline RAG completo.
Optimización de una consulta RAG con filtros y métricas en Chroma
En este ejercicio, optimizarás una consulta en Chroma para un sistema RAG que maneja documentos de noticias tecnológicas. Sigue estos pasos:
- Prepara el entorno: Asegúrate de tener Chroma instalado (
pip install chromadb) y crea una nueva colección llamada 'noticias_tech' con embeddings de un modelo como sentence-transformers. - Agrega datos de ejemplo: Inserta al menos 10 documentos ficticios de noticias con metadatos: 'fecha' (formato YYYY-MM-DD), 'categoria' (valores: 'inteligencia artificial', 'ciberseguridad', 'cloud'), y 'fuente' (e.g., 'Blog A', 'Sitio B'). Usa textos cortos como "Nuevo avance en IA generativa anunciado hoy".
- Diseña una consulta optimizada: Crea una consulta para recuperar noticias sobre 'ciberseguridad' publicadas después del 1 de enero de 2023, usando Euclidean distance como métrica. Genera un vector de consulta para el término 'ataques cibernéticos recientes'.
- Implementa y prueba: Ejecuta la consulta en Chroma con los filtros y métrica especificados, recuperando 3 resultados. Registra los documentos devueltos y verifica que cumplan los criterios.
- Analiza resultados: Compara los resultados con una consulta sin filtros o usando cosine similarity. Nota diferencias en relevancia o performance.
- Usa 'where' en collection.query() para aplicar filtros; recuerda que Chroma soporta operadores como $gte para fechas.
- Para Euclidean distance, asegúrate de que los embeddings estén normalizados; puedes usar metric='euclidean' directamente si los embeddings ya lo están.
- Si no obtienes resultados, revisa los valores de metadatos en tus documentos insertados con collection.peek().
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.