Μετάβαση στο περιεχόμενο
Δομημένες έξοδοι

Δομημένες έξοδοι

Ζητήστε την απάντηση ως JSON: οποιοδήποτε αντικείμενο JSON, ή JSON που ακολουθεί ένα schema που στέλνετε. Χρησιμοποιήστε το όταν την απάντηση τη διαβάζει ένα πρόγραμμα και όχι άνθρωπος.

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 είναι το κείμενο της απάντησης, στο 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}
  }
}

Οι λειτουργίες (modes) του response_format

Το response_format είναι πεδίο του /v1/chat/completions. Χωρίς αυτό η απάντηση είναι συνηθισμένο κείμενο.

Mode Τιμή Τι παίρνετε
Αντικείμενο JSON {"type": "json_object"} Η απάντηση είναι JSON χωρίς προκαθορισμένη μορφή. Πείτε στο prompt ποια κλειδιά θέλετε.
JSON schema {"type": "json_schema", "json_schema": {"name": "…", "schema": {…}}} Η απάντηση ακολουθεί το schema που στέλνετε: τα κλειδιά, τους τύπους και τα υποχρεωτικά πεδία του.
Strict "strict": true Πεδίο του json_schema, όχι τρίτο mode. Είναι true εκτός αν στείλετε false.
Πεδίο Τύπος Προεπιλογή Περιγραφή Εφαρμόζεται από
type string json_object ή json_schema. Υποχρεωτικό μέσα στο response_format. Το text γίνεται δεκτό και δίνει συνηθισμένη απάντηση κειμένου. Κάθε μοντέλο που δέχεται το mode
json_schema.schema object Το JSON Schema που ακολουθεί η απάντηση. Στείλτε το όποτε το type είναι json_schema. Κάθε μοντέλο που δέχεται το mode
json_schema.name string Μια ετικέτα για το schema, όπως στη μορφή OpenAI. Φιλοξενούμενα μοντέλα ανοιχτών βαρών
json_schema.strict boolean true Αν η απάντηση πρέπει να ακολουθεί ακριβώς το schema. Τα μοντέλα Shannon εφαρμόζουν κάθε schema ως strict. Φιλοξενούμενα μοντέλα ανοιχτών βαρών

Το mode αντικειμένου JSON δεν χρειάζεται schema. Ονομάστε τα κλειδιά στο prompt:

Σώμα αιτήματος
{
  "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"}
}

Υποστήριξη ανά μοντέλο

Μοντέλο json_object json_schema
Κάθε μοντέλο Shannon (shannon-*) Ναι Ναι
Φιλοξενούμενα μοντέλα ανοιχτών βαρών, εκτός από όσα ονομάζονται παρακάτω Ναι Ναι
Laguna-S-2.1-W4A16-AUTOROUND-REAP — —
inkling-W4A16-AUTOROUND-REAP Ναι —

Το GET /v1/models αναφέρει το ίδιο ανά id: capabilities.json_schema σε κάθε μοντέλο, και capabilities.response_format στα φιλοξενούμενα μοντέλα ανοιχτών βαρών. Μοντέλα & τιμές

Υποστηριζόμενες λέξεις-κλειδιά του schema

Όσα λαμβάνει ένα μοντέλο από το schema σας εξαρτώνται από το μοντέλο και από το endpoint:

Μοντέλα /v1/chat/completions /v1/responses
Μοντέλα Shannon Το υποσύνολο λέξεων-κλειδιών παρακάτω, εφαρμοσμένο ως strict. Το schema όπως το στέλνετε, εφαρμοσμένο ως strict.
Φιλοξενούμενα μοντέλα ανοιχτών βαρών Το schema όπως το στέλνετε. Το strict είναι true εκτός αν το στείλετε. Το schema όπως το στέλνετε. Το strict είναι true εκτός αν το στείλετε.

Το υποσύνολο λέξεων-κλειδιών των μοντέλων Shannon στο /v1/chat/completions:

