JJoeven

Reference/LLM APIs

Structured output and JSON schemas

Force {tool, args} or vendor tool_calls; reject extra keys; repair once then fail.

Free prose is for users. Machines get JSON.

Contract

text
{"tool": string, "args": object}

or finish payloads with an explicit schema (citations, cannot_answer, refused).

Vendor options (conceptual)

StyleNotes
Prompt "JSON only"cheapest, flakiest
JSON mode / response_formatbetter, still validate
Native tool_callsbest; still allowlist names
Grammar / constrained decodewhen the runtime supports it

Joeven fakes all of these with parse_action.

Validation checklist

  • json.loads
  • type checks
  • exact key set or explicit additionalProperties false
  • enum of tool names
  • per-tool arg schema (types, ranges, max length)
  • extra keys → error, do not silently drop if they look like execute: true

Repair

  1. Parse fail → system: "JSON only" → retry
  2. Cap max_parse_retries
  3. Then stop / cannot-answer

Do not regex-hope forever.

python
need = {class="tok-s">"tool", class="tok-s">"args"}
if set(obj) != need:
    raise ValueError(class="tok-s">"shape")
Note:Pydantic is the usual library on a real machine. In-browser Joeven uses hand-written checks so Pyodide stays stdlib-only.