Cómo depurar la recuperación vacía cuando un sistema RAG no devuelve nada.
Un sistema RAG que no devuelve nada, depurado paso a paso: ingestión, umbrales de puntuación, filtros, reescritura de consultas, búsqueda híbrida, reclasificación y soluciones alternativas.
La generación mejorada con recuperación de información proporciona a un modelo de lenguaje conocimientos externos, de modo que no tenga que responder únicamente con los datos de entrenamiento; esto significa que la respuesta final solo es tan buena como lo que la recuperación de información trae de vuelta. Cuando una búsqueda no arroja nada útil, el modelo dispone de poca o ninguna evidencia. Puede recurrir a una respuesta genérica, rechazar la solicitud o inventar detalles. A continuación se explica de dónde provienen los resultados vacíos o casi vacíos y cómo localizarlos.
La recuperación de información puede fallar en muchos aspectos
Un resultado vacío no representa un único tipo de fallo. Un candidato puede desaparecer durante la ingestión, el embedding, la búsqueda vectorial, el filtrado de metadatos, la definición de umbrales o el ranking. La depuración es más rápida cuando se examina cada etapa por separado y se deja de tratar toda la estructura RAG como una caja negra.
1. Comience con el indexado y los embeddings
Antes de tocar el recuperador, confirme que la base de conocimientos contiene lo que usted cree que contiene. Una ejecución de procesamiento exitosa muestra una progresión lógica desde los documentos originales hasta el texto analizado, luego a los fragmentos, las incrustaciones y los vectores almacenados. Si se generaron 2,000 fragmentos pero solo 200 vectores llegaron al almacenamiento, ninguna ajuste en el recuperador servirá de nada.
- Abra a mano un par de fragmentos almacenados. Deben contener texto legible, IDs estables, incrustaciones y cualquier metadato en el que dependan sus filtros.
- Utilice modelos e dimensiones de incrustación idénticos tanto para los documentos como para las consultas de los usuarios. Cambiar el modelo de consulta sin reconstruir el índice hará que las puntuaciones de similitud pierdan su significado.
- Evalúe también al analizador. Los archivos PDF, escaneos, tablas y páginas HTML pueden convertirse en fragmentos en blanco o dañados, aunque el proceso siga indicando que tuvo éxito.
2. Examine los umbrales, el significado de las puntuaciones y los filtros
Los umbrales de puntuación agresivos son una causa frecuente de resultados nulos. Las puntuaciones de incrustación no son porcentajes de confianza, y el rango útil varía según el modelo, la métrica de distancia, los datos y la base de datos vectorial. Al depurar, obtenga los 10 o 20 candidatos principales sin ningún umbral y lea sus puntuaciones en bruto:
results = vector_store.search(query_embedding, top_k=10)
for r in results:
print(r.score, r.metadata.get('source'))
Luego verifica en qué dirección se calculan las puntuaciones. Algunas API devuelven similitud coseno, donde cuanto mayor sea, mejor. Otras devuelven distancia coseno o euclidiana, donde cuanto menor sea, mejor. Utilizar la comparación incorrecta descarta silenciosamente a tus candidatos más fuertes y mantiene a los más débiles. Como regla general, no establezcas condiciones de umbral hasta que hayas confirmado la convención de puntuación de la base de datos y hayas analizado las distribuciones reales de puntuaciones de consultas representativas.
Los filtros pueden eliminar buenos resultados
El filtrado de metadatos es vital en los sistemas multiinquilino, para los permisos, los alcances de los productos, las fechas, los idiomas y los tipos de documentos, y también se encuentra entre las formas más simples de terminar con un conjunto vacío. Los culpables típicos incluyen comparaciones de cadenas con enteros, mayúsculas y minúsculas inconsistentes, registros antiguos sin metadatos, IDs de inquilino incorrectos, y filtros que individualmente son válidos pero imposibles de aplicar juntos.
3. Revisión de la reescritura de consultas y calidad de los fragmentos
Reescribir una consulta puede ayudar en la recuperación de información, pero también podría eliminar precisamente el término que hizo que la consulta fuera localizable. Imagine a alguien preguntando cómo restablecer el X500, mientras el herramienta de reescritura convierte esa pregunta en “restaurar la configuración predeterminada para la serie X”. Si el manual debe llamarse “Restablecimiento del X500”, es probable que la formulación utilizada por el propio usuario se ajuste mejor a él. Registre tanto la consulta original como la reescrita y pruebe cada una. En el caso de identificadores exactos, códigos de error, nombres de productos y parámetros de API, mantenga los tokens literales incluso si el resto de la consulta se normaliza.
El fragmentado falla de manera similar. Un título como “Restablecer el router X500” no debe separarse de las instrucciones que se encuentran debajo de él. Fragmenta siguiendo la estructura del documento para que el título, sus párrafos, sus elementos de lista y el contexto circundante permanezcan unidos. El tamaño adecuado de los fragmentos depende de la carga de trabajo, aunque un rango inicial razonable es de unos 500 a 1,000 tokens con una superposición moderada, seguido de una evaluación con consultas reales.
Qué medir: toma un pequeño conjunto de consultas etiquetadas y registra si la fuente esperada aparece entre los resultados top-k. Esa prueba centrada en la recuperación es mejor que elegir tamaños de fragmentos o umbrales por intuición.
4. Mezclar búsqueda léxica y vectorial
La búsqueda vectorial brilla cuando el usuario y el documento expresan la misma idea de manera diferente. La recuperación léxica, como BM25, es eficaz cuando son importantes los tokens exactos. Dado que las consultas complejas rara vez son de un solo tipo, los sistemas en producción suelen utilizar ambas. BM25 tiende a ser más útil para cosas como códigos de error (por ejemplo, ERR-XK-1042), códigos SKU, números de factura, nombres de productos, nombres de clases, claves de configuración y nombres de parámetros de API. La búsqueda vectorial añade coincidencias conceptuales cercanas, mientras que BM25 se asegura de no pasar por alto pruebas léxicas exactas. Un diseño típico primero obtiene un conjunto amplio de candidatos y luego aplica un reordenador más potente para mejorar la precisión.
5. Recuperar de forma amplia y luego reordenar
El recuperador de la primera etapa y el reordenador realizan tareas diferentes. El recuperador debe maximizar la recuperación al recopilar todo lo que pueda responder a la pregunta. El reordenador debe maximizar la precisión, comparando la consulta con esos candidatos y elevando las pruebas más relevantes a la parte superior.
Un patrón común consiste en reunir de 20 a 50 candidatos a partir de búsquedas vectoriales y léxicas, fusionarlos y eliminar las duplicadas, y luego reordenarlos hasta quedarse con los 5 a 10 fragmentos mejores. Los codificadores cruzados son eficientes y están diseñados para la puntuación de relevancia, mientras que un reordenador basado en LLM puede seguir instrucciones más detalladas, pero suele ser más lento y costoso.
Evite descartar candidatos demasiado pronto. Si un umbral estricto se activa antes que el reordenador, un fragmento que realmente habría sido útil podría no ser visto nunca por el modelo de relevancia más potente. A menudo, un primer análisis aproximado seguido de un reordenamiento funciona mejor que dejar que la puntuación vectorial determine todo el ranking.
Fusión y deduplicación
Cuando se combinan los resultados de vector y BM25, un mismo fragmento puede aparecer en ambas listas y las escalas de puntuación no coinciden. Utilice un método de fusión como la fusión por rango recíproco, puntuaciones ponderadas normalizadas o una simple unión de rangos, y elimine las repeticiones mediante IDs de fragmentos o documentos estables antes de pasar al reordenador. El objetivo del diseño es ajustar la primera etapa para lograr una buena recuperación de resultados y dejar que el reordenador y la lógica de selección de contexto se encarguen de la precisión, lo que facilita el ajuste y la evaluación del proceso.
6. Ampliar la consulta, con un plan de respaldo
Las personas y los documentos rara vez comparten vocabulario. Quien escriba “No puedo iniciar sesión” podría necesitar páginas tituladas “falla de autenticación”, “solución de problemas de inicio de sesión” o “acceso a la cuenta”. La expansión genera algunas búsquedas alternativas, las ejecuta todas y luego elimina las duplicadas y reordena los resultados. Hay que controlarlo: deja intactas las entidades nombradas y los identificadores exactos, no crees muchas consultas casi idénticas y limita los intentos para que una pregunta difícil no desencadene un bucle costoso.
Solo relaja lo que sea seguro hacerlo. Los filtros de seguridad, de inquilino y de permisos nunca son opcionales y deben permanecer activos. Algo como una categoría de documento opcional, un rango de fechas estricto o etiquetas secundarias puede relajarse si las reglas de tu aplicación lo permiten. Una secuencia sencilla:
docs = retrieve(query)
if not useful(docs): docs = retrieve(expand(query), hybrid=True)
if not useful(docs): return ask_for_clarification_or_no_answer()
Resultado vacío versus recuperación defectuosa
Estos dos casos requieren soluciones diferentes. Si no se obtiene ningún resultado, sospeche de problemas de ingestión, filtros, permisos, umbrales, interpretación de puntuaciones o de un índice al que no se puede acceder. Si los resultados llegan pero no son relevantes, analice la división en fragmentos, la calidad de los embeddings, las carencias en el vocabulario, la escasa cobertura léxica o el sistema de clasificación.
7. Una arquitectura de producción más resistente
Un sistema RAG maduro no aplica la misma ruta de búsqueda a todas las consultas. Clasifica la solicitud y elige una estrategia de recuperación adecuada a las necesidades: los identificadores exactos se basan en la búsqueda léxica, las preguntas conceptuales amplias se basan en la búsqueda vectorial, y las consultas ambiguas o mixtas utilizan ambas.
Después de eso, un paso de agregación permite combinar las fuentes en un único lugar, eliminar fragmentos duplicados, aplicar las reglas de metadatos y permisos necesarias, y enviar una lista de candidatos coherente al reclasificador. La confianza no debe basarse únicamente en una puntuación vectorial. Señales más útiles son la puntuación del reclasificador, la diferencia entre los resultados más destacados, la cantidad de fuentes que contribuyen, si las entidades necesarias para responder realmente aparecen en el contexto, y si varios fragmentos coinciden.
La confianza determina el siguiente paso
Con suficiente confianza, la evidencia mejor clasificada se envía al LLM. Con poca confianza, el sistema puede ampliar o reformular la consulta, intentarlo de nuevo o hacer al usuario una pregunta para aclararla. Esto es mejor que responder siempre, ya que al modelo se le indica claramente cuando la evidencia es insuficiente para sustentar una respuesta fundamentada.
Mantenga la seguridad fuera del bucle de intentos
Cualquier diseño de respaldo debe mantener las reglas de relevancia separadas de las reglas de autorización. La expansión puede suavizar la redacción, y a veces se pueden eliminar los filtros de tema opcionales, pero los límites de los inquilinos, los ACL, los permisos a nivel de fila y las políticas de privacidad permanecen inmutables en cada intento de recuperación. La ruta de intentos de recuperación nunca debe convertirse en una forma de eludir el control de acceso.
8. Hacer observable la recuperación
Al contar solo con la respuesta final en los registros, depurar RAG se convierte en adivinar. La capa de recuperación debe emitir suficientes datos como para reproducir lo que ocurrió con cualquier consulta. Registre al menos: la consulta original, las versiones reescritas o expandidas, los filtros, el modelo de embedding con sus dimensiones, qué recuperador se utilizó, el método top-k, cuántos candidatos brutos se obtuvieron, sus puntuaciones, los fragmentos seleccionados, las puntuaciones del reordenador, la latencia y qué mecanismo de respaldo se activó.
log({
'query': query, 'rewritten': rewritten_query, 'filters': filters,
'candidate_count': len(raw_results), 'scores': scores,
'selected_chunk_ids': selected_ids, 'fallback': fallback_stage
})
Un orden sensato para depurar
Cuando ocurre un incidente de recuperación vacía, proceda desde las verificaciones más económicas y deterministas hacia los cambios en el ranking más subjetivos. Esto evita que los equipos ajusten los prompts o embeddings cuando el problema real es la falta de un índice o un filtro imposible.
- Primero, la ingestión: verifique el número de documentos, el texto analizado, el número de fragmentos, los vectores almacenados y algunos registros que sabe que deberían existir.
- Luego, la recuperación en bruto: envíe la consulta original con todos los filtros y umbrales opcionales desactivados, y luego lea los resultados top-k y sus puntuaciones.
- Vuelva a introducir los filtros uno por uno, lo que permitirá identificar con precisión el filtro que vacía el conjunto de resultados.
- Verifique la semántica de las puntuaciones: ¿es mejor una puntuación más alta o más baja, y se aplica alguna normalización?
- Compare las consultas originales y las reescritas, manteniendo los identificadores exactos, para determinar si la reescritura ayuda o perjudica la capacidad de recuperación.
- Evaluar la recuperación híbrida y el reclasificado frente a un conjunto de consultas etiquetadas, verificando si las fuentes esperadas aparecen en los primeros k y n resultados después del reclasificado.
- Probar la solución de respaldo forzando resultados vacíos o débiles, para confirmar que el sistema aclara la situación o rechaza la respuesta sin generar ilusiones.
Qué medir
La calidad de la respuesta por sí sola no proporciona suficiente información sobre el proceso de recuperación. Debe registrarse el recall@k (¿la fuente esperada formó parte del conjunto de candidatos?), la precisión después del reclasificado, la tasa de resultados vacíos, la tasa de uso de la solución de respaldo, la latencia y la proporción de consultas que necesitaron ampliación o aclaración. Estos indicadores deben desglosarse por tipo de consulta, como preguntas semánticas frente a identificadores exactos, así como por usuario, idioma y colección de documentos, ya que las promedios generales pueden ocultar problemas en ciertos segmentos.
No culpe primero al LLM
Cuando RAG no devuelve nada, evite culpar al modelo. La causa suele estar en una etapa anterior del proceso de búsqueda: ingestión incompleta, embeddings incompatibles, umbrales estrictos, filtros de metadatos incorrectos, puntuaciones mal interpretadas, reescritura agresiva de consultas o una estrategia de recuperación que no se adapta a la consulta. Los sistemas fiables combinan un indexado adecuado con una recuperación híbrida, generación de candidatos amplia, reclasificación, expansión controlada de consultas, un comportamiento de respaldo explícito y telemetría sólida. El modelo mental útil es que RAG es, en primer lugar, un problema de búsqueda y clasificación, y solo en segundo lugar, un problema de generación. Cuando la capa de recuperación proporciona de manera fiable evidencias relevantes y autorizadas, y sabe cuándo no puede hacerlo, el modelo se vuelve más preciso, más fácil de explicar y menos propenso a generar alucinaciones.
Leer más
- Dartboard RAG: Qué hacer cuando Top-K devuelve el mismo fragmento tres veces — La recuperación simple con top-k puede devolver fragmentos casi idénticos. Dartboard RAG selecciona tanto la relevancia como la diversidad; aquí se explica el algoritmo, el código y cuándo utilizarlo.
- RAG avanzado en producción: arquitectura, herramientas y compromisos — Un recorrido por el RAG en entornos de producción: ingestión, análisis, fragmentación, embeddings, almacenes vectoriales, recuperación híbrida, reclasificación, evaluación y seguridad, junto con los compromisos de cada uno.