Preskoči na sadržaj
Strukturirani izlazi

Strukturirani izlazi

Tražite odgovor kao JSON: bilo koji JSON objekat, ili JSON koji prati šemu koju pošaljete. Koristite ga kada odgovor čita program, a ne osoba.

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)

JSON je tekst odgovora, u choices[0].message.content:

200 JSON
{
  "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}
  }
}

Režimi response_format

response_format je polje /v1/chat/completions. Bez njega je odgovor običan tekst.

Režim Vrednost Šta dobijate
JSON objekat {"type": "json_object"} Odgovor je JSON bez propisanog oblika. U promptu recite koje ključeve želite.
JSON šema {"type": "json_schema", "json_schema": {"name": "…", "schema": {…}}} Odgovor prati šemu koju pošaljete: njene ključeve, tipove i obavezna polja.
Strogo "strict": true Polje json_schema, a ne treći režim. Jeste true osim ako ne pošaljete false.
Polje Tip Podrazumevano Opis Primenjuju
type string json_object ili json_schema. Obavezno unutar response_format. text se prihvata i daje običan tekstualni odgovor. Svaki model koji prima režim
json_schema.schema object JSON šema koju odgovor prati. Pošaljite je kad god je type json_schema. Svaki model koji prima režim
json_schema.name string Oznaka šeme, kao u OpenAI formatu. Hostovani open-weight modeli
json_schema.strict boolean true Da li odgovor mora tačno da prati šemu. Shannon modeli primenjuju svaku šemu kao strogu. Hostovani open-weight modeli

Režim JSON objekta ne traži šemu. Navedite ključeve u promptu:

Telo zahteva
{
  "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"}
}

Podrška po modelu

Model json_object json_schema
Svaki Shannon model (shannon-*) Da Da
Hostovani open-weight modeli, osim onih navedenih ispod Da Da
Laguna-S-2.1-W4A16-AUTOROUND-REAP — —
inkling-W4A16-AUTOROUND-REAP Da —

GET /v1/models prijavljuje isto po id-ju: capabilities.json_schema na svakom modelu i capabilities.response_format na hostovanim open-weight modelima. Modeli i cene

Podržane ključne reči šeme

Šta model prima od vaše šeme zavisi od modela i od endpointa:

Modeli /v1/chat/completions /v1/responses
Shannon modeli Podskup ključnih reči ispod, primenjen kao strog. Šema onako kako je pošaljete, primenjena kao stroga.
Hostovani open-weight modeli Šema onako kako je pošaljete. strict je true osim ako ga ne pošaljete. Šema onako kako je pošaljete. strict je true osim ako ga ne pošaljete.

Podskup ključnih reči Shannon modela na /v1/chat/completions:

Ključna reč Kako se čita
Ključne reči koje se čitaju type, format, title, description, nullable, enum, items, properties, required, minItems, maxItems, minimum, maximum, minLength, maxLength, pattern, anyOf, default
$ref Razrešava se iz $defs ili definitions na vrhu šeme. Ključne reči napisane pored $ref, kao što je description, zadržavaju se. Referenca bez odgovarajuće definicije čita se kao {"type": "object"}.
allOf Članovi se spajaju u jednu šemu. Gde dva člana postavljaju istu ključnu reč, važi kasniji.
oneOf Čita se kao anyOf.
Šeme koje upućuju na sebe Šire se do 24 nivoa. Dublji nivo se čita kao {"type": "object"}.
Izvan podskupa Svaka druga ključna reč, na primer additionalProperties, const, multipleOf, uniqueItems, exclusiveMinimum, exclusiveMaximum, patternProperties, prefixItems, minProperties, maxProperties, not i if / then / else. Ove nisu deo šeme koju model prima.

Na /v1/responses: text.format

/v1/responses piše isti zahtev kao text.format. Šema stoji direktno u format, pored name i strict, a ne pod ključem json_schema. Za režim JSON objekta pošaljite {"format": {"type": "json_object"}}.

Telo zahteva
{
  "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 je text dela output_text stavke message:

200 JSON
{
  "output": [
    {
      "id": "msg_7e1d3c5b9a2f4d6e8c0b1a3f5e7d9c2b",
      "type": "message",
      "role": "assistant",
      "status": "completed",
      "content": [
        {
          "type": "output_text",
          "text": "{\"name\":\"John Doe\",\"age\":30,\"occupation\":\"engineer\"}",
          "annotations": []
        }
      ]
    }
  ]
}

Podrška po modelu i greške iste su kao na /v1/chat/completions. Responses API

Na /v1/messages: alat kao šema

Messages format nema polje za strukturirani izlaz. Za JSON sa istih modela pozovite /v1/chat/completions ili /v1/responses sa istim ključem.

Da ostanete na /v1/messages, opišite objekat kao alat: stavite svoju šemu u input_schema i imenujte alat u tool_choice. input bloka tool_use je tada vaš objekat, već parsiran. Imenovani tool_choice primenjuju hostovani open-weight modeli.

Telo zahteva
{
  "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"}
}
200 JSON
{
  "stop_reason": "tool_use",
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_4b8d2f6a1c3e4a5b9d7f0e2c4a6b8d1f",
      "name": "record_person",
      "input": {"name": "John Doe", "age": 30, "occupation": "engineer"}
    }
  ]
}

Proverite da je stop_reason tool_use pre nego što pročitate blok. Pozivanje funkcija

Kako JSON stiže

  • JSON je string. Odgovor nema parsiran objekat pored sebe: pokrenite svoj JSON parser nad message.content.
  • Sa stream: true JSON stiže u delovima delta.content. Spojite ih i parsirajte kada se stream završi; sam deo nije važeći JSON.
  • Hostovani open-weight model odgovara na response_format zahtev bez teksta rezonovanja: reasoning_content je null.

Proverite šta primate

Šema usmerava kako model piše. API ne poredi gotov odgovor sa vašom šemom, pa konačnu proveru radi vaš kod:

  • Parsirajte unutar rukovaoca greškama, kao što to radi primer na vrhu.
  • Validirajte parsirani objekat istom šemom u sopstvenom kodu, na primer pomoću biblioteke za JSON šemu, Pydantic ili Zod.
  • Dug odgovor može da se završi pre nego što je JSON kompletan. Odgovor bez streama prijavljuje finish_reason samo kao stop ili tool_calls, pa je greška parsiranja signal. Pitajte ponovo, ili tražite manji objekat.

Greške

Status Tip Poruka Kada
400 invalid_request_error <id> does not accept response_format Model ne prima nijedan režim.
400 invalid_request_error <id> does not accept response_format json_schema; use json_object Model prima json_object, a vi ste poslali json_schema.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … response_format nema type, ili nije JSON objekat.

Dva odgovora 400 šalju se pre nego što se bilo šta skine sa vašeg stanja. Upravljanje greškama