Structured Outputs یا Function Calling؛ JSON معتبر هنوز ابزار نیست

|نویسنده: تیم تحریریه QUASA|6 دقیقه مطالعه
Structured Outputs یا Function Calling؛ JSON معتبر هنوز ابزار نیست

برای استخراج اطلاعات فاکتور در قالب JSON مطابق schema، Structured Outputs را در text.format به کار ببرید؛ اگر مدل باید ثبت فاکتور را از طریق API درخواست کند، Function Calling را تعریف کنید. راهنمای خروجی ساخت‌یافتهٔ OpenAI این تفاوت را میان شکل پاسخ مدل و اتصال آن به ابزار برنامه توضیح می‌دهد.

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

مقصد فاکتور، روش را تعیین می‌کند

اگر نتیجه قرار است در فرم نمایش داده شود، به کاربر برای بازبینی برسد یا به مرحلهٔ دیگری از پردازش برود، برنامه به داده‌ای با شکل مشخص نیاز دارد. Structured Outputs در text.format برای همین خروجی مناسب است. برخلاف JSON mode که معتبر بودن نحو JSON را هدف می‌گیرد، این روش انطباق پاسخ با schema تعیین‌شده را نیز اعمال می‌کند؛ البته برنامه همچنان باید پاسخ ناتمام یا امتناع مدل را مدیریت کند.

اگر برنامه می‌خواهد مدل بر اساس درخواست، استفاده از یک تابع را پیشنهاد کند، Function Calling به کار می‌آید. مدل نام تابع و آرگومان‌های پیشنهادی را برمی‌گرداند و کد برنامه دربارهٔ اجرای آن تصمیم می‌گیرد. بنابراین یک گردش‌کار می‌تواند هر دو را داشته باشد: ابتدا دادهٔ فاکتور را در قالب مشخص استخراج کند و سپس، پس از بازبینی، درخواست ثبت همان داده را به جریان ابزار بسپارد.

استخراج فاکتور با text.format

فرض کنید در یک مثال فرضی، متن فاکتور نام فروشندهٔ «شرکت الف»، شمارهٔ «الف-۲۸»، مبلغ ۱۲۰۰۰۰۰ ریال و واحد پول «IRR» را دارد. برنامه در درخواست Responses API، داخل text.format نوع json_schema و گزینهٔ strict: true را می‌گذارد. schema چهار کلید seller، invoice_number، amount و currency را تعریف می‌کند؛ مبلغ عدد است و واحد پول می‌تواند به «IRR» محدود شود.

خروجی مورد انتظار در این مثال، شیئی مانند {"seller":"شرکت الف","invoice_number":"الف-۲۸","amount":1200000,"currency":"IRR"} است. این شیء برداشت ساخت‌یافتهٔ مدل از متن ورودی است؛ هنوز هیچ رکوردی در حسابداری ایجاد نشده است. پیش از نمایش یا استفاده از آن، برنامه باید کامل بودن پاسخ را بررسی کند و اگر مدل امتناع کرد یا پاسخ ناتمام ماند، آن وضعیت را به‌جای دادهٔ استخراج‌شده مدیریت کند.

انطباق با schema دربارهٔ شکل داده است. عدد بودن مبلغ ثابت نمی‌کند مدل آن را درست از فاکتور خوانده است؛ رشته بودن نام فروشنده نیز نشان نمی‌دهد آن فروشنده در سامانهٔ مقصد وجود دارد. اگر متن فاکتور مبهم یا خواندن مبلغ محل تردید باشد، دادهٔ استخراج‌شده باید برای بازبینی نگه داشته شود. schema می‌تواند واحد پول نامجاز یا کلید اضافه را کنار بگذارد، اما معنای درست مقدارهای مجاز را تضمین نمی‌کند.

ثبت همان فاکتور با Function Calling

