Skip to main content
When you need structured output from an LLM — a JSON object with specific fields and types — you pass a responseFormat that describes the expected shape. You can build this format as a plain array, or use Polyglot’s JsonSchema builder for a more expressive, composable approach. Native JSON Schema enforcement depends on the selected driver and model. If your provider does not support json_schema response format natively, consider using JSON mode or Markdown-JSON mode for best-effort output.

Why Use JsonSchema?

The JsonSchema builder offers several advantages over hand-crafting schema arrays:
  • Type safety — factory methods ensure each node has the correct structure
  • Composability — define sub-schemas once and embed them in multiple places
  • Readability — a fluent API makes complex schemas easy to scan
  • Conversion — convert the same schema to a response format or a tool/function definition

Quick Start

Here is a minimal example that requests structured city data from an LLM:
The JsonSchema class only helps you build the schema payload. Polyglot passes it to the provider, and the provider decides how strictly to enforce it.

Available Types

The JsonSchema class provides static factory methods for every JSON Schema primitive.

String

Integer and Number

Boolean

Array

Arrays require an itemSchema that describes the type of each element:
Arrays can also contain complex objects:

Enum

Enums restrict a field to a fixed set of string or integer values:

Object

Objects define nested structures with named properties:

Required and Nullable Fields

Required and nullable are independent concepts:
  • A required field must be present in the output.
  • A nullable field may contain a null value.
  • A field can be both required and nullable (must be present, but may be null).
  • A field can be optional and non-nullable (when present, cannot be null).
Required fields are specified at the object level:
Nullable fields are specified on individual properties:

OpenAI Strict Mode

When working with OpenAI in strict mode, all fields must be listed as required. Use nullable: true to indicate fields whose values are optional:

Common Patterns

Nested Schemas

For complex structures, define child schemas first and embed them into parent schemas:

Fluent API

The JsonSchema class supports method chaining for cases where you want to build schemas incrementally:
Available fluent methods include:

Converting Schemas

The JsonSchema class provides methods to convert schemas into different output formats:

Accessing Schema Properties

You can inspect any schema programmatically:

Meta Fields

You can attach custom meta fields to schemas. These are rendered with an x- prefix in the JSON Schema output:
In the generated schema, these become x-min_length, x-max_length, and x-pattern. Meta fields are useful for passing hints to post-processing validation or documentation generators.

Using Schemas as Tool Parameters

The toFunctionCall() method generates a tool/function definition that you can pass directly to the tools parameter of an inference request:

Full Example: User Profile Schema

Here is a complete example that defines a rich user profile schema and uses it to extract structured data from an LLM:

Best Practices

Write clear descriptions. The description string guides the LLM toward correct output. Be specific about format, length, and constraints.
Organize nested schemas. Define child schemas as separate variables before embedding them in a parent. This keeps your code readable and makes schemas reusable across different request types. Be explicit about requirements. Always specify both requiredProperties at the object level and nullable on individual fields. Leaving them implicit creates ambiguity that different providers handle differently. Use strict mode with OpenAI. When targeting OpenAI, set 'strict' => true in the json_schema block and make all fields required. Use nullable: true for optional values. This gives you the strongest possible enforcement of your schema.