Chilkat AI Structured Output (v11.6.0)
Chilkat v11.6.0 adds structured output to the Ai class: you supply a JSON Schema, and the AI model returns a response that conforms to it. This turns the model into a reliable data-extraction and function-argument generator — no more prompting "please respond only with JSON" and hoping for the best.
A single new method drives the feature, and the model's schema-conforming result is retrieved as ordinary JSON.
What was added
Two methods and two read-only properties:
SetOutputSchema(name, schema, strict)— request schema-constrained output for subsequent calls toAsk.GetOutputJson(json)— retrieve the model's structured output, parsed into aJsonObject.LastResponseRefused(read-only bool) — whether the model refused to produce the output.RefusalText(read-only string) — the model's explanation when it refuses.
Basic usage
Ai ai;
ai.put_Provider("openai");
ai.put_ApiKey(myKey);
ai.put_Model("gpt-5.1");
// Describe the desired output as a JSON Schema.
JsonObject schema;
schema.Load("{ \"type\": \"object\","
" \"properties\": {"
" \"name\": { \"type\": \"string\" },"
" \"age\": { \"type\": \"integer\" }"
" },"
" \"required\": [\"name\", \"age\"] }");
// Enable structured output. The 2nd argument is the schema; the 3rd requests strict conformance.
ai.SetOutputSchema("person", schema, true);
ai.InputAddText("Extract the person: Dr. Jane Doe is 42.");
ai.Ask("text");
// Retrieve the schema-conforming result, parsed.
JsonObject person;
if (ai.GetOutputJson(person)) {
// person.IntOf("age") -> 42
}
The raw JSON string is also available from GetOutputText / GetOutputTextSb, exactly as with any other response.
One schema, every provider
Structured output is requested the same way regardless of provider. Chilkat translates your single JSON Schema into whatever shape the selected provider's API expects:
Because only the request changes per provider, the same code works across OpenAI, Anthropic Claude, Google Gemini, xAI Grok, Mistral, and Perplexity — switch providers by changing the Provider property and nothing else. When a provider (such as DeepSeek) can't enforce a schema, the Ask proceeds in JSON-object mode and a note is written to LastErrorText, so provider-switching code keeps working.
Strict mode and automatic schema augmentation
When strict is true, Chilkat automatically augments your schema to satisfy the stricter providers (OpenAI and Anthropic), so you can supply an ordinary, readable JSON Schema. For every object in the schema, Chilkat adds "additionalProperties": false and marks all of its properties required, recursing through nested objects and array items. Your original schema object is left untouched — the augmentation is applied to an internal copy at request time.
If you prefer to control the exact schema sent to the provider, pass strict = false and Chilkat forwards the schema unmodified.
Refusals
A model may occasionally refuse to produce the requested output (for example, on a safety-sensitive request). Chilkat surfaces this distinctly rather than returning malformed JSON:
GetOutputJsonreturnsfalse.LastResponseRefusedistrue.RefusalTextcontains the model's explanation.
LastResponseRefused is reset at the start of every Ask. Refusals are detected for the OpenAI Responses API (a refusal content item), the Chat-Completions family (choices[0].message.refusal), and Anthropic Claude (stop_reason of "refusal").
Notes
- Clearing the schema. Pass an empty string as the name to
SetOutputSchemato disable structured output for subsequent calls. - Streaming. Structured output works in streaming mode — the JSON arrives as text deltas and can be parsed with
GetOutputJsonafter the response completes. - Conversations and tools. Structured output composes with conversations and with automatic tool/function calling.