Strukturierte Ausgaben
Fordern Sie die Antwort als JSON an: ein beliebiges JSON-Objekt oder JSON, das einem von Ihnen gesendeten Schema folgt. Verwenden Sie es, wenn ein Programm statt eines Menschen die Antwort liest.
POST https://api.shannon-ai.com/v1/chat/completions
import json
from openai import OpenAI
client = OpenAI(api_key="YOUR_API_KEY", base_url="https://api.shannon-ai.com/v1")
response = client.chat.completions.create(
model="Kimi-K3-3BIT-REAP",
messages=[
{"role": "user", "content": "Extract the person: John Doe, 30 years old, engineer."}
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "person",
"strict": True,
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"occupation": {"type": "string"},
},
"required": ["name", "age", "occupation"],
},
},
},
)
# The JSON arrives as text in message.content: parse it, then check it.
try:
person = json.loads(response.choices[0].message.content)
except json.JSONDecodeError:
person = None # ask again, or report the failure
print(person) import OpenAI from "openai";
const client = new OpenAI({ apiKey: "YOUR_API_KEY", baseURL: "https://api.shannon-ai.com/v1" });
const response = await client.chat.completions.create({
model: "Kimi-K3-3BIT-REAP",
messages: [
{ role: "user", content: "Extract the person: John Doe, 30 years old, engineer." },
],
response_format: {
type: "json_schema",
json_schema: {
name: "person",
strict: true,
schema: {
type: "object",
properties: {
name: { type: "string" },
age: { type: "integer" },
occupation: { type: "string" },
},
required: ["name", "age", "occupation"],
},
},
},
});
// The JSON arrives as text in message.content: parse it, then check it.
let person = null;
try {
person = JSON.parse(response.choices[0].message.content);
} catch {
// ask again, or report the failure
}
console.log(person); curl https://api.shannon-ai.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "Kimi-K3-3BIT-REAP",
"messages": [
{"role": "user", "content": "Extract the person: John Doe, 30 years old, engineer."}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "person",
"strict": true,
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"occupation": {"type": "string"}
},
"required": ["name", "age", "occupation"]
}
}
}
}' Das JSON ist der Text der Antwort, in choices[0].message.content:
{
"id": "chatcmpl-0c4e7a1b9d2f4e6a8b3c5d7e9f1a2b3c",
"object": "chat.completion",
"created": 1791590400,
"model": "Kimi-K3-3BIT-REAP",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\"name\":\"John Doe\",\"age\":30,\"occupation\":\"engineer\"}",
"reasoning_content": null
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 96,
"completion_tokens": 19,
"total_tokens": 115,
"prompt_tokens_details": {"cached_tokens": 0},
"completion_tokens_details": {"reasoning_tokens": 0}
}
} Die Modi von response_format
response_format ist ein Feld von /v1/chat/completions. Ohne es ist die Antwort gewöhnlicher Text.
| Modus | Wert | Was Sie erhalten |
|---|---|---|
| JSON-Objekt | {"type": "json_object"} | Die Antwort ist JSON ohne vorgeschriebene Form. Sagen Sie im Prompt, welche Schlüssel Sie wollen. |
| JSON-Schema | {"type": "json_schema", "json_schema": {"name": "…", "schema": {…}}} | Die Antwort folgt dem Schema, das Sie senden: seinen Schlüsseln, Typen und Pflichtfeldern. |
| Strict | "strict": true | Ein Feld von json_schema, kein dritter Modus. Es ist true, wenn Sie nicht false senden. |
| Feld | Typ | Standard | Beschreibung | Angewendet von |
|---|---|---|---|---|
type | string | json_object oder json_schema. Innerhalb von response_format erforderlich. text wird akzeptiert und ergibt eine gewöhnliche Textantwort. | Jedes Modell, das den Modus annimmt | |
json_schema.schema | object | Das JSON-Schema, dem die Antwort folgt. Senden Sie es, sobald type json_schema ist. | Jedes Modell, das den Modus annimmt | |
json_schema.name | string | Eine Bezeichnung für das Schema, wie im OpenAI-Format. | Gehostete Open-Weight-Modelle | |
json_schema.strict | boolean | true | Ob die Antwort dem Schema genau folgen muss. Die Shannon-Modelle wenden jedes Schema als strict an. | Gehostete Open-Weight-Modelle |
Der JSON-Objekt-Modus braucht kein Schema. Nennen Sie die Schlüssel im Prompt:
{
"model": "shannon-3",
"messages": [
{
"role": "user",
"content": "Name the capital of France. Answer as JSON with the keys city and country."
}
],
"response_format": {"type": "json_object"}
} Unterstützung pro Modell
| Modell | json_object | json_schema |
|---|---|---|
Jedes Shannon-Modell (shannon-*) | Ja | Ja |
| Gehostete Open-Weight-Modelle, außer den unten genannten | Ja | Ja |
Laguna-S-2.1-W4A16-AUTOROUND-REAP | — | — |
inkling-W4A16-AUTOROUND-REAP | Ja | — |
GET /v1/models meldet dasselbe pro ID: capabilities.json_schema bei jedem Modell und capabilities.response_format bei den gehosteten Open-Weight-Modellen. Modelle & Preise
Unterstützte Schema-Schlüsselwörter
Was ein Modell von Ihrem Schema erhält, hängt vom Modell und vom Endpunkt ab:
| Modelle | /v1/chat/completions | /v1/responses |
|---|---|---|
| Shannon-Modelle | Die Schlüsselwort-Teilmenge unten, als strict angewendet. | Das Schema so, wie Sie es senden, als strict angewendet. |
| Gehostete Open-Weight-Modelle | Das Schema so, wie Sie es senden. strict ist true, wenn Sie es nicht senden. | Das Schema so, wie Sie es senden. strict ist true, wenn Sie es nicht senden. |
Die Schlüsselwort-Teilmenge der Shannon-Modelle bei /v1/chat/completions:
| Schlüsselwort | Wie es gelesen wird |
|---|---|
| Gelesene Schlüsselwörter | type, format, title, description, nullable, enum, items, properties, required, minItems, maxItems, minimum, maximum, minLength, maxLength, pattern, anyOf, default |
$ref | Wird aus $defs oder definitions auf oberster Ebene des Schemas aufgelöst. Schlüsselwörter, die neben dem $ref stehen, wie description, bleiben erhalten. Ein Verweis ohne passende Definition wird als {"type": "object"} gelesen. |
allOf | Die Member werden zu einem Schema zusammengeführt. Setzen zwei Member dasselbe Schlüsselwort, zählt das spätere. |
oneOf | Wird als anyOf gelesen. |
| Schemas, die auf sich selbst verweisen | Auf 24 Ebenen aufgelöst. Eine tiefere Ebene wird als {"type": "object"} gelesen. |
| Außerhalb der Teilmenge | Jedes andere Schlüsselwort, zum Beispiel additionalProperties, const, multipleOf, uniqueItems, exclusiveMinimum, exclusiveMaximum, patternProperties, prefixItems, minProperties, maxProperties, not und if / then / else. Sie sind nicht Teil des Schemas, das das Modell erhält. |
Bei /v1/responses: text.format
/v1/responses schreibt dieselbe Anfrage als text.format. Das Schema steht direkt in format, neben name und strict, nicht unter einem Schlüssel json_schema. Für den JSON-Objekt-Modus senden Sie {"format": {"type": "json_object"}}.
{
"model": "Kimi-K3-3BIT-REAP",
"input": "Extract the person: John Doe, 30 years old, engineer.",
"text": {
"format": {
"type": "json_schema",
"name": "person",
"strict": true,
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"occupation": {"type": "string"}
},
"required": ["name", "age", "occupation"]
}
}
}
} Das JSON ist der text des output_text-Teils des Elements message:
{
"output": [
{
"id": "msg_7e1d3c5b9a2f4d6e8c0b1a3f5e7d9c2b",
"type": "message",
"role": "assistant",
"status": "completed",
"content": [
{
"type": "output_text",
"text": "{\"name\":\"John Doe\",\"age\":30,\"occupation\":\"engineer\"}",
"annotations": []
}
]
}
]
} Unterstützung pro Modell und Fehler sind dieselben wie bei /v1/chat/completions. Responses API
Bei /v1/messages: ein Tool als Schema
Das Messages-Format hat kein Feld für strukturierte Ausgabe. Für JSON von denselben Modellen rufen Sie /v1/chat/completions oder /v1/responses mit demselben Key auf.
Um bei /v1/messages zu bleiben, beschreiben Sie das Objekt als Tool: Legen Sie Ihr Schema in input_schema und nennen Sie das Tool in tool_choice. Der input des tool_use-Blocks ist dann Ihr Objekt, bereits geparst. Ein benanntes tool_choice wird von den gehosteten Open-Weight-Modellen angewendet.
{
"model": "Kimi-K3-3BIT-REAP",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "Extract the person: John Doe, 30 years old, engineer."
}
],
"tools": [
{
"name": "record_person",
"description": "Record the extracted person.",
"input_schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"occupation": {"type": "string"}
},
"required": ["name", "age", "occupation"]
}
}
],
"tool_choice": {"type": "tool", "name": "record_person"}
} {
"stop_reason": "tool_use",
"content": [
{
"type": "tool_use",
"id": "toolu_4b8d2f6a1c3e4a5b9d7f0e2c4a6b8d1f",
"name": "record_person",
"input": {"name": "John Doe", "age": 30, "occupation": "engineer"}
}
]
} Prüfen Sie, ob stop_reason tool_use ist, bevor Sie den Block lesen. Funktionsaufrufe
Wie das JSON eintrifft
- Das JSON ist ein String. Die Antwort enthält daneben kein geparstes Objekt: Lassen Sie Ihren JSON-Parser über
message.contentlaufen. - Mit
stream: truetrifft das JSON in Stücken vondelta.contentein. Fügen Sie sie zusammen und parsen Sie einmal, wenn der Stream beendet ist; ein einzelnes Stück ist kein gültiges JSON. - Ein gehostetes Open-Weight-Modell beantwortet eine Anfrage mit
response_formatohne Reasoning-Text:reasoning_contentistnull.
Prüfen, was Sie erhalten
Das Schema lenkt, wie das Modell schreibt. Die API vergleicht die fertige Antwort nicht mit Ihrem Schema, daher nimmt Ihr Code die abschließende Prüfung vor:
- Parsen Sie innerhalb eines Fehler-Handlers, wie es das Beispiel ganz oben tut.
- Validieren Sie das geparste Objekt mit demselben Schema in Ihrem eigenen Code, zum Beispiel mit einer JSON-Schema-Bibliothek, Pydantic oder Zod.
- Eine lange Antwort kann enden, bevor das JSON vollständig ist. Eine nicht gestreamte Antwort meldet
finish_reasonnur alsstopodertool_calls, daher ist ein Parse-Fehler das Signal. Fragen Sie erneut oder verlangen Sie ein kleineres Objekt.
Fehler
| Status | Typ | Nachricht | Wann |
|---|---|---|---|
400 | invalid_request_error | <id> does not accept response_format | Das Modell nimmt keinen der beiden Modi an. |
400 | invalid_request_error | <id> does not accept response_format json_schema; use json_object | Das Modell nimmt json_object an, und Sie haben json_schema gesendet. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | response_format hat keinen type oder ist kein JSON-Objekt. |
Die beiden 400-Antworten werden gesendet, bevor etwas von Ihrem Guthaben abgebucht wird. Fehlerbehandlung