|

Cómo Convertir PDFs en Grafos de Conocimiento

Un grafo de conocimiento es una representación estructurada donde conceptos se conectan mediante relaciones semánticas en lugar de existir como texto aislado. Convertir PDFs a grafos permite que cualquier LLM consulte la información de forma precisa y contextual, entendiendo no solo qué data existe sino cómo se relaciona. Existen herramientas open source como Neo4j LLM Graph Builder y knowledge_graph que automatizan este proceso, extrayendo entidades y relaciones directamente del documento con LLMs.

En 30 segundos

  • Un grafo de conocimiento captura conceptos como nodos conectados por relaciones semánticas, no como texto plano desestructurado
  • Herramientas open source como Neo4j LLM Graph Builder y knowledge_graph automatizan la conversión PDF → entidades → grafo en minutos
  • El flujo típico: extraer PDF → chunking inteligente → LLM identifica entidades y relaciones → almacenamiento en Neo4j o similar
  • Una vez construido, el grafo es consultable por cualquier LLM vía RAG o GraphRAG, permitiendo búsqueda semántica con contexto real
  • Aplicaciones concretas: bases de conocimiento empresariales, análisis científico, gestión de compliance, FAQs dinámicos a partir de manuales

¿Qué es un grafo de conocimiento y por qué convertir PDFs?

Un grafo de conocimiento es una estructura de datos donde información se organiza como nodos (conceptos, entidades) conectados por aristas (relaciones semánticas). Cuando se construye automáticamente a partir de PDFs usando LLMs, transforma documentos estáticos en bases de datos consultables por máquinas donde no solo existe “cliente tiene teléfono” sino que el LLM entiende qué tipo de relación es, cuándo se creó y qué contexto la rodea.

Pensalo de esta forma: si le pasás un PDF tradicional a un LLM, obtenés búsqueda de texto plano (coincidencia de palabras). Si le pasás un grafo de conocimiento, obtenés búsqueda de significado real. “¿Cuáles son los clientes de la rama Córdoba?” requeriría que el LLM busque en todo el documento. Con un grafo, la respuesta está estructurada: cliente → tiene_ubicación → Córdoba.

Los beneficios son claros. Primero, precisión: un grafo captura relaciones explícitas, no las interpreta. Segundo, reutilización: los datos ya estructurados se pueden consultar de múltiples formas. Tercero, razonamiento: el LLM puede conectar puntos que en texto plano están dispersos en el documento. Un investigador científico, ponele, busca “cuáles son los mecanismos propuestos en este paper que se relacionan con proteínas del grupo X”. En texto plano, tiene que leer párrafo por párrafo. Con un grafo, obtiene una relación directa.

Arquitectura técnica: cómo funciona la conversión PDF a grafo

El pipeline es directo: extraer → procesar → extraer estructura → guardar. Cada etapa determina la calidad final del grafo.

Paso uno: extracción de texto del PDF. Acá usás librerías como PyMuPDF4LLM o pdfplumber que preservan la estructura (tablas, listas, jerarquía de títulos). Si el PDF es apenas una imagen escaneada, necesitás OCR previo (Tesseract, Paddle OCR). Este primer paso es crítico porque si pierdés información acá, nunca la recuperás.

Paso dos: chunking inteligente. El LLM no procesa de golpe 500 páginas. Necesitás dividir el documento en fragmentos que mantengan contexto (típicamente 500-1500 tokens cada uno, con overlap entre chunks para no perder información en los bordes).

Paso tres: identificación de entidades. Aquí mandás cada chunk a un LLM (vía OpenRouter, o un Mistral 7B local vía Ollama, o Claude) con una instrucción tipo “extrae todas las entidades de tipo Persona, Organización, Concepto, Fecha de este texto”. El LLM devuelve JSON estructurado.

Paso cuatro: extracción de relaciones. La pregunta es “¿qué relación existe entre estas entidades?” El LLM responde con tripletas: (sujeto, predicado, objeto). Ejemplo: (Juan, trabaja_en, Acme Corp), (Acme Corp, está_ubicada_en, Buenos Aires). Relacionado: ejecutar agentes sin depender de APIs externas.

Paso cinco: creación de nodos y aristas en el grafo. Cada entidad se convierte en un nodo con propiedades (nombre, tipo, confianza de extracción). Cada relación se convierte en una arista dirigida con etiqueta.

Paso seis: almacenamiento. Lo típico es Neo4j (grafo nativo) o PostgreSQL con extensión pgVector si necesitás embeddings vectoriales. Hay alternativas como RDF stores, pero Neo4j es el estándar para este caso de uso.

Herramientas open source principales: comparativa

Existen varias opciones maduras. Cada una toma un enfoque diferente: simplicidad, localidad, o flexibilidad de LLMs.

