EKG + RAG/LLM para retroalimentación de códigoTrabajo de Fin de Máster · UNED
Validación con SHACL y ShEx

Validación con SHACL y ShEx

Cierro la fase de construcción del grafo con una garantía formal de integridad. Diseñé un grafo de formas SHACL con una sh:NodeShape por clase del esquema, comprobé que el EKG canónico es conforme y demostré que el validador es sensible con un control negativo. Como segundo formalismo de validación de formas, declaro un esquema ShEx equivalente para dos de esas clases.

1La validación en cifras

Estas son las cifras que sostienen el capítulo, todas recalculadas con pyshacl sobre el grafo canónico ekg-python-150.ttl tras el cierre OWL 2 RL.

10
formas sh:NodeShape
0
violaciones sobre el grafo real
6
violaciones en el control negativo
4786
afirmaciones validadas (tras OWL 2 RL)
2
formalismos de formas (SHACL · ShEx)
Qué certifica una validación conforme (y qué no)

Un resultado conforme demuestra que el grafo es estructuralmente íntegro respecto de las invariantes que el modelo declara. No certifica que el contenido sea correcto, es decir, ni que las relaciones entre conceptos sean pedagógicamente acertadas ni que cada enlace a Wikidata apunte a la entidad adecuada. SHACL ofrece una garantía necesaria pero no suficiente, y leo el resultado con esa modestia.

2El grafo de formas: una NodeShape por clase

Organicé el grafo de formas con un principio sistemático, a cada clase relevante del dominio le corresponde una sh:NodeShape cuyo sh:targetClass es esa clase. Así la estructura del grafo de formas refleja como un espejo la del esquema OWL, y cualquier cambio en una clase tiene un único lugar evidente donde traducirse a una restricción. Cada NodeShape agrupa las sh:PropertyShape que describen, propiedad a propiedad, lo que deben cumplir los valores de sus instancias. En total son 10 formas.

Las 10 formas SHACL y sus clases destino Diez NodeShape, cada una con su sh:targetClass: Concepto, Ejercicio, ErrorConceptual, EnvioEstudiante, Recurso, Estudiante, Tema, NivelDominio, EvaluacionActividad y Referencia. Cada forma valida etiquetas obligatorias, tipos de nodo, rangos numéricos y patrones de identificadores. 10 formasSHACL ConceptoEjercicioErrorConceptual EnvioEstudianteRecursoEstudiante TemaNivelDominio EvaluacionActividadReferencia
Las diez sh:NodeShape y sus clases destino (sh:targetClass), representación esquemática con la paleta del proyecto. La clase N-aria EvaluacionActividad recibe una forma específica que comprueba que cada nodo de reificación enlaza con todos sus participantes.

Constraints reforzados

El valor de una validación depende de la exigencia de sus restricciones. Reforcé las formas con tres familias de comprobaciones que elevan el nivel de aseguramiento más allá de la mera existencia de etiquetas.

Las tres familias de constraints reforzados y qué error previene cada una.
Familia de refuerzoMecanismo SHACLQué error previene
Tipo de nodosh:nodeKind (sh:IRI · sh:Literal)que una propiedad de objeto reciba un literal por error, o al revés
Rango numéricosh:minInclusive · sh:maxInclusivevalores acotados (dificultad, puntuaciones) fuera del intervalo admisible
Patrón de identificadorsh:pattern sobre skos:exactMatchenlaces a Wikidata con dominio incorrecto o identificador no Q+dígitos

La forma de conceptos exige una etiqueta rdfs:label con cardinalidad mínima, que los enlaces jerárquicos skos:broader apunten a otros conceptos del grafo y que cada skos:exactMatch case con el patrón de la entidad de datos de Wikidata. La elección de skos:exactMatch frente a owl:sameAs es deliberada, pues evita que el razonador OWL 2 RL fusione el concepto propio con la entidad externa.

3Resultado: conforme y control negativo

Ejecuté pyshacl sobre el grafo canónico con OWL 2 RL aplicado e inferencia RDFS activada durante la propia validación. El informe reporta el grafo como conforme, con cero violaciones, es decir, las 4.786 afirmaciones del grafo enriquecido satisfacen sin excepción todas las formas y todos los constraints reforzados.

Por qué hace falta un control negativo

Un resultado conforme, por sí solo, no prueba que el validador funcione, ya que un grafo de formas mal construido (sin objetivos correctos, con restricciones que nunca se activan) también informaría cero violaciones sobre cualquier entrada. Afirmar la integridad exige demostrar que el validador es sensible, esto es, que detecta las violaciones cuando existen.

Con ese propósito construí un ejemplo inválido en el que introduje seis defectos representativos de las categorías que las formas pretenden capturar. Ejecutado pyshacl sobre ese grafo defectuoso, el informe reporta 6 violaciones, una por cada defecto inyectado, señalando en cada caso el nodo afectado, la propiedad implicada y el constraint incumplido. La coincidencia exacta entre defectos introducidos y violaciones detectadas confirma que el grafo de formas no produce ni falsos negativos ni falsos positivos espurios en este escenario controlado.

Validación SHACL con pyshacl: grafo real frente a control negativo.
Grafo de datosConformeViolacionesLectura
ekg-python-150.ttl (canónico)0estructuralmente íntegro
ejemplo-invalido.ttl (control negativo)No6el validador es sensible
Lectura conjunta

Cero violaciones sobre el grafo canónico y seis sobre el control negativo, leídos juntos, evidencian que la validación es a la vez correcta (el grafo bueno pasa) y sensible (el grafo defectuoso se rechaza con la granularidad esperada). Sin el control negativo el resultado conforme sería ambiguo; con él adquiere fuerza probatoria.

Los seis defectos del control negativo se corresponden con las tres familias de refuerzo descritas arriba.

Defectos inyectados en el control negativo y la familia de constraint que los captura.
Defecto inyectadoFamilia de constraint
Concepto sin la etiqueta rdfs:label obligatoriacardinalidad mínima
skos:exactMatch con identificador de Wikidata que incumple el patrónsh:pattern
Propiedad de objeto cuyo valor es un literal en lugar de un IRIsh:nodeKind
Valor numérico fuera del intervalo admisiblesh:minInclusive / sh:maxInclusive
Omisión de participantes en una relación N-aria reificadacardinalidad de la forma N-aria

Cinco categorías de defecto producen seis violaciones porque uno de los patrones reincide en el ejemplo inválido. El recuento de violaciones del informe es seis, una por cada incumplimiento detectado.

4ShEx como segundo formalismo

Para validar formas con un segundo formalismo declaro un esquema ShEx (Shape Expressions) equivalente a dos de las NodeShape de SHACL, las de Concepto y Ejercicio. Cubre el mismo tipo de invariantes (etiqueta obligatoria, pertenencia a tema, jerarquía conceptual opcional, enlaces a Wikidata y rango de dificultad acotado entre 1 y 5) en la sintaxis ShExC. La validación efectiva del entregable se hace con pyshacl; el esquema ShEx se incluye como alternativa de validación de formas y es comprobable en RDFShape contra los mismos grafos de datos.

Correspondencia entre las dos formas SHACL y su equivalente ShEx (ekg-shapes.shex).
RestricciónSHACLShEx
Etiqueta obligatoria del conceptosh:minCount 1 sobre rdfs:labelrdfs:label rdfs:Literal+
Pertenencia a un temash:minCount 1 sobre pyedu:perteneceATemapyedu:perteneceATema IRI+
Jerarquía conceptual opcionalsh:nodeKind sh:IRI sobre skos:broaderskos:broader IRI*
Enlace a Wikidata opcionalsh:pattern de skos:exactMatchskos:exactMatch [ wd:~ ]*
Dificultad acotada del ejerciciosh:minInclusive 1 · sh:maxInclusive 5xsd:integer MININCLUSIVE 1 MAXINCLUSIVE 5

Estas son las dos formas en sintaxis ShExC, literales del fichero ontologia/ekg-shapes.shex.

PREFIX pyedu: <https://w3id.org/ekg-python/schema#>
PREFIX skos:  <http://www.w3.org/2004/02/skos/core#>
PREFIX rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd:   <http://www.w3.org/2001/XMLSchema#>
PREFIX wd:    <http://www.wikidata.org/entity/>

start = @<ConceptoShape>

<ConceptoShape> {
  rdfs:label            rdfs:Literal+ ;            # al menos una etiqueta
  pyedu:perteneceATema  IRI+ ;                     # al menos un tema
  skos:broader          IRI* ;                     # jerarquía conceptual (opcional)
  skos:exactMatch       [ wd:~ ]* ;                # enlaces a Wikidata (Q...) (opcional)
}

<EjercicioShape> {
  pyedu:cubreConcepto   @<ConceptoShape> + ;       # cubre ≥1 concepto
  pyedu:tieneDificultad xsd:integer MININCLUSIVE 1 MAXINCLUSIVE 5 ;
  pyedu:tieneEnunciado  rdfs:Literal+ ;            # enunciado obligatorio
}
SHACL y ShEx, dos caras de la validación de formas

SHACL y ShEx comparten propósito, describir y comprobar los patrones que un grafo concreto debe satisfacer, bajo una semántica próxima a la hipótesis de mundo cerrado, distinta de la de OWL, que infiere conocimiento bajo mundo abierto. Disponer del mismo conjunto de invariantes en ambos lenguajes hace explícito que la integridad del grafo no depende de una sola herramienta.

5Ver también

Páginas del sitio relacionadas con esta validación.

El grafo de conocimiento

El EKG canónico que se valida aquí: 157 conceptos, 1772 triples afirmados (4786 tras OWL 2 RL), 30 enlaces skos:exactMatch a Wikidata y las 10 formas SHACL.

Recursos y herramientas

El inventario de tecnologías: RDFLib, owlrl y pyshacl como núcleo, y el esquema ShEx equivalente comprobable en RDFShape.

Validación y conclusiones

La otra cara de la validación del proyecto, la del juez LLM y el cierre con conclusiones y trabajo futuro.

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.