Structured Output

Force the model to produce valid JSON conforming to a schema. Both APIs support this.

Provider support varies

Schema-constrained output is fully supported on OpenAI and OpenAI-compatible providers. Support differs on the native backends — see the provider notes in the Multi-Backend guide before relying on strict schemas elsewhere.

Chat Completions

Use ResponseFormat to control the output format:

Free-Form JSON

using UniLM
using JSON

chat = Chat(
    model="gpt-5.4-mini",
    response_format=ResponseFormat()  # type="json_object"
)
push!(chat, Message(Val(:system), "You output JSON. Always respond with valid JSON."))
push!(chat, Message(Val(:user), "List 3 programming languages with their year of creation."))
println("Response format type: ", chat.response_format.type)
println("Request body:")
println(JSON.json(chat))
Response format type: json_object
Request body:
{"messages":[{"content":"You output JSON. Always respond with valid JSON.","role":"system"},{"content":"List 3 programming languages with their year of creation.","role":"user"}],"model":"gpt-5.4-mini","response_format":{"type":"json_object"}}
result = chatrequest!(chat)
if result isa LLMSuccess
    println(JSON.json(JSON.parse(result.message.content), 2))
else
    println("Request failed — see result for details")
end
Request failed — see result for details

JSON Schema (Strict)

schema = ResponseFormat(UniLM.JsonSchemaAPI(
    name="languages",
    description="A list of programming languages",
    schema=Dict(
        "type" => "object",
        "properties" => Dict(
            "languages" => Dict(
                "type" => "array",
                "items" => Dict(
                    "type" => "object",
                    "properties" => Dict(
                        "name" => Dict("type" => "string"),
                        "year" => Dict("type" => "integer")
                    ),
                    "required" => ["name", "year"],
                    "additionalProperties" => false
                )
            )
        ),
        "required" => ["languages"],
        "additionalProperties" => false
    ),
    strict=true
))

chat = Chat(model="gpt-5.4-mini", response_format=schema)
push!(chat, Message(Val(:system), "Return structured data about programming languages."))
push!(chat, Message(Val(:user), "List Julia, Python, and Rust"))
println("Schema name: ", schema.json_schema.name)
println("Response format type: ", schema.type)
println("Strict: ", schema.json_schema.strict)
Schema name: languages
Response format type: json_schema
Strict: true
result = chatrequest!(chat)
if result isa LLMSuccess
    println(JSON.json(JSON.parse(result.message.content), 2))
else
    println("Request failed — see result for details")
end
Request failed — see result for details

Responses API

The Responses API uses TextConfig with convenience constructors:

JSON Object

result = respond("List 3 colors as a JSON object", text=json_object_format(), model="gpt-5.4-mini")
if result isa ResponseSuccess
    println(output_text(result))
else
    println("Request failed — ", output_text(result))
end
Request failed — Error: KeyError: key "OPENAI_API_KEY" not found

JSON Schema

fmt = json_schema_format(
    "colors",
    "A structured list of colors",
    Dict(
        "type" => "object",
        "properties" => Dict(
            "colors" => Dict(
                "type" => "array",
                "items" => Dict(
                    "type" => "object",
                    "properties" => Dict(
                        "name" => Dict("type" => "string"),
                        "hex" => Dict("type" => "string")
                    ),
                    "required" => ["name", "hex"],
                    "additionalProperties" => false
                )
            )
        ),
        "required" => ["colors"],
        "additionalProperties" => false
    ),
    strict=true
)
println("Format type: ", fmt.format.type)
println("Schema strict: ", fmt.format.strict)
Format type: json_schema
Schema strict: true
result = respond("List red, green, and blue with their hex codes", text=fmt, model="gpt-5.4-mini")
if result isa ResponseSuccess
    println(JSON.json(JSON.parse(output_text(result)), 2))
else
    println("Request failed — ", output_text(result))
end
Request failed — Error: KeyError: key "OPENAI_API_KEY" not found

Plain Text Format

tc = text_format()
println("Default format type: ", tc.format.type)
Default format type: text

Convenience Constructors

ConstructorFormat
json_object_format()Unstructured JSON
json_schema_format(name, desc, schema)Schema-constrained JSON
text_format()Plain text (default)

See Also