JSON به‌جای متن؛ وقتی خروجی باید ماشین‌خوان باشد

⏱ زمان مطالعه: حدود ۵ دقیقه

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

چرا متن آزاد برای پردازش خودکار خطرناک است

فرض کنید از مدل خواسته‌اید اطلاعات یک مشتری را از یک پیام استخراج کند: نام، شماره تماس و مبلغ سفارش. اگر خروجی را به‌صورت جمله بخواهید، مدل ممکن است یک بار بنویسد «نام مشتری: علی، تماس: ۰۹۱۲…» و بار دیگر «مشتری علی با شماره ۰۹۱۲… تماس گرفت». هر دو برای یک انسان قابل‌فهم‌اند، اما یک اسکریپت که با regex یا split این متن را پردازش می‌کند، به محض تغییر جزئیِ فرمت خراب می‌شود. مشکل دوم این است که متن آزاد مرز مشخصی بین فیلدها ندارد؛ اگر مقدار یک فیلد شامل ویرگول یا دونقطه باشد، الگوریتم استخراج به‌سادگی گمراه می‌شود.

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

JSON به‌جای متن؛ وقتی خروجی باید ماشین‌خوان باشد

Structured Output چطور کار می‌کند

اکثر ارائه‌دهندگان مدل‌های زبانی امروز یک قابلیت به نام structured output یا JSON mode دارند. در این حالت، شما یک schema (معمولاً به فرمت JSON Schema) به مدل می‌دهید و مدل موظف است خروجی را دقیقاً مطابق آن schema برگرداند — نه فقط «شبیه» آن. برخلاف روش قدیمی‌تر که در prompt می‌نوشتید «لطفاً JSON برگردان»، این روش در سطح API اجرا می‌شود و احتمال خروجی نامعتبر را به‌شدت کاهش می‌دهد.

یک نمونه ساده از schema برای استخراج اطلاعات سفارش:

{
  "type": "object",
  "properties": {
    "customer_name": { "type": "string" },
    "phone": { "type": "string" },
    "order_amount": { "type": "number" },
    "items": {
      "type": "array",
      "items": { "type": "string" }
    }
  },
  "required": ["customer_name", "phone", "order_amount"],
  "additionalProperties": false
}

خروجی مدل با این تعریف چیزی شبیه این خواهد بود:

{
  "customer_name": "علی رضایی",
  "phone": "09121234567",
  "order_amount": 450000,
  "items": ["کفش ورزشی", "جوراب"]
}

حالا این خروجی را می‌توان مستقیماً با JSON.parse یا معادل آن در هر زبانی خواند، بدون نیاز به regex یا حدس زدن قالب.

طراحی یک schema خوب

  • فیلدهای required را محدود و واقعی نگه دارید. هرچه فیلد اجباری بیشتر باشد، احتمال شکست خروجی وقتی داده ناقص است بیشتر می‌شود.
  • enum را برای فیلدهای محدود استفاده کنید. مثلاً وضعیت سفارش را به‌جای رشتهٔ آزاد، به ["pending", "paid", "cancelled"] محدود کنید تا مدل چیزی خارج از این سه حالت ننویسد.
  • additionalProperties را false بگذارید تا مدل فیلد اضافه و غیرمنتظره تولید نکند.
  • انواع داده را دقیق تعریف کنید — عدد را number بگذارید نه string، چون تبدیل نادرست در مرحلهٔ پردازش دردسرساز است.
  • schema را کوچک نگه دارید. یک schema با ده‌ها فیلد تودرتو، نرخ خطای مدل را بالا می‌برد؛ در صورت نیاز، استخراج را به چند مرحله تقسیم کنید.

اعتبارسنجی؛ کاری که مدل جای شما انجام نمی‌دهد

حتی با structured output، مدل تضمین نمی‌کند که مقادیر از نظر منطق کسب‌وکار درست باشند. مدل ممکن است یک شماره تماس با فرمت درست اما نامعتبر (مثلاً ۹ رقمی) تولید کند، یا مبلغ سفارش را منفی بنویسد. schema فقط ساختار را تضمین می‌کند، نه صحت معنایی را. به همین دلیل، لایهٔ اعتبارسنجی سمت برنامه — مثل بررسی طول شماره تلفن، محدودهٔ مبلغ، یا معتبر بودن تاریخ — همچنان ضروری است. خروجی JSON یک ورودی قابل‌اعتمادتر می‌دهد، اما جایگزین validation نیست.

معیار متن آزاد JSON ساختاریافته
قابلیت parse خودکار شکننده، وابسته به قالب پایدار، طبق schema
خطاهای پنهان زیاد، اغلب دیر کشف می‌شود کمتر، در همان مرحله رد می‌شود
مناسب برای خواندن توسط انسان ورودی به دیتابیس یا API
هزینهٔ نگهداری بالا (تغییر مدل = شکستن پارسر) پایین (schema ثابت می‌ماند)
نیاز به اعتبارسنجی جداگانه بله، شدید بله، اما محدودتر

خطاهای رایج و راه‌حل

یکی از خطاهای رایج، درخواست JSON در prompt بدون استفاده از قابلیت واقعی structured output ارائه‌دهنده است. در این حالت مدل معمولاً JSON درست تولید می‌کند، اما گاهی یک جملهٔ توضیحی قبل یا بعد از آن اضافه می‌کند و parser را خراب می‌کند. راه‌حل، استفاده از پارامتر رسمی API (مثل response_format یا tool calling) است، نه اتکا به دستورِ متنی.

خطای دیگر، schema بیش‌ازحد سخت‌گیرانه برای دادهٔ واقعاً ناقص است. اگر پیام مشتری شماره تماس نداشته باشد ولی phone را required گذاشته باشید، مدل مجبور می‌شود مقدار را حدس بزند یا رشتهٔ خالی بگذارد — که هر دو خطرناک‌اند. برای این موارد فیلدهای اختیاری را nullable تعریف کنید و در لایهٔ برنامه تصمیم بگیرید که با مقدار خالی چه کنید.

برای مطالعهٔ بیشتر دربارهٔ طراحی pipeline‌های داده‌محور با هوش مصنوعی، نقشهٔ راه هوش مصنوعی و داده را ببینید. اگر هنوز با اصول نوشتن prompt برای خروجی قابل‌اتکا آشنا نیستید، نقشهٔ راه مهندسی پرامپت نقطهٔ شروع خوبی است.

جمع‌بندی

  • هر جا خروجی مدل قرار است توسط برنامه پردازش شود، از structured output/JSON mode واقعی استفاده کنید، نه دستور متنیِ «JSON برگردان».
  • schema را کوچک، دقیق و با انواع داده و enum مشخص طراحی کنید.
  • additionalProperties را false بگذارید و فیلدهای required را به حداقل واقعی محدود کنید.
  • JSON معتبر بودن ساختار را تضمین می‌کند، نه صحت معنایی؛ اعتبارسنجی سمت برنامه را حذف نکنید.
  • فیلدهایی که ممکن است در داده واقعی وجود نداشته باشند را nullable/اختیاری تعریف کنید تا مدل مجبور به حدس زدن نشود.
(0 رأی)

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *