Debuggear grounding: trazar una respuesta equivocada hasta el retrieval
Una respuesta fundamentada volvió equivocada y tenés que arreglarla. El movimiento que lo hace posible es el que casi todos se saltean: traé los chunks que el retrieval devolvió de verdad antes de tocar el prompt — no podés arreglar lo que no podés ver. El playbook por síntoma para cinco formas en que el grounding sale mal — equivocado con seguridad, miss de recall, rankeado abajo, desactualizado, chunk del usuario equivocado — cada una con qué inspeccionar, el arreglo, y el caso de eval de retrieval que evita que vuelva.
Una respuesta fundamentada volvió equivocada y alguien está esperando el arreglo. El instinto es abrir el prompt y empezar a reescribir — y es el instinto equivocado, porque la respuesta son dos sistemas compuestos y estás por tunear la mitad que probablemente no falló. El movimiento que cambia todo es el que casi todos se saltean bajo presión: cuando una respuesta fundamentada está mal, inspeccioná qué devolvió el retrieval de verdad antes de tocar el prompt. No podés arreglar lo que no podés ver (principio 2). Traé los chunks exactos que se le pasaron al modelo en la corrida fallida y el bug casi siempre se nombra solo — el chunk correcto faltaba, o estaba enterrado, o estaba desactualizado, o nunca fue de este usuario. Sin eso, estás reescribiendo un prompt contra una historia que te inventaste sobre lo que leyó el modelo.
Esta página es la companion operativa de gotchas de grounding y calidad de retrieval: los gotchas nombran cómo falla el grounding y la página de calidad es la vara que pasa, y este es el loop de "ahora arreglalo" que corrés cuando una respuesta puntual está mal en producción. Es por síntoma: encontrá la falla que coincide con lo que estás viendo, inspeccioná el retrieval en la capa que la sección señala, aplicá el arreglo, y — el paso que separa debuggear de jugar al topo — convertí la query fallida en un caso de eval de retrieval para que la regresión no pueda volver. Nada de esto depende del toolkit: grounding sobre retrievers de Agentforce sobre el perfil de Data 360, o un pipeline de RAG externo sobre tus propios documentos, falla en las mismas cinco formas, y los chunks recuperados son donde las cazás a todas.
The loop: inspect retrieval → reproduce → eval-driven fix
Cada sesión de debug de abajo corre los mismos tres pasos, en este orden:
- Inspeccionar el retrieval. Traé los chunks exactos devueltos en la corrida fallida — el texto, el rank en el que aterrizó cada uno, la fuente de cada uno, y la query como la vio el retrieval de verdad. Si no podés, tenés un hueco de observabilidad que arreglar antes que nada; un grounding que no podés inspeccionar es uno que debuggeás por superstición (principio 11). La única pregunta que parte cada falla de abajo: ¿estaba siquiera el chunk correcto en el set, y dónde?
- Reproducir. Corré la misma query contra el retrieval hasta que puedas hacer que la falla pase cuando quieras. Un miss de retrieval que no podés reproducir es uno que no podés confirmar que arreglaste — y un arreglo que no podés reproducir pasando es una adivinanza con un tilde verde.
- Arreglar con evals. Agregá la query fallida al eval set de retrieval antes de cambiar nada —
query → el chunk que debería volver— miralo fallar, aplicá el arreglo, mirá volver el chunk correcto a un rank usable, y corré el set entero para confirmar que no rompiste un vecino. El caso de eval es lo que hace permanente el arreglo; sin él, el mismo miss vuelve a entrar en el próximo re-chunk, re-embed, o cambio de índice y nadie lo nota (principio 3).
Está equivocado con seguridad
Cómo reconocerlo. La respuesta afirma algo falso, con fluidez, y lo presenta como seguro. Es la falla de grounding más peligrosa porque se ve exactamente igual que una respuesta correcta — la única pista es que el contenido está mal, y alguien puede actuar sobre él antes de que nadie lo note.
Qué inspeccionar. Sospechá del retrieval antes que del modelo. Traé los chunks que se le pasaron al modelo en esta corrida y chequeá una cosa primero: ¿estaba siquiera el chunk correcto en el set? Si no estaba, frená — esto es un problema de retrieval, no del modelo, y ningún edit del prompt recupera un hecho que el modelo nunca recibió (gotchas de grounding gotcha 4, principio 2). Si el chunk correcto sí estaba en el set pero la respuesta igual está mal, la falla es o posición (cubierta más abajo) o genuinamente el modelo, y ahora sabés cuál. Leé los chunks recuperados antes de leer el prompt.
El arreglo. Si el chunk correcto faltaba, arreglá el índice, el chunking, o la query — no el prompt. La query volvió vacía o equivocada por algo río arriba: un corte de chunk que destruyó el hecho, un embedding model que no resuelve este corpus, una query redactada en nada parecido a la fuente. Arreglá la capa que perdió el chunk (el resto de esta página es la versión por síntoma de eso), y hacé de "no tengo eso" un camino que el sistema tiene permitido tomar — un sistema fundamentado que no puede decir "no está en la knowledge base" va a inventar cada vez que el retrieval vuelva vacío. Si un analista humano no pudiera contestar la pregunta desde los mismos chunks recuperados, el bug es el grounding, no el modelo — heredó el hueco.
Cómo hacerlo sostener. Agregá la query al eval set de retrieval con el chunk que debería responderla, y afirmá que ese chunk ahora vuelve. Puntualo sobre el retrieval — ¿volvió el chunk correcto — no sobre qué tan segura suena la respuesta final, porque la seguridad es justo lo que esta falla finge. Incluí al menos una query cuya respuesta correcta sea "no está en la knowledge base", para que una regresión que traiga de vuelta la alucinación con seguridad falle a los gritos.
El chunk correcto nunca volvió (miss de recall)
Cómo reconocerlo. Inspeccionaste el set y el chunk que responde la pregunta simplemente no está — ni enterrado, ni abajo, ausente. El corpus contiene la respuesta; el retrieval nunca la surfaceó. Esta es la falla debajo de la mayoría de las respuestas equivocadas-con-seguridad, por lo que se gana su propia sección.
Qué inspeccionar. Caminala río arriba por el pipeline (ver chunking y embeddings). Tres sospechosos, chequeados en orden. Primero, el chunking: encontrá el documento fuente y mirá dónde cayó el límite — un corte por el medio del hecho deja las dos mitades irrecuperables, y un chunk demasiado chico para cargar su propio contexto nunca aterriza cerca de la query. Segundo, el fit del embedding: un modelo general sobre un corpus cargado de códigos, jerga, o términos de dominio mapea el chunk y la query a vectores que no quedan cerca uno del otro. Tercero, la query en sí: redactada en un lenguaje lejano a cómo está escrita la fuente, o cargando un token exacto (un SKU, un código de error, un apellido) que la semantic search descarta en silencio.
El arreglo. Hacé coincidir el arreglo con el sospechoso que la inspección señaló (calidad de retrieval es el catálogo de palancas). Si el límite partió el hecho, re-chunkeá sobre costuras naturales y agregá un poco de overlap; si un chunk perdió su contexto, Contextual Retrieval se lo prepende de vuelta. Si el embedding model no encaja con el dominio, esa es la elección a revisar — y acordate de que la query y los documentos tienen que compartir un solo modelo, así que cambiarlo significa re-embeddear el corpus. Si falta un término exacto, sumá hybrid search para que BM25 atrape el token literal que la semantic search descarta. Si la query es vaga o llena de pronombres, sumá query rewriting antes del retrieval. Tirá de la palanca más barata que mueva el recall primero — un k más grande o mejores límites muchas veces arregla lo que estabas por resolver con un re-ranker.
Cómo hacerlo sostener. Agregá la query y su chunk correcto al eval set de retrieval y afirmá recall: el chunk ahora vuelve, en cualquier lugar del set devuelto. El recall es lo primero a trabar, porque nada río abajo — ni re-ranker, ni prompt — recupera un chunk que nunca se recuperó. El eval es lo que prueba que el re-chunk o el agregado de hybrid search arregló el miss real y no descartó en silencio un chunk que antes aterrizaba.
El chunk correcto volvió pero rankeó demasiado abajo (posición)
Cómo reconocerlo. Inspeccionaste el set y el chunk correcto está ahí — en la posición 9 de 10, o en cualquier lado cerca del fondo de la ventana. El recall está bien; el hecho se recuperó. Pero el modelo lo subponderó, porque compite con los distractores de arriba por la atención y un contexto largo entierra lo que queda abajo. Un chunk correcto rankeado abajo es un casi-miss, no un hit.
Qué inspeccionar. Leé el rank del chunk correcto contra lo que está arriba de él. Los chunks rankeados más alto son los distractores que le roban la atención al modelo — normalmente matches plausibles-pero-irrelevantes que puntuaron bien en similitud cruda. Confirmá la forma: el chunk que carga la respuesta está presente y abajo, y los primeros slots los toman chunks que no responden la pregunta. Eso es un problema de precisión-y-posición, no de recall, y tiene un arreglo distinto.
El arreglo. Sumá re-ranking (calidad de retrieval). Recuperá un set de candidatos más amplio de forma barata, después corré un re-ranker — un modelo que puntúa cada candidato contra la query por relevancia — y reordená para que el chunk correcto aterrice arriba. La primera pasada tira ancho por recall; el re-ranker compra precisión y posición. El hecho ya estaba ahí; solo lo estás moviendo a donde el modelo de verdad lo vaya a usar. El metadata filtering ayuda también — achicar el pool antes de rankear significa menos distractores compitiendo por los primeros slots de entrada.
Cómo hacerlo sostener. Agregá la query al eval set de retrieval y afirmá posición, no solo recall: el chunk correcto vuelve cerca del tope de la ventana, no solo en algún lado adentro de ella. Las regresiones de posición son silenciosas — un re-chunk o un cambio de embedding puede empujar el chunk correcto abajo en silencio mientras el recall igual pasa — así que la afirmación tiene que chequear dónde aterrizó el chunk, o el bug vuelve a entrar pareciendo sano.
La respuesta está desactualizada
Cómo reconocerlo. La respuesta es correcta contra el índice y equivocada contra la realidad — refleja un precio, una política, o un registro como era, no como es. Es la falla de grounding más difícil de atrapar, porque el retrieval se ve perfectamente sano: el chunk correcto volvió, rankeó bien, y el modelo groundeó sobre él con fidelidad. El chunk en sí está desactualizado respecto de la fuente que todos los demás están leyendo.
Qué inspeccionar. Compará el texto del chunk recuperado contra la fuente viva. Si no coinciden, el índice está atrasado — todavía tiene el embedding del texto viejo porque ningún re-index corrió desde que cambió la fuente (gotchas de grounding gotcha 3). Después inspeccioná el refresh path: qué se supone que dispara un re-index cuando esta fuente cambia, cuándo corrió por última vez, y cuán desactualizada se le permite estar a esta fuente. Un índice vectorial es un cache de tu corpus — equivocado en el momento en que la fuente cambia, correcto de vuelta solo después de un refresh.
El arreglo. Arreglá el contrato de frescura, no el prompt. Decidí cómo un edit llega al índice, cuánto puede ser el lag por fuente, y cuáles fuentes cambian lo bastante seguido como para que un rebuild nocturno ya sea demasiado tarde — después cableá el trigger que lo sostiene. Donde re-embeddear el corpus entero en cada edit no escala, actualizá de forma incremental: re-embeddeá solo lo que cambió. La meta es que un edit a la fuente llegue al índice dentro de la frescura que decidiste que podés tolerar, con una forma de notar cuándo no lo hace.
Cómo hacerlo sostener. Un caso de eval de retrieval solo no puede atrapar la desactualización, porque el chunk etiquetado del eval se desactualiza junto con el índice. Sumá en cambio un chequeo de frescura: una fuente fija que editás en un schedule, después afirmá que el retrieval devuelve el texto nuevo dentro del lag que el contrato promete. Eso convierte "el índice derivó en silencio de la verdad" en un test que falla el día que se rompe el refresh path, en vez de una respuesta equivocada que un usuario encuentra por vos.
Surfaceó un chunk del usuario equivocado
Cómo reconocerlo. El retrieval devolvió algo que el usuario nunca tuvo permitido ver — un chunk de un documento que no puede abrir por la puerta de adelante, surfaceado a través del agente. La respuesta hasta puede ser correcta; la falla es que este usuario la recibió siquiera. Se ve como una respuesta útil y es un incidente de exposición de datos.
Qué inspeccionar. Chequeá dónde corre el filtro de permisos — y confirmá que es en el retrieval, no en la UI. Traé los chunks devueltos para este usuario y preguntá si cada uno pertenece a una fuente a la que tiene acceso. Si un chunk restringido entró al set, el índice aplanó tu corpus en un solo espacio buscable y aplanó los permisos con él: el retriever devolvió un chunk sin importar quién preguntaba, la semantic search actuando como un confused deputy (gotchas de grounding gotcha 8). Inspeccionar solo la UI esconde esto — el chunk ya quedó expuesto en el momento en que el retrieval lo devolvió.
El arreglo. Filtrá por los permisos del usuario que pide antes de rankear, sobre metadata que indexaste para exactamente esto — para que un documento que el usuario no puede abrir sea también un chunk que el retriever no le devuelva a ese usuario. Imponer la visibilidad solo en la interfaz y confiar en que el índice sea discreto es cómo el grounding se vuelve un camino de exfiltración. Del lado de Agentforce, los retrievers que corren dentro del modelo de seguridad de Salesforce respetan las sharing rules del usuario en ejecución por construcción; un pipeline externo tiene que construir ese filtro él mismo, y no es opcional.
Cómo hacerlo sostener. Agregá un caso de permisos al eval set de retrieval: una query que surfacearía un chunk restringido, corrida como un usuario que no tiene acceso, afirmando que ese chunk es inalcanzable. Este es el único caso de eval donde el resultado correcto es que el chunk no vuelva. Sin él, un re-index que descarta la metadata de permisos, o un filtro que regresa, vuelve a abrir el camino de exfiltración en silencio — y una regresión de seguridad es justo la clase que sale sin que nadie la note hasta que alguien lee lo que no debería.
El hilo
Cinco fallas, un método debajo: traé los chunks que el retrieval devolvió de verdad, encontrá cuál de las cinco formas estás mirando — faltante, abajo, desactualizado, usuario equivocado, o un miss genuino del modelo — arreglá la capa que los chunks realmente señalan, y trabá el arreglo detrás de un caso de eval de retrieval para que no pueda volver en silencio. La razón por la que adivinar falla e inspeccionar gana es que una respuesta fundamentada son dos sistemas compuestos, y la que la mayoría de los equipos reescribe casi nunca es la que se rompió. Cada falla de arriba es un lugar donde el único retrieval feliz de la demo se separó del retrieve-from-everything de producción, y los chunks recuperados son donde encontrás la separación en vez de teorizar sobre ella. El mismo hábito recorre una corrida completa de agente — ver debuggear agentes, que traza el loop entero de la misma forma.
Si una falla de grounding le pegó a tu equipo y no está acá, escribí a hello@wearecleon.com — la agregamos, con crédito.
Related
- Gotchas de grounding — los modos de falla que esta página operacionaliza, cada uno con la pregunta a contestar primero
- Calidad de retrieval — las métricas y palancas que estos arreglos tiran, medidas aparte de la respuesta
- Chunking y embeddings — los inputs río arriba a los que un miss de recall suele rastrearse
- Qué es el grounding — el vocabulario en el que están nombrados los síntomas
- Retrievers de Agentforce — inspeccionar el retrieval dentro del modelo de seguridad de Salesforce
- RAG externo — inspeccionar el retrieval en un pipeline sobre tus propios documentos
- Style Guide de grounding — la vara que evita que estas sesiones de debug pasen dos veces
- Debuggear agentes — el mismo método para una corrida completa de agente, no solo el retrieval
- Principios de AI Engineering — fundamentá antes de generar (2), evaluá antes de lanzar (3), trazá todo (11)
Reference: