المخرج المنظم عبر الموردين
JSON بس عبر الـvendors — 3 أشكال فشل
أنضف اختبار لانضباط الـstructured-output بتاع أي vendor هو تعليمة strict-JSON. المستخدم بيقول صراحة "JSON object بس (من غير نثر، من غير markdown fence)" وبيدّيك الـschema. فيه شكل إجابة واحد مقبول. وفيه طرق كتير تخسّ بيها. بصّ على كل نموذج بيعمل إيه.
الـprompt
Extract the structured data from this paragraph and return ONLY a JSON object (no prose, no markdown fence). Schema: { "company": string, "founded_year": number, "headquarters_city": string, "products": string[] }
Paragraph: "Bayt Coffee, founded in 2019 in Cairo, sells three main products: a house blend, single-origin Ethiopian, and a cold-brew concentrate."
Claude Sonnet 4.5
{ "company": "Bayt Coffee", "founded_year": 2019, "headquarters_city": "Cairo", "products": ["house blend", "single-origin Ethiopian", "cold-brew concentrate"] }
GPT-4o-mini
{ "company": "Bayt Coffee", "founded_year": 2019, "headquarters_city": "Cairo", "products": [ "house blend", "single-origin Ethiopian", "cold-brew concentrate" ] }
Gemini 2.5 Flash
{"company": "Bayt Coffee", "founded_year": 2019, "headquarters_city": "Cairo", "products": ["a house blend", "single
بطاقة المقارنة
اختبار strict-JSON: مين بيرجّع bytes تتـparse؟
Claude Sonnet 4.5
- الـfence بيكسر قاعدة 'no markdown'
- محتاج تنضيف قبل الـparsing
GPT-4o-mini
- النموذج الوحيد اللي التزم بقاعدة الـno-fence
- بيتـparse على طول
- شال أداة التعريف من 'a house blend' من غير ما يقول
- الالتزام بالـprompt لوحده مش ضمانة — استخدم schema
Gemini 2.5 Flash
- اتقطع في نص الـstring عند 'single
- مش صالح كـJSON — لا closing quote ولا bracket ولا brace
اللي ده بيقوله لنا
3 failure modes مختلفة، باينة بالظبط في الـcaptures.
Claude لفّ الـJSON في ```json ... ``` markdown fence مع إن الـprompt قال "no markdown fence". المحتوى جوه الـfence هو JSON صالح، schema-correct، بـtypes صح. بس لو الكود ورا بيعمل JSON.parse(output) ببساطة، هيرمي error بسبب الـ ``` في الأول. ده failure mode بتاع Claude الأشهر في الـstructured-output: الـJSON نفسه صح، بس ملفوف.
GPT-4o-mini رجّع JSON عاري، من غير fence، من غير نثر، parse صالح. على الـprompt ده GPT-4o-mini هو الوحيد فيهم التلاتة اللي طلّع مخرج تقدر تبعته على طول لـJSON.parse. بصّ إن GPT-4o-mini اختار الـ"pretty" multi-line formatting؛ ده تمام للـparser. بس استنى شوية على أسامي المنتجات — مش مطابقة للمصدر بالقرب اللي شكلها بيوحي بيه، وده موضوع القسم اللي جاي.
Gemini 2.5 Flash وقف في نص الـstring: "products": ["a house blend", "single — من غير closing quote، من غير closing bracket، من غير closing brace. ده مش قابل للـparsing، وهو نفس السؤال المفتوح من الـmodule 1: المخرج اللي بيقف في نص token ده توقيع سقف tokens، والـharness بتاعنا ما سجّلش سبب الوقوف. تعامل معاه كـrun واحد، مش كخاصية.
فيه حاجة واحدة في الـcapture ده بتتقيّم غلط لو ما خدتش بالك، وتستاهل نوقف عندها. نسخة أقدم من الدرس ده كانت بتنقّص Gemini عشان "حرّف في صياغة المنتج" لأنه كتب "a house blend" واللي غيره كتبوا "house blend". ارجع اقرا الفقرة المصدر: "sells three main products: a house blend, single-origin Ethiopian, and a cold-brew concentrate." أداة التعريف موجودة في الـinput. Gemini نقل المصدر بالظبط؛ Claude و GPT رتّبوه من غير ما يقولوا.
في مهمة استخراج، الترتيب ده هو السلوك الأخطر. إنت طلبت البيانات اللي في الفقرة، واتنين من التلاتة رجّعوا بيانات مش موجودة في الفقرة بالظبط. في اسم منتج ده مش مؤذي. في جرعة دواء، أو رقم قضية، أو اسم كيان قانوني، أو رقم قطعة غيار، النموذج اللي بيوحّد اللي بينقله من غير ما يقول ده عيب مش هتمسكه بعينك. الـrubric اللي بيكافئ المخرج الشكله نضيف على حساب المخرج الأمين هيختار النموذج الغلط، ووضع الفشل ده هو موضوع درس التلخيص الأمين في الـmodule 2 كله.
يعني التقييم الأمين للصف ده: Gemini كان النموذج الوحيد اللي رجّع الـstring زي المصدر، وبرضه فشل في المهمة لأنه ما خلّصش. نتيجتين مستقلتين، ولمّهم في "Gemini كان الأوحش" بيضيّع المفيدة فيهم.
الـpatches، بالترتيب اللي المفروض تمد إيدك ليه
لـClaude، إنك تشيل الـfence قبل JSON.parse بيشتغل بس هو أضعف اختيار، لأنه إصلاح نصي لمشكلة الـAPI يقدر يمنعها. Anthropic دلوقتي بتشحن structured outputs: ابعت output_config: { format: { type: "json_schema", schema: {...} } } على call عادي بتاع messages.create والرد بيتقيّد وقت الـdecode إنه يطابق الـschema. مابقاش beta-gated، وclaude-sonnet-4-5 من ضمن النماذج المدعومة. الـtool-use mode — اللي الدرس ده كان بيوصّي بيه — كان الحل الصح قبل ما ده يوجد.
لـOpenAI، امد إيدك لـStructured Outputs، مش JSON mode. response_format: { type: "json_object" } هي الميزة الأقدم وOpenAI بتوثّقها كـlegacy؛ بتضمن إن المخرج يتـparse، وبتقول صراحة إنها ما بتضمنش إنه يطابق الـschema بتاعك — الحقول اللي علّمتها required ممكن تغيب برضه. response_format: { type: "json_schema", json_schema: {...}, strict: true } هي اللي بتفرض الشكل. لدرس موضوعه كله هو مطابقة الـschema، الفرق ده هو الدرس نفسه.
لـGemini، حدد response schema في الـgeneration config عشان النموذج يتقيّد بدل ما يتطلب منه، وارفع سقف الـoutput tokens قبل ما تستنتج أي حاجة عن مين بيتقطع.
الـpattern عبر التلاتة: كل vendor دلوقتي عنده طريقة تخلّي الـschema قيد بدل ما يكون طلب. لو لسه بتـparse نثر عشان تطلّع بيانات منظمة، إنت بتستخدم واجهة اتعدّى عليها على المنصات التلاتة.
راجع أسامي الـparameters الحالية قبل ما تكتب الـcall — Anthropic، OpenAI، Google. دول اتغيّروا في آخر سنة وهيتغيّروا تاني.
Captured 2026-04-27 من Claude Sonnet 4.5 و GPT-4o-mini و Gemini 2.5 Flash — سبب الوقوف مش مسجّل. الـre-runs ممكن تختلف.
التالي: function calling — نفس الفكرة، API surface مختلف، مشاكل parity مشابهة. :::
سجّل الدخول للتقييم