Neo4j LLM Graph Builder es el más sofisticado. Es una aplicación React + FastAPI que proporciona UI para subir PDFs, configura automáticamente el pipeline, y almacena el grafo directamente en Neo4j. Soporta múltiples proveedores de LLMs (OpenAI, Anthropic vía OpenRouter, modelos locales). Tiene validación de extracción y permite editar manualmente entidades y relaciones después. Setup: clonás el repo, instalás dependencias Python/Node, ejecutás docker-compose. Aproximadamente 20 minutos en una máquina limpia.

knowledge_graph (rahulnyk) es la alternativa minimalista. Script Python puro que lee un PDF, manda chunks a un LLM (Ollama local, Mistral 7B, o APIs remotas), y construye un grafo en memoria o Neo4j. Sin UI, pero totalmente personalizable. Excelente si ya sabés Python y querés controlar cada paso. Setup: 5 minutos, clonar y `pip install`.

LlamaIndex no es exclusivamente para grafos, pero su módulo KnowledgeGraphIndex hace exactamente esto: carga PDFs, extrae entidades y relaciones, construye un grafo consultable. La ventaja es que se integra con el ecosistema LlamaIndex completo (múltiples loaders, múltiples LLMs, múltiples almacenamientos). Si ya usás LlamaIndex en tu stack, es la opción obvia. La desventaja: menos control sobre detalles de extracción que knowledge_graph puro.

KONDA es un proyecto más experimental que usa anotación automática basada en LLM. Útil si la tarea es más compleja (relaciones con atributos temporales, confianza variable). Te puede servir nuestra cobertura de privacidad en el procesamiento de documentos.

HerramientaRepoLLMs soportadosBase de datosUICurva aprendizaje
Neo4j LLM Graph Builderneo4j-labs/llm-graph-builderOpenAI, Anthropic, OpenRouter, localNeo4j nativoReact webMedia (UI visible pero setup requiere Docker)
knowledge_graphrahulnyk/knowledge_graphOllama, OpenAI, Mistral, OpenRouterNeo4j o memoriaNoBaja (script directo, muy legible)
LlamaIndex + KnowledgeGraphIndexpip install llama-indexCualquiera soportada por LlamaIndexNeo4j, NetworkX, etc.Integrarse en tu appMedia-Alta (necesitás conocer LlamaIndex)
KONDAGitHub (menos mantenido)OpenAI, AnthropicNeo4jMinimalAlta (experimental)
grafo de conocimiento pdf diagrama explicativo

De PDF a grafo paso a paso: guía práctica con Python

Acá va un ejemplo funcional usando knowledge_graph + OpenRouter:

import pymupdf # o pdfplumber import json from openrouter import OpenRouter # pseudo-código, usá anthropic SDK real # 1. Extraer texto del PDF pdf_path = "documento.pdf" doc = pymupdf.open(pdf_path) texto_completo = "" for page in doc: texto_completo += page.get_text() # 2. Chunking simple (mejorable con langchain) chunk_size = 1000 chunks = [texto_completo[i:i+chunk_size] for i in range(0, len(texto_completo), chunk_size)] # 3. Extraer entidades con LLM client = OpenRouter(api_key="tu_key") prompt_entidades = """Extrae todas las entidades del siguiente texto. Categorías: Persona, Organización, Concepto, Fecha. Devuelve JSON: {"entidades": [{"nombre": "...", "tipo": "..."}, ...]} Texto: {chunk}""" entidades_totales = {} for chunk in chunks: response = client.messages.create( model="mistralai/mistral-7b-instruct", messages=[{"role": "user", "content": prompt_entidades.format(chunk=chunk)}] ) data = json.loads(response.content.text) for ent in data["entidades"]: if ent["nombre"] not in entidades_totales: entidades_totales[ent["nombre"]] = ent["tipo"] # 4. Extraer relaciones prompt_relaciones = """Del siguiente texto, extrae relaciones entre entidades. Formato: [{"sujeto": "...", "predicado": "...", "objeto": "..."}] Texto: {chunk}""" relaciones = [] for chunk in chunks: response = client.messages.create( model="mistralai/mistral-7b-instruct", messages=[{"role": "user", "content": prompt_relaciones.format(chunk=chunk)}] ) rels = json.loads(response.content.text) relaciones.extend(rels) # 5. Guardar en Neo4j from neo4j import GraphDatabase driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "password")) with driver.session() as session: # Crear nodos for nombre, tipo in entidades_totales.items(): session.run(f"MERGE (n:{tipo} {{nombre: $nombre}})", nombre=nombre) # Crear relaciones for rel in relaciones: session.run(""" MATCH (a), (b) WHERE a.nombre = $sujeto AND b.nombre = $objeto CREATE (a)-[r:RELACION {{tipo: $predicado}}]->(b) """, sujeto=rel["sujeto"], objeto=rel["objeto"], predicado=rel["predicado"])

