Módulo 2 · Parte B de 3

Un agente de indexación

Los datos pueden adoptar distintas formas, y cada una necesita una estrategia adecuada para extraerlos o recuperarlos desde algún repositorio de datos. Elegir una estrategia incompatible con los datos es la causa más frecuente de los fallos silenciosos en un agente de indexación de producción.

Un agente de indexación aplica la idea de flujo de trabajo a una fuente de conocimiento externo mediante un pipeline definido por el desarrollador. Primero genera embeddings e indexa información; después recupera fragmentos de información pertinentes (según la entrada recibida) que usa como contexto para producir una respuesta. El ejemplo muestra primero este proceso para texto no estructurado y luego presenta la recuperación como una herramienta que puede ser invocada por un bucle ReAct externo. Esta sección profundiza más tarde en diferentes formatos de datos.

Construye la secuencia de recuperación en orden.
  1. La generación sin recuperación responde con el contexto actual y el entrenamiento del modelo.
  2. El RAG tradicional ejecuta un paso fijo de recuperación antes de cada respuesta generada.
  3. La recuperación controlada por el agente expone la recuperación como herramienta, de modo que el bucle decide si necesita otra consulta.
Los ejercicios mantienen visibles el corpus y la pregunta mientras cambia quién controla la recuperación.
Profundo · Historia¿Seguir la evolución de RAG desde el entrenamiento conjunto hasta la recuperación?

El origen de RAG: un sistema entrenado de extremo a extremo

La versión de RAG más habitual hoy omite gran parte del diseño original. Conocer esa diferencia cambia la forma de entender el recuperador que vas a conectar.

Cuando Lewis y sus colaboradores acuñaron el término generación aumentada por recuperación (del inglés Retrieval Augmented Generation, RAG) en 2020, no describían un modelo con un buscador añadido. El recuperador y el generador se entrenaban juntos para la tarea. Lee primero la figura de izquierda a derecha y después observa la flecha superior.

La arquitectura original de Lewis et al. (2020), con la retroalimentación de la línea superior que la mayoría de los sistemas actuales omite.

La clave del diseño está en la flecha «Retroalimentación de extremo a extremo por q y pθ». Una sola función de coste (loss) actualizaba ambas partes. El codificador de consultas aprendía qué fragmentos de información podía aprovechar el generador, y el generador aprendía a apoyarse en la evidencia recuperada en vez de depender solo de su memoria.

El recuperador nació como parte del modelo y se adaptaba a la tarea, mucho antes de que se describiera como una herramienta de búsqueda colocada delante de un modelo.

Por qué hoy día la mayoría de los sistemas RAG descarta el entrenamiento conjunto

Hoy casi nadie entrena sistemas RAG de ese modo por dos razones prácticas. No se puede retroalimentar a través de un modelo avanzado al que se accede mediante una API. Incluso con un modelo alojado por ti, el entrenamiento conjunto del recuperador y el generador resulta costoso y fácil de desestabilizar.

La práctica convergió en un montaje más sencillo: tomar un modelo existente, mantenerlo congelado y anteponerle un recuperador para que el prompt llegue cargado de evidencia, sin entrenar nada. Las partes se construyen por separado y se conectan después. Con el tiempo, «RAG» pasó a designar ese acoplamiento, y no al sistema optimizado conjuntamente que describía el artículo.

El coste del acoplamiento. Un recuperador que nunca recibe la señal de pérdida del generador solo puede estimar qué necesita este. La calidad queda limitada por la adecuación del modelo de embeddings a los datos. El reranking, la reescritura de consultas y el ajuste o finetuning del modelo de embeddings son técnicas que intentan recuperar parte de lo que ofrecía el entrenamiento conjunto. Un stack de recuperación riguroso añade etapas para conseguir igualar los beneficios del entrenamiento conjunto. Entender el acoplamiento como sustituto pragmático de un sistema conjunto permite ver su techo y las opciones de mejora existentes.

El pipeline de recuperación y generación que vas a construir

Teniendo en cuenta las limitaciones comentadas, observa el montaje completo. Un recuperador opera delante del modelo congelado en dos líneas temporales. Una construye el índice con antelación; la otra atiende solicitudes usando ese índice. La figura muestra ambas.

Recreación para el curso del pipeline de dos etapas mostrado en Hayden Wolff, RAG 101 (NVIDIA, 2023) y Amit Bleiweiss, tips for building a RAG pipeline (NVIDIA, 2024).

Offline: construye el índice una vez, genera los embeddings de cada fragmento de datos y los guarda para realizar búsquedas rápidas.

En vivo: genera el embedding de una pregunta, recupera los K mejores fragmentos de datos y se los entrega al modelo junto con la pregunta.

