<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Kag on lo0 — Blog Técnico</title><link>https://blog.lo0.es/tags/kag/</link><description>Recent content in Kag on lo0 — Blog Técnico</description><generator>Hugo -- gohugo.io</generator><language>es</language><lastBuildDate>Wed, 03 Jun 2026 03:30:00 +0200</lastBuildDate><atom:link href="https://blog.lo0.es/tags/kag/index.xml" rel="self" type="application/rss+xml"/><item><title>Ontologías y knowledge graphs en LLMOps: la nomenclatura linneana que sostiene las seis etapas del pipeline</title><link>https://blog.lo0.es/posts/ontologias-knowledge-graphs-seis-etapas-llmops/</link><pubDate>Wed, 03 Jun 2026 03:30:00 +0200</pubDate><guid>https://blog.lo0.es/posts/ontologias-knowledge-graphs-seis-etapas-llmops/</guid><description>&lt;blockquote>
&lt;p>Este post atraviesa &lt;strong>las seis etapas del &lt;a href="https://blog.lo0.es/posts/pipeline-llmops-seis-etapas/">pipeline LLMOps&lt;/a>&lt;/strong> desde una perspectiva transversal: la &lt;strong>nomenclatura común&lt;/strong> que hace que las etapas compartan vocabulario. Conecta directamente con &lt;a href="https://blog.lo0.es/posts/rag-corpus-curation-fundamentos/">RAG corpus curation&lt;/a> (el corpus se cura &lt;em>contra&lt;/em> una ontología), &lt;a href="https://blog.lo0.es/posts/embeddings-modelos-2026-dense-sparse-multivector/">embeddings&lt;/a> (la ontología enriquece el embedding con metadatos tipados), &lt;a href="https://blog.lo0.es/posts/rag-reranker-hybrid-retrieval-fundamentos/">retrieval híbrido&lt;/a> (el KG es un cuarto canal junto a denso/esparso/multi-vector), &lt;a href="https://blog.lo0.es/posts/evals-llm-la-capa-despues-de-tracing/">evals&lt;/a> (los golden sets se estratifican por clase ontológica), &lt;a href="https://blog.lo0.es/posts/structured-output-fundamentos/">structured output&lt;/a> (las JSON Schemas derivan de OWL/SHACL), y los tres marcos de &lt;a href="https://blog.lo0.es/posts/iso-42001-aims-llm-on-premise/">ISO 42001&lt;/a>, &lt;a href="https://blog.lo0.es/posts/controles-tecnicos-ens-42001-eu-ai-act/">ENS&lt;/a> y &lt;a href="https://blog.lo0.es/posts/eu-ai-act-mapeo-arquitectura-llm-on-premise/">EU AI Act&lt;/a> (cada uno &lt;em>es&lt;/em> una ontología de control).&lt;/p>
&lt;/blockquote>
&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>La conversación de ontologías y LLMs ha oscilado entre dos posturas igualmente equivocadas en los últimos tres años: o &amp;ldquo;los LLMs ya extraen conocimiento solos, las ontologías son del siglo pasado&amp;rdquo;, o &amp;ldquo;todo el RAG hay que tirarlo y construir un knowledge graph encima&amp;rdquo;. La realidad operativa de mid-2026 es más sobria: &lt;strong>la ontología no es un sustituto del RAG sino su nomenclatura común&lt;/strong>, sin la cual las seis etapas del pipeline LLMOps trabajan con vocabularios distintos sin saberlo. El corpus se cura sin saber qué clases de entidad existen; los embeddings perforan documentos sin enriquecerse con metadatos tipados; los evals reportan una accuracy global que oculta gaps enteros de clase; el guardrail bloquea por listas de palabras en vez de por clasificación formal; el incident response agrupa mal porque cada alerta nombra &amp;ldquo;el activo afectado&amp;rdquo; a su manera; el compliance no puede mapear sus controles porque ENS, ISO 42001 y EU AI Act son tres ontologías y el sistema no tiene ninguna. Este post desmonta qué es una ontología en términos prácticos —TBox y ABox, RDF y SPARQL, los cuatro perfiles de OWL 2 (EL para terminologías enormes tipo SNOMED, QL para OBDA, RL para reasoning con reglas, DL para el full description-logic), SHACL para validación con shapes, SKOS para tesauros, JSON-LD como serialización viable—, recorre las &lt;strong>seis etapas LLMOps&lt;/strong> mostrando dónde la ontología cambia la operación, repasa el campo GraphRAG en 2026 con datos verificables (&lt;strong>Microsoft GraphRAG v2 oct-2025&lt;/strong>, &lt;strong>LightRAG&lt;/strong> dual-level y actualizaciones incrementales, &lt;strong>HippoRAG 2&lt;/strong> con Personalized PageRank, &lt;strong>KAG sobre OpenSPG&lt;/strong> ontology-grounded), inventaria las ontologías verticales realmente desplegadas en producción (FIBO, SNOMED CT, schema.org, IEC 81346, GS1, Wikidata, &lt;strong>ENS Anexo I-II del RD 311/2022&lt;/strong>, &lt;strong>EU AI Act Anexo III&lt;/strong>), fija el stack open source on-prem viable con las salvedades de licencia (&lt;strong>Neo4j Community es GPLv3 con implicaciones AGPL en algunos features&lt;/strong>, &lt;strong>KuzuDB upstream archivado oct-2025&lt;/strong>, forks &lt;code>bighorn&lt;/code> y &lt;code>ryugraph&lt;/code>), describe los cinco patrones de integración LLM × ontología y cierra con siete trampas operativas. La regla del pulgar: &lt;strong>el knowledge graph no es la respuesta; la nomenclatura formalizada compartida sí&lt;/strong>.&lt;/p>
&lt;h2 id="la-analogía-carl-linneo-1735">La analogía: Carl Linneo, 1735&lt;/h2>
&lt;p>En 1735 publicó Carl von Linné la primera edición de &lt;em>Systema Naturae&lt;/em>. Antes de Linneo, los naturalistas europeos tenían un problema operativo: la misma especie podía aparecer en cinco tratados con cinco nombres latinos distintos —cada uno una descripción polinómica del tipo &lt;em>&amp;ldquo;Felis cauda elongata cum maculis nigris in dorso et lateribus&amp;rdquo;&lt;/em>— y dos naturalistas que se carteaban tardaban meses en darse cuenta de que estaban discutiendo del mismo animal. La biología era un campo de &lt;strong>ruido lexicográfico&lt;/strong>: imposible comparar observaciones, imposible verificar replicación, imposible construir teoría acumulativa.&lt;/p>
&lt;p>Linneo no descubrió biología. Lo que descubrió fue que el campo necesitaba &lt;strong>una nomenclatura común con tres propiedades&lt;/strong>:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Jerarquía estricta&lt;/strong>. Reino → Filo → Clase → Orden → Familia → Género → Especie. Cada nivel es una clase con subclases bien definidas. Una propiedad de Felis (la dieta carnívora) se hereda automáticamente a Felis catus y a Felis silvestris sin redeclararse.&lt;/li>
&lt;li>&lt;strong>Naming inequívoco&lt;/strong>. Cada especie tiene &lt;strong>un único nombre binomial&lt;/strong> (Genus + epíteto específico) y un único type specimen anclado en un museo. &lt;em>&amp;ldquo;Felis silvestris&amp;rdquo;&lt;/em> significa exactamente lo mismo en Madrid, Estocolmo y Calcuta.&lt;/li>
&lt;li>&lt;strong>Reglas de prioridad&lt;/strong>. Si dos botánicos publican el mismo género con nombres distintos, gana el primero que lo registró válidamente. La convención de naming no se debate en cada paper: hay un metanivel de gobernanza explícita.&lt;/li>
&lt;/ol>
&lt;p>Tras Linneo, &lt;strong>la biología comparada se vuelve posible&lt;/strong>. Mendel puede hablar de &lt;em>Pisum sativum&lt;/em> y un botánico polaco sabe exactamente qué planta cultivar para replicarlo. Darwin puede comparar pinzones de las Galápagos con pinzones de otras islas sin confusión sobre qué es &amp;ldquo;el mismo tipo de pájaro&amp;rdquo;. El cambio no es de instrumentación —el microscopio existía desde Hooke (1665)—. El cambio es de &lt;strong>vocabulario formal compartido&lt;/strong>.&lt;/p>
&lt;p>Una ontología en computación es &lt;strong>exactamente esto&lt;/strong>:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Linneo (1735)&lt;/th>
&lt;th>Ontología (2026)&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Jerarquía Reino → … → Especie&lt;/td>
&lt;td>Jerarquía de clases (&lt;code>Person ⊑ Agent ⊑ Thing&lt;/code>) — el &lt;strong>TBox&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Type specimen en museo&lt;/td>
&lt;td>Instancia anclada con IRI única — el &lt;strong>ABox&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Nombre binomial&lt;/td>
&lt;td>IRI / URI única por concepto&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Reglas de prioridad&lt;/td>
&lt;td>Axiomas de la ontología + gobernanza&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;em>&amp;ldquo;Felis silvestris&amp;rdquo;&lt;/em> significa lo mismo en Madrid y Estocolmo&lt;/td>
&lt;td>&lt;code>&amp;lt;http://example.org/ont/Felis_silvestris&amp;gt;&lt;/code> significa lo mismo en cualquier sistema&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Cuando hoy un LLMOps team dice &amp;ldquo;nuestro corpus está curado, los embeddings son &lt;code>bge-m3&lt;/code> y los evals miden recall@5&amp;rdquo;, pero la pregunta &amp;ldquo;¿qué proporción de queries sobre &lt;strong>activos categoría alta&lt;/strong> del ENS están bien cubiertas?&amp;rdquo; no tiene respuesta — porque en el sistema no existe una clase formal &amp;ldquo;activo categoría alta ENS&amp;rdquo;—, el problema es &lt;strong>pre-Linneo&lt;/strong>: el campo todavía no se ha dotado de la nomenclatura que hace comparable cada etapa.&lt;/p>
&lt;div class="diagram" style="max-width:780px;margin:1.5rem auto;">
&lt;svg viewBox="0 0 780 380" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Ontología como nomenclatura compartida entre las seis etapas LLMOps">
&lt;style>
.obox{fill:#f8f8f8;stroke:#444;stroke-width:1.4;rx:8}
.ohead{fill:#ff8a4c;stroke:#444;stroke-width:1.4;rx:8}
.oont{fill:#d8a8ff;stroke:#444;stroke-width:1.4;rx:8}
.oet1{fill:#7aafff;stroke:#444;stroke-width:1.4;rx:8}
.oet2{fill:#a8d5a8;stroke:#444;stroke-width:1.4;rx:8}
.oet3{fill:#ffe18a;stroke:#444;stroke-width:1.4;rx:8}
.oet4{fill:#ffb86b;stroke:#444;stroke-width:1.4;rx:8}
.oet5{fill:#bce0fd;stroke:#444;stroke-width:1.4;rx:8}
.oet6{fill:#ffc4c4;stroke:#444;stroke-width:1.4;rx:8}
.oblt{font:600 13px sans-serif;fill:#222}
.osub{font:400 10.5px sans-serif;fill:#444}
.oarr{stroke:#666;stroke-width:1.3;fill:none;marker-end:url(#mo1)}
&lt;/style>
&lt;defs>&lt;marker id="mo1" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">&lt;path d="M0,0 L10,5 L0,10 z" fill="#666"/>&lt;/marker>&lt;/defs>
&lt;rect x="290" y="20" width="200" height="60" class="oont"/>
&lt;text x="390" y="44" text-anchor="middle" class="oblt">Ontología (TBox)&lt;/text>
&lt;text x="390" y="62" text-anchor="middle" class="osub">Clases, propiedades, axiomas, SHACL&lt;/text>
&lt;text x="390" y="76" text-anchor="middle" class="osub">FIBO · SNOMED · ENS · schema.org&lt;/text>
&lt;rect x="20" y="140" width="140" height="60" class="oet1"/>
&lt;text x="90" y="164" text-anchor="middle" class="oblt">1. Data&lt;/text>
&lt;text x="90" y="180" text-anchor="middle" class="osub">curación por clase&lt;/text>
&lt;text x="90" y="194" text-anchor="middle" class="osub">PII = ontology of types&lt;/text>
&lt;rect x="180" y="140" width="140" height="60" class="oet2"/>
&lt;text x="250" y="164" text-anchor="middle" class="oblt">2. Train / Adapt&lt;/text>
&lt;text x="250" y="180" text-anchor="middle" class="osub">datos estratificados&lt;/text>
&lt;text x="250" y="194" text-anchor="middle" class="osub">synthetic por clase&lt;/text>
&lt;rect x="340" y="140" width="140" height="60" class="oet3"/>
&lt;text x="410" y="164" text-anchor="middle" class="oblt">3. Eval&lt;/text>
&lt;text x="410" y="180" text-anchor="middle" class="osub">métricas por clase&lt;/text>
&lt;text x="410" y="194" text-anchor="middle" class="osub">cobertura ontológica&lt;/text>
&lt;rect x="500" y="140" width="140" height="60" class="oet4"/>
&lt;text x="570" y="164" text-anchor="middle" class="oblt">4. Deploy&lt;/text>
&lt;text x="570" y="180" text-anchor="middle" class="osub">routing semántico&lt;/text>
&lt;text x="570" y="194" text-anchor="middle" class="osub">tool calling tipado&lt;/text>
&lt;rect x="100" y="240" width="180" height="60" class="oet5"/>
&lt;text x="190" y="264" text-anchor="middle" class="oblt">5. Observe&lt;/text>
&lt;text x="190" y="280" text-anchor="middle" class="osub">taxonomía de incidentes&lt;/text>
&lt;text x="190" y="294" text-anchor="middle" class="osub">lineage tipado en KG&lt;/text>
&lt;rect x="320" y="240" width="180" height="60" class="oet6"/>
&lt;text x="410" y="264" text-anchor="middle" class="oblt">6. Govern&lt;/text>
&lt;text x="410" y="280" text-anchor="middle" class="osub">ENS · ISO 42001 · EU AI Act&lt;/text>
&lt;text x="410" y="294" text-anchor="middle" class="osub">son ontologías de control&lt;/text>
&lt;rect x="540" y="240" width="200" height="60" class="obox"/>
&lt;text x="640" y="262" text-anchor="middle" class="oblt">Estándares W3C&lt;/text>
&lt;text x="640" y="278" text-anchor="middle" class="osub">RDF · OWL 2 (EL/QL/RL/DL)&lt;/text>
&lt;text x="640" y="292" text-anchor="middle" class="osub">SHACL · SKOS · JSON-LD · SPARQL&lt;/text>
&lt;rect x="200" y="330" width="380" height="40" class="ohead"/>
&lt;text x="390" y="354" text-anchor="middle" class="oblt">Sin nomenclatura compartida = pipeline pre-linneano&lt;/text>
&lt;path class="oarr" d="M390 80 L90 140"/>
&lt;path class="oarr" d="M390 80 L250 140"/>
&lt;path class="oarr" d="M390 80 L410 140"/>
&lt;path class="oarr" d="M390 80 L570 140"/>
&lt;path class="oarr" d="M390 80 Q260 170 190 240"/>
&lt;path class="oarr" d="M390 80 Q390 170 410 240"/>
&lt;/svg>
&lt;p style="text-align:center;font-size:0.9rem;color:#555;margin-top:0.5rem;">La ontología atraviesa las seis etapas como vocabulario compartido. Sin ella, cada etapa tiene su propia definición de "cliente", "documento sensible" o "incidente".&lt;/p>
&lt;/div>
&lt;h2 id="qué-es-una-ontología-en-términos-operativos">Qué es una ontología en términos operativos&lt;/h2>
&lt;p>La palabra &amp;ldquo;ontología&amp;rdquo; tiene un parentesco filosófico ineludible —Aristóteles, las categorías de Kant, Quine— que confunde a la primera. En infraestructura LLM da igual: una ontología es &lt;strong>un grafo dirigido con tipos&lt;/strong>, descrito formalmente, sobre el que se puede razonar, validar y consultar. Lo importante son seis conceptos prácticos.&lt;/p>
&lt;h3 id="tbox-y-abox">TBox y ABox&lt;/h3>
&lt;p>La distinción que se usa todos los días. La &lt;strong>TBox&lt;/strong> (de &lt;em>terminology&lt;/em>) es el esquema: clases, jerarquía de subclases, propiedades, axiomas. La &lt;strong>ABox&lt;/strong> (de &lt;em>assertions&lt;/em>) son las instancias.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-turtle" data-lang="turtle">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># TBox — esquema&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">Person&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">rdfs:&lt;/span>&lt;span class="nt">subClassOf&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">Agent&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">Employee&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">rdfs:&lt;/span>&lt;span class="nt">subClassOf&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">Person&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">worksFor&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">rdfs:&lt;/span>&lt;span class="nt">domain&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">Employee&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">rdfs:&lt;/span>&lt;span class="nt">range&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">Organization&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c"># ABox — instancias&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">alice&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">Employee&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">alice&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">worksFor&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">acme&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Un reasoner verifica que la ABox es consistente con la TBox: si declaras &lt;code>:alice :worksFor :acme&lt;/code> pero &lt;code>:alice&lt;/code> no es &lt;code>:Employee&lt;/code>, el reasoner detecta la inconsistencia. Esa es la palanca: &lt;strong>validación automática del conocimiento&lt;/strong> que ningún sistema basado solo en embeddings densos puede dar.&lt;/p>
&lt;h3 id="rdf-y-la-unidad-de-información">RDF y la unidad de información&lt;/h3>
&lt;p>La unidad atómica del Semantic Web es la &lt;strong>tripla RDF&lt;/strong> &lt;code>(sujeto, predicado, objeto)&lt;/code>. Todo dato se expresa como una colección de triplas. Esto da la propiedad operativa más útil del paradigma: &lt;strong>dos grafos se mergean trivialmente uniéndolos&lt;/strong>. Si tu sistema indexa el corpus médico con SNOMED CT y el corpus legal con FIBO, ambos en RDF, fusionarlos para una query que cruce los dos dominios es literalmente &lt;code>g1 ∪ g2&lt;/code>. En propiedad-graph (Neo4j) esto requiere más cirugía.&lt;/p>
&lt;h3 id="los-cuatro-perfiles-de-owl-2">Los cuatro perfiles de OWL 2&lt;/h3>
&lt;p>La gente nueva al campo asume que OWL es una cosa. Son cuatro perfiles con trade-offs distintos, todos W3C Recommendation:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Perfil&lt;/th>
&lt;th>Expresividad&lt;/th>
&lt;th>Coste de razonamiento&lt;/th>
&lt;th>Casos de uso&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>OWL 2 EL&lt;/strong>&lt;/td>
&lt;td>restringido (subclase, intersección, propiedades)&lt;/td>
&lt;td>polinomial en tamaño de ontología&lt;/td>
&lt;td>terminologías enormes — &lt;strong>SNOMED CT&lt;/strong> (350k+ conceptos)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>OWL 2 QL&lt;/strong>&lt;/td>
&lt;td>subset que mapea a SQL/UCQ&lt;/td>
&lt;td>LOGSPACE en datos&lt;/td>
&lt;td>&lt;strong>OBDA&lt;/strong> (ontology-based data access) sobre DBs relacionales&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>OWL 2 RL&lt;/strong>&lt;/td>
&lt;td>subset implementable como reglas (Datalog)&lt;/td>
&lt;td>escalable, sin DL completo&lt;/td>
&lt;td>reasoning en producción con motores de reglas&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>OWL 2 DL&lt;/strong>&lt;/td>
&lt;td>SROIQ completo (la &amp;ldquo;full ontology&amp;rdquo;)&lt;/td>
&lt;td>decidible pero NEXPTIME en peor caso&lt;/td>
&lt;td>ontologías académicas, validación profunda&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Regla operativa&lt;/strong>: si tu equipo no va a leer un paper de description logics todos los meses, &lt;strong>no uses OWL 2 DL&lt;/strong>. Casi todo el valor está en EL/QL/RL. Para terminologías médicas grandes, EL. Para razonar sobre datos relacionales existentes, QL. Para reglas de negocio, RL.&lt;/p>
&lt;h3 id="shacl--la-validación-que-sí-se-opera">SHACL — la validación que sí se opera&lt;/h3>
&lt;p>OWL hace &lt;strong>reasoning&lt;/strong> (&amp;ldquo;dadas estas axiomas, ¿qué se puede deducir?&amp;rdquo;). SHACL hace &lt;strong>validación&lt;/strong> (&amp;ldquo;dado este grafo concreto, ¿cumple estos shapes?&amp;rdquo;). En producción, SHACL gana porque su semántica es más cercana al chequeo de tipos que el desarrollador entiende:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-turtle" data-lang="turtle">&lt;span class="line">&lt;span class="cl">&lt;span class="nn">:&lt;/span>&lt;span class="nt">PersonShape&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">sh:&lt;/span>&lt;span class="nt">NodeShape&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nn">sh:&lt;/span>&lt;span class="nt">targetClass&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">Person&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nn">sh:&lt;/span>&lt;span class="nt">property&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nn">sh:&lt;/span>&lt;span class="nt">path&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">nombre&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nn">sh:&lt;/span>&lt;span class="nt">minCount&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nn">sh:&lt;/span>&lt;span class="nt">datatype&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">xsd:&lt;/span>&lt;span class="nt">string&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nn">sh:&lt;/span>&lt;span class="nt">path&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">nif&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nn">sh:&lt;/span>&lt;span class="nt">pattern&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;^[0-9]{8}[A-Z]$&amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Validar un grafo entrante contra este shape detecta &lt;code>:alice :nombre 42&lt;/code> (tipo incorrecto), &lt;code>:alice :nif &amp;quot;12345678X9&amp;quot;&lt;/code> (formato incorrecto) o &lt;code>:alice a :Person&lt;/code> sin nombre (min count violado). Es &lt;strong>JSON Schema para grafos&lt;/strong>, conceptualmente. La spec SHACL 1.2 está en draft W3C 2025; SHACL 1.0 lleva en producción desde 2017.&lt;/p>
&lt;h3 id="skos--el-tesauro-ligero">SKOS — el tesauro ligero&lt;/h3>
&lt;p>No todo conocimiento merece OWL. Para &lt;strong>vocabularios controlados&lt;/strong> —tesauros, taxonomías, glosarios— hay SKOS:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-turtle" data-lang="turtle">&lt;span class="line">&lt;span class="cl">&lt;span class="nn">:&lt;/span>&lt;span class="nt">Mamifero&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">skos:&lt;/span>&lt;span class="nt">Concept&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nn">skos:&lt;/span>&lt;span class="nt">prefLabel&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;Mamífero&amp;#34;&lt;/span>&lt;span class="o">@&lt;/span>&lt;span class="ge">es&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;Mammal&amp;#34;&lt;/span>&lt;span class="o">@&lt;/span>&lt;span class="ge">en&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nn">skos:&lt;/span>&lt;span class="nt">broader&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">Animal&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nn">skos:&lt;/span>&lt;span class="nt">narrower&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">Felino&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nn">:&lt;/span>&lt;span class="nt">Canido&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>SKOS no expresa axiomas formales —&lt;code>skos:broader&lt;/code> no es &lt;code>rdfs:subClassOf&lt;/code>—. Sirve para clasificar contenidos sin pretensión de razonamiento, que es el 80% de los casos corporativos. &lt;strong>Empieza por SKOS&lt;/strong>: la mayoría de &amp;ldquo;ontologías&amp;rdquo; empresariales son en realidad tesauros que se sobreelevaron a OWL por moda y arrastran complejidad innecesaria.&lt;/p>
&lt;h3 id="json-ld-y-sparql--las-superficies-prácticas">JSON-LD y SPARQL — las superficies prácticas&lt;/h3>
&lt;p>&lt;strong>JSON-LD 1.1&lt;/strong> (W3C Rec 2020) es la serialización que sí se usa en sistemas reales: JSON normal con un campo &lt;code>@context&lt;/code> que mapea las claves a IRIs. El microformato de schema.org en páginas web es JSON-LD. Para un equipo LLMOps, JSON-LD es el formato natural de intercambio con tools y APIs.&lt;/p>
&lt;p>&lt;strong>SPARQL 1.1&lt;/strong> (W3C Rec 2013; 1.2 en draft 2025) es SQL para grafos:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sparql" data-lang="sparql">&lt;span class="line">&lt;span class="cl">&lt;span class="k">SELECT&lt;/span> &lt;span class="nv">?empleado&lt;/span> &lt;span class="nv">?empresa&lt;/span> &lt;span class="k">WHERE&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">?empleado&lt;/span> &lt;span class="k">a&lt;/span> &lt;span class="p">:&lt;/span>&lt;span class="nt">Employee&lt;/span> &lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">:&lt;/span>&lt;span class="nt">worksFor&lt;/span> &lt;span class="nv">?empresa&lt;/span> &lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">:&lt;/span>&lt;span class="nt">pais&lt;/span> &lt;span class="s">&amp;#34;España&amp;#34;&lt;/span> &lt;span class="p">.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">?empresa&lt;/span> &lt;span class="p">:&lt;/span>&lt;span class="nt">sector&lt;/span> &lt;span class="s">&amp;#34;fintech&amp;#34;&lt;/span> &lt;span class="p">.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Toda triple store moderna lo habla. Los Federation features permiten que una sola query toque varios endpoints —SNOMED CT + ontología corporativa propia—.&lt;/p>
&lt;h2 id="por-qué-importa-para-un-llm-en-producción">Por qué importa para un LLM en producción&lt;/h2>
&lt;p>La promesa romántica del año 2023-2024 era: &amp;ldquo;ahora que tenemos LLMs, no necesitamos ontologías; el modelo entiende el lenguaje natural y extrae conocimiento&amp;rdquo;. La realidad operativa de mid-2026 es más matizada y descansa sobre cuatro observaciones que cualquiera con un RAG en producción ha hecho ya:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>El LLM tiene memoria semántica pero no esquema declarado&lt;/strong>. Si preguntas &amp;ldquo;¿qué entidades de tipo &lt;code>Person&lt;/code> aparecen en este documento?&amp;rdquo;, responde algo razonable. Si preguntas &amp;ldquo;¿qué personas aparecen y cuáles son empleados del cliente?&amp;rdquo;, la respuesta depende de cómo el modelo &lt;em>interpreta&lt;/em> &amp;ldquo;empleado del cliente&amp;rdquo; en ese contexto. Sin un esquema externo que diga &amp;ldquo;Employee es subclase de Person y se relaciona con Organization vía worksFor&amp;rdquo;, la coherencia entre dos llamadas al mismo LLM no está garantizada.&lt;/li>
&lt;li>&lt;strong>La calidad varía por dominio sin que el sistema sepa por qué&lt;/strong>. Tu RAG tiene una accuracy global del 78% pero falla sistemáticamente en queries sobre instrumentos financieros derivados. Como no tienes una clasificación formal de queries por categoría, el problema es invisible hasta que un cliente se queja.&lt;/li>
&lt;li>&lt;strong>El compliance exige nomenclatura formal&lt;/strong>. ENS clasifica activos en cinco dimensiones (Confidencialidad, Integridad, Disponibilidad, Autenticidad, Trazabilidad) con tres niveles cada una. EU AI Act enumera ocho áreas de alto riesgo en Anexo III. Sin un mapeo formal entre tus assets y esas categorías, &lt;strong>no puedes auditar lo que no sabes nombrar&lt;/strong>. El auditor pregunta &amp;ldquo;¿qué chunks del corpus tocan datos personales especialmente protegidos?&amp;rdquo; y tu sistema no tiene esa columna.&lt;/li>
&lt;li>&lt;strong>La interoperabilidad entre componentes exige tipos&lt;/strong>. Tu retrieval devuelve &amp;ldquo;chunks relevantes&amp;rdquo;. Tu reranker los reordena. Tu guardrail filtra los sensibles. Si cada componente tiene su propia definición de qué es un &amp;ldquo;chunk sensible&amp;rdquo;, la cadena rompe en cada interface. Una ontología compartida es &lt;strong>el contrato de tipos del pipeline&lt;/strong>.&lt;/li>
&lt;/ol>
&lt;p>La consecuencia operativa: &lt;strong>la ontología no reemplaza el RAG&lt;/strong>. Lo &lt;em>tipa&lt;/em>. Lo hace auditable, comparable y debuggable. La pregunta correcta no es &amp;ldquo;¿necesito un knowledge graph?&amp;rdquo; sino &amp;ldquo;¿en qué etapas del pipeline gano si introduzco una nomenclatura formal compartida?&amp;rdquo;.&lt;/p>
&lt;h2 id="las-seis-etapas-llmops--ontología">Las seis etapas LLMOps × ontología&lt;/h2>
&lt;p>Recorramos las &lt;a href="https://blog.lo0.es/posts/pipeline-llmops-seis-etapas/">seis etapas del pipeline&lt;/a> preguntando qué cambia en cada una cuando hay ontología. Esto es el eje del post: la palanca no es &amp;ldquo;instalar Neo4j&amp;rdquo;, es introducir tipos donde antes había texto plano.&lt;/p>
&lt;h3 id="etapa-1--data">Etapa 1 — Data&lt;/h3>
&lt;p>La &lt;a href="https://blog.lo0.es/posts/rag-corpus-curation-fundamentos/">curación del corpus&lt;/a> se vuelve &lt;strong>curación dirigida por ontología&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>Cada chunk no es solo &amp;ldquo;texto + embedding&amp;rdquo;, lleva además &lt;code>chunk:tipoDocumento&lt;/code>, &lt;code>chunk:nivelClasificacion&lt;/code>, &lt;code>chunk:categoriaENS&lt;/code>, &lt;code>chunk:contienePII&lt;/code>.&lt;/li>
&lt;li>Estos tipos vienen de una ontología corporativa explícita, no de strings ad-hoc del data engineer del turno de mañana.&lt;/li>
&lt;li>La regla 4 de &lt;a href="https://blog.lo0.es/posts/rag-corpus-curation-fundamentos/">corpus curation&lt;/a> —anti-contaminación— se beneficia: los chunks del &lt;strong>golden eval set&lt;/strong> llevan &lt;code>dataset:goldenEval=true&lt;/code> declarado como tripla; cualquier reindexación que filtre por &lt;code>goldenEval=true&lt;/code> se vuelve trivial.&lt;/li>
&lt;li>El detector de PII deja de ser una expresión regular para volverse un clasificador contra el tesauro &lt;strong>categorías de datos personales&lt;/strong>: identificador, contacto, financiero, salud, biométrico. La columna &lt;code>chunk:pii&lt;/code> ya no es booleana sino una lista de categorías SKOS.&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Ingestion con tipado ontológico&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">chunk&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@context&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;https://ontology.fibercli.es/v1/context.jsonld&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;chunk:&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">uuid4&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Chunk&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;tipoDocumento&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;ContratoComercial&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;nivelClasificacion&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;ConfidencialMedio&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;categoriaENS&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Disponibilidad-M&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Confidencialidad-A&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;contienePII&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;IdentificadorFiscal&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Contacto&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;embedding&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="o">...&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;text&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;...&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Bajo el contexto JSON-LD, todas esas claves resuelven a IRIs y son consultables vía SPARQL.&lt;/p>
&lt;h3 id="etapa-2--train--adapt">Etapa 2 — Train / Adapt&lt;/h3>
&lt;p>El &lt;a href="https://blog.lo0.es/posts/fine-tuning-continuo-produccion/">fine-tuning continuo&lt;/a> y el &lt;a href="https://blog.lo0.es/posts/retrain-cerrar-el-bucle-feedback-dataset-adapter/">retrain&lt;/a> ganan dos palancas:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Datasets estratificados por clase&lt;/strong>. Cuando el feedback de producción se convierte en dataset de entrenamiento, cada ejemplo viene etiquetado por la clase ontológica del incidente que lo originó. Permite muestrear &lt;code>n&lt;/code> ejemplos &lt;em>por clase&lt;/em> en vez de &lt;code>n&lt;/code> ejemplos globales — corrige los gaps de cobertura del modelo.&lt;/li>
&lt;li>&lt;strong>Generación sintética guiada por ontología&lt;/strong>. Para clases con pocos ejemplos en el corpus real, se generan datos sintéticos contra el esquema: &amp;ldquo;genera 50 preguntas sobre &lt;code>FIBO:DerivativeInstrument&lt;/code> que un trader podría hacer&amp;rdquo;. La salida pasa por structured output validado contra el shape SHACL del schema antes de entrar al dataset.&lt;/li>
&lt;/ul>
&lt;h3 id="etapa-3--eval">Etapa 3 — Eval&lt;/h3>
&lt;p>La capa de &lt;a href="https://blog.lo0.es/posts/evals-llm-la-capa-despues-de-tracing/">evals&lt;/a> cambia más que ninguna. Sin ontología, el eval reporta una accuracy global que oculta:&lt;/p>
&lt;pre tabindex="0">&lt;code>accuracy = 0.78
&lt;/code>&lt;/pre>&lt;p>Con ontología, reporta &lt;strong>una matriz de cobertura por clase&lt;/strong>:&lt;/p>
&lt;pre tabindex="0">&lt;code> accuracy n_queries covered_in_corpus
ContratoComercial 0.82 142 si
EmpleadoENS-Alto 0.31 18 parcial
DerivadoFinanciero 0.74 67 si
SOAP_3.0_Endpoint 0.05 9 no
&lt;/code>&lt;/pre>&lt;p>La fila &lt;code>EmpleadoENS-Alto&lt;/code> con accuracy 0.31 visibiliza un problema invisible sin estratificación. La fila &lt;code>SOAP_3.0_Endpoint&lt;/code> con accuracy 0.05 y &lt;code>covered_in_corpus=no&lt;/code> indica que la clase ni siquiera tiene corpus — antes de tocar el modelo hay que tocar la ingestión. La métrica única &lt;strong>oculta&lt;/strong>; la métrica por clase &lt;strong>acciona&lt;/strong>.&lt;/p>
&lt;p>Esta es la regla que &lt;a href="https://blog.lo0.es/posts/llm-as-judge-fundamentos/">LLM-as-judge&lt;/a> y &lt;a href="https://blog.lo0.es/posts/evals-llm-la-capa-despues-de-tracing/">evals&lt;/a> deben implementar siempre que exista una ontología: &lt;strong>el golden eval set se etiqueta por clase y todas las métricas se reportan estratificadas&lt;/strong>.&lt;/p>
&lt;h3 id="etapa-4--deploy">Etapa 4 — Deploy&lt;/h3>
&lt;p>En el &lt;a href="https://blog.lo0.es/posts/router-inferencia-llm-gateway-l7/">router de inferencia LLM&lt;/a> la ontología habilita:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Semantic routing por clase&lt;/strong>. Queries que tras una primera clasificación caen bajo &lt;code>FIBO:Securities&lt;/code> se enrutan al adapter fine-tuneado en finanzas; queries bajo &lt;code>SNOMED:ClinicalFinding&lt;/code> al adapter médico. Sin ontología, este routing se basa en clasificadores ad-hoc o en heurísticas léxicas frágiles.&lt;/li>
&lt;li>&lt;strong>Tool calling tipado&lt;/strong>. Las herramientas que el agente puede invocar declaran sus argumentos contra clases de la ontología. El argumento &lt;code>cliente_id&lt;/code> no es &lt;code>string&lt;/code>; es &lt;code>:ClienteCorporativo&lt;/code>. Antes de ejecutar la tool, los argumentos se validan con SHACL. Reduce drásticamente los errores por argumentos mal poblados.&lt;/li>
&lt;li>&lt;strong>Feature flags con clase&lt;/strong>. El &lt;a href="https://blog.lo0.es/posts/canary-blue-green-shadow-modelos-llm/">canary&lt;/a> se hace &amp;ldquo;el nuevo modelo recibe el 10% de las queries de la clase X&amp;rdquo; en vez de un 10% indiferenciado: aísla el blast radius.&lt;/li>
&lt;/ul>
&lt;h3 id="etapa-5--observe">Etapa 5 — Observe&lt;/h3>
&lt;p>Es donde la ausencia de ontología duele más rápido en operación. Los &lt;a href="https://blog.lo0.es/posts/runbooks-incident-response-llm-keep-kafka/">runbooks de incident response&lt;/a> requieren:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Taxonomía de incidentes formal&lt;/strong>. &lt;code>IncidenteSeguridad ⊑ Incidente&lt;/code>, &lt;code>IncidenteIA ⊑ Incidente&lt;/code>, &lt;code>FugaDatos ⊑ IncidenteSeguridad&lt;/code>. Sin esta taxonomía, los cinco eventos del último mes etiquetados como &amp;ldquo;model issue&amp;rdquo;, &amp;ldquo;data drift&amp;rdquo;, &amp;ldquo;pii leak&amp;rdquo;, &amp;ldquo;prompt injection&amp;rdquo; y &amp;ldquo;hallucination&amp;rdquo; no son agrupables ni comparables. &lt;strong>Keep + Kafka aplican la deduplicación contra esa taxonomía&lt;/strong>.&lt;/li>
&lt;li>&lt;strong>Lineage tipado en el KG&lt;/strong>. La &lt;a href="https://blog.lo0.es/posts/tracing-llm-otel-genai/">observabilidad GPU + tracing&lt;/a> emite spans con atributos. Si esos atributos son tipados contra la ontología (&lt;code>span.input.classification = :ConfidencialMedio&lt;/code>), buscar todos los requests que tocaron clase &lt;code>ConfidencialAlto&lt;/code> en la última hora es una query SPARQL trivial; sin ontología, es un grep sobre logs no estructurados.&lt;/li>
&lt;/ul>
&lt;h3 id="etapa-6--govern">Etapa 6 — Govern&lt;/h3>
&lt;p>Donde la ontología se hace inevitable. Cada marco regulatorio &lt;strong>es una ontología&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>ENS RD 311/2022 Anexo I&lt;/strong>: define cinco dimensiones (C, I, D, A, T) × tres niveles (Bajo, Medio, Alto). Es un esquema de clasificación de activos. &lt;strong>Anexo II&lt;/strong> enumera 73 medidas de control con jerarquía organizativa / operacional / protección. Los &lt;a href="https://blog.lo0.es/posts/controles-tecnicos-ens-42001-eu-ai-act/">controles técnicos ENS&lt;/a> mapean cada control a componentes del stack — ese mapeo &lt;em>es&lt;/em> una ontología relacional.&lt;/li>
&lt;li>&lt;strong>ISO 42001 Annex A&lt;/strong>: enumera controles agrupados (A.5 políticas, A.6 organización interna, A.7 recursos para IA, A.8 evaluación, A.9 operación). El &lt;a href="https://blog.lo0.es/posts/iso-42001-aims-llm-on-premise/">AIMS sobre LLM on-premise&lt;/a> los formaliza.&lt;/li>
&lt;li>&lt;strong>EU AI Act Anexo III&lt;/strong>: ocho áreas de alto riesgo. Los &lt;a href="https://blog.lo0.es/posts/eu-ai-act-mapeo-arquitectura-llm-on-premise/">mapeos del expediente técnico&lt;/a> son una traducción de la ontología legal a la ontología técnica del sistema.&lt;/li>
&lt;/ul>
&lt;p>Sin una ontología que mapee tu inventario de assets, datasets, modelos y endpoints &lt;strong>a las clases de estos tres marcos&lt;/strong>, el compliance es manual, reactivo y se rompe con cada cambio del stack. Con la ontología, un cambio de modelo dispara automáticamente qué controles se ven afectados.&lt;/p>
&lt;h2 id="el-campo-graphrag-en-2026">El campo GraphRAG en 2026&lt;/h2>
&lt;p>GraphRAG es el nombre genérico de una familia de técnicas que &lt;strong>construyen un knowledge graph desde un corpus y lo usan como capa adicional de retrieval&lt;/strong> complementaria al dense / sparse / multi-vector que vimos en &lt;a href="https://blog.lo0.es/posts/embeddings-modelos-2026-dense-sparse-multivector/">embeddings&lt;/a>. La motivación es que algunas queries —&amp;ldquo;cuáles son los temas dominantes en este corpus&amp;rdquo;, &amp;ldquo;qué entidades aparecen conectadas con el cliente X en los últimos seis meses&amp;rdquo;— no se responden bien por similitud coseno entre vectores.&lt;/p>
&lt;h3 id="microsoft-graphrag">Microsoft GraphRAG&lt;/h3>
&lt;p>&lt;code>microsoft/graphrag&lt;/code> (julio 2024, v1.0 dic 2024, &lt;strong>v2.x oct 2025&lt;/strong>; cualquier referencia a v3 hay que verificar en GitHub releases antes de citar). Pipeline canónico:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Extracción&lt;/strong>. Un LLM lee el corpus por chunks y extrae entidades y relaciones — la TBox emerge de los datos en vez de declararse.&lt;/li>
&lt;li>&lt;strong>Construcción del grafo&lt;/strong>. Las entidades extraídas se desambiguan, se mergean y se conecta con las relaciones.&lt;/li>
&lt;li>&lt;strong>Detección de comunidades&lt;/strong> con el algoritmo de &lt;strong>Leiden&lt;/strong>. El grafo se particiona en comunidades jerárquicas.&lt;/li>
&lt;li>&lt;strong>Resúmenes por comunidad&lt;/strong>. Para cada comunidad, el LLM genera un resumen.&lt;/li>
&lt;li>&lt;strong>Búsqueda local vs global&lt;/strong>. &lt;em>Local&lt;/em>: traversal vecindario para queries sobre entidades específicas. &lt;em>Global&lt;/em>: map-reduce sobre resúmenes de comunidades para queries temáticas.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>El precio&lt;/strong>: la construcción del KG cuesta del orden de 5-20× más tokens que un pase de embeddings del mismo corpus. Para un corpus de 1 millón de chunks con embeddings &lt;code>bge-m3&lt;/code> (un día de cómputo en RTX 4090), un GraphRAG puro requiere típicamente 1-3 semanas de compute en LLM-extractor (Qwen2.5-72B o similar). La variante &lt;strong>LazyGraphRAG&lt;/strong> (mid-2025) demora la generación de resúmenes a query-time y reduce el coste de construcción en un orden de magnitud.&lt;/p>
&lt;h3 id="lightrag">LightRAG&lt;/h3>
&lt;p>&lt;code>HKUDS/LightRAG&lt;/code> (HKU, &lt;strong>arXiv:2410.05779&lt;/strong>, octubre 2024, EMNLP 2025). Mejoras prácticas sobre GraphRAG canónico:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Dual-level retrieval&lt;/strong>. Cada query genera tanto &lt;em>low-level keywords&lt;/em> (entidades específicas) como &lt;em>high-level keywords&lt;/em> (temas). El sistema busca por ambos y los fusiona. Captura tanto preguntas factuales como temáticas en el mismo pipeline.&lt;/li>
&lt;li>&lt;strong>Actualizaciones incrementales&lt;/strong>. Inserción de nuevos chunks sin reconstruir el grafo completo. GraphRAG canónico requiere reconstrucción periódica.&lt;/li>
&lt;li>&lt;strong>Coste reportado&lt;/strong>: comparativamente más barato que GraphRAG al servir queries similares.&lt;/li>
&lt;/ul>
&lt;p>Es el GraphRAG &lt;strong>operacionalmente más razonable&lt;/strong> cuando el corpus muta.&lt;/p>
&lt;h3 id="hipporag-2">HippoRAG 2&lt;/h3>
&lt;p>OSU-NLP-Group, &lt;strong>arXiv:2502.14802&lt;/strong> (feb 2025; HippoRAG original NeurIPS'24). Inspirado en el modelo de indexación hipocampal de la memoria humana:&lt;/p>
&lt;ul>
&lt;li>Construye un KG abierto y mantiene además los chunks originales.&lt;/li>
&lt;li>Para cada query, extrae entidades y ejecuta &lt;strong>Personalized PageRank&lt;/strong> sobre el grafo seeded por esas entidades — el PageRank &amp;ldquo;marca&amp;rdquo; los nodos relevantes y, transitivamente, los chunks asociados.&lt;/li>
&lt;li>Reportado &lt;strong>+7% en tareas de memoria asociativa&lt;/strong> sobre embedders SOTA, con &lt;strong>coste de indexación significativamente menor&lt;/strong> que GraphRAG, RAPTOR y LightRAG.&lt;/li>
&lt;/ul>
&lt;p>Es el GraphRAG más eficiente para corpora donde &amp;ldquo;qué chunks son relevantes a qué entidades&amp;rdquo; importa más que &amp;ldquo;cuál es la estructura semántica del corpus&amp;rdquo;.&lt;/p>
&lt;h3 id="kag--openspg">KAG / OpenSPG&lt;/h3>
&lt;p>Ant Group + OpenKG, &lt;strong>arXiv:2409.13731&lt;/strong> (sep 2024). Diferencia clave con los anteriores: &lt;strong>KAG es ontology-grounded&lt;/strong>. No deja que el LLM invente la TBox; la TBox la declara el dominio (FIBO, SNOMED, ontología corporativa) y el LLM solo puebla la ABox conforme a ese esquema. Cuatro pilares:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Representación amigable al LLM&lt;/strong> — el esquema se expone en formato que el LLM puede consumir como contexto.&lt;/li>
&lt;li>&lt;strong>Índice mutuo entre KG y chunks&lt;/strong> — cada nodo del KG enlaza a los chunks donde aparece.&lt;/li>
&lt;li>&lt;strong>Razonamiento lógico-formal híbrido&lt;/strong> — combina LLM con motor de reglas declarativo.&lt;/li>
&lt;li>&lt;strong>Alineamiento semántico&lt;/strong> — desambiguación de entidades contra el catálogo ontológico.&lt;/li>
&lt;/ol>
&lt;p>Reportado &lt;strong>+19.6% F1 en 2WikiMultiHopQA, +33.5% en HotpotQA&lt;/strong> sobre RAG baseline. Desplegado en Q&amp;amp;A de e-gobierno y e-salud de Ant en producción.&lt;/p>
&lt;p>&lt;strong>KAG es el GraphRAG que sí funciona cuando el dominio tiene una ontología estable&lt;/strong> (finanzas, salud, gobierno). GraphRAG canónico gana cuando el corpus es exploratorio y no existe TBox previa.&lt;/p>
&lt;h3 id="otros-del-panorama">Otros del panorama&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>nano-GraphRAG&lt;/strong>: port Python ligero de GraphRAG; ideal para prototipos.&lt;/li>
&lt;li>&lt;strong>Think-on-Graph (ToG) / GraphReader&lt;/strong>: agentes que &lt;em>planean traversal de hops&lt;/em> sobre el KG en vez de retrieval single-shot. Mejores en multi-hop QA.&lt;/li>
&lt;li>&lt;strong>Neo4j LLM Graph Builder&lt;/strong> + integración LangChain: el camino de menor resistencia para empresas con Neo4j ya operativo.&lt;/li>
&lt;/ul>
&lt;h2 id="ontologías-verticales-que-sí-se-usan-en-producción">Ontologías verticales que sí se usan en producción&lt;/h2>
&lt;p>Tres ontologías cubren el 90% de casos verticales en mid-2026:&lt;/p>
&lt;h3 id="fibo--financial-industry-business-ontology">FIBO — Financial Industry Business Ontology&lt;/h3>
&lt;p>EDM Council + OMG, &lt;strong>MIT license, OWL DL&lt;/strong>. Production release Q1/2026 contiene &lt;strong>2.446 clases&lt;/strong> distribuidas en Foundations, Business Entities, Securities, Derivatives, Loans, etc. Usado en producción para:&lt;/p>
&lt;ul>
&lt;li>KYC entity resolution: desambiguación de organizaciones legales (&lt;code>fibo-be-le-fbo:FormalBusinessOrganization&lt;/code>).&lt;/li>
&lt;li>Clasificación de instrumentos financieros (&lt;code>fibo-sec-sec-bsk:Basket&lt;/code>, &lt;code>fibo-der-drc-cds:CreditDefaultSwap&lt;/code>).&lt;/li>
&lt;li>Reporting regulatorio: mapeo de campos contra el esquema canónico.&lt;/li>
&lt;/ul>
&lt;p>Para un RAG corporativo en finanzas, &lt;strong>FIBO es el esquema de tipos que cualquier extracción debe satisfacer&lt;/strong>. Sin FIBO, dos chunks que hablan de &amp;ldquo;swap&amp;rdquo; pueden ser un swap de tipos de interés o uno de divisas.&lt;/p>
&lt;h3 id="snomed-ct">SNOMED CT&lt;/h3>
&lt;p>IHTSDO/SNOMED International. Releases mensuales (la International Edition de mayo de 2026 publicada el 15 de mayo). Aproximadamente &lt;strong>350.000+ conceptos activos&lt;/strong> en OWL 2 EL. &lt;strong>Licencia gratuita en países miembros&lt;/strong> (España es miembro vía CSI / Ministerio de Sanidad), comercial fuera. En producción:&lt;/p>
&lt;ul>
&lt;li>Codificación clínica asistida: el LLM propone códigos SNOMED y el sistema valida contra la ontología.&lt;/li>
&lt;li>Búsqueda cross-lingüe en historiales: &lt;code>Diabetes mellitus type 2&lt;/code> y &lt;code>Diabetes mellitus tipo 2&lt;/code> resuelven al mismo concepto (&lt;code>73211009&lt;/code>).&lt;/li>
&lt;li>Compliance HIPAA / RGPD salud: la trazabilidad de qué tipo de dato clínico maneja cada componente.&lt;/li>
&lt;/ul>
&lt;h3 id="schemaorg">schema.org&lt;/h3>
&lt;p>CC-BY-SA, ~800 tipos, JSON-LD nativo. La ontología de la web. Usado en cualquier RAG sobre crawls públicos para tipar &lt;code>Product&lt;/code>, &lt;code>Article&lt;/code>, &lt;code>Person&lt;/code>, &lt;code>Organization&lt;/code> desde los microformatos que el corpus ya trae embebidos.&lt;/p>
&lt;h3 id="las-otras-a-tener-en-el-radar">Las otras a tener en el radar&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Ontología&lt;/th>
&lt;th>Dominio&lt;/th>
&lt;th>Licencia&lt;/th>
&lt;th>Cuándo usarla&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>IEC 81346&lt;/strong>&lt;/td>
&lt;td>sistemas industriales (designación =K1-Q1)&lt;/td>
&lt;td>propietario IEC&lt;/td>
&lt;td>CMDB-as-graph, planta industrial&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>GS1&lt;/strong>&lt;/td>
&lt;td>cadena de suministro (GTIN, GLN, SSCC)&lt;/td>
&lt;td>membership; web vocab libre&lt;/td>
&lt;td>trazabilidad EUDR, retail&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>NIEM&lt;/strong>&lt;/td>
&lt;td>interoperabilidad gov US&lt;/td>
&lt;td>CC0&lt;/td>
&lt;td>integración gov-to-gov&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Wikidata&lt;/strong>&lt;/td>
&lt;td>KB universal (~115M items)&lt;/td>
&lt;td>CC0&lt;/td>
&lt;td>entity linking universal&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>ENS RD 311/2022 Anexo I-II&lt;/strong>&lt;/td>
&lt;td>seguridad ESP sector público&lt;/td>
&lt;td>BOE público&lt;/td>
&lt;td>clasificación de activos en cualquier despliegue ENS&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>EU AI Act Anexo III&lt;/strong>&lt;/td>
&lt;td>8 áreas de alto riesgo&lt;/td>
&lt;td>EU regulation&lt;/td>
&lt;td>tagging de compliance EU&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Para un cliente español del sector público con sistemas IA, &lt;strong>la ontología mínima que conviene tener formalizada es la unión ENS Anexo I + EU AI Act Anexo III + ISO 42001 Annex A&lt;/strong>. Ese mapeo se genera una vez, se mantiene como artefacto versionado en el repo de gobierno IA y se enlaza desde el lineage de cada modelo desplegado.&lt;/p>
&lt;h2 id="stack-open-source-on-prem-2026">Stack open source on-prem 2026&lt;/h2>
&lt;p>El landscape de implementación se divide en triple stores RDF, property graphs y herramientas auxiliares.&lt;/p>
&lt;h3 id="triple-stores-rdf--sparql">Triple stores RDF / SPARQL&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Stack&lt;/th>
&lt;th>Licencia&lt;/th>
&lt;th>Notas operativas&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>Apache Jena Fuseki&lt;/strong>&lt;/td>
&lt;td>Apache 2.0&lt;/td>
&lt;td>Referencia open. Storage TDB2. Releases trimestrales. El default razonable.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Eclipse RDF4J&lt;/strong>&lt;/td>
&lt;td>EDL/BSD-like&lt;/td>
&lt;td>Framework Java + servidor (Sesame-derived). Maduro.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Virtuoso Open Source&lt;/strong>&lt;/td>
&lt;td>GPLv2&lt;/td>
&lt;td>Alto rendimiento. La edición Community no incluye clustering.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Ontotext GraphDB Free&lt;/strong>&lt;/td>
&lt;td>EULA propietaria, gratuita hasta 2 queries concurrentes&lt;/td>
&lt;td>Razonamiento OWL 2 RL fuerte. &lt;strong>Cap operacional en concurrencia&lt;/strong>.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Stardog&lt;/strong>&lt;/td>
&lt;td>propietario&lt;/td>
&lt;td>Sin tier gratuito de producción genuino en 2026 — solo developer.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Blazegraph&lt;/strong>&lt;/td>
&lt;td>discontinuado&lt;/td>
&lt;td>Wikidata está migrando a Qlever / otros. &lt;strong>No empezar proyecto nuevo&lt;/strong>.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="property-graphs-cypher--gremlin">Property graphs (Cypher / Gremlin)&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Stack&lt;/th>
&lt;th>Licencia&lt;/th>
&lt;th>Notas operativas&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>Neo4j Community Edition&lt;/strong>&lt;/td>
&lt;td>&lt;strong>GPLv3&lt;/strong> (con histórico Commons Clause en algunos artefactos); Enterprise cerrado&lt;/td>
&lt;td>Vector index nativo desde 5.11. &lt;strong>Cypher 25&lt;/strong> añade cláusula &lt;code>SEARCH&lt;/code>. &lt;strong>Cypher AI procedures&lt;/strong> (dic 2025) integran LLM calls y embedding generation en la query. &lt;strong>Implicación AGPL&lt;/strong>: si redistribuyes un SaaS que expone funcionalidad de Neo4j Community puede exigir disclosure del source — verifica con legal.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Memgraph&lt;/strong>&lt;/td>
&lt;td>BSL → Apache tras 4 años&lt;/td>
&lt;td>In-memory, Cypher. Más rápido que Neo4j para workloads de query intensivos.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>NebulaGraph&lt;/strong>&lt;/td>
&lt;td>Apache 2.0&lt;/td>
&lt;td>Distribuido. Para tamaños grandes.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>ArangoDB&lt;/strong>&lt;/td>
&lt;td>Apache 2.0 (Community); features migradas a Enterprise post-3.12&lt;/td>
&lt;td>Multi-modelo (graph + document).&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>KuzuDB&lt;/strong>&lt;/td>
&lt;td>MIT&lt;/td>
&lt;td>&lt;strong>Kùzu Inc. archivó el repo upstream en oct-2025&lt;/strong>. Forks comunitarios: &lt;code>bighorn&lt;/code> (Kineviz), &lt;code>ryugraph&lt;/code>. &lt;strong>Considera el upstream sin mantenimiento.&lt;/strong>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="híbrido-vector--grafo">Híbrido vector + grafo&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Neo4j 5.x con HNSW nativo&lt;/strong>: vector como propiedad de nodo, búsqueda dentro de Cypher. La opción más integrada.&lt;/li>
&lt;li>&lt;strong>Memgraph + pgvector&lt;/strong>: dos stacks, dos puntos de operación.&lt;/li>
&lt;li>&lt;strong>Qdrant con payload de grafo&lt;/strong>: no es un grafo de verdad, pero permite filtros tipo k-hop básicos sobre payload.&lt;/li>
&lt;/ul>
&lt;h3 id="editores-y-herramientas">Editores y herramientas&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Protégé&lt;/strong> (Stanford, BSD): editor de ontologías de facto. Suite con HermiT, Pellet, ELK reasoners.&lt;/li>
&lt;li>&lt;strong>TopBraid Composer&lt;/strong>: comercial; útil si ya está en la organización.&lt;/li>
&lt;li>&lt;strong>Atomgraph&lt;/strong>: editor web LGPL.&lt;/li>
&lt;/ul>
&lt;h3 id="construcción-del-kg-con-llm">Construcción del KG con LLM&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>GLiNER / GLiREL&lt;/strong> (Apache 2.0): NER y relation extraction zero-shot. &lt;strong>Mucho más baratos que LLM-extractor&lt;/strong> (10-100× menos tokens).&lt;/li>
&lt;li>&lt;strong>REBEL&lt;/strong> (MIT): joint entity + relation extraction basado en BART. SOTA durante años, hoy superado por LLM-extractors pero sigue siendo razonable para baseline.&lt;/li>
&lt;li>&lt;strong>LLM-extractor con structured output&lt;/strong>: &lt;code>vLLM + XGrammar&lt;/code> o &lt;code>Outlines&lt;/code> enforcing un JSON Schema derivado de SHACL. XGrammar es el backend por defecto de vLLM / SGLang / TensorRT-LLM desde marzo 2026, con &amp;lt;40 µs/token de overhead.&lt;/li>
&lt;/ul>
&lt;h3 id="sparql-clients">SPARQL clients&lt;/h3>
&lt;p>&lt;code>rdflib&lt;/code> (Python, BSD), Apache Jena CLI, &lt;strong>Comunica&lt;/strong> (MIT, JS, federación SPARQL nativa).&lt;/p>
&lt;h2 id="cinco-patrones-de-integración-llm--ontología">Cinco patrones de integración LLM × ontología&lt;/h2>
&lt;p>Casi todo lo útil cabe en cinco patrones repetibles.&lt;/p>
&lt;h3 id="1-extracción-guiada-por-esquema">1. Extracción guiada por esquema&lt;/h3>
&lt;p>El LLM emite &lt;strong>JSON conforme a un schema derivado de la ontología&lt;/strong>, validado en el decoder con &lt;a href="https://blog.lo0.es/posts/structured-output-fundamentos/">structured output&lt;/a>. La salida es ABox tipada lista para insertar como triplas:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">schema&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">derive_json_schema_from_shacl&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;PersonShape.ttl&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># El LLM solo puede emitir tokens que mantengan la salida válida.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">extracted&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llm&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">generate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">prompt&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">document&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">schema&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">schema&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">graph&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_triples&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">jsonld_to_rdf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">extracted&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Coste: prácticamente cero overhead por token con XGrammar; eliminación efectiva de &amp;ldquo;salidas que no validan&amp;rdquo;.&lt;/p>
&lt;h3 id="2-text-to-sparql-con-firewall-semántico">2. Text-to-SPARQL con firewall semántico&lt;/h3>
&lt;p>El LLM genera SPARQL; &lt;strong>un firewall semántico&lt;/strong> valida cada predicado y clase contra el TBox antes de ejecutar la query:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">sparql_text&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llm&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">generate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">prompt&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">user_query&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">context&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">ontology_summary&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">query&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sparql_text&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">predicate&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">query&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">predicates&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">predicate&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">ontology&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">declared_predicates&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">raise&lt;/span> &lt;span class="n">UnknownPredicate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">predicate&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">endpoint&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">execute&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">query&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Captura el patrón clásico del LLM inventando un predicado plausible que no existe en la ontología, &lt;strong>antes de tocar el triple store&lt;/strong>.&lt;/p>
&lt;h3 id="3-retrieval-híbrido-dense--sparse--kg-con-rrf">3. Retrieval híbrido dense + sparse + KG con RRF&lt;/h3>
&lt;p>El &lt;a href="https://blog.lo0.es/posts/rag-reranker-hybrid-retrieval-fundamentos/">reranker hybrid retrieval&lt;/a> se amplía con un cuarto canal: traversal en el KG seeded por las entidades extraídas de la query. Los rankings de los cuatro canales se fusionan con &lt;strong>Reciprocal Rank Fusion&lt;/strong>:&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-math" data-lang="math">\text{RRF}(d) = \sum_{c \in \{\text{dense}, \text{sparse}, \text{colbert}, \text{kg}\}} \frac{1}{k + \text{rank}_c(d)}
&lt;/code>&lt;/pre>&lt;p>con &lt;code>k=60&lt;/code> típico. El canal KG cubre exactamente las queries que rompen los otros tres: queries con entidades nombradas que el dense malinterpreta o que aparecen rara vez en el corpus.&lt;/p>
&lt;h3 id="4-reranking-por-distancia-de-grafo">4. Reranking por distancia de grafo&lt;/h3>
&lt;p>Entre los candidatos del primer comité de retrieval, &lt;strong>se prefieren los chunks cuyas entidades estén dentro de k hops en el KG&lt;/strong> de las entidades de la query. Implementación práctica: añadir un score &lt;code>graph_distance&lt;/code> y fusionarlo en el reranker:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">graph_distance_score&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chunk&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">query_entities&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chunk_entities&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">chunk&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;entities&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">distances&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">shortest_path_length&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">kg&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">qe&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">ce&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">qe&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">query_entities&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">ce&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">chunk_entities&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nb">min&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">distances&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="5-tool-calling-tipado--evals-estratificados">5. Tool calling tipado + evals estratificados&lt;/h3>
&lt;p>&lt;strong>Tools&lt;/strong> declaran sus argumentos como clases ontológicas. Antes de invocar, los argumentos pasan SHACL validation. Evita el bug clásico del agente llamando &lt;code>buscar_cliente(cliente_id=&amp;quot;cliente del que se quejó ayer&amp;quot;)&lt;/code> — un string libre cuando esperaba un IRI.&lt;/p>
&lt;p>&lt;strong>Evals estratificados&lt;/strong> por &lt;code>rdf:type&lt;/code> o &lt;code>skos:Concept&lt;/code>: cada query del golden set lleva su clase ontológica como label, las métricas se reportan por clase, y la accuracy global se complementa con cobertura por clase. Es el mecanismo que &lt;a href="https://blog.lo0.es/posts/evals-llm-la-capa-despues-de-tracing/">evals&lt;/a> recomienda y la ontología hace operativo.&lt;/p>
&lt;h2 id="implicaciones-para-inferencia-on-premise">Implicaciones para inferencia on-premise&lt;/h2>
&lt;p>El triple store o property graph &lt;strong>no come GPU&lt;/strong>: corre en CPU + NVMe. Lo que sí compite por GPU es el &lt;strong>LLM-extractor&lt;/strong> que construye y mantiene el KG.&lt;/p>
&lt;h3 id="en-la-rtx-4090-24-gb">En la RTX 4090 (24 GB)&lt;/h3>
&lt;p>Setup razonable para PoC y sedes pequeñas:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">GPU 24 GB ┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ├─ TEI bge-m3 (dense + sparse + colbert) │ ~6 GB VRAM
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ├─ vLLM Qwen2.5-7B-Instruct AWQ Q4 (LLM principal) │ ~8 GB VRAM
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> └─ Carga puntual: vLLM Qwen2.5-7B-Instruct para extracción nocturna │ comparte VRAM en otra ventana
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">CPU/RAM ┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ├─ Apache Jena Fuseki (TBox + ABox del KG corporativo) │ ~2 GB RAM por M triplas
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ├─ Qdrant (denso + sparse + colbert) │ ~3 GB RAM por M chunks
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> └─ GLiNER + REBEL para extracción rápida en batch │ CPU-only
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Para corpora de hasta unos pocos millones de chunks, una RTX 4090 hace el trabajo combinando GLiNER/REBEL en CPU para extracción masiva (barato pero menos preciso) y el LLM en GPU para casos críticos.&lt;/p>
&lt;h3 id="en-el-cluster-4h100-80-gb">En el cluster 4×H100 80 GB&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">H100 #1 (80 GB) ── vLLM Qwen3-72B-Instruct AWQ + Qwen2.5-7B speculative │ LLM principal
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">H100 #2 (80 GB) ── vLLM gte-Qwen2-7B-instruct (embedding 32k ctx) │ embedder grande
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">H100 #3 (80 GB) ── vLLM Qwen2.5-32B-Instruct (extractor KG dedicado) │ construcción + mantenimiento KG
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">H100 #4 (80 GB) ── Hold-out para canary y evals offline │ ver post canary
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Apache Jena Fuseki cluster (3 nodos CPU + NVMe RAID)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ├─ Ontología corporativa (TBox)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ├─ ABox (cientos de millones de triplas)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> └─ FIBO / ENS / EU AI Act como named graphs
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Qdrant cluster (3 nodos CPU + NVMe)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ├─ Chunks indexados con triplas en payload
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> └─ Lineage hacia nodos del KG
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>La H100 dedicada al extractor KG es el pago real del enfoque GraphRAG. Si el corpus es estable, esa H100 puede dedicarse a evals offline o speculative decoding. Si el corpus muta a diario, está ocupada manteniendo el grafo en línea.&lt;/p>
&lt;h2 id="las-siete-trampas-operativas">Las siete trampas operativas&lt;/h2>
&lt;ol>
&lt;li>&lt;strong>Sobreelevar SKOS a OWL DL por ego académico&lt;/strong>. La mayoría de &amp;ldquo;ontologías corporativas&amp;rdquo; son taxonomías que no requieren razonamiento de description logic. Una SKOS con &lt;code>skos:broader&lt;/code>/&lt;code>skos:narrower&lt;/code> y &lt;code>skos:prefLabel&lt;/code> por idioma cubre el 80% de los casos. OWL DL solo tiene sentido cuando hay axiomas de consistencia que el reasoner debe verificar. &lt;strong>Empieza por SKOS, sube a OWL EL/RL si lo necesitas, evita OWL DL salvo necesidad probada.&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Construir un KG de todo el corpus&lt;/strong>. GraphRAG canónico aplicado a 100 millones de chunks cuesta como entrenar un modelo pequeño. La alternativa correcta es &lt;strong>HippoRAG 2 / LightRAG / KAG&lt;/strong> según el caso o &lt;strong>GraphRAG solo sobre el subset crítico&lt;/strong> del corpus. La regla: si el coste de construcción excede el coste anual de servir el modelo, has elegido la herramienta equivocada.&lt;/li>
&lt;li>&lt;strong>TBox creada por LLM sin gobernanza&lt;/strong>. Microsoft GraphRAG genera la TBox emergente desde los datos. Para un corpus exploratorio funciona; para un dominio regulado (finanzas, salud, gobierno) &lt;strong>la TBox no se descubre, se declara&lt;/strong> — FIBO, SNOMED, ENS. KAG es la elección correcta en esos casos.&lt;/li>
&lt;li>&lt;strong>Olvidar el mantenimiento del KG cuando el corpus cambia&lt;/strong>. Los nuevos chunks introducen entidades nuevas. Si no hay proceso de &lt;strong>reconciliación de entidades&lt;/strong> (desambiguación, merging), el grafo acumula duplicados de la misma entidad con IRIs distintos y la calidad colapsa silenciosamente en seis meses. LightRAG tiene primitivas para esto; GraphRAG canónico requiere reconstrucción periódica.&lt;/li>
&lt;li>&lt;strong>JSON Schema desincronizado del SHACL&lt;/strong>. Si la ontología vive en RDF/SHACL y los structured outputs vienen de un JSON Schema escrito a mano, &lt;strong>se desincronizan&lt;/strong>. Lo correcto es &lt;strong>generar el JSON Schema desde el SHACL&lt;/strong> con herramientas como &lt;code>shacl-to-json-schema&lt;/code> y regenerarlo en CI cada vez que cambia el shape.&lt;/li>
&lt;li>&lt;strong>Neo4j Community licenciado mal&lt;/strong>. GPLv3 implica que cualquier modificación que distribuyas tiene que liberarse con la misma licencia. Si vas a redistribuir un producto que embebe Neo4j Community, &lt;strong>verifica con legal o usa una alternativa con licencia más permisiva&lt;/strong> (Memgraph BSL, Apache Jena para RDF, Kùzu fork bighorn).&lt;/li>
&lt;li>&lt;strong>Ontología de compliance no enlazada al stack técnico&lt;/strong>. Tu mapeo de ENS / ISO 42001 / EU AI Act vive en un Excel del equipo de gobierno. Tu inventario de modelos, datasets y endpoints vive en otro sistema. Sin enlace formal entre ambos, ningún cambio del stack dispara la revisión de compliance correspondiente. &lt;strong>El mapeo va al grafo, no al Excel&lt;/strong>.&lt;/li>
&lt;/ol>
&lt;h2 id="conclusión">Conclusión&lt;/h2>
&lt;p>Una ontología no es una alternativa al RAG; es la nomenclatura que hace comparables sus piezas. Sin ella, el corpus se cura con categorías ad-hoc, los embeddings perforan documentos sin enriquecerse, los evals miden la media en vez de la varianza por clase, el guardrail bloquea por listas en vez de por tipos, el incident response agrupa mal porque cada alerta nombra a su manera, y el compliance es un Excel desincronizado del sistema. Las seis etapas LLMOps &lt;strong>están todas mejor cuando comparten vocabulario&lt;/strong>, y compartir vocabulario quiere decir formalizar una ontología corporativa pequeña, alineada con los marcos verticales pertinentes (FIBO, SNOMED, schema.org, ENS, EU AI Act), serializada en JSON-LD para que el código la consuma sin fricción, validada con SHACL en cada interface y consultada con SPARQL cuando hace falta razonar. GraphRAG en sus variantes 2026 (Microsoft v2, LightRAG, HippoRAG 2, KAG) es una palanca complementaria, no el plato principal: el plato principal es la nomenclatura formal compartida. Lo demás —Neo4j vs Jena, OWL DL vs SKOS, GLiNER vs LLM-extractor— son decisiones técnicas que se resuelven mejor cuando ya hay claridad sobre qué nomenclatura hace falta. Linneo descubrió esto en 1735 y la biología no ha vuelto atrás; el campo LLM lo está descubriendo en 2026 y tampoco volverá.&lt;/p>
&lt;h2 id="ver-también">Ver también&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://blog.lo0.es/posts/pipeline-llmops-seis-etapas/">El pipeline LLMOps de seis etapas&lt;/a> — el mapa maestro de las seis etapas que este post atraviesa transversalmente.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/rag-corpus-curation-fundamentos/">RAG corpus curation: el bibliotecario activo&lt;/a> — la curación se vuelve curación dirigida por ontología cuando hay TBox declarado.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/embeddings-modelos-2026-dense-sparse-multivector/">Embeddings en 2026: las tres familias&lt;/a> — los embeddings se enriquecen con metadatos tipados desde la ontología.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/rag-reranker-hybrid-retrieval-fundamentos/">Reranker y hybrid retrieval&lt;/a> — el KG es el cuarto canal de retrieval, fusionado vía RRF junto a dense / sparse / multi-vector.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/structured-output-fundamentos/">Structured output&lt;/a> — los JSON Schemas con los que se construye el KG desde el LLM derivan de SHACL.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/evals-llm-la-capa-despues-de-tracing/">Evals para LLMs&lt;/a> — las métricas estratificadas por clase ontológica son la palanca operacional que la ontología habilita.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/tracing-llm-otel-genai/">Tracing LLM con OpenTelemetry GenAI&lt;/a> — los spans llevan atributos tipados contra el TBox.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/runbooks-incident-response-llm-keep-kafka/">Runbooks de incident response&lt;/a> — la taxonomía formal de incidentes habilita la deduplicación de Keep + Kafka.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/router-inferencia-llm-gateway-l7/">Router de inferencia LLM&lt;/a> — el routing semántico por clase ontológica.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/canary-blue-green-shadow-modelos-llm/">Canary, blue-green y shadow&lt;/a> — el canary por clase reduce el blast radius.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/controles-tecnicos-ens-42001-eu-ai-act/">Controles técnicos ENS × ISO 42001 × EU AI Act&lt;/a> — cada marco regulatorio &lt;em>es&lt;/em> una ontología y se mapea como tal.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/iso-42001-aims-llm-on-premise/">ISO/IEC 42001: AIMS&lt;/a> — el Annex A es una jerarquía de controles formalizable como SKOS.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/eu-ai-act-mapeo-arquitectura-llm-on-premise/">EU AI Act: expediente técnico&lt;/a> — el Anexo III es una clasificación enumerable mapeable a las clases del sistema.&lt;/li>
&lt;/ul>
&lt;h2 id="referencias">Referencias&lt;/h2>
&lt;ul>
&lt;li>W3C. &lt;em>RDF 1.1 Concepts and Abstract Syntax&lt;/em>. &lt;a href="https://www.w3.org/TR/rdf11-concepts/">https://www.w3.org/TR/rdf11-concepts/&lt;/a>&lt;/li>
&lt;li>W3C. &lt;em>OWL 2 Profiles (EL, QL, RL, DL)&lt;/em>. &lt;a href="https://www.w3.org/TR/owl2-profiles/">https://www.w3.org/TR/owl2-profiles/&lt;/a>&lt;/li>
&lt;li>W3C. &lt;em>SHACL — Shapes Constraint Language&lt;/em>. &lt;a href="https://www.w3.org/TR/shacl/">https://www.w3.org/TR/shacl/&lt;/a>&lt;/li>
&lt;li>W3C. &lt;em>SKOS Reference&lt;/em>. &lt;a href="https://www.w3.org/TR/skos-reference/">https://www.w3.org/TR/skos-reference/&lt;/a>&lt;/li>
&lt;li>W3C. &lt;em>JSON-LD 1.1&lt;/em>. &lt;a href="https://www.w3.org/TR/json-ld11/">https://www.w3.org/TR/json-ld11/&lt;/a>&lt;/li>
&lt;li>W3C. &lt;em>SPARQL 1.1 Query Language&lt;/em>. &lt;a href="https://www.w3.org/TR/sparql11-query/">https://www.w3.org/TR/sparql11-query/&lt;/a>&lt;/li>
&lt;li>Edge et al. &lt;em>From Local to Global: A Graph RAG Approach to Query-Focused Summarization&lt;/em>. Microsoft Research, 2024. &lt;a href="https://arxiv.org/abs/2404.16130">https://arxiv.org/abs/2404.16130&lt;/a>&lt;/li>
&lt;li>Microsoft GraphRAG. &lt;a href="https://github.com/microsoft/graphrag">https://github.com/microsoft/graphrag&lt;/a>&lt;/li>
&lt;li>Guo et al. &lt;em>LightRAG: Simple and Fast Retrieval-Augmented Generation&lt;/em>. arXiv:2410.05779, 2024. &lt;a href="https://arxiv.org/abs/2410.05779">https://arxiv.org/abs/2410.05779&lt;/a>&lt;/li>
&lt;li>Gutiérrez et al. &lt;em>HippoRAG: Neurobiologically Inspired Long-Term Memory for Large Language Models&lt;/em>. NeurIPS 2024. &lt;a href="https://arxiv.org/abs/2405.14831">https://arxiv.org/abs/2405.14831&lt;/a>&lt;/li>
&lt;li>Gutiérrez et al. &lt;em>From RAG to Memory: Non-Parametric Continual Learning for Large Language Models&lt;/em> (HippoRAG 2). arXiv:2502.14802, 2025. &lt;a href="https://arxiv.org/abs/2502.14802">https://arxiv.org/abs/2502.14802&lt;/a>&lt;/li>
&lt;li>Liang et al. &lt;em>KAG: Boosting LLMs in Professional Domains via Knowledge Augmented Generation&lt;/em>. arXiv:2409.13731, 2024. &lt;a href="https://arxiv.org/abs/2409.13731">https://arxiv.org/abs/2409.13731&lt;/a>&lt;/li>
&lt;li>OpenSPG / KAG. &lt;a href="https://github.com/OpenSPG/openspg">https://github.com/OpenSPG/openspg&lt;/a>&lt;/li>
&lt;li>EDM Council. &lt;em>Financial Industry Business Ontology (FIBO)&lt;/em>. &lt;a href="https://spec.edmcouncil.org/fibo/">https://spec.edmcouncil.org/fibo/&lt;/a>&lt;/li>
&lt;li>SNOMED International. &lt;a href="https://www.snomed.org/">https://www.snomed.org/&lt;/a>&lt;/li>
&lt;li>schema.org. &lt;a href="https://schema.org/">https://schema.org/&lt;/a>&lt;/li>
&lt;li>Real Decreto 311/2022, de 3 de mayo, por el que se regula el Esquema Nacional de Seguridad. BOE-A-2022-7191. &lt;a href="https://www.boe.es/eli/es/rd/2022/05/03/311">https://www.boe.es/eli/es/rd/2022/05/03/311&lt;/a>&lt;/li>
&lt;li>&lt;em>Reglamento (UE) 2024/1689 (EU AI Act)&lt;/em>. &lt;a href="https://eur-lex.europa.eu/eli/reg/2024/1689">https://eur-lex.europa.eu/eli/reg/2024/1689&lt;/a>&lt;/li>
&lt;li>&lt;em>ISO/IEC 42001:2023 — Artificial Intelligence Management System&lt;/em>. &lt;a href="https://www.iso.org/standard/81230.html">https://www.iso.org/standard/81230.html&lt;/a>&lt;/li>
&lt;li>Apache Jena. &lt;a href="https://jena.apache.org/">https://jena.apache.org/&lt;/a>&lt;/li>
&lt;li>Neo4j Cypher and AI procedures. &lt;a href="https://neo4j.com/docs/">https://neo4j.com/docs/&lt;/a>&lt;/li>
&lt;li>Protégé. &lt;a href="https://protege.stanford.edu/">https://protege.stanford.edu/&lt;/a>&lt;/li>
&lt;li>GLiNER. &lt;a href="https://github.com/urchade/GLiNER">https://github.com/urchade/GLiNER&lt;/a>&lt;/li>
&lt;li>REBEL. &lt;a href="https://github.com/Babelscape/rebel">https://github.com/Babelscape/rebel&lt;/a>&lt;/li>
&lt;/ul></description></item></channel></rss>