Habilidad GraphRAG
Generación aumentada por recuperación sobre un grafo de conocimiento en lugar de fragmentos planos. Las entidades y relaciones se extraen de tus documentos, se almacenan en una base de datos de grafos, y el LLM razona sobre la estructura del grafo en el momento de la consulta.
Por qué un Grafo en Lugar de Vectores
La búsqueda vectorial encuentra fragmentos similares. No puede seguir conexiones:
- "¿Qué proveedores se vieron afectados por la interrupción en la planta X?" necesita
Interrupción → afecta → Planta → suministrada_por → Proveedor— dos saltos que ningún fragmento individual contiene. - "Resume todo lo que sabemos sobre el proyecto Y" necesita la comunidad de entidades alrededor de Y, no los diez párrafos más similares.
Si tus preguntas son búsquedas de hechos únicos, quédate con RAG vectorial — es más simple. Recurre a GraphRAG cuando las preguntas abarquen relaciones.
Stack
- Kuzu — base de datos de grafos incrustada (
pip install kuzu), no necesita servidor, lenguaje de consulta Cypher. Empieza aquí. - Neo4j — cuando superes la versión incrustada: multiusuario, grafos más grandes, visualización Bloom. Las mismas habilidades de Cypher son transferibles.
- Extracción LLM — cualquier modelo potente con salida estructurada para extracción de entidades/relaciones.
Pipeline
1. Define el esquema primero
No dejes que el extractor invente tipos libremente — obtendrás 40 ortografías de la misma relación. Declara los tipos de nodo y arista de antemano:
CREATE NODE TABLE Persona(nombre STRING, PRIMARY KEY(nombre));
CREATE NODE TABLE Proyecto(nombre STRING, estado STRING, PRIMARY KEY(nombre));
CREATE NODE TABLE Documento(titulo STRING, fecha DATE, PRIMARY KEY(titulo));
CREATE REL TABLE TRABAJA_EN(DESDE Persona HASTA Proyecto, rol STRING);
CREATE REL TABLE MENCIONA(DESDE Documento HASTA Persona);
CREATE REL TABLE MENCIONA_PROYECTO(DESDE Documento HASTA Proyecto);
Mantén el esquema pequeño (5-10 tipos de nodo). Puedes extenderlo; no puedes "des-extraer" un grafo desordenado de manera económica.
2. Extrae entidades y relaciones
Fragmenta los documentos (500-1000 tokens, con superposición), luego incita al extractor:
Extrae entidades y relaciones del texto a continuación.
Tipos de nodo permitidos: Persona, Proyecto, Documento
Tipos de arista permitidos: TRABAJA_EN (Persona→Proyecto), MENCIONA (Documento→Persona),
MENCIONA_PROYECTO (Documento→Proyecto)
Reglas:
- Normaliza nombres ("J. Pérez" y "Juan Pérez" son la misma Persona)
- Extrae solo relaciones declaradas o claramente implícitas en el texto
- Devuelve JSON: {"nodes": [...], "edges": [...]}
Texto:
<fragmento>
Revisa manualmente 10-20 fragmentos. La calidad de la extracción es el límite para todo el flujo posterior — un grafo ruidoso da respuestas ruidosas.
3. Carga en Kuzu
import kuzu
db = kuzu.Database("./conocimiento.kz")
conn = kuzu.Connection(db)
# crea esquema, luego MERGE/CREATE parametrizado por nodo/arista extraído
Desduplica en la carga (MERGE en la clave primaria) — la misma entidad aparece
en muchos fragmentos.
4. Patrones de consulta
Búsqueda local — todo lo conectado a una entidad:
MATCH (p:Persona {nombre: $nombre})-[r]-(vecino)
RETURN type(r), vecino;
Razonamiento multi-salto — sigue relaciones a través del grafo:
// ¿Quién trabaja en proyectos mencionados en documentos sobre la interrupción?
MATCH (d:Documento)-[:MENCIONA_PROYECTO]->(proy:Proyecto)<-[:TRABAJA_EN]-(p:Persona)
WHERE d.titulo CONTAINS 'interrupción'
RETURN DISTINCT p.nombre, proy.nombre;
Resumen global — detección de comunidades, luego resume cada comunidad:
// Encuentra clústeres densamente conectados (ejecutar una vez, almacenar id de comunidad en nodos)
CALL show_tables(); // luego usa la detección de comunidades de tu grafo
Resume cada comunidad con el LLM: "estas entidades se agrupan alrededor del tema X." Esta es la "consulta global" de GraphRAG — preguntas como "¿cuáles son los temas principales en estos documentos?"
5. Responde con el LLM
El patrón de consulta que funciona:
- El agente traduce la pregunta a 1-3 consultas Cypher
- Los resultados vuelven como filas estructuradas
- El LLM sintetiza la respuesta a partir de las filas, citando evidencia de nodos/aristas
- Si una consulta no devuelve nada, el agente reformula — nunca alucina contenido del grafo
Conocimiento temporal (memoria del agente)
Para la memoria del agente entre sesiones, agrega tiempo a las aristas: marcas de tiempo VALIDO_DESDE /
VALIDO_HASTA, hechos reemplazados marcados en lugar de eliminados. Este es el
patrón de grafo de conocimiento temporal (ver Graphiti/Zep): "el usuario solía preferir X, ahora prefiere Y"
sigue siendo consultable en lugar de ser sobrescrito.
Anti-patrones
- Extraer sin un esquema. La extracción libre produce un grafo que nadie puede consultar.
- GraphRAG para todo. ¿Búsqueda de hechos únicos sobre documentos limpios? La búsqueda vectorial es más barata y mejor. Usa el grafo donde las relaciones importan.
- Confiar ciegamente en la extracción. Cada pipeline necesita un bucle de revisión; los errores de extracción se acumulan en silencio.
- Fragmentos enormes. La extracción de entidades se degrada más allá de ~1000 tokens — el modelo empieza a omitir relaciones. Fragmentos más pequeños, más cantidad.
- Sin desduplicación en la carga. "Juan Pérez", "J. Pérez", "Pérez" como tres nodos rompe en silencio las consultas multi-salto.