رفتن به محتوا

راهنماها

شیوهٔ اجرای درخواست در مهوش

از لحظهٔ فرستادن request تا رسیدن پاسخ چه اتفاقی می‌افتد: انتخاب مدل، بررسی قابلیت‌ها، ابزارها و بازیابی اسناد، تلاش نزد ارائه‌دهنده، اجرای پس‌زمینه، لغو و محاسبهٔ هزینه؛ همه در حدی که کلاینت شما می‌بیند و می‌تواند به آن تکیه کند.

از request تا پاسخ

هر request هوش مصنوعی به همین ترتیب از چند مرحلهٔ ثابت عبور می‌کند:

  1. ۱احراز هویت و تعیین محدوده. مهوش فرستنده را شناسایی می‌کند و پیش از دست زدن به هر داده‌ای، سازمان و پروژه را مشخص می‌کند.
  2. ۲بررسی request. request با قرارداد عمومی API مقایسه می‌شود. فیلد ناشناخته، نوع داده‌ای اشتباه یا ترکیب پشتیبانی‌نشده، پیش از هر هزینه‌ای با خطای 400 رد می‌شود.
  3. ۳اعمال تنظیمات پروژه. دستورالعمل‌ها، prompt و مقدارهای پیش‌فرض پروژه اضافه می‌شوند؛ هر چیزی که خودتان صریحاً در request بفرستید، اولویت دارد.
  4. ۴پذیرش. محدودیت‌ها، کارهای همزمان و بودجه بررسی می‌شوند، هزینهٔ تخمینی رزرو می‌شود و یک run ماندگار با شناسهٔ عمومی ثبت می‌شود.
  5. ۵انتخاب مسیر و اجرا. مهوش مسیری نزد ارائه‌دهنده انتخاب می‌کند که کل request را پشتیبانی کند و برای فراخوانی ارائه‌دهنده یک تلاش (attempt) ثبت می‌کند.
  6. ۶یکدست‌سازی و ارائه. نتیجه یا stream ارائه‌دهنده به قالب عمومی مهوش و OpenAI تبدیل می‌شود.
  7. ۷تسویه. مصرفی که ارائه‌دهنده گزارش کرده ثبت و از حساب سازمان کسر می‌شود.

چون هر run ماندگار است، حتی اگر اتصال شما قطع شده باشد، می‌توان آن را بازیابی، بررسی، لغو یا دوباره دریافت کرد.

مدل منطقی، مسیر و قابلیت‌ها

model که می‌فرستید یک مدل منطقی است؛ یعنی نامی عمومی و ثابت. پشت این نام ممکن است یک یا چند مسیر وجود داشته باشد؛ یعنی حساب‌هایی مشخص نزد ارائه‌دهندگان که می‌توانند آن مدل را اجرا کنند.

در هر request، مسیری انتخاب می‌شود که همهٔ خواسته‌های request را پشتیبانی کند: نوع عملیات (Responses، embedding، تصویر و...)، نوع ورودی و خروجی، تک‌تک ابزارها، stream، گزینه‌های استدلال و هر پارامتر اختیاری که مقدار غیرپیش‌فرض دارد. GET /v1/models قابلیت‌های مدل‌های منطقی را نشان می‌دهد، اما در دسترس بودن مسیر برای هر request جداگانه مشخص می‌شود.

به همین دلیل ممکن است requestی که روی کاغذ درست است، پاسخ 503 provider_unavailable بگیرد؛ یعنی در آن لحظه هیچ مسیر تنظیم‌شده‌ای نمی‌توانست کل request را اجرا کند. با این حالت مثل یک وضعیت عادی در زمان اجرا برخورد کنید:

  • فهرست مدل‌ها را بگیرید و مدلی را انتخاب کنید که قابلیت‌هایش با نیاز شما جور است؛
  • پارامترهای اختیاری‌ای را که واقعاً لازم ندارید حذف کنید؛
  • پیام روشنی به کاربر نشان دهید و بعداً دوباره تلاش کنید یا مدل دیگری پیشنهاد دهید.

با model: "auto" (در Responses و Chat Completions) انتخاب مدل مناسب را به مهوش می‌سپارید. هرجا پشتیبانی شود، فیلد mode نوع انتخاب خودکار را تعیین می‌کند؛ مثلاً chat، reasoning یا vision.

