أدلة الذكاء الاصطناعي · 10 دقيقة للقراءة

Structured Outputs: كيف تعيد نماذج LLM بيانات JSON صالحة؟

تُلزم Structured Outputs استجابات LLM باتباع JSON Schema. تعرّف على الفرق بينها وبين JSON mode وtool calling وحدود OpenAI وClaude وGemini.

رسم لتدفق متناثر من الجسيمات المضيئة يمر عبر قالب هندسي شفاف ويخرج في صفوف منتظمة من الكتل الملونة

Structured outputs، أو المخرجات المنظمة، ميزة في LLM API تُلزم استجابة النموذج بالالتزام بـ JSON Schema الذي تحدده. وباستخدام فك الترميز المقيّد، تُحوّل API المخطط إلى قواعد نحوية أو آلة حالات تقيّد توليد الرموز، مما يمنع أخطاء الصياغة والحقول المفقودة في واجهات API لدى OpenAI وAnthropic وGoogle.

ما المقصود بـ Structured Outputs في LLM API؟

تقيّد structured outputs في LLM API الرموز التي يولدها النموذج، بحيث تطابق الاستجابة المكتملة JSON Schema الذي يقدمه المطوّر. تصف كل من Anthropic وGoogle الآلية الأساسية بأنها فك ترميز مقيّد: قبل بدء أخذ العينات، تُحوّل API المخطط إلى قواعد نحوية أو آلة حالات منتهية تستبعد أي رمز تالٍ قد يخالف بنية المخطط أو أسماء مفاتيحه أو أنواع قيمه.

من دون structured outputs، لا ينجح طلب استجابة JSON من نموذج لغوي عبر موجّه بصورة متسقة في بيئة الإنتاج. تسلط وثائق Anthropic الضوء على أربعة أنواع شائعة من الإخفاق عند الاعتماد على تعليمات الموجّه وحدها: أخطاء التحليل الناجمة عن صياغة JSON غير صالحة، والحقول الإلزامية المفقودة، وأنواع البيانات غير المتسقة، ومخالفات المخطط التي تتطلب معالجة الأخطاء وإعادة المحاولة. وتظهر هذه الإخفاقات عمليًا في أمثلة عامة مثل الآتي:

  • أخطاء التحليل الناجمة عن صياغة JSON غير صالحة: قد تؤدي مثلًا الأقواس المعقوفة غير المغلقة، أو الفواصل الختامية، أو نص Markdown المحيط بالبيانات إلى تعطيل محلل JSON.
  • الحقول الإلزامية المفقودة: قد يحذف النموذج مثلًا مفتاحًا تتوقعه شيفرة التطبيق اللاحقة.
  • أنواع البيانات غير المتسقة: قد يصل حقل رقمي مثلًا على هيئة سلسلة نصية، أو تصل قيمة مفردة بدلًا من مصفوفة.
  • مخالفات المخطط التي تتطلب معالجة الأخطاء وإعادة المحاولة: قد تفرض المفاتيح غير المطلوبة أو القيم خارج النطاق مثلًا استخدام حلقات إعادة المحاولة وشيفرة تحقق دفاعية.

يلغي فك الترميز المقيّد الحاجة إلى تعليمات تنسيق مشددة في الموجّه. وللحفاظ على توافق أنواع التطبيق مع المخطط المرسل إلى API، توفر OpenAI وGoogle أدوات مساعدة أصلية في SDK تقبل فئات Pydantic من نوع BaseModel في Python وكائنات Zod في JavaScript، بينما تقبل Python SDK من Anthropic نموذج Pydantic عبر client.messages.parse() وتحلل الاستجابة إلى ذلك النوع.

كيف تختلف Structured Outputs عن JSON mode وطلب JSON بالموجّه وحده؟

تضمن structured outputs الالتزام الدقيق بـ JSON Schema المحدد، بينما لا تستطيع JSON mode أو التعليمات المعتمدة على الموجّه وحده فرض أسماء خصائص محددة أو بنى متداخلة أو حقول إلزامية.

كانت JSON mode مرحلة وسيطة قبل ظهور قيود المخطط الكاملة. لدى OpenAI، يضمن تفعيل JSON mode عبر { "type": "json_object" } إنتاج النموذج لبيانات JSON صحيحة الصياغة، ما لم تواجه الطلبات حالة استثنائية مثل نفاد رموز الإخراج في منتصف كائن. لكن وثائق OpenAI تذكر تحفظات صريحة: يجب تضمين تعليمات لإخراج JSON في موضع ما من سياق المحادثة، وإلا أصدرت API خطأ عند غياب كلمة JSON، وقد يولّد النموذج بخلاف ذلك تدفقًا لا ينتهي من المسافات البيضاء حتى يبلغ حد الرموز.

