الرئيسيةمن أناالدوراتالمدونةسوق الأوامرالمناهج والباقاتالشركاء

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • المناهج والباقات
  • سوق الأوامر
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالمناهجالمدونةالدخول
الذكاء الاصطناعي

المخرجات المنظّمة: خلّي نموذجك يرجّع JSON صالح كل مرة

متوسط13 أغسطس 20265 دقائق قراءة
المخرجات المنظّمة: خلّي نموذجك يرجّع JSON صالح كل مرة
مستوى المقال: متوسط. محتاج تكون كتبت كود بيستدعي نموذج لغة قبل كده، وتعرف JSON يعني إيه. مش لازم تكون خبير في NLP.

لو رد النموذج بيتكسر عندك في json.loads مرة كل كام طلب، المشكلة مش في الموديل. المشكلة إنك بتطلب منه JSON بدل ما تجبره عليه. المقال ده هيوريك إزاي تخلّي المخرج مطابق لمخططك 100%.

المخرجات المنظّمة: من "اطلب JSON" إلى "اجبر على JSON"

المشكلة باختصار

الطريقة الشائعة إنك تكتب في البرومبت "رجّعلي JSON بالشكل ده" وتصلّي إنه يلتزم. الطريقة دي بتفشل بشكل عشوائي: مرة بيزوّد جملة "Sure, here is the data"، ومرة بينسى علامة اقتباس، ومرة بيحط "30" نص بدل رقم. لو عندك خدمة بتفكّك 5000 فاتورة يوميًا لـ JSON، وواحد بالمية بس بيرجع مكسور، يبقى 50 فاتورة بتقع كل يوم في الـ parser. المخرجات المنظّمة (Structured Outputs) بتشيل الاحتمالية دي من أساسها.

مثال يقرّب الفكرة قبل التعريف العلمي

تخيّل إنك طالب من موظف يملالك بيانات عميل. لو سبته يكتب على ورقة بيضا، هيكتب "الراجل ده عنده حوالي 30 سنة وساكن القاهرة تقريبًا". كلام مفهوم لبني آدم، لكن مستحيل تفكّكه بالكود. دلوقتي ادّيله استمارة بخانات محددة: خانة الاسم، خانة السن مكتوب جمبها "أرقام فقط"، خانة المدينة. الموظف مش هيقدر يحط كلمة "تقريبًا" في خانة الأرقام، لأن الخانة نفسها مش بتسمح. المخرجات المنظّمة هي الاستمارة دي، بس للنموذج.

علميًا: المخرجات المنظّمة تقنية بتحوّل مخطط JSON (JSON Schema) بتاعك إلى نحو (grammar)، وبتُجبر النموذج على توليد نص يطابق النحو ده عبر فك التشفير المقيّد (constrained decoding). النتيجة مضمونة تركيبيًا: الحقول موجودة، وأنواعها صح، والقوسين مقفولين.

الحل عمليًا: كود شغّال

مع OpenAI SDK، بتعرّف المخطط كـ Pydantic model، والمكتبة بتتكفّل بالباقي:

Python
from pydantic import BaseModel
from openai import OpenAI

class Person(BaseModel):
    name: str
    age: int
    city: str

client = OpenAI()
completion = client.beta.chat.completions.parse(
    model="gpt-4o-2024-08-06",
    messages=[{"role": "user", "content": "استخرج: علي، عمره 30، من القاهرة"}],
    response_format=Person,   # ده اللي بيفعّل التقييد
)

person = completion.choices[0].message.parsed
print(person.age + 1)   # 31 — رقم فعلي تقدر تحسب بيه، مش نص

خد بالك من person.age + 1. مفيش try/except، ومفيش int(...) ترقيعي. القيمة رجعت رقم لأن المخطط قال كده. الافتراض هنا إنك بتستخدم نموذجًا يدعم response_format زي إصدارات gpt-4o الحديثة.

ولو شغّال على نموذج مفتوح محليًا، نفس الفكرة عبر llama.cpp بنحو GBNF، أو مكتبة Outlines اللي بتاخد نفس الـ Pydantic model:

Bash
# نموذج مفتوح عبر llama.cpp مع نحو JSON جاهز
llama-cli -m model.gguf --grammar-file json.gbnf \
  -p "رجّع بيانات المستخدم كـ JSON"

الفرق بالأرقام

في إعلان OpenAI للميزة سنة 2024، قياسهم على مخططات معقدة أعطى مطابقة كاملة 100% مع المخرجات المنظّمة، مقابل أقل من 40% (حوالي 35.9%) لما تعتمد على gpt-4 بالمطالبة النصية بس. يعني مش تحسّن بسيط، ده فرق بين "بيشتغل" و"مش بتثق فيه".

إزاي بتشتغل من جوّه: فك التشفير المقيّد

النموذج بيولّد توكن ورا توكن. في كل خطوة بيطلع توزيع احتمالات على كل التوكنات الممكنة. فك التشفير المقيّد بيضيف خطوة قبل الاختيار: بيبص للنحو، يحسب أنهي توكنات مسموحة في الحالة دي، ويصفّر احتمال أي توكن تاني. فالنموذج ببساطة ما بيقدرش يختار توكن هيكسر المخطط.

في الصورة: بعد ما النموذج كتب { "age":، النحو مستني رقم. فالتوكنات زي 3 و0 والإشارة - مسموحة، لكن توكن نصي زي "Ali أو true احتماله اتصفّر. مفيش طريقة يطلع JSON مكسور حتى لو الموديل "عايز".

الـ trade-offs: بتكسب إيه وبتخسر إيه

  • بتكسب: مخرج مضمون التركيب، فتحذف كود إعادة المحاولة، والـ try/except، والـ regex الترقيعي اللي بيصلّح رد الموديل.
  • بتخسر مرونة: النموذج مقيّد بالمخطط حرفيًا. لو القيمة مش موجودة في المدخل، هيحطّ حاجة عشان يملأ الخانة بدل ما يقولك "مش لاقي".
  • تكلفة أول مرة: أول طلب بمخطط جديد بياخد زمن إضافي لبناء الـ artifact بتاع النحو، وبعدها بيتخزّن مؤقتًا فالطلبات التالية بتبقى سريعة.
  • ضمان تركيبي مش دلالي: التقييد بيمنع كسر الشكل، لكنه ما بيضمنش صحة القيمة. ممكن يحط رقم غلط في خانة صحيحة النوع.

متى لا تستخدم المخرجات المنظّمة

  • لو محتاج نص حر إبداعي (رد محادثة، مقال، ملخص). التقييد بيقتل طبيعية اللغة.
  • لو المخطط بيتغيّر مع كل طلب تقريبًا، فبتدفع تكلفة بناء النحو كل مرة.
  • لو المزود أو النموذج ما بيدعمش الميزة أصلًا. ساعتها استخدم JSON mode العادي + تحقق برمجي بـ Pydantic.
  • لو المخطط عميق ومعقّد لدرجة مبالغة، ممكن يُرفض أو يبطّئ التوليد.

الخطوة التالية

افتح أقرب مكان في كودك بتعمل فيه json.loads على رد الموديل جوه try/except. لو الموديل بتاعك بيدعم response_format، حوّل الرد لـ Pydantic model واحذف الـ try/except. بعد كده قِس نسبة الفشل قبل وبعد على 100 طلب حقيقي من عندك؛ لو نزلت لصفر، امسح كل كود الترقيع القديم.

المصادر

  • OpenAI — Introducing Structured Outputs in the API (2024) — رقم 100% مقابل 35.9%.
  • OpenAI Docs — Structured Outputs Guide — response_format وفك التشفير المقيّد.
  • Pydantic Documentation — تعريف المخططات بـ BaseModel.
  • llama.cpp — GBNF Grammars — تقييد المخرجات في النماذج المفتوحة.
  • Outlines (dottxt-ai) — توليد JSON مقيّد من Pydantic.
  • Willard & Louf — Efficient Guided Generation for LLMs (2023) — الأساس النظري لفك التشفير المقيّد.

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة