تخطَّ إلى المحتوى
مخرجات منظمة

مخرجات منظمة

اطلب الإجابة بصيغة 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. النماذج المفتوحة الأوزان المستضافة
json_schema.strict boolean true هل يجب أن تتبع الإجابة المخطط تماماً. تطبّق نماذج Shannon كل مخطط بصرامة (strict). النماذج المفتوحة الأوزان المستضافة

وضع كائن 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-*) نعم نعم
النماذج المفتوحة الأوزان المستضافة، عدا المذكورة أدناه نعم نعم
Laguna-S-2.1-W4A16-AUTOROUND-REAP — —
inkling-W4A16-AUTOROUND-REAP نعم —

يبلّغ GET /v1/models بالشيء نفسه لكل معرّف: capabilities.json_schema في كل نموذج، وcapabilities.response_format في النماذج المفتوحة الأوزان المستضافة. النماذج والأسعار

كلمات المخطط المفتاحية المدعومة

ما يتلقاه النموذج من مخططك يعتمد على النموذج وعلى نقطة النهاية:

النماذج /v1/chat/completions /v1/responses
نماذج Shannon مجموعة الكلمات المفتاحية الفرعية أدناه، وتُطبَّق بصرامة (strict). المخطط كما ترسله، ويُطبَّق بصرامة (strict).
النماذج المفتوحة الأوزان المستضافة المخطط كما ترسله. وتكون 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 المسمّى.

نص الطلب
{
  "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. اجمعها وحلّلها بعد انتهاء البث؛ فالقطعة وحدها ليست JSON صالحاً.
  • يجيب النموذج المفتوح الأوزان المستضاف عن طلب response_format دون نص استدلال: فتكون reasoning_content هي null.

تحقق مما تتلقاه

يوجّه المخطط طريقة كتابة النموذج. ولا تقارن API الإجابة النهائية بمخططك، ولذلك يجري كودك الفحص الأخير:

  • حلّل داخل معالج أخطاء، كما يفعل المثال في الأعلى.
  • تحقق من الكائن المحلَّل بالمخطط نفسه في كودك، مثلاً بمكتبة JSON Schema أو Pydantic أو Zod.
  • قد تنتهي الإجابة الطويلة قبل اكتمال JSON. والرد غير المبثوث لا يبلّغ عن 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 قبل أن يُخصم أي شيء من رصيدك. معالجة الأخطاء