Structured outputs & tools¶
Tool calling and JSON output, validated by Keln.
Tool calling¶
Standard OpenAI shape, tools, tool_choice, parallel calls where the model supports them:
{
"model": "moonshotai/kimi-k2.7-code",
"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
}]
}
JSON output¶
Both modes:
response_format: {"type": "json_object"}, valid JSON, shape up to the model.response_format: {"type": "json_schema", "json_schema": {…}}, conform to your schema.
json_object guarantees syntactic JSON and, per the OpenAI contract, expects the word "JSON"
to appear somewhere in your prompt. json_schema enforces your shape without that prompt help;
prefer it when the shape matters.
Validation¶
response_format output is checked for parseable JSON (and your schema, where given);
tool-call arguments are checked for valid JSON. Non-streaming responses are checked before
delivery. Streamed responses are validated as they flow; a route that emits broken structure
is penalized and de-routed, so a malformed stream can reach you at most transiently. When the
check must complete before delivery, use non-streaming.
Unsupported combinations¶
When no capacity serving the model supports the requested mode in the transport you asked for,
the request returns a 400: response_format_not_supported or tools_not_supported
(errors).