Este ejemplo es esquelético pero funcional. En producción, querrías: mejor chunking (recursive splitting), deduplicación de entidades (dos “Juan” distintos), asignación de confianza a cada extracción, y validación humana antes de commitear al grafo.

Hacer el grafo consultable: búsqueda semántica y RAG

Un grafo bonito no sirve de nada si no podés hacerle preguntas. Aquí es donde entra RAG (Retrieval-Augmented Generation). La idea: cuando un usuario pregunta “¿quiénes son los clientes en Córdoba?”, el sistema no manda la pregunta directo al LLM. Primero busca en el grafo los nodos y relaciones relevantes, construye un contexto estructurado, y recién ahí manda todo al LLM para generar respuesta.

Hay dos enfoques. GraphRAG (recomendado) usa el grafo directamente: transforma la pregunta en Cypher (lenguaje de Neo4j), ejecuta la query, obtiene nodos y relaciones, y arma el contexto. SPARQL o GraphQL si usás otros stores.

El otro enfoque es embeddings + vector search: convertís nodos a embeddings (usando modelos como sentence-transformers), almacenás los embeddings en pgVector, y cuando llega una pregunta, convertís también la pregunta a embedding y buscás los nodos más similares. Es más flexible (funciona con cualquier BD) pero pierde información de las relaciones explícitas.

La combinación de ambos es lo ideal: el grafo te da estructura lógica, los embeddings te dan flexibilidad semántica.

Casos de uso reales y aplicaciones prácticas

Base de conocimiento empresarial. Una empresa tiene 500 PDFs de políticas, manuales, procedimientos. En lugar de un buscador de palabra clave (inútil), construyen un grafo donde Procedimiento conecta a Departamento, Rol, Requerimiento. Un empleado nuevo pregunta “¿cuál es el workflow de aprobación de gastos para el área de IT?” y el sistema trae exactamente eso, no 47 documentos que mencionan “gasto”. En herramientas de procesamiento IA profundizamos sobre esto.

Análisis de documentos científicos. Un investigador tiene 100 papers en PDF sobre proteínas de COVID. Construye un grafo donde Paper conecta a Proteína, Técnica, Resultado Experimental, Autor. Luego pregunta: “¿qué proteínas se estudiaron con espectrometría de masas?” El grafo responde en segundos.

Gestión de regulaciones y compliance. Un equipo legal tiene regulaciones GDPR, PCI-DSS, HIPAA en PDF. Construyen un grafo donde Regulación conecta a Requisito, Pena, Plazo de Implementación. Cuando le preguntan “¿cuáles son los requisitos que vencen este trimestre?”, el sistema filtra por fecha y devuelve exactamente eso.

FAQ dinámico. En lugar de mantener un FAQ estático, un e-commerce construye un grafo a partir de sus manuales de producto, términos de servicio y política de devoluciones. El chatbot consulta el grafo para responder preguntas de usuarios sin necesidad de reescribir FAQs cada vez.

Descubrimiento de insights. Una consultora analiza reportes de clientes (100+ PDFs) y construye un grafo donde Cliente, Problema, Solución, Resultado se conectan. Luego hace queries tipo “¿cuáles son los problemas más comunes entre clientes de industria X que resultaron en reducción de costos?” y obtiene patrones que de otro modo estarían ocultos.

Errores comunes y mejores prácticas

Over-chunking y pérdida de contexto

Dividir el PDF en chunks muy pequeños (200 palabras) significa que el LLM no ve el contexto necesario para entender relaciones. Un párrafo dice “Juan trabaja aquí desde 2020” y el siguiente dice “fue promovido a gerente”, pero si los dividís en chunks diferentes, el LLM nunca conecta que Juan es la misma persona. Solución: chunks de 800-1500 palabras con overlap de 200 palabras.

Extracción pobre de PDFs complejos

Un PDF con tablas, gráficos incrustados, o escaneo de baja calidad requiere preprocesamiento. Si usás PyMuPDF sobre una imagen escaneada, obtenés basura. Ojo: PyMuPDF4LLM hace un trabajo mejor que pdfplumber para algunos casos, pero OCR sigue siendo necesario para PDFs que son imágenes. Dedica tiempo acá — es cimiento del grafo.

Relaciones genéricas sin peso

