skill-grafo-conocimiento
Skill: Grafo de Conocimiento desde Directorios (v2.0.0)
Este skill permite construir grafos de conocimiento a partir de colecciones de documentos en directorios locales o almacenamiento cloud (AWS S3, Azure Blob Storage, GCP Cloud Storage). Basado en investigación de más de 20 artículos de Medium publicados en 2025-2026.
El grafo captura relaciones entre archivos, secciones, conceptos y pares pregunta-respuesta, con soporte para grafos temporales, construcción multi-agente, y múltiples bases de datos de grafos.
Flujo de trabajo principal
- Configurar fuente → local, S3, Azure o GCP
- Elegir arquitectura → GraphRAG clásico, LightRAG, Graphiti (temporal), GraphOS (producción)
- Recorrer directorios → descubrir todos los documentos
- Procesar documentos → extraer texto, chunking semántico/contextual
- Extraer entidades y relaciones → usando multi-agente (schema, NER, fact extraction)
- Construir el grafo → Neo4j, FalkorDB, NetworkX, o Amazon Neptune
- Consultar el grafo → GraphRAG, LightRAG dual-level, MCP server para Claude
Para detalles de cada fase, consulta las referencias:
references/01-fuentes-datos.md— local, S3, Azure, GCP, Amazon Neptunereferences/02-procesamiento-documentos.md— chunking contextual, Docling, atomic factsreferences/03-extraccion-grafo.md— multi-agente, LLMGraphTransformer, GenKMreferences/04-almacenamiento.md— Neo4j, FalkorDB, Graphiti temporal, Cogneereferences/05-consultas-agentes.md— LightRAG, GraphRAG, MCP, self-evolving
Inicio rápido
Paso 1: Elegir la arquitectura adecuada
| Caso de uso | Arquitectura recomendada |
|---|---|
| Documentos estáticos, preguntas globales | Microsoft GraphRAG (community detection) |
| Velocidad + produción real-time | LightRAG (dual-level: local + global) |
| Agentes con memoria a lo largo del tiempo | Graphiti/Zep (temporal bi-temporal) |
| Graph + vector hybrid en producción | FalkorDB GraphRAG SDK (sub-50ms) |
| Desarrollo/prototipo local | NetworkX + JSON |
| Enterprise cloud | Amazon Neptune + MCP |
Paso 2: Instalar dependencias
# Core
pip install networkx python-dotenv tqdm
# Procesamiento de documentos (2026)
pip install pypdf2 python-docx markdown beautifulsoup4
pip install docling # Reemplaza a Unstructured, mejor para tablas/PDFs complejos
# LLM e IA
pip install anthropic langchain-anthropic langchain-community langchain-core
# LightRAG (2024-2026, alternativa eficiente a GraphRAG)
pip install lightrag-hku
# Graphiti - grafos temporales para agentes
pip install graphiti-core
# Cognee - memoria unificada con múltiples backends
pip install cognee
# Neo4j (producción, estándar)
pip install neo4j langchain-neo4j
# FalkorDB (open-source, sub-50ms, para agentes real-time)
pip install falkordb
# Cloud
pip install boto3 # AWS S3
pip install azure-storage-blob # Azure Blob
pip install google-cloud-storage # GCP
pip install boto3 # Amazon Neptune (via NeptuneClient)
# Vectores y embeddings
pip install sentence-transformers faiss-cpu
pip install chonkie # chunking semántico moderno (2026)
Paso 3: Crear el grafo con LightRAG (recomendado para 2026)
from lightrag import LightRAG, QueryParam
from lightrag.llm import anthropic_complete
from lightrag.utils import EmbeddingFunc
import asyncio, os
# Inicializar LightRAG
rag = LightRAG(
working_dir="./knowledge_graph",
llm_model_func=anthropic_complete,
embedding_func=EmbeddingFunc(
embedding_dim=1024,
max_token_size=512,
func=lambda texts: get_anthropic_embeddings(texts)
)
)
# Insertar documentos desde directorio
async def build_from_directory(source_path: str):
from scripts.build_graph import DocumentTraverser
traverser = DocumentTraverser(source_path)
for doc_text, doc_meta in traverser.iter_documents():
await rag.ainsert(doc_text)
print(f"Procesado: {doc_meta['path']}")
asyncio.run(build_from_directory("/ruta/a/documentos"))
# Consultas dual-level
# Local: entidades específicas
result_local = rag.query("¿Qué dice el documento X sobre autenticación JWT?",
param=QueryParam(mode="local"))
# Global: temas y comunidades
result_global = rag.query("¿Qué patrones arquitectónicos aparecen en todos los documentos?",
param=QueryParam(mode="global"))
# Híbrido: combina ambos
result_hybrid = rag.query("¿Cómo se relaciona JWT con los servicios de auth en el proyecto?",
param=QueryParam(mode="hybrid"))
Tipos de relaciones en el grafo
El grafo captura cuatro niveles de relaciones:
1. Archivo → Archivo (RELATED_TO, REFERENCES, SAME_DIRECTORY)
Documentos que comparten temas, referencias cruzadas, o están en el mismo directorio.
doc_A.pdf --[RELATED_TO {similarity: 0.87}]--> doc_B.md
doc_A.pdf --[REFERENCES]--> doc_C.txt
2. Sección → Sección (SIMILAR_TO, ELABORATES)
Fragmentos (chunks) de diferentes documentos que tratan el mismo tema.
chunk_A3 --[SIMILAR_TO {cosine: 0.92}]--> chunk_B7
chunk_A5 --[ELABORATES]--> chunk_C2
3. Concepto → Concepto (RELATED_CONCEPT, USED_IN)
Entidades y conceptos extraídos que aparecen en múltiples documentos.
"autenticación" --[RELATED_CONCEPT]--> "JWT"
"JWT" --[USED_IN]--> "API REST"
4. Pregunta → Respuesta (ANSWERS)
Preguntas detectadas en un documento enlazadas con sus respuestas en otros.
Q: "¿Cómo configurar SSL?" --[ANSWERS {confidence: 0.89}]--> chunk con instrucciones SSL
5. Temporal (VÁLIDO_DESDE, VÁLIDO_HASTA) — Graphiti
Para grafos con memoria temporal de agentes:
entidad_A --[RELACIONADO_CON {valid_from: "2026-01-01", valid_to: null}]--> entidad_B
Esquema del grafo
Nodos
# Documento
{
"id": "hash_del_archivo",
"type": "Document",
"name": "archivo.pdf",
"path": "/ruta/al/archivo.pdf",
"format": "pdf",
"size_bytes": 45231,
"created_at": "2026-01-15",
"directory": "/ruta/al/",
"summary": "Resumen generado por LLM",
"community": "cluster_3" # para GraphRAG community detection
}
# Chunk (fragmento de documento)
{
"id": "doc_hash_chunk_3",
"type": "Chunk",
"parent_doc": "hash_del_archivo",
"text": "Contenido del fragmento...",
"section_title": "Configuración",
"embedding": [0.12, -0.34, ...],
"chunk_index": 3,
"chunk_strategy": "contextual", # fixed|semantic|contextual|paragraph
"has_question": false,
"has_answer": false,
"atomic_facts": ["JWT requiere clave secreta", "Token expira en 24h"]
}
# Concepto / Entidad
{
"id": "concepto_autenticacion",
"type": "Concept",
"name": "autenticación",
"category": "security",
"frequency": 15,
"documents": ["doc1", "doc2"],
"community_id": "cluster_2"
}
# Comunidad (GraphRAG)
{
"id": "community_3",
"type": "Community",
"label": "Arquitectura de Seguridad",
"summary": "Resumen de conceptos de seguridad en el corpus",
"level": 1,
"nodes": ["concepto_jwt", "concepto_ssl", "concepto_oauth"]
}
Pipeline de extracción multi-agente (2026)
Sistema con 5 agentes especializados (patrón de Shilpa Thota / Neo4j):
class MultiAgentGraphBuilder:
"""
Agentes:
1. UserIntentAgent - entiende el objetivo y tipo de grafo a construir
2. SchemaProposalAgent - propone el esquema de entidades y relaciones
3. NERAgent - Named Entity Recognition sobre los documentos
4. FactExtractionAgent - extrae hechos y relaciones entre entidades
5. GraphRAGAgent - selecciona estrategia de retrieval al consultar
"""
SCHEMA_PROMPT = """Eres un experto en diseño de grafos de conocimiento.
Analiza estos tipos de documentos y propón un esquema de grafo:
Documentos de ejemplo:
{sample_docs}
Objetivo del usuario: {user_goal}
Propón en JSON:
{
"node_types": [{"name": str, "description": str, "properties": [str]}],
"relationship_types": [{"name": str, "from": str, "to": str, "description": str}],
"reasoning": str
}"""
EXTRACTION_PROMPT = """Analiza este fragmento y extrae:
1. ENTIDADES según este esquema: {schema}
2. RELACIONES entre entidades
3. TIPO_CONTENIDO: question|answer|definition|procedure|example|reference
4. CONCEPTOS_CLAVE: 3-5 conceptos principales
5. ATOMIC_FACTS: hechos atómicos individuales extraíbles
Fragmento:
{chunk_text}
Contexto: {file_path}
Responde en JSON:
{
"entities": [{"name": str, "type": str, "description": str, "properties": {}}],
"relations": [{"subject": str, "predicate": str, "object": str, "confidence": float}],
"content_type": "question|answer|definition|procedure|example|reference",
"key_concepts": [str],
"is_question": bool,
"questions_found": [str],
"atomic_facts": [str]
}"""
Chunking avanzado (2026)
Estrategias disponibles
from chonkie import SemanticChunker, TokenChunker, SentenceChunker
# 1. Contextual chunking (recomendado 2026)
# Genera contexto para cada chunk usando el documento completo
class ContextualChunker:
def chunk(self, text: str, doc_summary: str) -> list[dict]:
chunks = self.base_chunker.chunk(text)
return [
{
"text": chunk,
"context": self.llm.generate(
f"Dado el documento: {doc_summary}\n\nExplica brevemente este fragmento: {chunk}"
)
}
for chunk in chunks
]
# 2. Atomic Facts / GFS (Graph Fact Synthesis)
class AtomicFactChunker:
"""Convierte texto en hechos atómicos individuales para el grafo."""
def chunk(self, text: str) -> list[str]:
return self.llm.generate(
f"Extrae hechos atómicos y auto-contenidos de este texto:\n{text}\n"
"Cada hecho debe ser una oración completa y verificable."
)
# 3. Semántico con Chonkie (2026)
chunker = SemanticChunker(
embedding_model="sentence-transformers/all-MiniLM-L6-v2",
chunk_size=512,
similarity_threshold=0.8
)
Almacenamiento: bases de datos de grafos
Neo4j (estándar de producción)
from neo4j import GraphDatabase
class Neo4jGraphStore:
def __init__(self, uri: str, user: str, password: str):
self.driver = GraphDatabase.driver(uri, auth=(user, password))
def create_document(self, doc: dict):
with self.driver.session() as session:
session.run("""
MERGE (d:Document {id: $id})
SET d.name = $name, d.path = $path,
d.summary = $summary, d.community = $community
""", **doc)
def create_relationship(self, from_id: str, to_id: str, rel_type: str, props: dict):
with self.driver.session() as session:
session.run(f"""
MATCH (a {{id: $from_id}}), (b {{id: $to_id}})
MERGE (a)-[r:{rel_type}]->(b)
SET r += $props
""", from_id=from_id, to_id=to_id, props=props)
FalkorDB (open-source, real-time, sub-50ms)
from falkordb import FalkorDB
class FalkorDBGraphStore:
"""Alternativa a Neo4j: más rápida para agentes real-time."""
def __init__(self, host: str = "localhost", port: int = 6379):
self.db = FalkorDB(host=host, port=port)
self.graph = self.db.select_graph("knowledge_graph")
def create_document(self, doc: dict):
self.graph.query(
"MERGE (d:Document {id: $id}) SET d.name = $name, d.path = $path",
{"id": doc["id"], "name": doc["name"], "path": doc["path"]}
)
def hybrid_search(self, query_embedding: list, query_text: str, top_k: int = 5):
"""Búsqueda híbrida: vector + grafo."""
# Vector search
vector_results = self.graph.query(
"CALL db.idx.vector.queryNodes('Chunk', 'embedding', $k, $embedding) "
"YIELD node, score RETURN node, score",
{"k": top_k, "embedding": query_embedding}
)
# Graph traversal desde los resultados
return self._expand_via_graph(vector_results.result_set)
Graphiti - Grafos Temporales (Zep/Zep AI)
from graphiti_core import Graphiti
from graphiti_core.nodes import EpisodeType
class TemporalKnowledgeGraph:
"""
Graphiti: bi-temporal model para agentes con memoria.
Cada relación tiene valid_from + valid_to para rastrear cambios.
"""
def __init__(self, neo4j_uri: str, neo4j_user: str, neo4j_password: str):
self.graphiti = Graphiti(neo4j_uri, neo4j_user, neo4j_password)
async def add_document_episode(self, text: str, source_path: str):
"""Agrega un documento como episodio temporal."""
await self.graphiti.add_episode(
name=f"document:{source_path}",
episode_body=text,
source=EpisodeType.text,
source_description=source_path,
reference_time=datetime.utcnow()
)
async def search(self, query: str) -> list:
"""Búsqueda con consciencia temporal."""
return await self.graphiti.search(query)
async def get_timeline(self, entity: str) -> list:
"""Historial de cambios de una entidad a lo largo del tiempo."""
return await self.graphiti.get_entity_edge_history(entity)
Cognee - Memoria Unificada (múltiples backends)
import cognee
# Cognee abstrae Neo4j, FalkorDB, NetworkX sin cambiar código
cognee.config.set_vector_db_config({"provider": "lancedb"})
cognee.config.set_graph_db_config({"provider": "neo4j", "url": "...", "username": "...", "password": "..."})
# O usar FalkorDB en producción:
cognee.config.set_graph_db_config({"provider": "falkordb", "url": "...", "port": 6379})
# Añadir documentos
await cognee.add("directorio/documentos/")
await cognee.cognify() # construye el grafo automáticamente
# Buscar
results = await cognee.search("autenticación JWT")
GraphRAG: recuperación sobre el grafo
LightRAG (recomendado 2026) - Dual-Level Retrieval
LightRAG usa dos niveles de recuperación:
- Local (low-level): entidades específicas y sus relaciones directas
- Global (high-level): temas, comunidades y patrones que emergen del corpus
# Modo local: preguntas específicas
result = rag.query("¿Cuál es la función authenticate() en el módulo auth?",
param=QueryParam(mode="local"))
# Modo global: síntesis del corpus
result = rag.query("¿Cuáles son los patrones de diseño predominantes en el proyecto?",
param=QueryParam(mode="global"))
# Modo híbrido: combina ambos (recomendado en general)
result = rag.query("¿Cómo funciona la seguridad end-to-end en este sistema?",
param=QueryParam(mode="hybrid"))
GraphRAG Clásico (Microsoft) - Community Detection
def graphrag_global_query(question: str, graph: nx.DiGraph, communities: dict) -> str:
"""Responde preguntas que requieren síntesis de todo el corpus."""
# 1. Generar resúmenes de comunidades
community_summaries = {
cid: llm.summarize(get_community_nodes(graph, cid))
for cid, nodes in communities.items()
}
# 2. Map: obtener respuesta parcial de cada comunidad
partial_answers = [
llm.answer(question, context=summary)
for summary in community_summaries.values()
]
# 3. Reduce: combinar respuestas parciales
return llm.reduce(question, partial_answers)
GraphRAG Multi-documento - Preguntas que cruzan documentos
def cross_document_qa(question: str, graph: nx.DiGraph) -> str:
"""
Para preguntas cuya respuesta está distribuida en múltiples documentos.
Patrón: Knowledge Graph Prompting (Anthony Alcaraz, 2025).
"""
# 1. Extraer subgrafo relevante a la pregunta
entities = extract_question_entities(question)
subgraph = extract_subgraph(graph, entities, hops=3)
# 2. Serializar el subgrafo como contexto estructurado
graph_context = serialize_subgraph(subgraph)
# 3. Responder con el grafo como contexto
return llm.answer(
question=question,
context=f"Grafo de conocimiento relevante:\n{graph_context}"
)
Integración MCP para Claude (2026)
El grafo puede exponerse como servidor MCP para que Claude interactúe en lenguaje natural:
# mcp_server.py - Servidor MCP para el grafo de conocimiento
from mcp.server import MCPServer, Tool
from neo4j import GraphDatabase
app = MCPServer("knowledge-graph")
@app.tool("search_graph")
def search_graph(query: str, mode: str = "hybrid") -> str:
"""Busca en el grafo de conocimiento con GraphRAG."""
return rag.query(query, QueryParam(mode=mode))
@app.tool("cypher_query")
def cypher_query(cypher: str) -> str:
"""Ejecuta una query Cypher en Neo4j (Claude traduce NL → Cypher)."""
with driver.session() as session:
result = session.run(cypher)
return str(result.data())
@app.tool("find_related_documents")
def find_related_documents(concept: str, max_hops: int = 2) -> list:
"""Encuentra documentos relacionados con un concepto."""
return graph_querier.find_related(concept, max_hops)
@app.tool("find_qa_pairs")
def find_qa_pairs(question: str) -> list:
"""Encuentra respuestas en el corpus para una pregunta."""
return graph_querier.find_answers(question)
if __name__ == "__main__":
app.run()
Configurar en Claude Code:
{
"mcpServers": {
"knowledge-graph": {
"command": "python",
"args": ["/ruta/al/mcp_server.py"]
}
}
}
Soporte cloud
AWS S3 + Amazon Neptune
import boto3
from gremlin_python.driver import client as gremlin_client
def list_s3_documents(bucket: str, prefix: str = ""):
s3 = boto3.client('s3')
paginator = s3.get_paginator('list_objects_v2')
for page in paginator.paginate(Bucket=bucket, Prefix=prefix):
for obj in page.get('Contents', []):
key = obj['Key']
if is_document(key):
yield f"s3://{bucket}/{key}"
# Amazon Neptune para grafos cloud-native
neptune = gremlin_client.Client('wss://mi-neptune.cluster.amazonaws.com:8182/gremlin', 'g')
Azure Blob Storage
from azure.storage.blob import BlobServiceClient
def list_azure_documents(connection_string: str, container: str):
client = BlobServiceClient.from_connection_string(connection_string)
container_client = client.get_container_client(container)
for blob in container_client.list_blobs():
if is_document(blob.name):
yield f"azure://{container}/{blob.name}"
GCP Cloud Storage
from google.cloud import storage
def list_gcp_documents(bucket_name: str, prefix: str = ""):
client = storage.Client()
bucket = client.bucket(bucket_name)
for blob in bucket.list_blobs(prefix=prefix):
if is_document(blob.name):
yield f"gs://{bucket_name}/{blob.name}"
Grafos auto-evolutivos (2026)
Los grafos de conocimiento modernos se actualizan automáticamente con nuevos documentos:
class SelfEvolvingKnowledgeGraph:
"""
Patrón de Modern Data 101 (Medium, 2026).
Los agentes enriquecen y actualizan el grafo, no solo lo consultan.
"""
async def ingest_new_document(self, doc_path: str):
"""Añade un nuevo documento y actualiza relaciones existentes."""
text = self.extract_text(doc_path)
# Extraer nuevas entidades
new_entities = await self.ner_agent.extract(text)
# Detectar si alguna entidad ya existe (merge, no duplicate)
for entity in new_entities:
existing = await self.find_existing_entity(entity.name)
if existing:
await self.merge_entities(existing, entity)
else:
await self.create_entity(entity)
# Actualizar comunidades afectadas
await self.recompute_affected_communities(new_entities)
async def prune_outdated_knowledge(self, max_age_days: int = 365):
"""Elimina o archiva conocimiento obsoleto."""
cutoff = datetime.utcnow() - timedelta(days=max_age_days)
await self.archive_edges_before(cutoff)
Grafos como protocolo de comunicación entre agentes (2026)
Patrón de Vishal Mysore (Feb 2026): los agentes intercambian subgrafos en lugar de texto:
class AgenticKnowledgeGraph:
"""
En lugar de que los agentes envíen texto o JSON,
envían subgrafos estructurados que representan:
- Contexto actual
- Suposiciones del agente
- Riesgos identificados
- Intención del siguiente paso
"""
def agent_to_agent_message(self,
context_nodes: list,
assumptions: list,
risks: list,
intent: str) -> dict:
"""Construye un subgrafo de comunicación entre agentes."""
return {
"type": "agent_message_graph",
"nodes": context_nodes,
"assumptions": [{"claim": a, "confidence": 0.9} for a in assumptions],
"risks": [{"description": r, "severity": "medium"} for r in risks],
"intent": {"next_action": intent, "rationale": "..."}
}
Configuración de opciones
@dataclass
class GraphConfig:
# Fuente
source: str = "local" # "local", "s3", "azure", "gcp"
source_path: str = "."
recursive: bool = True
# Documentos
formats: list = field(default_factory=lambda:
["pdf", "docx", "txt", "md", "json", "yaml", "py", "js", "ts"])
exclude_patterns: list = field(default_factory=lambda:
[".git", "node_modules", "__pycache__", ".venv"])
max_file_size_mb: float = 50.0
# Chunking (2026)
chunk_strategy: str = "contextual" # "fixed", "semantic", "contextual", "atomic_facts"
chunk_size: int = 512
chunk_overlap: int = 50
# Extracción
extract_entities: bool = True
extract_relationships: bool = True
detect_qa_pairs: bool = True
use_multi_agent: bool = True # 5-agent system
llm_model: str = "claude-sonnet-4-6"
# Arquitectura de grafo
architecture: str = "lightrag" # "lightrag", "graphrag", "graphiti", "cognee", "custom"
similarity_threshold: float = 0.75
max_neighbors: int = 10
detect_communities: bool = True # Leiden algorithm
# Almacenamiento
output_format: str = "neo4j" # "neo4j", "falkordb", "networkx", "json", "neptune"
output_path: str = "./knowledge_graph"
use_embeddings: bool = True
embedding_model: str = "sentence-transformers/all-MiniLM-L6-v2"
# Temporal (Graphiti)
use_temporal: bool = False
track_changes: bool = False
# MCP Server
expose_as_mcp: bool = False
mcp_port: int = 8765
Salida esperada
knowledge_graph/
├── graph.json # Grafo principal en formato NetworkX
├── graph.graphml # Formato GraphML para visualización
├── embeddings.npy # Embeddings de chunks
├── communities/ # Comunidades detectadas (GraphRAG)
│ ├── community_0.json
│ └── community_1.json
├── index/
│ ├── chunks.json # Índice de todos los chunks
│ ├── entities.json # Entidades extraídas con esquema
│ ├── concepts.json # Catálogo de conceptos
│ └── qa_pairs.json # Pares pregunta-respuesta detectados
├── atomic_facts/ # Hechos atómicos (GFS approach)
│ └── facts.json
├── stats/
│ ├── summary.json # Estadísticas del grafo
│ └── relationships.json # Distribución de tipos de relaciones
└── reports/
└── graph_report.md # Informe legible del grafo construido
Artículos de referencia (2026)
Basado en investigación de:
- Claudiu Branzan — "From LLMs to Knowledge Graphs: Building Production-Ready Graph Systems in 2025"
- Akash Goyal — "Building Agentic GraphOS: The 16-Layer Architecture"
- Vishal Mysore — "Agentic Knowledge Graphs as a Communication Protocol Between AI Agents" (Feb 2026)
- Vishal Mysore — "Knowledge Graphs in Action: MCP and Agentic Workflows"
- Jose F. Sosa — "Comparative Analysis of RAG, Graph RAG, Agentic Graphs"
- Shilpa Thota — "Agentic Knowledge Graph Construction with Neo4j"
- Saeed Hajebi — "Building AI Agents with Knowledge Graph Memory: Graphiti"
- Nitish Kumar — "Temporal Graph RAG: Why Time-Aware Knowledge Graphs Are Reshaping AI Memory" (Feb 2026)
- Brian James Curry — "Building a Knowledge Graph: A Comprehensive End-to-End Guide" (Jan 2026)
- QuarkAndCode — "GraphRAG with LangChain & LangGraph: Neo4j and FalkorDB Guide" (Feb 2026)
- QuarkAndCode — "Hybrid GraphRAG on FalkorDB: Smarter RAG with Knowledge Graphs" (Feb 2026)
- Thomas Rehmer — "Claude + Neo4j with MCP: Turning Your Knowledge Graph into an AI Interface" (Jan 2026)
- Tongbing — "GraphRAG in 2026: A Practical Buyer's Guide" (Jan 2026)
- Vishal Mysore — "Chunking Strategies for RAG: Early, Late, and Contextual Chunking"
- James Stakelum — "Beyond Basic Chunking: Atomic Facts and Graph Fact Synthesis (GFS)"
- Alexander Shereshevsky — "Graph RAG in 2026: A Practitioner's Guide to What Actually Works" (Feb 2026)
- Modern Data 101 — "Building Self-Evolving Knowledge Graphs Using Agentic Systems"
- Fanghua Yu — "A Unified Framework for AI-Native Knowledge Graphs" (Jan 2026)
- Tomaz Bratanic — "Building Knowledge Graphs with LLM Graph Transformer"
- Anthony Alcaraz — "Knowledge Graph Prompting for Multi-Document Question Answering"