Gå til indhold
Strukturerede outputs

Strukturerede outputs

Bed om svaret som JSON: et vilkårligt JSON-objekt eller JSON, der følger et skema, du sender. Brug det, når et program, ikke et menneske, 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'en er svarets tekst, 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}
  }
}

Tilstandene i response_format

response_format er et felt i /v1/chat/completions. Uden det er svaret almindelig tekst.

Tilstand Værdi Hvad du får
JSON-objekt {"type": "json_object"} Svaret er JSON uden en foreskrevet form. Sig i prompten, hvilke nøgler du ønsker.
JSON-skema {"type": "json_schema", "json_schema": {"name": "…", "schema": {…}}} Svaret følger det skema, du sender: dets nøgler, typer og påkrævede felter.
Strict "strict": true Et felt i json_schema, ikke en tredje tilstand. Det er true, medmindre du sender false.
Felt Type Standard Beskrivelse Anvendes af
type string json_object eller json_schema. Påkrævet inde i response_format. text accepteres og giver et almindeligt tekstsvar. Hver model, der tager tilstanden
json_schema.schema object Det JSON-skema, svaret følger. Send det, når type er json_schema. Hver model, der tager tilstanden
json_schema.name string En etiket til skemaet, som i OpenAI-formatet. Hostede open-weight-modeller
json_schema.strict boolean true Om svaret skal følge skemaet præcist. Shannon-modellerne anvender hvert skema som strict. Hostede open-weight-modeller

JSON-objekt-tilstand kræver intet skema. Nævn nøglerne i prompten:

Anmodningens body
{
  "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"}
}

Understøttelse per model

Model json_object json_schema
Hver Shannon-model (shannon-*) Ja Ja
Hostede open-weight-modeller, undtagen dem der er nævnt nedenfor Ja Ja
Laguna-S-2.1-W4A16-AUTOROUND-REAP — —
inkling-W4A16-AUTOROUND-REAP Ja —

GET /v1/models melder det samme per id: capabilities.json_schema på alle modeller og capabilities.response_format på de hostede open-weight-modeller. Modeller og priser

Understøttede skemanøgleord

Hvad en model modtager af dit skema, afhænger af modellen og af endpointet:

Modeller /v1/chat/completions /v1/responses
Shannon-modeller Delmængden af nøgleord nedenfor, anvendt som strict. Skemaet, som du sender det, anvendt som strict.
Hostede open-weight-modeller Skemaet, som du sender det. strict er true, medmindre du sender det. Skemaet, som du sender det. strict er true, medmindre du sender det.

Delmængden af nøgleord for Shannon-modellerne på /v1/chat/completions:

Nøgleord Hvordan det læses
Nøgleord, der læses type, format, title, description, nullable, enum, items, properties, required, minItems, maxItems, minimum, maximum, minLength, maxLength, pattern, anyOf, default
$ref Opløses fra $defs eller definitions på skemaets øverste niveau. Nøgleord skrevet ved siden af $ref, f.eks. description, bevares. En henvisning uden en tilsvarende definition læses som {"type": "object"}.
allOf Medlemmerne slås sammen til ét skema. Hvor to medlemmer sætter det samme nøgleord, gælder det sidste.
oneOf Læses som anyOf.
Skemaer, der henviser til sig selv Udvides til 24 niveauer. Et dybere niveau læses som {"type": "object"}.
Uden for delmængden Alle andre nøgleord, f.eks. additionalProperties, const, multipleOf, uniqueItems, exclusiveMinimum, exclusiveMaximum, patternProperties, prefixItems, minProperties, maxProperties, not og if / then / else. De er ikke en del af det skema, modellen modtager.

På /v1/responses: text.format

/v1/responses staver den samme anmodning som text.format. Skemaet står direkte i format, ved siden af name og strict, ikke under en json_schema-nøgle. For JSON-objekt-tilstand sendes {"format": {"type": "json_object"}}.

Anmodningens body
{
  "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 af 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": []
        }
      ]
    }
  ]
}

Understøttelse per model og fejlene er de samme som på /v1/chat/completions. Responses API

På /v1/messages: et værktøj som skema

Messages-formatet har intet felt til struktureret output. For JSON fra de samme modeller skal du kalde /v1/chat/completions eller /v1/responses med den samme nøgle.

For at blive på /v1/messages skal du beskrive objektet som et værktøj: læg dit skema i input_schema, og navngiv værktøjet i tool_choice. input i tool_use-blokken er så dit objekt, allerede parset. Et navngivet tool_choice anvendes af de hostede open-weight-modeller.

Anmodningens body
{
  "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"}
    }
  ]
}

Kontrollér, at stop_reason er tool_use, før du læser blokken. Funktionskald

Hvordan JSON'en ankommer

  • JSON'en er en streng. Svaret har intet parset objekt ved siden af: kør din JSON-parser på message.content.
  • Med stream: true ankommer JSON'en i delta.content-stykker. Sæt dem sammen, og parse, når streamen er slut; et enkelt stykke er ikke gyldig JSON.
  • En hostet open-weight-model besvarer en response_format-anmodning uden ræsonnementstekst: reasoning_content er null.

Kontrollér det, du modtager

Skemaet vejleder, hvordan modellen skriver. API'et sammenligner ikke det færdige svar med dit skema, så din kode foretager den endelige kontrol:

  • Parse inde i en fejlhåndterer, som eksemplet øverst gør.
  • Valider det parsede objekt med det samme skema i din egen kode, f.eks. med et JSON Schema-bibliotek, Pydantic eller Zod.
  • Et langt svar kan slutte, før JSON'en er komplet. Et svar, der ikke streames, melder kun finish_reason som stop eller tool_calls, så en parsefejl er signalet. Spørg igen, eller bed om et mindre objekt.

Fejl

Status Type Besked Hvornår
400 invalid_request_error <id> does not accept response_format Modellen tager ingen af tilstandene.
400 invalid_request_error <id> does not accept response_format json_schema; use json_object Modellen tager 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-svar sendes, før der trækkes noget fra din saldo. Fejlhåndtering