El resto de esta sección construye este recorrido por partes.

Aplicado · Alcance¿Elegir paquetes, límites y formas de datos?

Define el paquete de contexto antes de elegir el almacenamiento

Antes de elegir una primitiva de recuperación, define un paquete: el conjunto completo y acotado de contexto que circulará por el pipeline.

  • Para un sistema sencillo de preguntas y respuestas de un solo turno, el paquete puede ser pequeño: la pregunta, unos pocos fragmentos recuperados y la respuesta.
  • Para un agente autónomo, el paquete es la memoria de trabajo que conserva durante varios turnos: restricciones, decisiones anteriores, resultados parciales, herramientas disponibles y reglas operativas.
  • Para un agente de indexación de alcance arbitrario, el paquete de salida puede contener solo los fragmentos recuperados, sus fuentes, puntuaciones de relevancia y quizá un resumen. Un paquete interno distinto puede representar el pipeline lineal de la solicitud o un bucle ReAct que evalúa la relevancia y reintenta hasta reunir suficiente contexto.

La idea impone una disciplina: definir el paquete antes de elegir la base de datos. Elegir primero un almacén vectorial y esperar que cubra todo origina muchas historias de «funcionó en la demostración, pero falló en producción». La siguiente taxonomía permite comprobar si una primitiva puede entregar el paquete que exige la tarea.

Dónde encaja MCP en un sistema de recuperación

MCP le proporciona a un sistema de recuperación una interfaz definida para descubrir y consultar fuentes de contexto externas. Sin embargo, el agente todavía necesita un motor de ejecución que decida cuándo recuperar esa información, valide los resultados y los integre con el estado actual de la tarea en curso. Otras interfaces se encargan de los componentes restantes del sistema: los paquetes de habilidades (skills) agrupan instrucciones de capacidades reutilizables, el sistema A2A (Agent-to-Agent) puede derivar el trabajo a especialistas remotos, y los protocolos de interfaz de usuario transmiten en tiempo real (stream) el estado generado de vuelta a la aplicación.

La figura separa esas fronteras. Léela de izquierda a derecha para seguir la entrada de contexto mediante MCP y la entrega de tareas mediante A2A; de abajo arriba, para seguir la intermediación de capacidades mediante skills, la ejecución en el runtime y la experiencia generada. Elige la frontera que corresponda al paquete y al estado del sistema que debe transportar.

Cuatro fronteras alrededor del runtime de recuperación: MCP para la entrada de contexto, A2A para la entrega de tareas y skills, runtime e interfaz para el flujo de capacidades.

Asocia una primitiva de recuperación a la forma de los datos

Cada tipo de datos exige una primitiva de extracción adecuada. Si eliges la vía equivocada, el sistema seguirá devolviendo resultados plausibles mientras omite lo que pide la consulta, sin emitir ningún error. La tabla siguiente relaciona cada tipo de datos con su primitiva de extracción.

Forma Ejemplos Primitiva adecuada
Prosa no estructuradaDocumentos, artículos, comentarios de código, transcripcionesVector denso y reranking con cross-encoder
Documentos jerárquicosContratos legales, manuales técnicos, especificaciones anidadasÍndice de árbol con punteros al elemento padre
Tablas estructuradas o gobernadasRegistros de clientes, libros contables, tablas de recursos humanosCapa semántica sobre la fuente de verdad
Datos relacionales o grafosOrganigramas, dependencias de código, grafos de conocimientoRecorrido de grafos (Cypher, GraphQL o personalizado)

El ejemplo de prosa no estructurada lleva un corpus a través de la recuperación y la generación hasta obtener una respuesta fundamentada.

Cada solicitud recorre los mismos cuatro pasos:

  • Convertir la consulta en un vector mediante un embedding.
  • Buscar en el índice los fragmentos más similares.
  • Añadir esos fragmentos al prompt.
  • Generar una respuesta fundamentada en ellos.

Los agentes de indexación que gestionan otras primitivas suelen conservar esta estructura y cambiar la lógica de búsqueda, representación y verificación. Experimenta con la opción que mejor se ajuste a tus datos.

El embedding, la primitiva fundamental para el resto

Cada agente de indexación para prosa no estructurada parte de la misma primitiva. Un embedding es una dirección numérica aprendida para un fragmento de texto: es un vector de longitud fija creado de forma que textos semánticamente similares queden próximos en el espacio vectorial. Esto tiene dos consecuencias prácticas:

Comparar: la similitud coseno entre dos vectores requiere un producto escalar y dos magnitudes.

Almacenar: un índice vectorial se utiliza para organizar los fragmentos de texto para buscar vecinos cercanos (similares semánticamente) con eficiencia.

