volver al blog

GraphRAG: cuándo el grafo le gana al vector

raggraphraggrafosllm

La pregunta que el RAG vectorial no sabe contestar

Monta un RAG clásico sobre tu documentación y pregúntale “¿qué dice el contrato sobre las penalizaciones por retraso?”. Responde de maravilla: la respuesta vive en un párrafo, el embedding de ese párrafo se parece al de tu pregunta, lo recupera y listo.

Ahora prueba con otra: “¿qué proveedores comparten cláusula de exclusividad con clientes del sector energético?”. Silencio, o peor, una respuesta segura y equivocada. Esa respuesta no está en ningún párrafo. Está repartida entre veinte contratos, y solo aparece si conectas proveedor con cláusula y cláusula con sector. La similitud coseno no hace saltos. El grafo, sí.

Eso es lo que resuelve GraphRAG. Y también es donde mucha gente lo mete con calzador y acaba pagando de más.

Qué es GraphRAG, sin la niebla del marketing

La idea, popularizada por el trabajo de Microsoft Research en 2024, es sencilla de contar y cara de ejecutar: en lugar de trocear el texto y guardar embeddings, usas un LLM para extraer de cada fragmento las entidades (personas, empresas, conceptos) y las relaciones entre ellas. Con eso construyes un grafo de conocimiento.

Sobre ese grafo corres un algoritmo de detección de comunidades, típicamente Leiden, que agrupa entidades muy conectadas entre sí. Cada comunidad recibe un resumen generado también por el LLM. Así tienes dos niveles: el detalle fino de las entidades y una vista de pájaro por temas.

El paso de extracción es el corazón, y es un prompt más que un algoritmo:

# Extracción de entidades y relaciones por fragmento.
# El LLM devuelve tripletas que alimentan el grafo.
PROMPT_EXTRACCION = """
Del texto siguiente, extrae:
1. Entidades: (nombre, tipo, descripción breve).
2. Relaciones entre esas entidades: (origen, destino, descripción, fuerza 1-10).

Devuelve JSON estricto. No inventes relaciones que el texto no afirme.

Texto:
{fragmento}
"""

def indexar_fragmento(fragmento: str, grafo: nx.Graph) -> None:
    respuesta = llm.completar(PROMPT_EXTRACCION.format(fragmento=fragmento))
    datos = json.loads(respuesta)  # valida contra un esquema Pydantic en producción
    for e in datos["entidades"]:
        grafo.add_node(e["nombre"], tipo=e["tipo"], desc=e["descripcion"])
    for r in datos["relaciones"]:
        grafo.add_edge(r["origen"], r["destino"], desc=r["descripcion"], peso=r["fuerza"])

Fíjate en dos cosas. La primera: cada fragmento cuesta una llamada al LLM solo para indexar, antes de que nadie pregunte nada. La segunda: la calidad del grafo depende por completo de lo bien que el modelo extraiga. Basura entra, grafo de basura sale.

Local y global: dos maneras de preguntar

GraphRAG brilla porque separa dos tipos de consulta que el RAG vectorial trata igual y resuelve mal.

La búsqueda local parte de las entidades que menciona tu pregunta, se mueve por sus vecinos en el grafo y reúne ese contexto. Es lo que necesitas para “¿qué sabemos de este proveedor concreto y con quién se relaciona?”.

La búsqueda global ignora las entidades y trabaja sobre los resúmenes de comunidades. Sirve para preguntas panorámicas: “¿cuáles son los temas principales de todo el corpus?”. Un RAG vectorial nunca contesta bien a eso, porque no hay un párrafo que resuma el conjunto; la respuesta es una propiedad del todo, no de las partes.

Esa distinción es la que justifica el coste. Si tus preguntas nunca son globales ni relacionales, no la estás aprovechando.

Vector RAG frente a GraphRAG, sin medias tintas

CriterioRAG vectorialGraphRAG
Preguntas puntuales (“¿qué dice X?”)ExcelenteCorrecto, pero sobra maquinaria
Preguntas relacionales (multi-salto)Flojo o inventaSu terreno
Preguntas globales (“temas del corpus”)No sabeDiseñado para eso
Coste de indexaciónBajo (solo embeddings)Alto (una o varias llamadas LLM por fragmento)
Coste por consultaBajoMedio-alto (más contexto, más pasos)
Actualización incrementalTrivial: añades vectoresCostosa: reextraer y recalcular comunidades
ExplicabilidadOpaca (¿por qué este chunk?)Alta (ves el camino en el grafo)

La tabla deja claro el patrón: GraphRAG no sustituye al RAG vectorial, resuelve un tipo de pregunta que el otro no toca. Y lo hace pagando por adelantado en la indexación.

El coste que no aparece en las demos

Las demos de GraphRAG siempre corren sobre un corpus pequeño y estático. La realidad de producción tiene tres aristas incómodas.

La indexación no es barata. Extraer entidades de cada fragmento con un LLM puede multiplicar por diez o más el coste de indexar frente a calcular embeddings. Sobre un corpus grande, eso es dinero real antes de la primera consulta.

La actualización duele. Añadir un documento nuevo no es meter un vector: es reextraer, fusionar entidades duplicadas (“Red Eléctrica” y “REE” son la misma) y, si quieres resúmenes globales correctos, recalcular comunidades. En un corpus que cambia a diario, ese peaje se paga a diario.

La resolución de entidades es un proyecto en sí. Que el modelo llame igual a la misma cosa en mil fragmentos distintos no pasa gratis. Sin una capa de normalización, tu grafo se llena de nodos casi-duplicados y las relaciones se diluyen.

Cuándo merece la pena de verdad

Después de montarlo un par de veces, mi regla de campo es esta. Empieza siempre con RAG vectorial más un buen reranker: cubre la mayoría de casos, es barato y se actualiza solo. Añade GraphRAG cuando se cumplan a la vez dos condiciones concretas.

La primera: tus usuarios hacen preguntas que cruzan documentos o piden síntesis del conjunto, no búsquedas puntuales. Si el 90 % de las consultas son “¿qué dice el manual sobre X?”, el grafo es un lujo caro.

La segunda: el corpus es lo bastante estable como para amortizar la indexación. Documentación técnica, normativa o informes históricos encajan. Un flujo de tickets o noticias que cambia cada hora, no.

Y un consejo que ahorra disgustos: no lo trates como todo o nada. Un enfoque híbrido —recuperación vectorial para el detalle, grafo solo para las preguntas relacionales y globales— te da lo mejor de ambos sin pagar el coste completo en cada consulta. El grafo no es una religión. Es una herramienta que gana en un terreno muy concreto, y conviene saber cuál es antes de construirlo.

Fuentes