مدل یک پاراگراف تحلیلی درخشان می‌نویسد و برنامه‌ی شما هیچ استفاده‌ای از آن نمی‌تواند بکند — چون انتظار یک فیلد sentiment با مقدار مشخص را دارد. مرز بین «چت‌بات جالب» و «سرویس قابل‌ادغام» دقیقاً همین‌جاست: تا وقتی خروجی مدل متن آزاد است، نرم‌افزار باید از میان نثر، حدس بزند. خروجی ساختاریافته یا Structured Output راه‌حل رسمی این مسئله است: به مدل می‌گویید جواب را در قالبی از پیش تعیین‌شده — معمولاً JSON — برگرداند، و API مطمئن می‌کند که واقعاً برگردانده شود.

سه نسل گرفتن خروجی از مدل

مسیر رسیدن به خروجی قابل‌اعتماد سه پله دارد و ارزش دارد هر سه را بشناسید. پله‌ی اول — امید و پرامپت: در متن درخواست می‌نویسید «فقط JSON معتبر بده» و چند نمونه می‌گذارید. این روش کار می‌کند... تا وقتی که نکند: یک کاما اضافه، یک جمله‌ی توضیحی قبل از براکت، یا عبارت «در این‌جا خروجی هست» — و پارس‌ر شما می‌شکند. پله‌ی دوم — JSON Mode: اکثر APIها حالتی دارند که تولید خروجی متنی معمولی را قفل می‌کند و مدل را مجبور به تولید JSON معتبر می‌کند. تضمین این پله «معتبر بودن JSON» است — نه «مطابق بودن شکل با خواسته‌ی شما»؛ فیلد جا می‌افتد، نامش فرق می‌کند، ساختار تودرتویی عوض می‌شود.

پله‌ی سوم — Structured Output با Schema: شکل دقیق خروجی را با JSON Schema تعریف می‌کنید — نام فیلدها، نوع‌ها، اجباری یا اختیاری بودن، مقادیر مجاز — و API خروجی را از نظر ساختاری به همان شکل محدود می‌کند. این همان سطحی است که برای محصول لازم دارید: نه JSON معتبر، بلکه JSON مطابق قرارداد.

Constrained Decoding چگونه کار می‌کند؟

بامزه‌ترین بخش ماجرای فنی این‌جاست: مدل در هر لحظه، توزیع احتمال روی توکن‌های بعدی می‌دهد. سرویس‌دهنده‌ها روی این توزیع یک لایه‌ی ماسک می‌گذارند که با وضعیت فعلی schema هم‌گام است — اگر داخل رشته‌ی یک مقدار enum هستید و فقط «active» و «expired» مجازند، هر توکنی که خلاف آن باشد احتمالش صفر می‌شود. به این می‌گویند decoding محدودشده. نتیجه: خروجی از نظر ساختاری به‌طور قطعی مطابق schema است — نه تقریباً، بلکه ریاضی‌وار.

اما یک مرز مهم: این تضمین ساختاری است، نه معنایی. مدل ممکن است دقیقاً مطابق schema، مقدار اشتباه تولید کند — شماره‌ی سفارشی که وجود ندارد، تاریخ با فرمت درست و مقدار غلط. constrained decoding جای اعتبارسنجی کسب‌وکاری را نمی‌گیرد.

به خروجی مدل مثل ورودی کاربر نگاه کنید: هرگز — حتی با schema فعال — بدون اعتبارسنجی، وارد منطق و دیتابیس نشود.

الگوهای عملی

چند قاعده که در استفاده‌ی واقعی فرق می‌سازد: schema را ساده نگه دارید — فیلدهای کمتر، عمق کمتر، و برای مقادیر محدود از enum استفاده کنید؛ هرچه قرارداد ساده‌تر باشد، مدل با محتوای بهتر آن را پُر می‌کند. توضیح فیلد بنویسید — schemaهای خوب فیلد description دارند؛ مدل همان را می‌خواند. حالت خطا را در خود schema تعریف کنید — مثلاً فیلد status با مقادیر ok/error و فیلد دلیل؛ بهتر از این است که مدل در نبود داده، فیلد را با توهم پر کند. اعتبارسنجی + تلاش مجدد هدفمند: خروجی را با همان schema در سمت برنامه چک کنید و اگر شکست خورد، خطای دقیق را به مدل برگردانید و بخواهید اصلاح کند — یک دور معمولاً کافی است. و برای استخراج داده، دمای پایین انتخاب کنید؛ خلاقیت این‌جا عیب است.

نسبت با Function Calling و عامل‌ها

اگر مطلب Function Calling را خوانده باشید، این‌جا ارتباط روشن می‌شود: فراخوانی تابع، عملاً «خروجی ساختاریافته + اجرا» است — مدل آرگومان‌ها را در قالب اسکیمای تابع تولید می‌کند و برنامه اجرایش می‌کند. هر ابزاری که عامل صدا می‌زند، یک قرارداد schema است؛ به همین دلیل عامل‌های پایدار بدون خروجی ساختاریافته معنا ندارند — قدم بعدی زنجیره باید قابل‌پارس باشد. در ساخت اولین عامل این قرارداد را در عمل می‌بینید.

جمع‌بندی

خروجی ساختاریافته یعنی تبدیل مدل زبانی از یک نویسنده به یک مؤلفه‌ی نرم‌افزاری: ورودی و خروجی هر دو قرارداد دارند. سه پله را یادتان باشد — پرامپتِ محض شکننده است، JSON Mode فقط معتبر بودن را تضمین می‌کند و Schema-محور، شکل را قید می‌کند؛ اما معنا را شما با اعتبارسنجی می‌بندید. همین‌جا مرز بین دمو و محصول است. برای معماری کامل‌تر ورودی مدل، مهندسی زمینه را بخوانید — و برای تست روی سرویس واقعی، یک حساب بسازید.