تصف OpenAI ‏structured outputs بأنها تطور لـ JSON mode وتوصي باستخدام structured outputs كلما كانت مدعومة، مع تخصيص JSON mode للنماذج الأقدم مثل gpt-4-turbo وما قبله.

الميزة JSON بالموجّه وحده JSON mode Structured Outputs
ضمان صياغة JSON صالحة لا نعم، ما لم تُقتطع نعم، ما لم تُرفض أو تُقتطع
فرض المخطط والأنواع بدقة لا لا نعم
اشتراط تعليمات JSON في الموجّه نعم نعم، تشترطها OpenAI لا
إلغاء إعادة المحاولة بسبب التنسيق لا جزئيًا نعم، لبنية المخطط
تحليل أصلي باستخدام Pydantic وZod يدوي يدوي تدعمه SDK لدى الموردين

Structured Outputs مقابل Function Calling: متى تستخدم كلًا منهما؟

تنسّق structured outputs استجابة النموذج النهائية لتطبيقك أو للمستخدم النهائي، بينما يربط function calling النموذج بالأدوات الخارجية وواجهات API ومصادر البيانات أثناء التنفيذ.

كثيرًا ما يخلط المطوّرون بين الميزتين لأن كلتيهما تعتمد على تعريفات JSON Schema. وتضع OpenAI وGoogle الحد المعماري نفسه بينهما:

  • استخدم structured outputs عندما تريد تنسيق رسالة المساعد النهائية بوضوح لواجهة المستخدم أو قاعدة البيانات أو مسار المعالجة اللاحق، كما في استخراج البيانات أو التصنيف المنظم.
  • استخدم function calling (tool use) عندما يحتاج النموذج إلى طلب إجراء أو البحث في سجلات مباشرة أو استدعاء إجراء في الواجهة الخلفية قبل إكمال الإجابة. لمعرفة المزيد عن دور تعريفات الأدوات في البروتوكولات الحديثة، راجع دليل tool calling وMCP.

تقدم OpenAI المخططات الصارمة بصيغتين مختلفتين: function calling بمخططات صارمة عند ربط النموذج بالأدوات أو البيانات، وصيغة الاستجابة json_schema عند تنظيم الرد على المستخدم. وتفصل Anthropic ميزتيها بين output_config.format لاستجابة Claude النهائية وstrict: true على الأدوات الفردية لضمان صلاحية أسماء الأدوات ووسائط الإدخال، وتدعم صراحة استخدامهما معًا في طلب واحد. ويكون الجمع بينهما عمليًا خصوصًا في مسارات عمل وكلاء الذكاء الاصطناعي، حيث يجب أن تتبع استدعاءات الأدوات الوسيطة والملخص النهائي عقودًا صارمة.

كيف تطبق OpenAI وAnthropic وGoogle ميزة Structured Outputs

تطبق كل من OpenAI وAnthropic وGoogle ميزة structured outputs عبر ترجمة المخطط إلى قواعد اعتبارًا من نوفمبر 2026، لكن معلمات الطلب وكلمات JSON Schema المدعومة وحدود التعقيد تختلف بينها.

المزوّد طريقة التفعيل أدوات المخطط المساعدة في SDK قواعد بارزة للمخطط حدود بارزة
OpenAI ‏Responses API عبر text.format أو Chat Completions عبر response_format مع type: "json_schema" وstrict: true ‏Pydantic BaseModel ‏(Python)، وZod ‏(JS) يجب أن يكون الجذر كائنًا لا anyOf؛ جميع الحقول في required؛ يلزم additionalProperties: false؛ تُصدر المفاتيح بترتيب المخطط حتى 5,000 خاصية، و10 مستويات تداخل، و120,000 محرف للأسماء وقيم enum، و1,000 قيمة enum
Anthropic Claude ‏output_config.format مع type: "json_schema"، إضافة إلى strict: true على الأدوات ‏client.messages.parse() مع Pydantic ‏(Python) يدعم $ref/$defs وanyOf وallOf ضمن حدود؛ يلزم additionalProperties: false؛ لا توجد حدود رقمية أو حدود لطول السلاسل بحد أقصى 20 أداة صارمة، و24 معلمة اختيارية، و16 معلمة اتحاد، ومهلة ترجمة 180s؛ وذاكرة تخزين للقواعد لمدة 24 ساعة
Google Gemini API إعداد الاستجابة بنوع نصي وmime_type: "application/json" والمخطط ‏Pydantic ‏(Python)، وZod ‏(JS) يدعم minimum/maximum وminItems/maxItems وprefixItems؛ يزيل الحدود غير المدعومة بصمت تفشل المخططات الكبيرة أو العميقة التداخل مع 400 INVALID_ARGUMENT

