ELAI S.r.l.

Un JSON válido puede pedir algo equivocado: cómo comprobar las propuestas de un agente

¿Diez milímetros o diez centímetros? Un experimento reproducible distingue esquema, límites de dominio y correspondencia con la petición.

Un JSON válido puede pedir algo equivocado: cómo comprobar las propuestas de un agente

Una petición pequeña con una diferencia importante

Imaginemos un asistente de IA que prepara una propuesta de desplazamiento de 10 milímetros. El programa receptor espera un objeto con un valor numérico y una unidad. El asistente devuelve 10 y cm. El JSON se puede analizar, contiene los campos esperados y la cantidad incluso podría estar dentro del intervalo permitido. Sin embargo, describe 100 milímetros. El problema no es una coma ausente: es una petición diferente.

¿Qué demuestra realmente superar un control? Construiremos tres predicados, preguntas cuya respuesta es verdadera o falsa: cumplir el esquema S, respetar el límite B y coincidir con el objetivo I. Una regla imaginaria basta para seguir el razonamiento; las ecuaciones y el código explicitan lo que suele ocultar la expresión “salida válida”. No ejecutamos movimientos, llamadas a máquinas ni acciones empresariales: todo el caso simula propuestas.

Antes del modelo: definir qué debe cumplirse

El objetivo no se deduce de la propia salida del modelo. Es una referencia ya disponible y considerada fiable: 1/100 de metro. El límite de dominio, elegido solo para este ejemplo didáctico, es 3/20 de metro, o 150 milímetros. Son informaciones distintas: el límite acota las propuestas en el modelo del problema, mientras la referencia expresa el desplazamiento solicitado. Estar bajo un techo no equivale a estar en el punto pedido.

Este supuesto delimita el resultado. Mostramos que algunos controles no bastan para verificar una petición estructurada conocida; no demostramos comprensión automática de instrucciones arbitrarias en lenguaje natural. Si el usuario solo dice “muévelo un poco”, falta el objetivo. Una comparación numérica exacta no puede reconstruir información que nunca se proporcionó. Primero hace falta una especificación utilizable y resolver la ambigüedad en su contexto.

Qué exigimos al esquema

JSON es un formato de representación de datos; JSON Schema describe restricciones que debe satisfacer un documento. Usamos el dialecto Draft 2020-12. El esquema base exige un objeto, los campos value y unit, ningún campo adicional, un number entre 0 y 150 inclusive y una unidad elegida entre mm y cm. Son reglas de este contrato, no propiedades universales de las medidas o los agentes. El límite numérico 150 se aplica antes de interpretar la unidad.

S(x) = object(x) AND required(value, unit) AND no_extra_fields(x)\n AND number(x.value) AND 0 <= x.value <= 150\n AND x.unit IN {"mm", "cm"}

Aquí x representa la propuesta; AND exige que se cumplan todas las condiciones. El tipo importa: la cadena “10” no es el número 10 y el booleano true no es una cantidad numérica según el contrato. Una unidad no admitida o un campo adicional también provocan rechazo. Estos controles mantienen la entrada dentro del formato acordado. Sin embargo, tanto 10 mm como 10 cm cumplen exactamente esas reglas.

Llevar las cantidades a una unidad común

Comparar cantidades físicas exige una representación común. Definimos N, que normaliza a metros las propuestas conformes a S. Cambia la representación, no el desplazamiento descrito. Un centímetro pasa a ser 1/100 de metro y diez milímetros pasan a 10/1000 de metro. Ambos son 1/100 de metro. Primero verificamos tipos y unidades: no interpretamos arbitrariamente campos desconocidos.

N(x) = x.value / 1000 m, if x.unit = "mm"\nN(x) = x.value / 100 m, if x.unit = "cm"\nB(x) = [0 m <= N(x) <= 3/20 m]\nI(x) = [N(x) = 1/100 m]

B pregunta si la cantidad normalizada está en el intervalo del modelo; I pregunta si coincide con la referencia. Los corchetes indican una comparación lógica, no una unidad nueva. Para 10 cm, N(x)=1/10 m: está por debajo de 3/20 m, pero no es 1/100 m. Tenemos S verdadero, B verdadero e I falso. Un solo contraejemplo refuta la implicación general de que esquema y límite garanticen el objetivo.

