Skip to main content
Structured output forces the agent to produce validated JSON conforming to a schema you provide. The extraction runs as a separate turn after agentic work completes, with automatic retry on validation failure. Schemas are normalized across providers — the same schema works with Anthropic, OpenAI, and Gemini, with provider-specific lowering handled transparently.
This page is the task-first guide. For the low-level schema/type inventory, see Structured output reference.

What this guide is for

Use this guide when you want to:
  • extract validated JSON from an agent run
  • choose schema compatibility behavior
  • understand retry and warning behavior

How it works

When output_schema is configured on an agent, the execution flow is:
1

Agentic loop runs normally

The agent processes the prompt, calls tools, and iterates until no more tool calls remain.
2

Extraction turn fires

An additional LLM call is made with no tools, temperature 0.0 for deterministic output, and a prompt asking for valid JSON matching the schema.
3

Validation

The response is parsed as JSON and validated against the schema using the jsonschema crate’s Validator.
4

On success

RunResult.structured_output contains the parsed serde_json::Value.
5

On failure

Retries validation failures up to structured_output_retries times with error feedback, then returns the completed main run with RunResult.extraction_error.

Schema types

OutputSchema

The primary schema type:

Construction methods

Builder methods

OutputSchema supports a wrapper format for explicit configuration. If the JSON object contains a schema key and either a format: "meerkat_v1" marker or only wrapper keys (schema, name, strict, compat, format), it is parsed as a wrapper:
Otherwise, the entire JSON value is treated as a raw schema.

MeerkatSchema

Newtype around serde_json::Value with normalization:
  • Constructed via MeerkatSchema::new(Value) which applies normalize_schema().
  • Normalization: ensures all object-typed nodes have properties and required keys (inserting empty defaults if missing). This prevents provider-specific compilation issues.
  • Returns SchemaError::InvalidRoot if the root is not a JSON object.

SchemaFormat

Schema format versions:

SchemaCompat

Compatibility mode for provider-specific schema lowering:

SchemaWarning

Warnings emitted during schema compilation:

CompiledSchema

Provider-compiled schema output:

SchemaError

Schema errors:

Extraction turn details

The extraction turn logic:

Attempt flow

  1. Max attempts = structured_output_retries + 1 (default: 2 + 1 = 3 attempts).
  2. First attempt prompt: "Provide the final output as valid JSON matching the required schema. Output ONLY the JSON, no additional text or markdown formatting." (overridable via the extraction_prompt config field)
  3. Retry prompt (on validation failure): "The previous output was invalid: {error}. Please provide valid JSON matching the schema. Output ONLY the JSON, no additional text."
  4. LLM is called with no tools and temperature 0.0.
  5. Response text is trimmed, then markdown code fences are stripped (handles ```json and ``` wrappers).
  6. Parsed as JSON via serde_json::from_str.
  7. Validated against the compiled schema via jsonschema::Validator.
If Meerkat is built without the jsonschema feature, configuring an output_schema fails closed: extraction surfaces a typed InvalidOutputSchema error rather than returning unvalidated JSON as if it had passed.

On success

Returns RunResult with:
  • text: the committed main-turn assistant output
  • structured_output: Some(parsed_value) — the validated JSON
  • schema_warnings: any warnings from schema compilation
  • turns: includes extraction attempts in the count

On failure

Returns Ok(RunResult) for the completed main run with structured_output: None and extraction_error: Some(error):
Extraction failure can come from validation exhaustion, provider errors, hook or budget denial, schema compilation failure, or tool-call-shaped output during the post-main-turn extraction phase.

Provider schema compilation

The AgentLlmClient trait includes a compile_schema() method:
The default implementation passes through the normalized schema without provider-specific lowering. Provider adapters override this to apply transformations:
  • Anthropic: may add additionalProperties: false to object nodes
  • Gemini: may strip unsupported JSON Schema keywords
  • OpenAI: may apply strict-mode transformations
Schema warnings are collected during compilation and included in RunResult.schema_warnings.

Configuration

Agent config fields

Usage

The --schema flag accepts either a file path or inline JSON. The CLI detects files by checking if the value is an existing path.

Wire parameters

Structured output is passed directly on the normal per-request session surfaces:

RunResult fields

When structured output extraction succeeds, the RunResult contains:
The structured_output field is Some(value) when extraction succeeds and None when no schema was configured or extraction failed. The text field remains the committed main-turn assistant output.

SDK usage

Basic structured output

Using from_type with schemars

Handling the result

See also