OpenAI

تدعم OpenAI ‏structured outputs بدءًا من GPT-4o وتوصي بـ gpt-6-astra للمشروعات الجديدة. يؤدي استدعاء API مع strict: true وكلمة مفتاحية غير مدعومة مثل allOf أو not أو if/then/else أو dependentRequired أو dependentSchemas إلى إرجاع خطأ بدلًا من الإخفاق بصمت. تدعم OpenAI تنسيقات السلاسل ومنها date-time وtime وdate وduration وemail وhostname وipv4 وipv6 وuuid، إلى جانب الحدود الرقمية (minimum وmaximum وexclusiveMinimum وexclusiveMaximum وmultipleOf) وحدود المصفوفات (minItems وmaxItems).

Anthropic Claude

تدعم Anthropic ‏structured outputs في جميع النماذج على Messages API، ولكن ليس داخل Managed Agents. عند استخدام client.messages.parse() في Python SDK، تُنقل القيود غير المدعومة مثل minimum وmaximum وminLength وmaxLength تلقائيًا إلى أوصاف الحقول لكي يفهم Claude المقصود، وتتحقق SDK محليًا من البيانات المعادة بمقارنتها بنموذج Pydantic الأصلي.

يخزّن Claude القواعد المترجمة مؤقتًا لمدة 24 ساعة من آخر استخدام؛ ويؤدي تغيير بنية المخطط أو مجموعة الأدوات إلى إبطال ذاكرة القواعد هذه، بينما لا يؤدي تعديل أسماء الحقول أو أوصافها إلى ذلك. ولأن Claude يتلقى أيضًا موجّه نظام تلقائيًا يشرح تنسيق JSON، يرتفع عدد رموز الإدخال قليلًا، ويؤدي تغيير output_config.format إلى إبطال ذاكرة موجّه المحادثة. تُصدر الخصائص الإلزامية أولًا ثم الاختيارية. تعمل structured outputs مع البث وحساب الرموز وBatch processing، مع خصم Anthropic بنسبة 50 بالمئة. لكن الجمع بين مخرجات JSON وCitations يعيد خطأ 400، ولا تتوافق structured outputs مع التعبئة المسبقة للرسائل.

Google Gemini API

يبرز Google استخراج البيانات والتصنيف المنظم ومسارات عمل الوكلاء بوصفها حالات الاستخدام الرئيسية لـ structured outputs في Gemini. وعلى خلاف OpenAI وAnthropic، يزيل Gemini عدة كلمات مفتاحية ويتجاهلها بصمت من دون إصدار خطأ، ومنها minLength وmaxLength وminProperties وmaxProperties وuniqueItems وcontains وminContains وmaxContains. ينبغي دائمًا تشغيل Pydantic ‏model_validate_json() أو Zod ‏.parse() على استجابات Gemini لفرض هذه القيود في شيفرة التطبيق. إذا أعاد Gemini الخطأ 400 INVALID_ARGUMENT بسبب مخطط مفرط التعقيد، ينصح Google بتبسيط التداخل وتقليل الحقول الاختيارية أو قيم enum وتقصير أسماء الخصائص ونقل القواعد غير البنيوية إلى أوصاف الحقول.

كيف تصمم JSON Schema موثوقًا لنماذج LLM؟

يحافظ JSON Schema الموثوق لـ structured outputs في نماذج LLM على بنية مسطحة، ويجعل الحقول إلزامية، ويستخدم أنواعًا تقبل null بدلًا من المفاتيح الاختيارية. ويساعد تصميم المخططات وفق قواعد مشتركة بين المزوّدين على منع أخطاء الترجمة والرفض غير المتوقع أثناء التنفيذ.