El ejemplo inverso evita una solución excesivamente rígida. Comparar con una sola cadena JSON esperada rechazaría 1 cm si esa cadena especificara 10 mm, pese a describir el mismo desplazamiento. La comprobación del objetivo necesita una equivalencia adecuada al dominio. Aquí es la igualdad de cantidades normalizadas. Esto no convierte documentos arbitrarios en equivalentes: un identificador textual podría requerir identidad carácter por carácter.

Un esquema más fuerte: condiciones entre campos

Sería incorrecto concluir que JSON Schema solo comprueba puntuación o no puede expresar B. Para nuestras dos unidades basta añadir una condición: si unit es cm, value debe ser como máximo 15. El esquema base ya limita los mm a 150. allOf combina restricciones; if y then aplican la condición. El esquema reforzado S_B representa también el límite convertido dentro de este contrato.

S_B = S AND { if: {properties: {unit: {const: "cm"}}, required: ["unit"]}, then: {properties: {value: {maximum: 15}}} }

La expresión mostrada es una notación legible de composición, no un documento JSON para pegar sin cambios; el archivo contiene el esquema completo válido. El código verifica su concordancia con S y B en los 302 casos de la cuadrícula. Aun así, 10 cm supera S_B y falla el objetivo. Un contrato de dominio más rico resuelve una clase de errores, pero no añade por sí mismo la referencia de esta petición concreta.

Con el objetivo conocido también se puede generar un esquema específico que admita 10 mm o 1 cm mediante constantes y alternativas. No hay una frontera mágica entre “esquema” y “significado”: importa qué información y restricciones se codificaron realmente. Una solución coloca conversión y comparación en el programa; otra incorpora parte de esa lógica al esquema. Ambas dependen de una referencia fiable y de traducir correctamente los requisitos.

Un experimento finito que podemos revisar por completo

El experimento usa Python 3.14.0 y jsonschema 4.26.0 con Draft202012Validator. Enumeramos todos los enteros de 0 a 150 inclusive con cada una de las dos unidades: 151 por 2, es decir, 302 propuestas. No es una muestra de un modelo lingüístico: no hay prompts ni llamadas a servicios de IA y no estimamos probabilidades. Enumeramos un conjunto propio para poder comprobar el resultado sin depender del gráfico.

Las 302 propuestas satisfacen S por construcción. B acepta los 151 valores en milímetros y solo los 16 valores de 0 a 15 en centímetros: 167 en total. I acepta dos pares enteros: 10 mm y 1 cm. Quedan 165 propuestas dentro del límite que no cumplen el objetivo. Otra cuadrícula, intervalo o más decimales cambiarían los recuentos. El contraejemplo lógico seguiría siendo válido; las cifras no constituyen un benchmark general de agentes.

PropuestaSBI
10 mmTTT
1 cmTTT
10 cmTTF
100 mmTTF
20 cmTFF
"10" mmF——
true mmF——

En la tabla T significa verdadero y F falso. El guion indica no aplicable: tras fallar el esquema no interpretamos la propuesta como cantidad admitida ni calculamos B o I. Confundir un control no ejecutado con un resultado negativo dificulta interpretar los registros. La figura repite estos casos: destacan 10 cm y 100 mm, cuyas dos primeras columnas pasan y la última falla.

Recuentos sobre la cuadrícula entera de 302 propuestas y controles de los ejemplos. T/F indican verdadero/falso; gris y guion significan no aplicable. El límite es una hipótesis didáctica, no una certificación de seguridad.
Recuentos sobre la cuadrícula entera de 302 propuestas y controles de los ejemplos. T/F indican verdadero/falso; gris y guion significan no aplicable. El límite es una hipótesis didáctica, no una certificación de seguridad.

Del texto a los números: qué hace realmente el código

El archivo incluye experiment.py, los esquemas reales, dependencias fijadas y resultados completos. El analizador lee decimales con Decimal y rechaza explícitamente NaN e Infinity; no suponemos que cualquier analizador Python aplique esa política automáticamente. Tras validar, Fraction representa exactamente las razones de conversión. Comparar con 1/100 y 3/20 no depende de aproximaciones binarias de 0,01 o 0,15. Esta exactitud corresponde a los números declarados, no a la precisión de un sensor físico.

