Langkau ke kandungan
Output Berstruktur

Output Berstruktur

Minta jawapan sebagai JSON: sebarang objek JSON, atau JSON yang mengikut skema yang anda hantar. Gunakannya apabila program, bukan orang, yang membaca balasan.

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 ialah teks jawapan, dalam 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}
  }
}

Mod response_format

response_format ialah medan /v1/chat/completions. Tanpanya, jawapan ialah teks biasa.

Mod Nilai Apa yang anda dapat
Objek JSON {"type": "json_object"} Jawapan ialah JSON tanpa bentuk yang ditetapkan. Nyatakan dalam prompt kunci yang anda mahu.
JSON schema {"type": "json_schema", "json_schema": {"name": "…", "schema": {…}}} Jawapan mengikut skema yang anda hantar: kunci, jenis dan medan wajibnya.
Strict "strict": true Medan json_schema, bukan mod ketiga. Ia ialah true melainkan anda menghantar false.
Medan Jenis Lalai Penerangan Dilaksanakan oleh
type string json_object atau json_schema. Wajib di dalam response_format. text diterima dan memberikan jawapan teks biasa. Setiap model yang menerima mod itu
json_schema.schema object JSON Schema yang diikuti jawapan. Hantarkannya apabila type ialah json_schema. Setiap model yang menerima mod itu
json_schema.name string Label untuk skema, seperti dalam format OpenAI. Model open-weight yang dihoskan
json_schema.strict boolean true Sama ada jawapan mesti mengikut skema dengan tepat. Model Shannon menggunakan setiap skema sebagai strict. Model open-weight yang dihoskan

Mod objek JSON tidak memerlukan skema. Namakan kunci dalam prompt:

Badan permintaan
{
  "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"}
}

Sokongan bagi setiap model

Model json_object json_schema
Setiap model Shannon (shannon-*) Ya Ya
Model open-weight yang dihoskan, kecuali yang dinamakan di bawah Ya Ya
Laguna-S-2.1-W4A16-AUTOROUND-REAP — —
inkling-W4A16-AUTOROUND-REAP Ya —

GET /v1/models melaporkan perkara yang sama bagi setiap id: capabilities.json_schema pada setiap model, dan capabilities.response_format pada model open-weight yang dihoskan. Model & harga

Kata kunci skema yang disokong

Apa yang diterima model daripada skema anda bergantung pada model dan endpoint:

Model /v1/chat/completions /v1/responses
Model Shannon Subset kata kunci di bawah, dikenakan sebagai strict. Skema seperti yang anda hantar, dikenakan sebagai strict.
Model open-weight yang dihoskan Skema seperti yang anda hantar. strict ialah true melainkan anda menghantarnya. Skema seperti yang anda hantar. strict ialah true melainkan anda menghantarnya.

Subset kata kunci model Shannon pada /v1/chat/completions:

Kata kunci Cara ia dibaca
Kata kunci yang dibaca type, format, title, description, nullable, enum, items, properties, required, minItems, maxItems, minimum, maximum, minLength, maxLength, pattern, anyOf, default
$ref Diselesaikan daripada $defs atau definitions di peringkat atas skema. Kata kunci yang ditulis di sebelah $ref, seperti description, dikekalkan. Rujukan tanpa takrifan yang sepadan dibaca sebagai {"type": "object"}.
allOf Ahli digabungkan menjadi satu skema. Apabila dua ahli menetapkan kata kunci yang sama, yang kemudian yang diambil kira.
oneOf Dibaca sebagai anyOf.
Skema yang merujuk dirinya sendiri Dikembangkan sehingga 24 peringkat. Peringkat yang lebih dalam dibaca sebagai {"type": "object"}.
Di luar subset Setiap kata kunci lain, contohnya additionalProperties, const, multipleOf, uniqueItems, exclusiveMinimum, exclusiveMaximum, patternProperties, prefixItems, minProperties, maxProperties, not dan if / then / else. Ini bukan sebahagian daripada skema yang diterima model.

Pada /v1/responses: text.format

/v1/responses mengeja permintaan yang sama sebagai text.format. Skema terletak terus dalam format, di sebelah name dan strict, bukan di bawah kunci json_schema. Untuk mod objek JSON, hantar {"format": {"type": "json_object"}}.

Badan permintaan
{
  "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 ialah text bahagian output_text dalam item 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": []
        }
      ]
    }
  ]
}

Sokongan bagi setiap model dan ralat adalah sama seperti pada /v1/chat/completions. API Responses

Pada /v1/messages: alat sebagai skema

Format Messages tidak mempunyai medan output berstruktur. Untuk JSON daripada model yang sama, panggil /v1/chat/completions atau /v1/responses dengan kunci yang sama.

Untuk kekal pada /v1/messages, huraikan objek sebagai alat: letakkan skema anda dalam input_schema dan namakan alat dalam tool_choice. input blok tool_use kemudian ialah objek anda, yang sudah dihuraikan. tool_choice yang dinamakan dikenakan oleh model open-weight yang dihoskan.

Badan permintaan
{
  "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"}
    }
  ]
}

Semak bahawa stop_reason ialah tool_use sebelum anda membaca blok itu. Panggilan Fungsi

Cara JSON tiba

  • JSON ialah rentetan. Balasan tidak mempunyai objek yang telah dihuraikan di sebelahnya: jalankan penghurai JSON anda pada message.content.
  • Dengan stream: true, JSON tiba dalam bahagian delta.content. Gabungkannya dan huraikan sekali selepas stream tamat; satu bahagian sahaja bukan JSON yang sah.
  • Model open-weight yang dihoskan menjawab permintaan response_format tanpa teks penaakulan: reasoning_content ialah null.

Semak apa yang anda terima

Skema membimbing cara model menulis. API tidak membandingkan jawapan yang siap dengan skema anda, jadi kod anda membuat semakan akhir:

  • Huraikan di dalam pengendali ralat, seperti sampel di bahagian atas.
  • Sahkan objek yang dihuraikan dengan skema yang sama dalam kod anda sendiri, contohnya dengan pustaka JSON Schema, Pydantic atau Zod.
  • Jawapan yang panjang boleh berakhir sebelum JSON lengkap. Balasan yang tidak di-stream melaporkan finish_reason sebagai stop atau tool_calls sahaja, jadi ralat penghuraian ialah isyaratnya. Tanya semula, atau minta objek yang lebih kecil.

Ralat

Status Jenis Mesej Bila
400 invalid_request_error <id> does not accept response_format Model tidak menerima kedua-dua mod.
400 invalid_request_error <id> does not accept response_format json_schema; use json_object Model menerima json_object dan anda menghantar json_schema.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … response_format tidak mempunyai type, atau bukan objek JSON.

Kedua-dua balasan 400 dihantar sebelum apa-apa ditolak daripada baki anda. Pengendalian Ralat