استخدم قائمة التحقق هذه قبل نشر مخطط عبر OpenAI أو Claude أو Gemini:

  1. اجعل التداخل محدود العمق: بسّط الكائنات العميقة التداخل حيثما أمكن للبقاء دون حد OpenAI البالغ 10 مستويات بفارق مريح وتجنب رفض الترجمة لدى Gemini أو Claude.
  2. اجعل كل حقل إلزاميًا: أدرج كل مفتاح كائن في required، لأن OpenAI تطبق هذه القاعدة بصرامة وتحد Claude إجمالي المعلمات الاختيارية في الطلب إلى 24.
  3. استخدم اتحادات تقبل null للبيانات المفقودة: مثّل القيم الاختيارية باستخدام "type": ["string", "null"] بدلًا من حذف المفاتيح من required.
  4. قيّد الكائنات: اضبط "additionalProperties": false في كل تعريف كائن، كما تشترط OpenAI وAnthropic كلتاهما.
  5. قيّد الخيارات الثابتة باستخدام enum: استبدل فئات السلاسل المفتوحة بمصفوفات enum صريحة عندما تكون مجموعة معروفة من التسميات وحدها صالحة.
  6. اكتب أوصافًا واضحة: ضع قواعد المجال والقيود المتجاهلة، مثل أطوال المحارف المستهدفة أو تعليمات البدائل، داخل description لكل خاصية.

فيما يلي مثال توضيحي لمخطط يصنف تذكرة دعم عملاء. يتبع المثال القواعد المشتركة أعلاه: جذر كائن، وجميع الحقول إلزامية، وحقل يقبل null للبيانات الوصفية الاختيارية، وadditionalProperties: false، وenum للتوجيه.

{
  "type": "object",
  "additionalProperties": false,
  "required": ["category", "urgency", "summary", "order_id"],
  "properties": {
    "category": {
      "type": "string",
      "enum": ["billing", "bug_report", "account_access", "other"],
      "description": "Primary topic of the support message."
    },
    "urgency": {
      "type": "string",
      "enum": ["low", "normal", "high"],
      "description": "Escalation priority based on user impact."
    },
    "summary": {
      "type": "string",
      "description": "One-sentence summary of the issue in 25 words or fewer."
    },
    "order_id": {
      "type": ["string", "null"],
      "description": "Order identifier if present in the message, otherwise null."
    }
  }
}

ما الذي قد يظل عرضة للخطأ مع Structured Outputs؟

تضمن structured outputs صياغة صالحة وفق المخطط، لكن تطبيقات الإنتاج لا تزال تواجه حالات الرفض واقتطاع الرموز والقيم المتخيلة واختلاف حالة أحرف enum وزمن الاستجابة في الطلب الأول ومدخلات المستخدم غير الموثوقة. يساعد التعامل مع الالتزام بالمخطط بوصفه تحققًا من الصياغة لا من الحقيقة أو السلامة على منع الإخفاقات الصامتة في الإنتاج.

الرفض لأسباب تتعلق بالسلامة والاقتطاع عند حد الرموز

لا تزال النماذج قادرة على رفض الطلبات غير الآمنة التي ينشئها المستخدمون أو التوقف في منتصف التوليد عند بلوغ حد رموز الإخراج. لدى OpenAI، يملأ الرفض لأسباب السلامة حقلًا منفصلًا هو refusal لا يلتزم بـ JSON Schema المحدد. لدى Anthropic Claude، يعيد الرفض HTTP 200 مع ضبط stop_reason على "refusal"، وتظل هناك رسوم عليه، ويتجاوز المخطط؛ وبالمثل، يؤدي بلوغ حد الإخراج إلى إرجاع stop_reason بالقيمة "max_tokens" مع JSON غير مكتمل. تحقق دائمًا من مؤشرات الرفض وأسباب التوقف قبل استدعاء JSON.parse() أو أداة تحقق.

قيم صالحة وفق المخطط لكنها خاطئة من حيث الوقائع

يجبر فك الترميز المقيّد النموذج على ملء المخطط حتى عندما يفتقر النص المصدر إلى إجابة أو يناقض افتراضات المخطط. قد تجتاز الاستجابة جميع عمليات التحقق من النوع وenum رغم احتوائها على تواريخ مختلقة أو فئات خاطئة أو تخمينات تبدو معقولة. تنصح OpenAI بتوجيه النموذج في الموجّه إلى ما يجب إرجاعه عندما لا يتوافق الإدخال مع المخطط، مثل إرجاع null أو حقول فارغة، ويحذر Google المطوّرين من ضرورة التحقق من القيم وفق قواعد العمل في الشيفرة. لمعرفة المزيد عن سبب بقاء المخرجات الواثقة عرضة للخطأ، اقرأ دليلنا عن معدلات هلوسة الذكاء الاصطناعي.

حالة أحرف enum في Claude وزمن الترجمة