Ambas operaciones dependen de una sola primitiva: el modelo de embeddings. El curso dirige las llamadas mediante helpers.embed al endpoint de embeddings alojado por NVIDIA, por lo que todo funciona en el navegador sin un laboratorio ni un servidor local.

Aplicado · Contrato¿Revisar el contrato de solicitud de embeddings?
Contrato de la API de embeddings.

El endpoint acepta una solicitud JSON con tres campos y devuelve un array de vectores:

  • input contiene un conjunto (batch) de textos, con tipo string[].
  • model identifica el modelo de embeddings, con tipo string.
  • input_type es "query" o bien "passage".
  • La respuesta contiene un array data; cada entrada del mismo incluye un embedding de tipo number[].

Los modelos de embeddings de NVIDIA asignan vectores distintos al mismo texto según el input_type que le pases. El objetivo durante el entrenamiento es acercar una pregunta hacia los pasajes que la responden, en lugar de hacia textos que simplemente repiten sus palabras. Por eso, una puntuación de coseno entre dos entradas con el tipo correcto refleja muy bien la relevancia. Generar el embedding de una consulta con el tipo "passage" (o viceversa) altera la función de puntuación de forma silenciosa, lo que produce un recall más bajo sin mostrar ningún mensaje de error.

Un recuperador completo en treinta líneas de top-K por coseno

Una «base de datos vectorial» presenta una interfaz elaborada para una tarea sencilla: almacena cada pasaje junto a su embedding y devuelve los top-K más cercanos al embedding de la consulta según la similitud coseno. En el navegador, el núcleo cabe en treinta líneas de JavaScript.

La celda siguiente construye un agente de indexación sobre unos pocos documentos. Edita el corpus y la consulta; después observa qué pasajes llegan a las primeras posiciones y por qué.

Modo de fallo: embeddings desactualizados.

Un índice vectorial almacena en caché las salidas de un modelo de embeddings. Los sistemas de producción deben protegerse contra varios fallos:

Un índice fiable registra el identificador del modelo junto a cada vector y se niega a mezclar versiones. El modelo fijado en este curso es nvidia/llama-nemotron-embed-1b-v2, servido mediante el proxy alojado del curso en build.nvidia.com.

Aplicado · Fragmentos¿Recuperar fragmentos pequeños con su contexto superior?

Buscar fragmentos pequeños y devolver el documento padre

Un agente de indexación top-K básico afronta una tensión entre recall y precisión que ningún modelo de embeddings elimina. Debes elegir entre fragmentos breves y documentos largos:

  • Los fragmentos breves producen embeddings precisos, pero aportan poco contexto: el vector representa una sola idea concreta.
  • Los documentos largos conservan el contexto, pero generan embeddings difusos: el vector promedia muchas ideas.

El patrón de producción indexa en dos niveles. Genera embeddings de fragmentos pequeños para mantener la precisión y, cuando uno coincide, devuelve el documento padre para que el modelo vea el contexto completo.

El ejercicio usa tres documentos padre, cada uno dividido en fragmentos breves, y una consulta que devuelve el documento padre correspondiente.

Indexamos y buscamos los fragmentos hijos; cada coincidencia entrega al LLM el documento padre completo.
Aplicado · Agente¿Dejar que el modelo decida cuándo recuperar información?

Presenta el índice como una herramienta que el modelo puede invocar

Un índice aislado solo responde cuando algo lo consulta. Se convierte en un agente de indexación cuando se presenta como una herramienta que el modelo puede elegir. Así, el modelo decide cuándo merece la pena recuperar datos. La celda lo hace en cinco etapas:

  1. El corpus se procesa una vez y se conserva en un índice en memoria.
  2. Se declara una herramienta retrieve(question, k) mediante un esquema JSON.
  3. El agente recibe la pregunta y decide si invoca la herramienta.
  4. Si la invoca, ejecuta la recuperación por coseno; los pasajes top-K se añaden como mensaje de herramienta.
  5. Una segunda llamada al LLM redacta la respuesta final a partir de los pasajes recuperados.

El patrón de «recuperador como herramienta» se traslada directamente a producción. Sustituir la función en memoria por un pipeline de servidor con FAISS, BM25 y reranking solo cambia el ejecutor; el esquema, el bucle del agente y la respuesta final permanecen iguales.

Aplicado · Formas¿Comparar las demás formas de índice?

Cómo se construyen las otras tres formas