ابزارها و بازیابی اسناد

ابزارها کارهایی را که مدل هنگام نوشتن پاسخ می‌تواند انجام دهد بیشتر می‌کنند. سه نوع ابزار داریم و نتیجهٔ همه در همان قالب عمومی output برمی‌گردد:

  • تابع‌های خودتان. ابزار function تعریف می‌کنید؛ مدل یک آیتم function_call برمی‌گرداند، کد شما آن را اجرا می‌کند و نتیجه را در request بعدی می‌فرستید.
  • ابزارهای ارائه‌دهنده مثل web_search، file_search یا image_generation که اگر مسیر پشتیبانی کند، مستقیم نزد ارائه‌دهنده اجرا می‌شوند.
  • ابزارهای مدیریت‌شده. وقتی مسیری قابلیتی را که پروژه فعال کرده ندارد، مهوش می‌تواند خودش آن را فراهم کند؛ مثل جست‌وجوی وب، ساخت تصویر یا خواندن تصویر و سند. هزینهٔ این کارها هم مثل بقیه محاسبه می‌شود.

می‌توانید ابزارهای مدیریت‌شده را در هر request تنظیم کنید:

{
  "model": "auto",
  "input": "What changed in the latest Python release?",
  "managed_tools": {
    "enabled": true,
    "tools": ["web_search"],
    "max_rounds": 3
  }
}

برای بازیابی اسناد، اگر auto-search پروژه فعال باشد و request خودش ابزاری تعیین نکرده باشد، یک file_search روی منابع دادهٔ پروژه اضافه می‌شود؛ با tools: [] یا tool_choice: "none" می‌توانید آن را غیرفعال کنید. بنابراین ممکن است پیش از پیام مدل، آیتمی از نوع file_search_call در خروجی ببینید.

نکته:نتیجه را بر اساس type هر آیتم خروجی و annotationهایی مثل file_citation بخوانید و روش اجرای مشخصی را فرض نکنید. یک request ممکن است در یک مسیر با ابزار ارائه‌دهنده و در مسیری دیگر با ابزار مدیریت‌شده اجرا شود.

تلاش‌ها و مسیر جایگزین

هر فراخوانی ارائه‌دهنده به‌عنوان یک تلاش (attempt) ثبت می‌شود. اگر یک مسیر پیش از بروز هر وضعیت مبهمی شکست بخورد (مثلاً ارائه‌دهنده صریحاً درخواست را رد کند یا پاسخ غیرقابل‌استفاده بدهد)، مهوش ممکن است مسیر مناسب دیگری را در قالب یک تلاش تازه و ثبت‌شده امتحان کند.

استفاده از مسیر جایگزین در دو حالت متوقف می‌شود:

  • وقتی نتیجه مبهم است. اگر ممکن باشد ارائه‌دهنده request را پردازش کرده باشد (مثلاً بعد از ارسال، timeout رخ داده باشد)، مهوش دوباره تلاش نمی‌کند؛ چون ممکن است کار دو بار انجام و دو بار محاسبه شود. در این حالت run خطای provider_outcome_unknown می‌گیرد.
  • وقتی بخشی از خروجی دیده شده است. همین که بخشی از stream به کلاینت شما رسید، run به همان مسیر وابسته می‌ماند.

کلاینت شما هم باید همین اصل را رعایت کند: کار پولی را بعد از یک نتیجهٔ مبهم هرگز خودکار دوباره نفرستید و اول response ذخیره‌شده را بررسی کنید. سیاست امن تکرار request در Headerها و ساختار Response آمده است.

اجرای پس‌زمینه

بعضی کارها چند دقیقه طول می‌کشند؛ مثل پژوهش عمیق، سندهای طولانی یا زنجیره‌های بزرگ ابزار. به‌جای باز نگه داشتن اتصال، background: true بفرستید:

# 1. Submit. The answer arrives immediately with status "queued".
curl https://api.mahvashai.ir/v1/responses \
  -H "Authorization: Bearer $MAHVASH_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: research-q3-report" \
  -d '{"model": "<model-id>", "input": "Compare Q3 supplier contracts.", "background": true}'

