AI and LLMs

Language models generate Markdown with ease: it is the format most present in their training data. However, "valid" Markdown guarantees nothing: any output passes, including hallucinated fields, missing sections and incorrect metadata.

STXT is a suitable format for AI-generated documents:
as easy to write as Markdown, and verifiable.

Why an LLM writes good STXT

STXT does not appear in model training data, but with an example and a template in context, following a regular format is a task that models perform reliably.

STXT is more regular than Markdown:

  • Every line is Name:, Name >> or indented text.
  • There are no alternative syntaxes for the same element.
  • The structure is linear: it is generated top to bottom, with no backward references.

The possible mistakes are few and well known:

  • Indentation drift in very long documents.
  • Omitting the indentation of a line inside a >> block.

Both are detected at validation time.

The difference: verifiable

When an LLM generates Markdown, there is nothing to check the result against. When it generates STXT with a template:

  • The parser validates the output immediately.
  • The closed content model rejects undeclared node names.
  • ENUM values and cardinalities reject invented values.
  • Types (DATE, EMAIL, NUMBER...) reject incorrect formats.

A valid STXT document means the structure is correct. Valid Markdown means nothing.

The loop: generate, validate, fix

Validation turns generation into an iterative process:

  1. The LLM generates the STXT document.
  2. The parser validates it against the template.
  3. If there are errors, they are fed back to the model.
  4. The model fixes them and the loop repeats.

Each iteration reduces the errors to those the validator reports; the process ends when the document validates. This loop does not exist for Markdown: there is nothing to validate against.

Step 2 is stxt validate -: the CLI reads the document from standard input, validates it against the grammars of the current directory and emits each finding as <stdin>:line: [CODE] message, with exit code 1 if there are errors. It is designed for pipes and CI, so the model's output is validated without going through a file. See The CLI.

Example of a template included in the prompt:

Template (@stxt.template): com.acme.reports
	Structure >>
		Report (com.acme.reports):
			Title: (1)
			Date: (1) DATE
			Status: (1) ENUM [Draft, Final]
			Summary: (1) TEXT
			Section: (*)
				Title: (1) @Title
				Content: (1) TEXT

Generated output with typical LLM mistakes, all of them detected:

Report (com.acme.reports):
	Title: Market analysis
	# ERROR: DATE requires YYYY-MM-DD
	Date: tomorrow
	# ERROR: not an ENUM value
	Status: Pending
	# ERROR: undeclared child (closed model)
	Subtitle: Short version
	# ERROR: Summary is missing, and it is mandatory

A runnable example

The whole loop lives in examples/llm/ of the specification repository: a Node program of about eighty lines that turns free-text meeting notes into a valid Report (com.acme.reports). Next to it are the template in .stxt/, a correct example document, the prompt with the format rules and the source notes.

  • Generate: the prompt carries the STXT rules in ten lines, the whole template, the valid example and the text to convert; it asks for the document and nothing else.
  • Validate: UnifiedSchemaProvider loads the template and Parser with a SchemaValidator returns the errors with line and code, as stxt validate - would.
  • Fix: the errors go back to the model verbatim, after its own answer, and the loop repeats until the document validates or the attempts run out.
$ 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' not allowed. Only: Draft, Final (schema)
    line 1: [TOO_FEW_CHILDREN] 0 nodes of 'com.acme.reports:summary' and min is 1 (schema)
--- attempt 2: valid

The document goes to standard output and the dialogue to standard error, with exit code 0 only when the last version validates: one more pipeline step. The example uses the Anthropic API, but nothing in the loop depends on the provider; the call to the model is a function that returns text. The directory's README lists which model mistake produces which code.

No escaping: long prose inside structure

The weak spot of LLMs generating JSON is escaping: quotes, \n, line breaks inside strings.

{"summary": "Line 1\nLine 2 with \"quotes\" and more text..."}

In STXT, >> blocks are literal text: the model only has to indent.

Summary >>
	Line 1
	Line 2 with "quotes" and more text...

For documents with long free text, STXT is a more reliable output surface than JSON or YAML.

Normalization absorbs variance

The canonical node name absorbs the usual variations of an LLM: TITLE:, Title: and title: are the same node. Where other formats would report "unknown field", STXT identifies the same element.

Strict validation is reserved for where it matters: ENUM values are case-sensitive and exact.

Prompting practices

  • Include the full template of the namespace in the prompt: it is compact and declares which fields exist, their cardinalities and their allowed values before generating.
  • Add one complete, correct example document.
  • Ask for consistent indentation (tabs, or 4 spaces per level).
  • Always validate the output with the parser, not by visual inspection.
  • Ensure the validator's error messages include the line, what was expected and what was found: that is what the model needs to fix the document in the next iteration.

Use cases

  • AI-assisted CMS content: the build rejects generated pages that are incomplete or inconsistent before publishing them.
  • Data extraction: turning free text (emails, reports, minutes) into STXT documents validated against a template.
  • Generated reports and documentation: validated structure, free prose inside >> blocks.
  • Agents and pipelines: STXT as the interchange format between steps, with validation at every boundary.

Summary

  • With a template and an example in context, an LLM generates STXT reliably.
  • Validation detects undeclared fields, invented values and incorrect formats.
  • The generate → validate → fix loop produces a verifiable result, unlike Markdown, which has nothing to be validated against.
  • Literal blocks remove escaping, the weak spot of JSON.
  • Verifiable structure and free text: the two requirements of AI-generated content.