Structured output

Typed responses with json_schema

Pass a JSON schema in response_format and the model is constrained to return JSON that matches. Strict mode rejects unknown fields; in non-strict mode the model still tries to match but can drift on edge cases.

Python

python
import os, json
from openai import OpenAI

client = OpenAI(
    base_url="https://api.quicksilverpro.io/v1",
    api_key=os.environ["QSP_KEY"],
)

resp = client.chat.completions.create(
    model="deepseek-v3",
    messages=[{
        "role": "user",
        "content": "Extract the city and temperature from: It was 18C in Paris today.",
    }],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "weather_reading",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "city": {"type": "string"},
                    "temp_c": {"type": "number"},
                },
                "required": ["city", "temp_c"],
                "additionalProperties": False,
            },
        },
    },
)

data = json.loads(resp.choices[0].message.content)
print(data["city"], data["temp_c"])  # Paris 18

Strict vs non-strict

  • Strict (strict: true): output is constrained at decode time to match the schema. Unknown keys are impossible. additionalProperties: false is required on every object in the schema. Recommended for production.
  • Non-strict (json_object): output is JSON but not schema-constrained. The model tries to match but can drift on long-tail prompts. Use only for prototyping.

Schema rules

Strict mode has a few constraints to be aware of:

  • Every object must have additionalProperties: false and required listing every property.
  • enum, const, oneOf are supported. Recursive schemas via $ref are also supported.
  • Defaults aren't enforced — if you need a default, post-process the parsed JSON in your client.

When to use

  • Structured extraction — pulling typed fields from free-form text.
  • Form-filling agents — guaranteeing the agent emits keys your downstream code can consume.
  • Pipelines— when the model's output is the input to the next stage, schema-constrained output eliminates a class of parse errors.

For function/tool calling, the same constraint mechanism is available via the tools[].function.parameters field. See Tool calling.