Ya has construido la vía de la prosa no estructurada desde el corpus hasta la respuesta. Las otras tres aparecen aquí para que puedas reconocerlas y elegir la primitiva adecuada. Cada una tiene un patrón de producción establecido:

  • Documentos jerárquicos. Un segmentador conserva la jerarquía de títulos y combina extracción atómica de tablas, punteros al elemento padre y un índice doble para búsqueda estructural y semántica. Se indexan fragmentos hijos para mejorar el recall y se recupera el padre correspondiente para que el modelo lea la cláusula dentro de su sección.
  • Recuperación de imágenes de página para figuras y gráficos. Una configuración con dos espacios vectoriales genera embeddings de la página renderizada y de su texto. Así, la consulta también puede recuperar una figura o diapositiva cuando la respuesta esté en el contenido visual.
  • Tablas estructuradas y gobernadas. No se construyen en este curso. El patrón de producción sitúa una capa semántica entre el agente y los datos por fila, y expone solo las métricas seleccionadas que requiere el paquete.
  • Datos relacionales o grafos. En lugar de un almacén vectorial, el agente invoca una herramienta de recorrido de grafos escrita en Cypher, GraphQL o una interfaz propia. Recibe un subgrafo cuyas aristas explícitas llegan al prompt y conservan las relaciones entre entidades.
Profundo · GraphRAG¿Explorar la recuperación sobre todo el corpus con GraphRAG?

Cuando top-K es la herramienta equivocada: GraphRAG y preguntas globales

Cada recuperador de esta página responde a una pregunta local cuya respuesta aparece en unos pocos pasajes que top-K puede encontrar, como qué dice un contrato sobre la rescisión o qué artículo introdujo HyDE. Otra clase de pregunta no tiene respuesta en ningún pasaje aislado. Si preguntas por los temas principales de mil documentos, la respuesta emerge del corpus completo.

Top-K devuelve solo las tres mejores coincidencias. El modelo resume esos fragmentos sin ver los otros 997 pasajes del corpus. GraphRAG (Edge et al. 2024) cambia la forma del problema en vez de aumentar K. Durante la indexación usa un LLM para:

  • leer el corpus y extraer entidades y las relaciones entre ellas en un grafo de conocimiento;
  • detectar las comunidades del grafo, es decir, grupos de entidades densamente conectadas;
  • resumir cada comunidad por separado.

En el momento de la consulta, el sistema resume las comunidades pertinentes y reduce las respuestas parciales a una sola. Es un proceso map-reduce sobre la estructura, no una búsqueda por similitud.

Pipeline de GraphRAG, redibujado a partir de Edge et al. (2024). Las etapas azules se construyen una vez, offline; las verdes se ejecutan para cada pregunta.

La celda muestra la diferencia en un corpus pequeño mediante el pipeline real. Responde a una pregunta global de dos maneras: recuperación top-K básica y map-reduce de GraphRAG sobre comunidades identificadas. Observa cómo top-K usa los fragmentos cuyas palabras coinciden con la pregunta, mientras que las comunidades recuperan el tema del corpus completo. Edita el corpus, las comunidades o la pregunta y vuelve a ejecutar.

Un modelo congelado con un recuperador top-K responde bien a preguntas locales, pero no a preguntas globales. Reestructurar el corpus en comunidades resumidas permite obtener la respuesta global a cambio de una indexación más costosa que se ejecuta una sola vez.

Antes de continuar

  1. La similitud coseno puntúa dos vectores de la misma manera sin importar cuál sea la consulta. El modelo de NVIDIA usa input_type para distinguir consulta y pasaje. ¿Qué aporta esa asimetría?
  2. El índice genera una vez los embeddings del corpus, mientras que la ruta en vivo procesa cada pregunta. ¿Qué cambios exigen reindexar el corpus y cuáles solo requieren un nuevo embedding de consulta?
  3. Top-K siempre devuelve K pasajes, aunque todas las puntuaciones sean débiles. ¿Qué señal debería examinar el agente antes de incorporarlos al prompt?
Profundo · Fuentes¿Rastrear las fuentes de investigación sobre recuperación?

Referencias

Lista completa en Para ir más lejos · Referencias.

Prueba · recuperación en vivo

Formula una pregunta. El artefacto usa el mismo endpoint de la página para generar su embedding y clasifica un corpus pequeño mediante similitud coseno. Las barras muestran todas las puntuaciones. Después, el modelo responde a partir de los pasajes mejor clasificados y los cita. Cambia la pregunta y observa cómo varía el orden.

El corpus se procesó offline y se distribuye junto a la página como índice preconstruido; solo la pregunta necesita un embedding en vivo. Así puedes observar la separación entre indexación y servicio. Las preguntas de ejemplo también incluyen vectores preconstruidos y recuperan resultados antes de añadir una clave; al editar un pasaje, solo se vuelve a procesar ese pasaje.

← Módulo 2a: Flujos de trabajo