Hoppa till innehållet
Strukturerade utdata

Strukturerade utdata

Be om svaret som JSON: vilket JSON-objekt som helst, eller JSON som följer ett schema som du skickar. Använd det när ett program, inte en person, läser svaret.

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 är svarets text, i 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}
  }
}

Lägena i response_format

response_format är ett fält i /v1/chat/completions. Utan det är svaret vanlig text.

Läge Värde Vad du får
JSON-objekt {"type": "json_object"} Svaret är JSON utan föreskriven form. Ange i prompten vilka nycklar du vill ha.
JSON-schema {"type": "json_schema", "json_schema": {"name": "…", "schema": {…}}} Svaret följer schemat som du skickar: dess nycklar, typer och obligatoriska fält.
Strict "strict": true Ett fält i json_schema, inte ett tredje läge. Det är true om du inte skickar false.
Fält Typ Standard Beskrivning Tillämpas av
type string json_object eller json_schema. Obligatoriskt inuti response_format. text accepteras och ger ett vanligt textsvar. Varje modell som tar läget
json_schema.schema object Det JSON Schema som svaret följer. Skicka det alltid när type är json_schema. Varje modell som tar läget
json_schema.name string En etikett för schemat, som i OpenAI-formatet. Hostade open-weight-modeller
json_schema.strict boolean true Om svaret måste följa schemat exakt. Shannon-modellerna tillämpar varje schema som strict. Hostade open-weight-modeller

Läget JSON-objekt behöver inget schema. Namnge nycklarna i prompten:

Begäranbody
{
  "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"}
}

Stöd per modell

Modell json_object json_schema
Varje Shannon-modell (shannon-*) Ja Ja
Hostade open-weight-modeller, utom de som nämns nedan Ja Ja
Laguna-S-2.1-W4A16-AUTOROUND-REAP — —
inkling-W4A16-AUTOROUND-REAP Ja —

GET /v1/models rapporterar samma sak per id: capabilities.json_schema på varje modell, och capabilities.response_format på de hostade open-weight-modellerna. Modeller och priser

Nyckelord i scheman som stöds

Vad en modell får av ditt schema beror på modellen och på endpointen:

Modeller /v1/chat/completions /v1/responses
Shannon-modeller Delmängden av nyckelord nedan, tillämpad som strict. Schemat så som du skickar det, tillämpat som strict.
Hostade open-weight-modeller Schemat så som du skickar det. strict är true om du inte skickar det. Schemat så som du skickar det. strict är true om du inte skickar det.

Delmängden av nyckelord för Shannon-modellerna på /v1/chat/completions:

Nyckelord Hur det läses
Nyckelord som läses type, format, title, description, nullable, enum, items, properties, required, minItems, maxItems, minimum, maximum, minLength, maxLength, pattern, anyOf, default
$ref Löses upp från $defs eller definitions på schemats översta nivå. Nyckelord som skrivs bredvid $ref, som description, behålls. En referens utan matchande definition läses som {"type": "object"}.
allOf Medlemmarna slås ihop till ett schema. Där två medlemmar anger samma nyckelord gäller den senare.
oneOf Läses som anyOf.
Scheman som hänvisar till sig själva Expanderas till 24 nivåer. En djupare nivå läses som {"type": "object"}.
Utanför delmängden Varje annat nyckelord, till exempel additionalProperties, const, multipleOf, uniqueItems, exclusiveMinimum, exclusiveMaximum, patternProperties, prefixItems, minProperties, maxProperties, not och if / then / else. De ingår inte i det schema som modellen får.

På /v1/responses: text.format

/v1/responses skriver samma begäran som text.format. Schemat ligger direkt i format, bredvid name och strict, inte under en json_schema-nyckel. För läget JSON-objekt skickar du {"format": {"type": "json_object"}}.

Begäranbody
{
  "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 är text i output_text-delen av message-objektet:

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": []
        }
      ]
    }
  ]
}

Stöd per modell och felen är desamma som på /v1/chat/completions. Responses API

På /v1/messages: ett verktyg som schema

Messages-formatet har inget fält för strukturerad output. För JSON från samma modeller anropar du /v1/chat/completions eller /v1/responses med samma nyckel.

För att stanna kvar på /v1/messages, beskriv objektet som ett verktyg: lägg ditt schema i input_schema och namnge verktyget i tool_choice. input i tool_use-blocket är då ditt objekt, redan parsat. Ett namngivet tool_choice tillämpas av de hostade open-weight-modellerna.

Begäranbody
{
  "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"}
    }
  ]
}

Kontrollera att stop_reason är tool_use innan du läser blocket. Funktionsanrop

Hur JSON kommer

  • JSON är en sträng. Svaret har inget parsat objekt bredvid: kör din JSON-parser på message.content.
  • Med stream: true kommer JSON i bitar i delta.content. Foga ihop dem och parsa när strömmen har tagit slut; en enskild bit är inte giltig JSON.
  • En hostad open-weight-modell besvarar en response_format-begäran utan resonemangstext: reasoning_content är null.

Kontrollera det du får

Schemat styr hur modellen skriver. API:et jämför inte det färdiga svaret med ditt schema, så din kod gör den slutliga kontrollen:

  • Parsa inuti en felhanterare, som exemplet högst upp gör.
  • Validera det parsade objektet mot samma schema i din egen kod, till exempel med ett JSON Schema-bibliotek, Pydantic eller Zod.
  • Ett långt svar kan ta slut innan JSON är komplett. Ett svar som inte streamas rapporterar finish_reason bara som stop eller tool_calls, så ett parsningsfel är signalen. Fråga igen, eller be om ett mindre objekt.

Fel

Status Typ Meddelande När
400 invalid_request_error <id> does not accept response_format Modellen tar inget av lägena.
400 invalid_request_error <id> does not accept response_format json_schema; use json_object Modellen tar json_object och du skickade json_schema.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … response_format saknar type, eller är inte ett JSON-objekt.

De två 400-svaren skickas innan något dras från din balans. Felhantering