Rezultate structurate
Cere răspunsul ca JSON: orice obiect JSON sau JSON care urmează o schemă pe care o trimiți. Folosește-l când un program, nu un om, citește răspunsul.
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"]
}
}
}
}' JSON-ul este textul răspunsului, în 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}
}
} Modurile lui response_format
response_format este un câmp al lui /v1/chat/completions. Fără el, răspunsul este text obișnuit.
| Mod | Valoare | Ce primești |
|---|---|---|
| Obiect JSON | {"type": "json_object"} | Răspunsul este JSON fără o formă prescrisă. Spune în prompt ce chei vrei. |
| Schemă JSON | {"type": "json_schema", "json_schema": {"name": "…", "schema": {…}}} | Răspunsul urmează schema pe care o trimiți: cheile, tipurile și câmpurile ei obligatorii. |
| Strict | "strict": true | Un câmp al lui json_schema, nu un al treilea mod. Este true dacă nu trimiți false. |
| Câmp | Tip | Implicit | Descriere | Aplicat de |
|---|---|---|---|---|
type | string | json_object sau json_schema. Obligatoriu în response_format. text este acceptat și dă un răspuns text obișnuit. | Fiecare model care acceptă modul | |
json_schema.schema | object | JSON Schema pe care o urmează răspunsul. Trimite-o ori de câte ori type este json_schema. | Fiecare model care acceptă modul | |
json_schema.name | string | O etichetă pentru schemă, ca în formatul OpenAI. | Modele open-weight găzduite | |
json_schema.strict | boolean | true | Dacă răspunsul trebuie să urmeze exact schema. Modelele Shannon aplică orice schemă ca strictă. | Modele open-weight găzduite |
Modul obiect JSON nu cere o schemă. Numește cheile în 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"}
} Suport pe model
| Model | json_object | json_schema |
|---|---|---|
Fiecare model Shannon (shannon-*) | Da | Da |
| Modele open-weight găzduite, cu excepția celor numite mai jos | Da | Da |
Laguna-S-2.1-W4A16-AUTOROUND-REAP | — | — |
inkling-W4A16-AUTOROUND-REAP | Da | — |
GET /v1/models raportează același lucru pe id: capabilities.json_schema pe fiecare model și capabilities.response_format pe modelele open-weight găzduite. Modele și prețuri
Cuvinte-cheie de schemă acceptate
Ce primește un model din schema ta depinde de model și de endpoint:
| Modele | /v1/chat/completions | /v1/responses |
|---|---|---|
| Modele Shannon | Subsetul de cuvinte-cheie de mai jos, aplicat ca strict. | Schema așa cum o trimiți, aplicată ca strictă. |
| Modele open-weight găzduite | Schema așa cum o trimiți. strict este true dacă nu îl trimiți. | Schema așa cum o trimiți. strict este true dacă nu îl trimiți. |
Subsetul de cuvinte-cheie al modelelor Shannon pe /v1/chat/completions:
| Cuvânt-cheie | Cum este citit |
|---|---|
| Cuvinte-cheie citite | type, format, title, description, nullable, enum, items, properties, required, minItems, maxItems, minimum, maximum, minLength, maxLength, pattern, anyOf, default |
$ref | Rezolvat din $defs sau definitions de la nivelul de sus al schemei. Cuvintele-cheie scrise lângă $ref, precum description, sunt păstrate. O referință fără definiție corespunzătoare este citită ca {"type": "object"}. |
allOf | Membrii sunt uniți într-o singură schemă. Unde doi membri setează același cuvânt-cheie, contează cel de-al doilea. |
oneOf | Citit ca anyOf. |
| Scheme care se referă la ele însele | Expandate până la 24 de niveluri. Un nivel mai adânc este citit ca {"type": "object"}. |
| În afara subsetului | Orice alt cuvânt-cheie, de exemplu additionalProperties, const, multipleOf, uniqueItems, exclusiveMinimum, exclusiveMaximum, patternProperties, prefixItems, minProperties, maxProperties, not și if / then / else. Acestea nu fac parte din schema pe care o primește modelul. |
Pe /v1/responses: text.format
/v1/responses scrie aceeași cerere ca text.format. Schema stă direct în format, lângă name și strict, nu sub o cheie json_schema. Pentru modul obiect JSON, trimite {"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"]
}
}
}
} JSON-ul este text din partea output_text a elementului message:
{
"output": [
{
"id": "msg_7e1d3c5b9a2f4d6e8c0b1a3f5e7d9c2b",
"type": "message",
"role": "assistant",
"status": "completed",
"content": [
{
"type": "output_text",
"text": "{\"name\":\"John Doe\",\"age\":30,\"occupation\":\"engineer\"}",
"annotations": []
}
]
}
]
} Suportul pe model și erorile sunt aceleași ca pe /v1/chat/completions. Responses API
Pe /v1/messages: un instrument ca schemă
Formatul Messages nu are un câmp de ieșire structurată. Pentru JSON de la aceleași modele, apelează /v1/chat/completions sau /v1/responses cu aceeași cheie.
Ca să rămâi pe /v1/messages, descrie obiectul ca un instrument: pune schema ta în input_schema și numește instrumentul în tool_choice. input al blocului tool_use este atunci obiectul tău, deja parsat. Un tool_choice numit este aplicat de modelele open-weight găzduite.
{
"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"}
}
]
} Verifică dacă stop_reason este tool_use înainte de a citi blocul. Apelare funcții
Cum sosește JSON-ul
- JSON-ul este un șir. Răspunsul nu are alături un obiect parsat: rulează parserul tău JSON pe
message.content. - Cu
stream: true, JSON-ul sosește în bucățidelta.content. Unește-le și parsează o singură dată, după încheierea stream-ului; o bucată singură nu este JSON valid. - Un model open-weight găzduit răspunde la o cerere cu
response_formatfără text de raționament:reasoning_contentestenull.
Verifică ce primești
Schema ghidează cum scrie modelul. API-ul nu compară răspunsul final cu schema ta, deci codul tău face verificarea finală:
- Parsează într-un handler de erori, ca în exemplul de la început.
- Validează obiectul parsat cu aceeași schemă în propriul cod, de exemplu cu o bibliotecă JSON Schema, Pydantic sau Zod.
- Un răspuns lung se poate termina înainte ca JSON-ul să fie complet. Un răspuns fără streaming raportează
finish_reasondoar castopsautool_calls, deci o eroare de parsare este semnalul. Cere din nou sau cere un obiect mai mic.
Erori
| Stare | Tip | Mesaj | Când |
|---|---|---|---|
400 | invalid_request_error | <id> does not accept response_format | Modelul nu acceptă niciun mod. |
400 | invalid_request_error | <id> does not accept response_format json_schema; use json_object | Modelul acceptă json_object, iar tu ai trimis json_schema. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | response_format nu are type sau nu este un obiect JSON. |
Cele două răspunsuri 400 sunt trimise înainte de a se scădea ceva din soldul tău. Gestionare erori