IA y LLMs
Un documento STXT generado por un modelo se valida contra una plantilla:
la salida es verificable, y cada error vuelve al modelo con su línea y su código.
Un modelo de lenguaje que genera un documento, o que extrae uno de un texto libre, produce texto. Si ese texto es Markdown, no hay contra qué comprobarlo: cualquier salida pasa, con campos inventados, secciones que faltan o fechas mal escritas. Si es STXT con una plantilla, la salida se valida como cualquier otro documento, y lo que no cumple la plantilla es un error con línea y código.
Lo que el validador comprueba
- El modelo de contenido cerrado rechaza los nombres de nodo no
declarados (
CHILD_NOT_DECLARED,NODE_NOT_DEFINED_IN_SCHEMA). - Las cardinalidades rechazan los nodos que faltan o sobran (
TOO_FEW_CHILDREN,TOO_MANY_CHILDREN). - Los tipos (
DATE,EMAIL,NUMBER...) rechazan los formatos incorrectos, y losENUMlos valores fuera de la lista (INVALID_VALUE).
La plantilla del ejemplo ejecutable de esta página, tal cual está en su .stxt/:
Template (@stxt.template): com.acme.reports
Structure >>
Report (com.acme.reports):
Title: (1)
Date: (1) DATE
Author: (1)
Status: (1) ENUM [Draft, Final]
Summary: (1) TEXT
Section: (*)
Title: (1) @Title
Content: (1) TEXT
Action: (*)
Owner: (1)
Due: (?) DATE
Description: (1) TEXT
Description >>
Report: A short internal report extracted from free text (notes, emails, minutes)
Date: Date of the source material, YYYY-MM-DD
Status: Draft until a person has reviewed it
Summary: Three sentences at most
Section: One per topic discussed
Action: One per agreed follow-upUna salida con cuatro errores, todos detectados:
Report (com.acme.reports): Análisis de mercado
Title: Análisis de mercado
# ERROR: DATE exige YYYY-MM-DD
Date: mañana
Author: Ana García
# ERROR: no es un valor del ENUM
Status: Pendiente
# ERROR: hijo no declarado (modelo cerrado)
Subtitle: Versión corta
# ERROR: falta Summary, que es obligatorioEl bucle: generar, validar, corregir
- El modelo genera el documento STXT.
- El validador lo comprueba contra la plantilla.
- Si hay errores, se devuelven al modelo tal cual, con línea y código.
- El modelo corrige y se repite, hasta que el documento valida o se agotan los intentos.
El paso 2 es stxt validate -: la CLI lee el documento por la entrada estándar, lo
valida contra las gramáticas del directorio actual y emite cada hallazgo como
<stdin>:línea: [CÓDIGO] mensaje (error), con código de salida 1 si hay errores
(La línea de comandos). Con la biblioteca, es UnifiedSchemaProvider
para cargar la plantilla y Parser con SchemaValidator para obtener los mismos
errores.
El bucle completo está en
examples/llm/
del repositorio de la especificación: un programa de Node que convierte unas notas de
reunión en texto libre en un Report (com.acme.reports) válido. Lo acompañan la
plantilla de arriba, un documento de ejemplo correcto, el prompt con las reglas del
lenguaje y las notas de partida. El prompt lleva las reglas de STXT, la plantilla
entera, el ejemplo válido y el texto a convertir, y pide solo el documento.
$ node generate.mjs > report.stxt
--- attempt 1: 3 error(s)
line 3: [INVALID_VALUE] Date: Invalid date (12 March 2026) (schema)
line 5: [INVALID_VALUE] The value 'draft' is not one of the allowed values of Status (schema)
line 1: [TOO_FEW_CHILDREN] 0 nodes of 'com.acme.reports:summary' and min is 1 (schema)
--- attempt 2: valid
El documento sale por la salida estándar y el diálogo por la de error, con código de
salida 0 solo si la última versión valida. El ejemplo usa la API de Anthropic, pero
nada del bucle depende del proveedor: la llamada al modelo es una función que devuelve
texto. El README del directorio resume qué error del modelo produce qué código.
Lo que facilita la generación
- Pocas formas de línea. Cada línea es
Nombre: valor,Nombre:,Nombre >>o texto de un bloque, y no hay sintaxis alternativas para un mismo elemento. El documento se genera de arriba abajo, sin referencias hacia atrás. - Sin escapado. Un bloque
>>es texto literal: el modelo solo tiene que indentarlo. En JSON, el mismo texto exige escapar comillas y saltos de línea:
{"summary": "Línea 1\nLínea 2 con \"comillas\" y más texto..."}
- Los nombres se comparan por su forma canónica.
TITLE:,Title:ytitle:son el mismo nodo (STXT-SPEC §4.3); los valores de unENUM, en cambio, se comparan exactos, con mayúsculas y minúsculas.
Prácticas de prompting
- Incluir la plantilla completa del namespace: declara qué nodos existen, sus cardinalidades y sus valores permitidos.
- Añadir un documento de ejemplo completo y válido.
- Pedir una indentación fija: tabuladores, o cuatro espacios por nivel.
- Validar siempre la salida con el parser, nunca por inspección.
- Devolver al modelo los mensajes del validador tal cual, con línea y código.
Los casos donde este flujo encaja se desarrollan en CMS y publicaciones, donde el build rechaza las páginas generadas que no validan, y en Documentos corporativos, para la extracción de datos de texto libre.