Especificación
sustituye a JSON Schema · prompts a mano
Gramática EBNF, 15 códigos de error estables y protocolo de extensión. La norma se escribe antes que el código y decide cuando las implementaciones difieren.
1.1 Tu JSON. Tu contrato. Tu .mini. →
Entrega muestras JSON de tu dominio. mini-format construye tu contrato, el prompt y las herramientas para recibir JSON validado desde respuestas compactas de IA. Detecta errores y aplica reparaciones seguras con un informe verificable.
Instalar mini-format 1.2.0
pip install https://mini-format.pmoluna.com/downloads/mini_format-1.2.0-py3-none-any.whl
npm install ./mini-format-core-1.2.0.tgz
Python 3.9+ · núcleo sin dependencias · código abierto MIT. El ZIP incluye el paquete Python, TypeScript, ejemplos y documentación.
Crear mi primer .mini →194 registros · Datos públicos de prueba
Tokens de salida relativos a .mini · menos es mejor. o200k_base
208 registros · Datos públicos de prueba
Tokens de salida relativos a .mini · menos es mejor. o200k_base
500 registros · Datos públicos de prueba
Tokens de salida relativos a .mini · menos es mejor. o200k_base
1.000 registros · Observaciones reales
Tokens de salida relativos a .mini · menos es mejor. o200k_base
Para tu aplicación
mini validate y parse() entran en un proyecto Python o Node ya existente. No cambias de proveedor de modelo ni de framework.
sustituye a JSON Schema · prompts a mano
Gramática EBNF, 15 códigos de error estables y protocolo de extensión. La norma se escribe antes que el código y decide cuando las implementaciones difieren.
sustituye a regex · json.loads · try/except
Python y TypeScript, escritas por separado desde la misma norma. Parser, serializador, modo tolerante, bloque de prompt y lector en streaming.
sustituye a jq · scripts de validación
Construye tu toolkit, valida, diagnostica, convierte en ambos sentidos, genera prompts, cuenta tokens y comprueba familias.
sustituye a pruebas por implementación
303 casos independientes del lenguaje, con expectativas escritas desde la norma y nunca calculadas ejecutando el código. Python y TypeScript pasan 303/303.
Un minuto con mini-format
Declarar, instruir, llamar, validar, reparar y usar con la misma herramienta. Cada paso es un comando real; la salida está abreviada. Pulsa uno, o solo mira.
Un build por dominio
Reúne los JSON que tu aplicación necesita. Un comando genera una carpeta .mini reutilizable en tu flujo de trabajo.
mini build phones.json more.json --prefix phone --out .miniGrabación de esta demostración. Comandos reales; salida abreviada.
Integración
No es un servicio ni un framework: es una biblioteca. Cargas el registro de familias, pides el bloque de prompt con spec_block(), llamas a tu proveedor como siempre y pasas la respuesta por parse().
from minifmt import Registry, parse, spec_block
reg = Registry.load() # descubre forks/*/contract.json
c = reg.get("a")
def generar_items(tema):
respuesta = cliente.completar(sistema=spec_block(c, lang="es"), usuario=tema)
doc = parse(respuesta, c, strict=False) # tolerante: acumula errores
return doc.records, doc.errors # válidos tipados, rechazados con códigoJSON repite el nombre de cada campo en cada objeto. mini-format lo declara una vez en el contrato. El coste de los nombres crece como O(W·N) en JSON y como O(W) aquí.
registro estrecho
registro típico de negocio
registro ancho
Ahorro frente a JSON compacto · escala lineal, origen en 0 %, máximo del eje 50 % · 1000 registros · tokenizador o200k_base · mediana de 5 documentos por celda · datos sintéticos deterministas (semilla 20260915). La curva satura cerca de 32 campos. reproducir →
1.902 registros de cuatro conjuntos públicos. 35,64 % menos tokens que JSON compacto y 9,65 % menos que TOON plano en el total medido.
| Conjunto | N | .mini | TOON flat | Ahorro vs TOON | Ahorro vs CSV | Prompt .mini |
|---|---|---|---|---|---|---|
| DummyJSON products | 194 | 64.090 | 68.260 | 6,11 % | 4,42 % | 1.206 |
| DummyJSON users | 208 | 43.268 | 60.926 | 28,98 % | 27,92 % | 1.796 |
| JSONPlaceholder comments | 500 | 30.268 | 31.022 | 2,43 % | -1,35 % | 477 |
| USGS earthquake observations | 1.000 | 164.137 | 173.803 | 5,56 % | 4,11 % | 1.336 |
USGS: 1.000 observaciones reales. DummyJSON y JSONPlaceholder: 902 registros de prueba sintéticos, sin duplicación para inflar el lote. Ida y vuelta JSON exacta en los ocho formatos. TOON oficial 4.1.1; se elige el menor de dos aplanados reversibles. Los porcentajes son de salida: el prompt de .mini se muestra aparte. CSV sigue siendo menor en comentarios. Es una medición de serialización, no de precisión de generación de un LLM. Método y reproducción → · JSON
Los separadores no se segmentan igual en todos los vocabularios. Mismos 14 dominios, lote de 10, frente a JSON compacto.
vocabulario de 50k
IC95 [26,8 % · 31,5 %] · k=14
vocabulario de 100k
IC95 [29,1 % · 33,5 %] · k=14
vocabulario de 200k
IC95 [31,5 % · 35,5 %] · k=14
Escala lineal, origen en 0 %, máximo del eje 36 %: la diferencia es real pero pequeña — 3,9 puntos entre el vocabulario más antiguo y el más reciente. Los tres vocabularios pertenecen a la familia tiktoken. reproducir →
Interfaz
from minifmt import Registry, parse, dumps, spec_block, roundtrip_ok
reg = Registry.load() # descubre forks/*/contract.json
c = reg.get("log")
instruccion = spec_block(c, lang="es") # bloque para el prompt de sistema
doc = parse(respuesta, c, strict=False) # tolerante: no lanza, acumula
doc.records # registros válidos, ya tipados
for e in doc.errors: # MiniError: code, line, field, message
print(e)
texto = dumps(doc.to_canonical(), c) # canónico -> .mini
assert roundtrip_ok(doc.to_canonical(), c)import { Registry, parse, dumps, specBlock } from '@mini-format/core';
const reg = Registry.load(); // descubre ../forks/*/contract.json
const c = reg.get('log');
const lenient = parse(texto, c, { strict: false });
lenient.records; // registros válidos
lenient.errors; // MiniError[] con code, line, field, message
lenient.invalidLines(); // líneas rechazadas: las que hay que regenerar
lenient.missingRecords; // n − líneas recibidas
lenient.diagnostics(); // mismas claves que la referencia Pythonimport { createReader } from '@mini-format/core';
const reader = createReader(c, { // strict: false por defecto
onRecord: ({ record, line, index }) => mostrar(record),
onError: (e) => console.warn(String(e)),
});
for await (const token of respuestaDelModelo) reader.push(token);
const res = reader.end();
res.missing; // registros que faltan respecto de n
res.truncated; // se cortó: incompleto o menos líneas que n
res.terminated; // el flujo terminó en salto de líneamini forks # lista las familias
mini validate respuesta.mini # estricto: sale con 1 si hay errores
mini diagnose respuesta.mini # tolerante: informe JSON con líneas a regenerar
mini to-json respuesta.mini | jq . # .mini -> JSON canónico
mini from-json datos.json -p log # JSON canónico -> .mini
mini prompt log --lang es # bloque de especificación para el modelo
mini tokens respuesta.mini --enc o200k_base # tokens y bytes, con el tokenizador declarado
mini check-forks # invariantes + fixtures de ida y vuelta
mini new-fork quiz2 --from a --add "nivel:enum{facil|dificil}"$ python conformance/run_python.py
303 casos · 303 pasan · 0 fallan
$ cd ts && npm test
conformance.test.ts · 303/303
# las expectativas salen de la norma y de los fixtures publicados,
# nunca se calculan ejecutando la implementación$ mini new-fork quiz2 --from a --add "feedback:str" "level:enum{easy|hard}"
$ mini check-forks
# cinco invariantes mantienen toda familia analizable por construcción:
# I1 una línea = un registro I4 campos nuevos solo al final
# I2 prefijo y n obligatorios I5 los fixtures hacen ida y vuelta
# I3 el núcleo heredado no cambia (cambio incompatible => prefijo nuevo)Cada familia conserva el núcleo, añade campos al final y mantiene cinco invariantes verificables. Una familia es un archivo de datos, no código.
aítems de evaluación: opción múltiple, Bloom, IRT 3PL, CAT
qquiz formativo: extiende a con feedback, pista y objetivo
cardtarjetas de repaso espaciado
sumsegmentos de resumen de microlección
maparistas de mapas conceptuales
rcriterios de rúbrica analítica
sítems de encuesta Likert
codeejercicios de programación con pruebas
tccasos de prueba de software
ushistorias de usuario con criterios de aceptación
logeventos e incidentes de servicios
neranotaciones de entidades nombradas
catfichas de catálogo de productos
clsclasificación de texto multietiqueta
Playground
Se ejecuta entero en tu navegador con el port JavaScript de la referencia. Sin servidor, sin cuenta.
Abrir el playgroundComparativa
| Capacidad | mini-format | JSON | CSV | TOON |
|---|---|---|---|---|
| Menos tokens que JSON compacto | ✓ | — | ✓ | ✓ |
| Tipos declarados en el contrato | ✓ | parcial | ✗ | parcial |
| Error con código, línea y campo | ✓ | parcial | ✗ | ✗ |
| Códigos de error estables en la norma | 15 | ✗ | ✗ | ✗ |
| Recuperación ante truncamiento | ✓ | ✗ | ✓ | parcial |
| Reparación selectiva por línea | ✓ | ✗ | ✗ | ✗ |
| Lectura en streaming, registro a registro | ✓ | parcial | ✓ | ✗ |
| Suite de conformidad publicada | 303 | ✓ | ✗ | ✗ |
| Dos implementaciones independientes | ✓ | ✓ | ✓ | parcial |
| Listas con elemento marcado | ✓ | ✗ | ✗ | ✗ |
| Compatibilidad hacia adelante declarada | ✓ | ✗ | ✗ | ✗ |
| Anidamiento arbitrario | ✗ | ✓ | ✗ | ✓ |
| Lectura directa sin contrato | parcial | ✓ | ✓ | ✓ |
| Soporte nativo en APIs de proveedores | ✗ | ✓ | ✗ | ✗ |
La compatibilidad conserva los campos conocidos cuando el mismo prefijo declara una versión superior. El perfil base usa registros planos; el toolkit generado reconstruye la estructura JSON de tu dominio. El modelo necesita el prompt y el lector, el contrato.
Descarga el toolkit, reúne tus muestras JSON y construye el contrato de tu aplicación.
mini build phones.json --prefix phone --out .miniDocumentación · Especificación 1.1 · Índice de errores · Playground