# 2. Poll. Retrieval reads stored state and never starts provider work.
curl https://api.mahvashai.ir/v1/responses/resp_<uuid> \
  -H "Authorization: Bearer $MAHVASH_API_KEY"

# 3. Optional: ask Mahvash to cancel
curl -X POST https://api.mahvashai.ir/v1/responses/resp_<uuid>/cancel \
  -H "Authorization: Bearer $MAHVASH_API_KEY"

پاسخ به محض ثبت request برمی‌گردد؛ با status: "queued" و output خالی. بعد یا GET /v1/responses/{id} را هر چند وقت یک بار بخوانید، یا برای پروژه webhook تعریف کنید تا خبرتان کنند.

statusمعنا
queuedمهوش request را پذیرفته، ولی هنوز نزد ارائه‌دهنده شروع نشده است
in_progressنزد ارائه‌دهنده در حال اجراست، یا درخواست لغو آن در انتظار تأیید است
completedتمام شده و output و usage کامل‌اند
incompleteزودتر متوقف شده (مثلاً به سقف max_output_tokens رسیده) و خروجی ناقص در دسترس است
cancelledلغو تأیید شده است
failedنزد ارائه‌دهنده ناموفق بوده یا نتیجه قابل تشخیص نبوده است
  • خواندن وضعیت فقط دادهٔ ذخیره‌شده را برمی‌گرداند و هیچ کاری نزد ارائه‌دهنده شروع نمی‌کند؛ پس امن و کم‌هزینه است. با این حال فاصلهٔ معقولی بگذارید؛ مثلاً هر چند ثانیه یک بار و با افزایش تدریجی فاصله.
  • managed_tools را نمی‌توان همراه با background: true فرستاد.
  • مدل‌هایی که برای پژوهش عمیق تنظیم شده‌اند، به background: true و دست‌کم یک ابزار منبع داده نیاز دارند.

لغو

با POST /v1/responses/{id}/cancel از مهوش می‌خواهید اجرای یک response پس‌زمینه را متوقف کند. لغو را می‌توان بی‌خطر تکرار کرد و هیچ‌وقت سابقه را تغییر نمی‌دهد:

  • responseی که پیش‌تر کامل شده، completed می‌ماند؛ چون کار انجام شده و هزینه‌اش محاسبه شده است.
  • اگر ارائه‌دهنده هنوز لغو را تأیید نکرده باشد، response تا روشن شدن نتیجهٔ واقعی در وضعیت in_progress می‌ماند.
  • ممکن است response لغوشده بابت کاری که ارائه‌دهنده پیش‌تر انجام داده، هزینه داشته باشد.

برای runهای Chat Completions از POST /v1/chat/completions/cancel استفاده کنید.

مصرف و محاسبهٔ هزینه

هر run تعداد tokenها و فراخوانی‌های ابزاری را که ارائه‌دهنده گزارش می‌کند ثبت می‌کند و هزینه‌اش هنگام تسویه از حساب سازمان کسر می‌شود. این نکته‌ها برای یکپارچه‌سازی شما مهم‌اند:

  • شیء usage در هر response تعداد tokenهای همان run است. اگر از مشتریان خود هزینه می‌گیرید، آن را کنار رکوردهای خودتان ذخیره کنید.
  • فراخوانی ابزارهای مدیریت‌شده، مثلاً هر جست‌وجوی وبی که مدل انجام می‌دهد، کار جداگانه‌ای با هزینهٔ خودش در همان response است.
  • کاری که پیش از رسیدن به ارائه‌دهنده رد شود (به دلیل خطای اعتبارسنجی، محدودیت یا بودجه) هزینه‌ای ندارد. اما کاری که ارائه‌دهنده انجام داده، ممکن است بر اساس مصرف گزارش‌شده هزینه داشته باشد؛ حتی اگر run بعداً شکست بخورد (مثلاً خروجی با JSON schema درخواستی جور نباشد) یا لغو شود.
  • حذف response یا فرستادن store: false محتوای آن را پاک می‌کند، اما سابقهٔ حسابداری باقی می‌ماند؛ چون مدرک درستی هزینهٔ ثبت‌شده است.