דילוג לתוכן
פלט מובנה

פלט מובנה

בקשו את התשובה כ-JSON: כל אובייקט JSON, או JSON שעוקב אחרי סכמה שאתם שולחים. השתמשו בזה כשתוכנה, ולא אדם, קוראת את התשובה.

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}
  }
}

המצבים של response_format

response_format הוא שדה של /v1/chat/completions. בלעדיו התשובה היא טקסט רגיל.

מצב ערך מה מקבלים
אובייקט JSON {"type": "json_object"} התשובה היא JSON בלי צורה קבועה מראש. אמרו בפרומפט אילו מפתחות אתם רוצים.
סכמת JSON {"type": "json_schema", "json_schema": {"name": "…", "schema": {…}}} התשובה עוקבת אחרי הסכמה שאתם שולחים: המפתחות, הסוגים ושדות החובה שלה.
Strict "strict": true שדה של json_schema, לא מצב שלישי. הוא true אלא אם שלחתם false.
שדה סוג ברירת מחדל תיאור מופעל על ידי
type string json_object או json_schema. חובה בתוך response_format. text מתקבל ונותן תשובת טקסט רגילה. כל מודל שמקבל את המצב
json_schema.schema object ה-JSON Schema שהתשובה עוקבת אחריו. שלחו אותו בכל פעם ש-type הוא json_schema. כל מודל שמקבל את המצב
json_schema.name string תווית לסכמה, כמו בפורמט של OpenAI. מודלי open-weight מתארחים
json_schema.strict boolean true האם התשובה חייבת לעקוב אחרי הסכמה במדויק. מודלי Shannon מיישמים כל סכמה כ-strict. מודלי open-weight מתארחים

מצב אובייקט JSON אינו צריך סכמה. נקבו במפתחות בפרומפט:

גוף הבקשה
{
  "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-*) כן כן
מודלי open-weight מתארחים, חוץ מאלה שמפורטים להלן כן כן
Laguna-S-2.1-W4A16-AUTOROUND-REAP — —
inkling-W4A16-AUTOROUND-REAP כן —

GET /v1/models מדווח אותו דבר לכל מזהה: capabilities.json_schema בכל מודל, ו-capabilities.response_format במודלי ה-open-weight המתארחים. מודלים ותמחור

מילות מפתח נתמכות בסכמה

מה שמודל מקבל מהסכמה שלכם תלוי במודל וב-endpoint:

מודלים /v1/chat/completions /v1/responses
מודלי Shannon תת-קבוצת מילות המפתח שלהלן, מיושמת כ-strict. הסכמה כפי ששלחתם, מיושמת כ-strict.
מודלי open-weight מתארחים הסכמה כפי ששלחתם. strict הוא true אלא אם שלחתם אותו. הסכמה כפי ששלחתם. 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 ברמה העליונה של הסכמה. מילות מפתח שנכתבות לצד ה-$ref, כמו description, נשמרות. הפניה בלי הגדרה מתאימה נקראת כ-{"type": "object"}.
allOf החברים ממוזגים לסכמה אחת. כששני חברים קובעים אותה מילת מפתח, המאוחר קובע.
oneOf נקרא כ-anyOf.
סכמות שמפנות לעצמן מורחבות עד 24 רמות. רמה עמוקה יותר נקראת כ-{"type": "object"}.
מחוץ לתת-הקבוצה כל מילת מפתח אחרת, למשל additionalProperties, const, multipleOf, uniqueItems, exclusiveMinimum, exclusiveMaximum, patternProperties, prefixItems, minProperties, maxProperties, not ו-if / then / else. אלה אינן חלק מהסכמה שהמודל מקבל.

ב-/v1/responses: איך משתמשים בשדה text.format של הבקשה

/v1/responses מאיית את אותה בקשה כ-text.format. הסכמה יושבת ישירות ב-format, לצד name ו-strict, ולא תחת מפתח json_schema. למצב אובייקט 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: כלי כסכמה

בפורמט Messages אין שדה לפלט מובנה. כדי לקבל JSON מאותם מודלים, קראו ל-/v1/chat/completions או ל-/v1/responses עם אותו מפתח.

כדי להישאר ב-/v1/messages, תארו את האובייקט ככלי: שימו את הסכמה שלכם ב-input_schema ונקבו בשם הכלי ב-tool_choice. ה-input של בלוק ה-tool_use הוא אז האובייקט שלכם, כבר מפוענח. tool_choice בשם מיושם על ידי מודלי ה-open-weight המתארחים.

גוף הבקשה
{
  "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 לפני שאתם קוראים את הבלוק. קריאת פונקציות

איך ה-JSON מגיע

  • ה-JSON הוא מחרוזת. אין לצד התשובה אובייקט מפוענח: הריצו את מפענח ה-JSON שלכם על message.content.
  • עם stream: true ה-JSON מגיע בחתיכות delta.content. חברו אותן ופענחו פעם אחת אחרי שה-stream הסתיים; חתיכה בפני עצמה אינה JSON תקין.
  • מודל open-weight מתארח עונה על בקשת response_format בלי טקסט reasoning: reasoning_content הוא null.

בדקו מה שקיבלתם

הסכמה מנחה איך המודל כותב. ה-API אינו משווה את התשובה הסופית לסכמה שלכם, ולכן הקוד שלכם מבצע את הבדיקה הסופית:

  • פענחו בתוך מטפל שגיאות, כמו בדוגמה שבראש הדף.
  • אמתו את האובייקט המפוענח מול אותה סכמה בקוד שלכם, למשל עם ספריית JSON Schema, Pydantic או Zod.
  • תשובה ארוכה יכולה להסתיים לפני שה-JSON שלם. תשובה בלי streaming מדווחת על finish_reason רק כ-stop או tool_calls, ולכן שגיאת פענוח היא האות. בקשו שוב, או בקשו אובייקט קטן יותר.

שגיאות

סטטוס סוג הודעה מתי
400 invalid_request_error <id> does not accept response_format המודל אינו מקבל אף אחד מהמצבים.
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 נשלחות לפני שדבר נגרע מהיתרה שלכם. טיפול בשגיאות