Hopp til innholdet
Strukturerte utdata

Strukturerte utdata

Be om svaret som JSON: et vilkårlig JSON-objekt, eller JSON som følger et skjema du sender. Bruk det når et program, ikke en person, leser 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-en er teksten i svaret, 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}
  }
}

Modusene i response_format

response_format er et felt i /v1/chat/completions. Uten det er svaret vanlig tekst.

Modus Verdi Hva du får
JSON-objekt {"type": "json_object"} Svaret er JSON uten foreskrevet form. Si i prompten hvilke nøkler du vil ha.
JSON-skjema {"type": "json_schema", "json_schema": {"name": "…", "schema": {…}}} Svaret følger skjemaet du sender: nøklene, typene og de påkrevde feltene.
Strict "strict": true Et felt i json_schema, ikke en tredje modus. Det er true med mindre du sender false.
Felt Type Standard Beskrivelse Brukes av
type string json_object eller json_schema. Påkrevd inne i response_format. text godtas og gir et vanlig tekstsvar. Alle modeller som tar imot modusen
json_schema.schema object JSON Schema-et svaret følger. Send det hver gang type er json_schema. Alle modeller som tar imot modusen
json_schema.name string En etikett for skjemaet, som i OpenAI-formatet. Hostede åpne vektmodeller
json_schema.strict boolean true Om svaret må følge skjemaet nøyaktig. Shannon-modellene bruker hvert skjema som strict. Hostede åpne vektmodeller

JSON-objektmodus trenger ikke noe skjema. Oppgi nøklene i prompten:

Forespørselskropp
{
  "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øtte per modell

Modell json_object json_schema
Alle Shannon-modeller (shannon-*) Ja Ja
Hostede åpne vektmodeller, unntatt de som er nevnt nedenfor Ja Ja
Laguna-S-2.1-W4A16-AUTOROUND-REAP — —
inkling-W4A16-AUTOROUND-REAP Ja —

GET /v1/models rapporterer det samme per id: capabilities.json_schema på alle modeller, og capabilities.response_format på de hostede åpne vektmodellene. Modeller og priser

Støttede skjema-nøkkelord

Hva en modell mottar av skjemaet ditt, avhenger av modellen og av endepunktet:

Modeller /v1/chat/completions /v1/responses
Shannon-modeller Nøkkelordundersettet nedenfor, brukt som strict. Skjemaet slik du sender det, brukt som strict.
Hostede åpne vektmodeller Skjemaet slik du sender det. strict er true med mindre du sender det. Skjemaet slik du sender det. strict er true med mindre du sender det.

Nøkkelordundersettet til Shannon-modellene på /v1/chat/completions:

Nøkkelord Hvordan det leses
Nøkkelord som leses type, format, title, description, nullable, enum, items, properties, required, minItems, maxItems, minimum, maximum, minLength, maxLength, pattern, anyOf, default
$ref Løses fra $defs eller definitions på øverste nivå i skjemaet. Nøkkelord skrevet ved siden av $ref, som description, beholdes. En referanse uten samsvarende definisjon leses som {"type": "object"}.
allOf Medlemmene slås sammen til ett skjema. Der to medlemmer setter samme nøkkelord, gjelder det siste.
oneOf Leses som anyOf.
Skjemaer som refererer til seg selv Utvidet til 24 nivåer. Et dypere nivå leses som {"type": "object"}.
Utenfor undersettet Alle andre nøkkelord, for eksempel additionalProperties, const, multipleOf, uniqueItems, exclusiveMinimum, exclusiveMaximum, patternProperties, prefixItems, minProperties, maxProperties, not og if / then / else. Disse er ikke en del av skjemaet modellen mottar.

På /v1/responses: text.format

/v1/responses skriver den samme forespørselen som text.format. Skjemaet ligger direkte i format, ved siden av name og strict, ikke under en json_schema-nøkkel. For JSON-objektmodus sender du {"format": {"type": "json_object"}}.

Forespørselskropp
{
  "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-en er text i output_text-delen av message-elementet:

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øtte per modell og feilene er de samme som på /v1/chat/completions. Responses API

På /v1/messages: et verktøy som skjema

Messages-formatet har ikke noe felt for strukturert utdata. For JSON fra de samme modellene kaller du /v1/chat/completions eller /v1/responses med samme nøkkel.

For å bli på /v1/messages beskriver du objektet som et verktøy: legg skjemaet ditt i input_schema og oppgi verktøyet i tool_choice. input i tool_use-blokken er da objektet ditt, allerede parset. Et navngitt tool_choice brukes av de hostede åpne vektmodellene.

Forespørselskropp
{
  "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"}
    }
  ]
}

Sjekk at stop_reason er tool_use før du leser blokken. Funksjonskall

Hvordan JSON-en kommer

  • JSON-en er en streng. Svaret har ikke noe parset objekt ved siden av: kjør JSON-parseren din på message.content.
  • Med stream: true kommer JSON-en i delta.content-stykker. Slå dem sammen og parse én gang når strømmen er over; et enkelt stykke er ikke gyldig JSON.
  • En hostet åpen vektmodell besvarer en response_format-forespørsel uten resonneringstekst: reasoning_content er null.

Kontroller det du mottar

Skjemaet veileder hvordan modellen skriver. API-et sammenligner ikke det ferdige svaret med skjemaet ditt, så det er koden din som gjør den endelige kontrollen:

  • Parse inne i en feilbehandler, slik eksemplet øverst gjør.
  • Valider det parsede objektet mot det samme skjemaet i din egen kode, for eksempel med et JSON Schema-bibliotek, Pydantic eller Zod.
  • Et langt svar kan ta slutt før JSON-en er komplett. Et svar uten streaming rapporterer bare finish_reason som stop eller tool_calls, så en parsefeil er signalet. Spør på nytt, eller be om et mindre objekt.

Feil

Status Type Melding Når
400 invalid_request_error <id> does not accept response_format Modellen tar ikke imot noen av modusene.
400 invalid_request_error <id> does not accept response_format json_schema; use json_object Modellen tar imot json_object, og du sendte json_schema.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … response_format har ingen type, eller er ikke et JSON-objekt.

De to 400-svarene sendes før noe trekkes fra saldoen din. Feilhåndtering