تفاجئ فرق العمل أثناء النشر خاصيتان تشغيليتان:

  • حالة أحرف enum في Claude: تشير Anthropic إلى أن حالة أحرف enum غير مضمونة أثناء فك الترميز المقيّد، لذا قارن سلاسل enum المعادة من دون تمييز بين الأحرف الكبيرة والصغيرة في منطق التطبيق.
  • تأخر الترجمة في الطلب الأول: يضيف Claude زمن استجابة إضافيًا عند ترجمة مخطط جديد إلى قواعد للمرة الأولى قبل تخزينها مؤقتًا لمدة 24 ساعة، وتشير OpenAI إلى تأخر مماثل في معالجة المخطط للطلب الأول مع النماذج المضبوطة بدقة.

حقن الموجّه داخل قيم الحقول

لا يؤدي تقييد بنية الإخراج إلى تحييد التعليمات الخبيثة المخفية داخل نص غير موثوق يُلخّص أو يُستخرج إلى حقل سلسلة JSON. قد يعيد النموذج بيانات JSON صالحة كما طُلب، بينما يحمل الحقل summary أو notes تعليمات محقونة أو محتوى مضللًا يستهدف الأدوات اللاحقة أو المراجعين البشر. تعامل مع كل قيمة حقل محللة بوصفها إدخالًا غير موثوق، وراجع مقدمتنا عن ما هو حقن الموجّه قبل تمرير الحقول المستخرجة إلى إجراءات آلية.

الأسئلة الشائعة

هل تبطئ structured outputs استجابات LLM؟

قد تضيف structured outputs زمن استجابة إلى الطلب الأول باستخدام مخطط جديد، بينما تعمل الطلبات اللاحقة المخزنة مؤقتًا من دون تكلفة الترجمة. تخزّن Anthropic قواعد Claude المترجمة لمدة 24 ساعة من آخر استخدام ما لم تغيّر بنية المخطط أو تعريفات الأدوات. وتشير OpenAI إلى زمن إضافي لمعالجة المخطط في الطلب الأول فقط عند استخدام نماذج مضبوطة بدقة.

هل يمكن أن يهلوس LLM رغم استخدام structured outputs؟

نعم، يمكن أن يهلوس LLM قيمًا مع إرجاع JSON صالح وفق المخطط بنسبة 100 بالمئة. يقيّد فك الترميز المقيّد صياغة الرموز وأنواع الحقول، لا دقة الوقائع. إذا افتقر الإدخال إلى معلومات إلزامية، فقد يختلق النموذج قيمًا لاستيفاء المفاتيح المطلوبة ما لم تسمح بحقول تقبل null وتوجهه إلى وقت إرجاع null.

هل ينبغي استخدام Pydantic أم Zod مع واجهات structured output API؟

يساعد استخدام أدوات المخطط الأصلية في SDK على إبقاء أنواع التطبيق ومخططات API متوافقة. تدعم OpenAI وGoogle كلًا من Pydantic في Python وZod في JavaScript، بينما تدعم Python SDK من Anthropic ‏Pydantic عبر client.messages.parse(). تحوّل هذه الأدوات نماذجك إلى JSON Schema، وتحلل الاستجابات إلى كائنات محددة الأنواع، وتتحقق من قيود مثل أطوال السلاسل التي يزيلها Gemini أو تنقلها Anthropic إلى أوصاف الحقول.

ماذا يحدث إذا رفض النموذج طلبًا مع تفعيل structured outputs؟

عندما يرفض النموذج طلبًا لأسباب تتعلق بالسلامة، يتجاوز الرفض JSON Schema المحدد. تضع OpenAI التفسير في حقل refusal مخصص بدلًا من اتباع المخطط، بينما تعيد Anthropic ‏HTTP 200 مع ضبط stop_reason على "refusal". يجب أن يفحص التطبيق هذه الحقول قبل محاولة تحليل JSON.

لماذا يرفض Claude أو Gemini مخطط JSON Schema بخطأ 400؟

يرفض كل من Claude وGemini المخططات التي تتجاوز حدود التعقيد الداخلية للقواعد أو آلة الحالات بخطأ 400. ويعيد Claude أيضًا خطأ 400 عند تضمين ميزات مخطط غير مدعومة مثل المخططات العودية أو الحدود الرقمية، أو عند الجمع بين مخرجات JSON وCitations. يؤدي عادةً تبسيط الكائنات المتداخلة وتقصير الأسماء وتقليل المعلمات الاختيارية أو معلمات الاتحاد إلى حل حالات رفض الترجمة.

المصادر

بقلم

Chunyu Cai

Chunyu Cai هو الرئيس التنفيذي لشركة Lotook, LLC ورائد أعمال يكتب عن نماذج الذكاء الاصطناعي ووكلائه وكيف تغير العمل اليومي. يحمل Chunyu Cai درجة الماجستير من Imperial College London.