Λέξη-κλειδί Πώς διαβάζεται
Λέξεις-κλειδιά που διαβάζονται type, format, title, description, nullable, enum, items, properties, required, minItems, maxItems, minimum, maximum, minLength, maxLength, pattern, anyOf, default
$ref Επιλύεται από τα $defs ή definitions στο ανώτατο επίπεδο του schema. Οι λέξεις-κλειδιά που γράφονται δίπλα στο $ref, όπως το description, διατηρούνται. Μια αναφορά χωρίς αντίστοιχο ορισμό διαβάζεται ως {"type": "object"}.
allOf Τα μέλη συγχωνεύονται σε ένα schema. Όπου δύο μέλη ορίζουν την ίδια λέξη-κλειδί, ισχύει το μεταγενέστερο.
oneOf Διαβάζεται ως anyOf.
Schemas που αναφέρονται στον εαυτό τους Αναπτύσσονται μέχρι 24 επίπεδα. Ένα βαθύτερο επίπεδο διαβάζεται ως {"type": "object"}.
Εκτός του υποσυνόλου Κάθε άλλη λέξη-κλειδί, για παράδειγμα additionalProperties, const, multipleOf, uniqueItems, exclusiveMinimum, exclusiveMaximum, patternProperties, prefixItems, minProperties, maxProperties, not και if / then / else. Αυτές δεν ανήκουν στο schema που λαμβάνει το μοντέλο.

Στο /v1/responses: το πεδίο text.format

Το /v1/responses γράφει το ίδιο αίτημα ως text.format. Το schema βρίσκεται απευθείας στο format, δίπλα στα name και strict, όχι κάτω από κλειδί json_schema. Για mode αντικειμένου JSON στείλτε {"format": {"type": "json_object"}}.

Σώμα αιτήματος
{
  "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 είναι το text του μέρους output_text του στοιχείου 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": []
        }
      ]
    }
  ]
}

Η υποστήριξη ανά μοντέλο και τα σφάλματα είναι ίδια με το /v1/chat/completions. Responses API

Στο /v1/messages: ένα εργαλείο ως schema

Η μορφή Messages δεν έχει πεδίο δομημένης εξόδου. Για JSON από τα ίδια μοντέλα, καλέστε το /v1/chat/completions ή το /v1/responses με το ίδιο κλειδί.

Για να μείνετε στο /v1/messages, περιγράψτε το αντικείμενο ως εργαλείο: βάλτε το schema σας στο input_schema και ονομάστε το εργαλείο στο tool_choice. Το input του block tool_use είναι τότε το αντικείμενό σας, ήδη μετά από parse. Ένα tool_choice με όνομα εφαρμόζεται από τα φιλοξενούμενα μοντέλα ανοιχτών βαρών.

Σώμα αιτήματος
{
  "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"}
    }
  ]
}

Ελέγξτε ότι το stop_reason είναι tool_use πριν διαβάσετε το block. Κλήση συναρτήσεων

Πώς φτάνει το JSON

  • Το JSON είναι string. Η απάντηση δεν έχει δίπλα της αντικείμενο που έχει ήδη γίνει parse: εκτελέστε τον parser JSON σας στο message.content.
  • Με stream: true το JSON φτάνει σε κομμάτια delta.content. Ενώστε τα και κάντε parse όταν τελειώσει το stream· ένα κομμάτι από μόνο του δεν είναι έγκυρο JSON.
  • Ένα φιλοξενούμενο μοντέλο ανοιχτών βαρών απαντά σε αίτημα με response_format χωρίς κείμενο συλλογισμού: το reasoning_content είναι null.

Ελέγξτε ό,τι λαμβάνετε

Το schema καθοδηγεί τον τρόπο που γράφει το μοντέλο. Το API δεν συγκρίνει την ολοκληρωμένη απάντηση με το schema σας, οπότε ο κώδικάς σας κάνει τον τελικό έλεγχο:

  • Κάντε parse μέσα σε χειριστή σφαλμάτων, όπως το παράδειγμα στην κορυφή.
  • Επικυρώστε το αντικείμενο μετά το parse με το ίδιο schema στον δικό σας κώδικα, για παράδειγμα με βιβλιοθήκη JSON Schema, Pydantic ή Zod.
  • Μια μεγάλη απάντηση μπορεί να τελειώσει πριν ολοκληρωθεί το JSON. Μια απάντηση χωρίς streaming αναφέρει το finish_reason μόνο ως stop ή tool_calls, οπότε το σφάλμα parse είναι το σήμα. Ρωτήστε ξανά, ή ζητήστε μικρότερο αντικείμενο.

Σφάλματα

Κατάσταση Τύπος Μήνυμα Πότε
400 invalid_request_error <id> does not accept response_format Το μοντέλο δεν δέχεται κανένα από τα δύο modes.
400 invalid_request_error <id> does not accept response_format json_schema; use json_object Το μοντέλο δέχεται json_object και στείλατε json_schema.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … Το response_format δεν έχει type, ή δεν είναι αντικείμενο JSON.

Οι δύο απαντήσεις 400 στέλνονται πριν αφαιρεθεί οτιδήποτε από το υπόλοιπό σας. Χειρισμός σφαλμάτων