La función assess separa análisis del texto, esquema, normalización, límite y objetivo. Conserva el texto original en los resultados para identificar la propuesta comprobada. Los tests adicionales incluyen una cadena en vez de número, un booleano, una unidad desconocida, un campo adicional, uno ausente, un número negativo y uno no finito. El caso 1.0 cm comprueba que una representación decimal admitida sigue coincidiendo con la referencia. El código breve final aísla el contraejemplo; el archivo también ejecuta validación y enumeración completa.

El coste de enumerar crece con el número de propuestas manteniendo fijo este esquema pequeño. No es una afirmación sobre la complejidad general de JSON Schema, que puede incluir referencias y estructuras más elaboradas. No medimos latencia de agentes ni coste de inferencia. Para reproducir, se instalan las versiones de requirements.txt y se ejecuta experiment.py; plot.py genera las cuatro figuras. No hace falta un modelo generativo ni conexión a dispositivos.

Qué queda fuera de la prueba

Las medidas reales pueden requerir tolerancias. Si el requisito admite un error absoluto epsilon en metros, I puede convertirse en |N(x)−q|≤epsilon. Epsilon debe proceder del requisito, no elegirse después de ver la respuesta para hacerla pasar. Una comparación relativa necesita una política adicional cerca de cero. Usamos cantidad exacta y tolerancia cero para controlar el contraejemplo, no como regla metrológica universal.

Un objeto que supera los tres predicados no queda por ello autorizado para controlar una máquina. Identidad, permisos, estado de la aplicación y condiciones físicas no están en estos dos campos. B es un límite del ejemplo matemático: no prueba seguridad robótica, ausencia de colisiones ni certificación. Las políticas de campos JSON duplicados, tamaño de entrada y recursos del analizador requieren decisiones separadas; esto no valida completamente la seguridad de una API.

No atribuimos a EL-AI un sistema de agentes o robótico que haya ejecutado estos controles en producción. El interés expresado por robótica industrial y colaborativa es una dirección a explorar; aquí la conexión aplicativa es una hipótesis didáctica. La evidencia es el comportamiento del validador y de la comparación numérica sobre los datos sintéticos publicados. Evaluar un agente real exige peticiones representativas, referencia independiente, errores clasificados y protocolo documentado; nuestros 302 puntos no los sustituyen.

Respuesta a la pregunta inicial

Un JSON válido demuestra conformidad con las restricciones escritas, no con las que solo teníamos en mente. En este caso, estructura e intervalo aceptan 10 cm cuando se pidieron 10 mm. Normalizar y comparar con una referencia fiable revela la diferencia; también acepta 1 cm, otra representación de la cantidad correcta. Se trata de conservar los esquemas entendiendo qué pregunta responde cada control y qué información le falta.

Fuentes y reproducibilidad

Documentación primaria leída: Draft 2020-12 Validation, secciones 6.1.1–6.1.3, 6.2.2, 6.2.4 y 6.5.3; Core, secciones 10.2.1.1, 10.2.2 y 10.3.2.3. El nombre del dialecto contiene 2020-12, mientras los documentos consultados indican una revisión Internet-Draft del 16 de junio de 2022. No se presentan como RFC definitiva. La versión ejecutada del validador es 4.26.0, contrastada en su página de distribución. Es una explicación metodológica con experimento didáctico, no investigación original revisada por pares.

JSON Schema Draft 2020-12 — Validation.

JSON Schema Draft 2020-12 — Core.

jsonschema 4.26.0 — PyPI.

from fractions import Fraction
proposal={"value":10,"unit":"cm"}
metres=Fraction(proposal["value"])*Fraction(1,100)
bounded=0 <= metres <= Fraction(3,20)
intent=metres == Fraction(1,100)
assert bounded and not intent
print(metres,bounded,intent)  # 1/10 True False

Código, datos e instrucciones · JSON. Cálculos didácticos ejecutados con Python 3.14.0; figuras con Matplotlib 3.11.2. Análisis asistido por IA, sin afirmar revisión por pares ni humana. Portada original ImageGen ilustrativa: no documenta personas, sedes ni instalaciones de EL-AI. Fuentes consultadas el 21 de octubre de 2026.