Skip to main content
← AI Engine

Structured JSON Output, guaranteed by construction

Token-level constraint enforcement: JSON Schema, choice lists, regex patterns, and Lark grammars. The model literally cannot produce output that doesn't parse.

The Problem

LLMs produce free-form text. Game code needs structured data. The standard approach (generate text, parse it, hope it's valid JSON, handle parse errors, retry on failure) is fragile, slow, and adds complexity to every integration point.

Four Constraint Types

Four ways to lock the output shape, all enforced during generation rather than after. Every token the model emits is masked against the constraint, so the output is guaranteed to be valid: no retries, no error handling, no fallback parsers.

Auto Schema Injection

By default the engine prepends a concise description of the active constraint to the system message, so the model knows the target shape ahead of time and the constraint engine has less work to do during sampling. Configurable via the schema_injection setting (none / light / concise / full). Constraint trees are also cached across requests with the same shape so the per-call overhead drops to near-zero.

Example: JSON Schema

// Define the schema for a generated item
let schema = json!({
    "type": "object",
    "properties": {
        "name": { "type": "string" },
        "rarity": {
            "type": "string",
            "enum": ["common", "uncommon", "rare", "legendary"]
        },
        "damage": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100
        },
        "description": { "type": "string" }
    },
    "required": ["name", "rarity", "damage", "description"]
});

// Generate: output is guaranteed to match the schema
let item = engine.llm().generate_structured(
    "Create a fire-enchanted sword for a level 20 warrior",
    &schema
).await?;

The result:

{
  "name": "Embercleaver",
  "rarity": "rare",
  "damage": 47,
  "description": "A longsword wreathed in smoldering flame, forged in the heart of Mount Valdris."
}

Use Cases

How It Works

Each constraint compiles to a finite-state machine (or pushdown automaton, for Lark grammars). At every sampling step, the engine asks the FSM which next tokens are legal and zeroes out the logits of the rest, then samples normally from what remains. Invalid output is impossible (not unlikely, impossible). Constraint compilation is cached across requests, so the second call with the same schema pays only the per-token mask cost.

Schema-constrained generation: schema compiles to a finite-state machine, sampler masks logits at each step, output is always valid.

Related