برای مسیر ثبت، برنامه می‌تواند تابعی فرضی به نام register_invoice با همان چهار آرگومان تعریف کند. راهنمای Function Calling در OpenAI جریان را از دریافت فراخوانی مدل تا اجرای کد در برنامه و بازگرداندن خروجی ابزار شرح می‌دهد. در این مسیر، پاسخ مدل درخواست استفاده از تابع است؛ اجرای API حسابداری کار برنامه خواهد بود.

  1. برنامه متن فاکتور و تعریف تابع را به مدل می‌دهد. در parameters نوع و نام چهار آرگومان مشخص می‌شود و strict: true انطباق آرگومان‌های فراخوانی با schema تابع را اعمال می‌کند.
  2. مدل ممکن است فراخوانی register_invoice را با مقدارهای «شرکت الف»، «الف-۲۸»، ۱۲۰۰۰۰۰ و «IRR» برگرداند. برنامه نام تابع، آرگومان‌ها و شناسهٔ فراخوانی را دریافت می‌کند؛ در این مرحله هنوز ثبت موفقی رخ نداده است.
  3. برنامه داده‌های پیشنهادی را با فاکتور بازبینی‌شده و قواعد حسابداری تطبیق می‌دهد، مجوز کاربر را بررسی می‌کند و تنها پس از تأیید لازم، API ثبت را صدا می‌زند.
  4. برنامه خروجی واقعی API را با شناسهٔ همان فراخوانی به جریان مدل برمی‌گرداند. پاسخ نهایی به کاربر باید از وضعیت ثبت یا خطای برگشتی سامانه پیروی کند.

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

strict مرز ساختار را نگه می‌دارد

در تعریف تابعِ سخت‌گیرانه، برای هر شیء در parameters باید additionalProperties: false تعیین شود و همهٔ فیلدهای تعریف‌شده در required بیایند. برای فیلدی که ممکن است مقدار نداشته باشد، می‌توان نوع null را نیز مجاز کرد. schema ناسازگار با این الزامات در درخواست دارای strict: true رد می‌شود.

این سخت‌گیری احتمال دریافت آرگومان‌هایی با ساختار نامنتظر را کاهش می‌دهد، ولی اعتبار تجاری آن‌ها را تعیین نمی‌کند. مبلغی که از نظر نوع و محدودهٔ schema مجاز است، ممکن است با فاکتور اصلی نخواند. شمارهٔ فاکتور نیز ممکن است از نظر ساختار درست باشد اما قبلاً برای همان فروشنده ثبت شده باشد. تطبیق فروشنده، مبلغ، واحد پول و وضعیت ثبت قبلی باید در منطق برنامه یا API مقصد انجام شود.

به رفتار پیش‌فرض strict تکیه نکنید: Responses می‌کوشد schema تابع را در صورت امکان به حالت سخت‌گیرانه ببرد و اگر سازگار نباشد ممکن است به حالت غیرسخت‌گیرانه برگردد؛ Chat Completions به‌طور پیش‌فرض سخت‌گیرانه نیست. وقتی انطباق آرگومان‌ها لازم است، گزینه را صریح تعیین کنید و اعتبارسنجی ورودی را در مرز اجرای API خود نیز نگه دارید.

مجوز، خطا و تأیید ثبت

ثبت فاکتور دادهٔ سامانهٔ مقصد را تغییر می‌دهد. راهنمای کنترل‌ها و بازبینی انسانی OpenAI بررسی آرگومان‌ها یا نتایج ابزار و توقف برای تأیید پیش از اقدام حساس را کنترل‌هایی جداگانه معرفی می‌کند. در مثال فاکتور، برنامه می‌تواند هویت درخواست‌کننده، محدودهٔ دسترسی او و نیاز به تأیید انسانی مبلغ یا فروشنده را پیش از اجرای ثبت بررسی کند.

نتیجهٔ API نیز بخشی از تصمیم است. اگر API خطای اعتبارسنجی یا رد مجوز برگرداند، پیام کاربر باید شکست ثبت را نشان دهد. اگر ارتباط پس از ارسال درخواست قطع شود و نتیجه معلوم نباشد، تکرار بی‌بررسی می‌تواند فاکتور را دوباره ثبت کند؛ برنامه باید وضعیت را با شناسهٔ درخواست یا شمارهٔ فاکتور پیگیری کند و، اگر API مقصد پشتیبانی می‌کند، از سازوکار جلوگیری از ثبت تکراری بهره ببرد.

برای اعلام موفقیت، برنامه به وضعیت موفق و شناسهٔ رکورد از سامانهٔ مقصد نیاز دارد. تا پیش از دریافت آن، وضعیت دقیق‌تر این است که اطلاعات فاکتور استخراج شده، درخواست ثبت در انتظار تأیید است یا نتیجهٔ ثبت هنوز روشن نیست. چنین تفکیکی اجازه می‌دهد JSON ساخت‌یافته در جای خود مفید باشد، بی‌آنکه شکل درست داده با اجازهٔ انجام عمل یا نتیجهٔ آن اشتباه گرفته شود.

بیشتر بخوانید:

اشتراک‌گذاری:

عضویت در خبرنامه

تازه‌ترین اخبار Web3، هوش مصنوعی و رمزارز را مستقیم در صندوق ایمیل خود دریافت کنید.

0