EKG + RAG/LLM para retroalimentación de códigoTrabajo de Fin de Máster · UNED
Inferencia y razonamiento

Inferencia y razonamiento

Cuento aquí cómo razono sobre el grafo. Modelé el EKG bajo el perfil OWL 2 RL para que un motor de inferencia pudiera deducir lo que no escribí de forma explícita. La consecuencia se mide bien, el grafo crece de 1772 triples afirmados a 4786 una vez aplicado el cierre, y aparecen relaciones que estaban implícitas en mi modelo y que el razonador hace visibles.

1Materialización por razonamiento

Lo que llamo materializar es pedirle al razonador que calcule todas las consecuencias lógicas de mi grafo y las añada como triples nuevos. Contrasté dos regímenes sobre el mismo fichero canónico ekg-python-150.ttl, sin inferencia (régimen NONE) y con el cierre RDFS/OWL 2 RL. La diferencia es directa, parto de 1772 triples afirmados y termino con 4786 triples después del cierre, es decir 3014 triples inferidos que yo nunca tecleé.

1772
triples afirmados (NONE)
4786
triples tras OWL 2 RL
+3014
triples inferidos por el razonador
157
conceptos (sin inferencia)

Esos 3014 triples no son ruido, provienen de las reglas del perfil, jerarquías de clases y propiedades, dominios y rangos, simetrías e inversas y la maquinaria de SKOS. El grafo afirmado se queda deliberadamente escueto y legible, mientras que el grafo materializado es el que sostiene las consultas que dependen de consecuencias implícitas.

Crecimiento del grafo por materialización: NONE frente a OWL 2 RL Sin inferencia el grafo tiene 1772 triples afirmados. Tras el cierre OWL 2 RL alcanza 4786 triples, de los cuales 3014 son inferidos por el razonador. 478623930 NONEOWL 2 RL 17721772+3014
triples afirmados (1772)triples inferidos (+3014) · Cierre sobre ekg-python-150.ttl con scripts/consultar.py.

2El contraste 0 → 157

El ejemplo que mejor muestra para qué sirve la inferencia es una consulta sencilla, recuperar todo lo que es un concepto del dominio. Sin razonador la consulta ?x a pyedu:Concepto devuelve 0 filas, porque en el grafo afirmado ningún recurso lleva esa etiqueta de tipo de forma directa. Con el cierre RDFS/OWL 2 RL la misma consulta devuelve 157 filas, exactamente los 157 conceptos propios. El salto de 0 a 157 es enteramente fruto del razonamiento sobre la jerarquía de clases que declaré.

Contraste NONE frente a inferencia sobre el grafo canónico ekg-python-150.ttl (regenerado con scripts/consultar.py).
ConsultaSin inferencia (NONE)Con inferencia (OWL 2 RL)
?x a pyedu:Concepto (02)0 filas157 filas
Prerrequisitos transitivos de búsqueda binaria (03)55
CONSTRUCT de prerrequisitos directos (06)340 triples356 triples
Por qué 157 y no 187

El salto se detiene justo en 157 por una decisión semántica deliberada. Los 30 enlaces a Wikidata los escribí con skos:exactMatch y no con owl:sameAs, de modo que el razonador OWL 2 RL no fusiona mi concepto con la entidad de Wikidata. Si hubiese usado owl:sameAs, las 30 entidades externas se habrían inferido también como Concepto. Con skos:exactMatch la consulta con inferencia devuelve solo los 157 conceptos propios.

No toda consulta cambia con la inferencia, los prerrequisitos transitivos de la búsqueda binaria (consulta 03) dan 5 tanto con razonador como sin él, y el CONSTRUCT de prerrequisitos directos (consulta 06) pasa de 340 a 356 triples, un incremento modesto. El razonamiento aflora sobre todo allí donde la consulta depende de tipos, jerarquías o propiedades que dejé implícitas, no en todas partes por igual.

3Motores: owlrl y GraphDB

El cierre lo calculo en local con owlrl sobre rdflib, el mismo apilado que uso para serializar y validar el grafo. Es el motor que produce las cifras canónicas que recojo aquí, 1772 afirmados que pasan a 4786 materializados, y es el que ejecuta mis scripts de consulta. Esta vía no exige ningún servidor, encaja con la naturaleza autocontenida y sin red del entregable.

La alternativa de servidor es GraphDB, que trae su propio razonador OWL 2 RL y permitiría materializar el mismo cierre en una base de datos de triples consultable por SPARQL. En mi entorno de ejecución GraphDB figura como no instalado ni activo, con la carga automatizada lista para ejecutarse, de modo que las cifras que presento proceden del cierre con owlrl, no de GraphDB.

owlrl + rdflib

Razonador OWL 2 RL en proceso, sin servidor. Calcula el cierre 1772 → 4786 y alimenta las consultas de scripts/consultar.py. Es la fuente de las cifras canónicas.

GraphDB

Motor OWL 2 RL de servidor, alternativa para materializar el mismo cierre y servirlo por SPARQL. En el entorno actual no está instalado ni activo, con la carga lista para ejecutar.

4Mundo abierto y sus implicaciones

RDF y OWL operan bajo la hipótesis de mundo abierto. Esto significa que lo que no está afirmado ni se deduce no se considera falso, simplemente se considera desconocido. Es lo contrario de una base de datos relacional, donde lo ausente suele tratarse como inexistente. La consecuencia práctica para mi grafo es que el razonador solo añade lo que se sigue lógicamente de lo que afirmé, nunca niega ni descarta posibilidades por silencio.

El contraste 0 → 157 ilustra esta lógica. Antes del cierre, que un recurso no apareciera como pyedu:Concepto no significaba que no lo fuera, solo que no estaba afirmado todavía. La inferencia hace explícito lo que ya se seguía de mis declaraciones de clase, no inventa hechos nuevos. Por eso encaja bien con un grafo educativo en crecimiento, puedo añadir conceptos y enlaces sin que las consultas previas pasen a ser inválidas.

El mundo abierto no valida, solo deduce

Como el razonamiento no cierra el mundo, no puede por sí solo detectar lo que falta o lo que está mal formado. Esa función la cubro aparte con SHACL, que sí impone restricciones de cierre local sobre las formas que defino. La inferencia OWL 2 RL deduce consecuencias, la validación SHACL comprueba conformidad. Son tareas distintas y complementarias, y el grafo canónico es conforme con cero violaciones.

5Ver también

El grafo de conocimiento

El modelo RDF/OWL 2 RL completo, sus métricas canónicas y la decisión de enlazar a Wikidata con skos:exactMatch que explica el límite de 157.

Sistema RAG

Cómo el grafo materializado provee el subgrafo de contexto que inyectan los sistemas C y D del proyecto.

Resultados

Las métricas de evaluación de los sistemas que se apoyan en el grafo razonado.

Cómo citar

Si este trabajo te resulta útil y quieres referenciarlo, esta es la cita recomendada.

Bueno Junquero, A. (2026). Integración de un grafo de conocimiento educativo con un LLM mediante RAG. Trabajo Fin de Máster, Máster Universitario en Investigación en Inteligencia Artificial, UNED. Director, José Luis Fernández Vindel.