Si extraes relaciones tipo “Juan aparece_en página 5” no sirve de nada. El LLM tiende a ser demasiado literal. Mejor: estructura el prompt para que extraiga solo relaciones semánticamente relevantes (trabaja_en, es_autor_de, desarrolló_concepto_de). Y mejor aún: asignale confianza a cada relación (0-1). Una relación con confianza 0.3 no debería entrar al grafo final. Más contexto en alternativas de almacenamiento en la nube.

No validar el grafo

Un grafo construido 100% automático tendrá errores. El LLM confunde “Apple” (empresa) con “apple” (fruta), duplica entidades, inventa relaciones. Antes de usar el grafo en producción, invierte en validación: revisión humana del 5-10% de nodos, ejecución de queries de prueba, análisis de densidad (si hay 500 nodos pero solo 10 relaciones, algo falla). Las herramientas como Neo4j LLM Graph Builder permiten editar manualmente; úsalo.

Preguntas Frecuentes

¿Cuánto cuesta construir un grafo a partir de un PDF?

Si usás APIs remotas (OpenAI, Anthropic vía OpenRouter), depende del tamaño del PDF y modelo. Un PDF de 100 páginas con Mistral 7B vía OpenRouter cuesta aproximadamente USD 0.30-0.50 (entrada más salida, múltiples chunks). Si usás un LLM local (Ollama con Mistral 7B), el costo es cero pero el tiempo sube (15-30 minutos para 100 páginas en CPU, 2-5 minutos en GPU). Neo4j Community Edition es gratis; Enterprise cuesta desde USD 10k/año. Para proyectos pequeños, Community + OpenRouter local es lo más económico.

¿Qué diferencia hay entre un grafo de conocimiento y una base de datos relacional?

Una BD relacional (PostgreSQL, MySQL) almacena datos en tablas y requiere JOINs complejos para conectar información. Un grafo almacena nodos y relaciones directamente, optimizado para traversals rápidos. Si preguntás “¿amigos de amigos de Juan?” en SQL necesitás 3 JOINs y es lento. En grafo, es una query de una línea. Para datos altamente conectados, grafos ganan. Para datos tabular puro, relacional sigue siendo mejor.

¿Cualquier LLM puede consultar el grafo?

Técnicamente sí, pero no todos son iguales. El LLM necesita poder generar queries válidas en Cypher (Neo4j) o SPARQL (RDF). Los mejores en esto son GPT-4, Claude, y Gemini 1.5. Mistral 7B también funciona, pero con tasa de error más alta. Para producción, es recomendable validar que la query generada sea válida antes de ejecutarla en el grafo.

¿Necesito Neo4j obligatoriamente?

No. Neo4j es el estándar porque está optimizado para grafos, pero alternativas incluyen: PostgreSQL con extension pgGraph o networkx (menos optimizado pero funciona), RDF stores (Apache Jena, Virtuoso), o almacenamiento en memoria si el grafo es pequeño. Para comenzar, LlamaIndex puede usar NetworkX (en memoria, perfecto para prototipado rápido). Para producción con millones de nodos, Neo4j es la opción obvia.

¿Cómo escalo un grafo si crece a millones de nodos?

Neo4j Enterprise soporta particionamiento y replicación. Para escala extrema (miles de millones de nodos), algunos usan ArangoDB o TigerGraph, pero eso es nivel Netflix/Uber. Para la mayoría de casos, una instancia Neo4j con 64GB de RAM aguanta 100 millones de nodos sin problemas. Si necesitás más, primero optimizá: elimina relaciones duplicadas, normaliza entidades (deduplicación), y filtré por relevancia antes de agregar al grafo.

Conclusión

Convertir PDFs en grafos de conocimiento consultables es un enfoque sólido para transformar documentos estáticos en sistemas inteligentes. No es magia: es ingeniería: extracción de texto → LLM para estructura → almacenamiento optimizado → queries inteligentes. Las herramientas open source (Neo4j LLM Graph Builder, knowledge_graph, LlamaIndex) eliminan la barrera de entrada. El verdadero trabajo está en validación: asegurarse de que entidades no estén duplicadas, que las relaciones sean semánticamente válidas, que el grafo responda preguntas reales de forma precisa.

Si tenés 50+ documentos PDF que necesitás consultar frecuentemente, construir un grafo te ahorraría días de lectura manual. Si solo tenés uno o dos, un buscador de texto plano alcanza. El punto de inflexión está alrededor de 10 documentos: cuando comienzan a aparecer preguntas que requieren conectar información entre documentos, el grafo pasa a ser herramienta, no luxo.

El ecosistema sigue madurando — hace un año estas herramientas casi no existían. Hoy, con LLMs más confiables en extracción de estructura, es un problema resuelto. Probá uno de estos proyectos con un PDF que tengas a mano. 20 minutos y tendrás un prototipo funcional.

Fuentes

Te puede interesar...