رفتن به محتوا

راهنماها

پردازش انبوه تیکت‌ها

هزاران تیکت قدیمی را با یک batch در پس‌زمینه دسته‌بندی یا خلاصه کنید؛ به‌جای اینکه اپلیکیشن را با فرستادن تک‌به‌تک requestها معطل کنید.

بخش‌های این سناریو چطور به هم وصل‌اند

  1. 01استخراج تیکت‌ها
  2. 02worker سازندهٔ JSONL
  3. 03batch در مهوش
  4. 04به‌روزرسانی تیکت‌ها

یک مثال واقعی

کالالند را در نظر بگیرید؛ یک بازارگاه اینترنتی. تیکت‌های پشتیبانی یک سال گذشته‌اش هرگز دسته‌بندی نشده‌اند و مدیران می‌خواهند بدانند مشتریان چرا با پشتیبانی تماس می‌گیرند: کالای اشتباه، تأخیر ارسال، بازگشت وجه یا مشکل حساب؟ برچسب‌زدن دستی ممکن نیست و ارسال تک‌به‌تک تیکت‌ها هم با ترافیک زندهٔ سایت رقابت می‌کند.

با batch مهوش، یک job شبانه تیکت‌ها را استخراج می‌کند، همه را در یک فایل می‌فرستد و برای هر تیکت یک دسته، یک حس (sentiment) و یک خلاصهٔ یک‌خطی دریافت می‌کند — در قالب JSON دقیقی که مستقیم به سیستم تیکت برمی‌گردد.

آنچه کسب‌وکار به دست می‌آورد

  • پردازش کل سابقه بدون ساختن سامانهٔ صف.
  • اجرا در پس‌زمینه. کار batch به‌صورت ناهمگام و با محدودیت ظرفیت خودش پردازش می‌شود و اپلیکیشن شما منتظر نمی‌ماند.
  • نتیجهٔ تمیز و ساختاریافته که مستقیم به داشبورد و گزارش می‌رسد.
  • شکست محدود. مشکل یک تیکت بقیه را متوقف نمی‌کند و فقط خط‌های ناموفق تکرار لازم دارند.

با یک تیکت ببینید

مرحلهچه اتفاقی می‌افتددر این مثال
۱. استخراجیک job شبانه متن تیکت‌ها را بدون نام و شمارهٔ تلفن استخراج می‌کند.تیکت ۱۰۴۸۲: «کتری آبی سفارش دادم ولی فروشنده قرمز فرستاده…»
۲. ساخت فایلبرای هر تیکت یک خط JSONL نوشته می‌شود که دسته، حس و خلاصه را در قالب JSON ثابت می‌خواهد.custom_id: ticket-10482
۳. ارسالفایل با purpose=batch آپلود و batch ساخته می‌شود.وضعیت از validating به in_progress می‌رسد.
۴. جمع‌آوریپس از پایان batch، job فایل‌های خروجی و خطا را دانلود می‌کند.{"category": "wrong_item", "sentiment": "negative", …}
۵. اعمالبرچسب‌های اعتبارسنجی‌شده ذخیره می‌شوند و داشبورد تیکت‌ها را بر اساس دلیل گروه‌بندی می‌کند.«کالای اشتباه» به دسته‌ای قابل‌مشاهده و قابل‌اندازه‌گیری تبدیل می‌شود.

هر خط فایل ورودی یک request کامل به Responses است. این یک خط ورودی و خط متناظرش در فایل خروجی است:

{"custom_id": "ticket-10482", "method": "POST", "url": "/v1/responses", "body": {"model": "auto", "instructions": "Label this support ticket.", "input": "کتری آبی سفارش دادم ولی فروشنده قرمز فرستاده. رنگ درست را می‌خواهم، نه بازگشت وجه.", "text": {"format": {"type": "json_schema", "name": "ticket_label", "strict": true, "schema": {"type": "object", "additionalProperties": false, "required": ["category", "sentiment", "summary"], "properties": {"category": {"type": "string", "enum": ["delivery", "wrong_item", "damaged", "refund", "account", "other"]}, "sentiment": {"type": "string", "enum": ["positive", "neutral", "negative"]}, "summary": {"type": "string"}}}}}}}

JSON schemaیی که در text.format آمده، باعث می‌شود مدل دقیقاً همان فیلدها و دسته‌هایی را برگرداند که شما تعریف کرده‌اید؛ پس worker شما می‌تواند هر نتیجه را پیش از ذخیره بررسی کند. custom_id هم همان چیزی است که این خروجی را به تیکت ۱۰۴۸۲ وصل می‌کند.

نکته:قالب دقیق پوشش خط‌های خروجی نمونه است. نتیجه‌ها را همیشه با custom_id تطبیق دهید و مقدارهای parseشده را پیش از استفاده اعتبارسنجی کنید.

چرا batch

رسیدگی به تیکت‌های انباشته، دسته‌بندی دوبارهٔ شبانه یا خلاصه‌سازی انبوه به پاسخ فوری نیاز ندارد. با batch همهٔ کار را در یک فایل می‌فرستید و نتیجه را بعداً تحویل می‌گیرید.

  • job شما شناسهٔ تیکت‌ها و متن پاک‌سازی‌شدهٔ آن‌ها را از سیستم خودتان استخراج می‌کند.
  • مهوش هر خط را مثل یک request معمولی و با همان بررسی‌ها، محدودیت‌ها و محاسبهٔ هزینه پردازش می‌کند.
  • job شما هر نتیجه را با کمک custom_id به تیکت خودش وصل می‌کند و اعمالش می‌کند.

ساخت یک فایل JSONL معتبر

در هر خط یک شیء JSON بنویسید. هر خط باید یک custom_id یکتا، method: "POST"، مسیر endpoint در فیلد url (مثلاً /v1/responses یا /v1/moderations) و body مربوط به request را داشته باشد. همهٔ خط‌ها باید همان endpointی را داشته باشند که batch برایش ساخته می‌شود.

  • requestهای stream یا پس‌زمینه داخل batch مجاز نیستند.
  • خط خالی، custom_id تکراری، فیلد ناشناخته یا JSON نامعتبر باعث می‌شود batch پیش از اجرای هر خطی رد شود.

فایل نهایی .jsonl را با purpose=batch از طریق /v1/files آپلود کنید.

ارسال و پیگیری

  1. ۱batch را با شناسهٔ file-... فایل آپلودشده، endpoint مربوط و completion_window: "24h" بسازید.
  2. ۲شناسهٔ batch را ذخیره کنید. وضعیت batch اول validating است و وقتی همهٔ خط‌ها پذیرفته شدند، به in_progress تغییر می‌کند.
  3. ۳یک worker زمان‌بندی‌شده GET /v1/batches/{batch_id} را می‌خواند و request_counts را دنبال می‌کند.
  4. ۴وقتی batch تمام شد، فایل‌های output_file_id و error_file_id را جداگانه دانلود کنید؛ ممکن است یکی از آن‌ها وجود نداشته باشد.

پیاده‌سازی worker

این نمونه فایل JSONL را از رکوردهای تیکت می‌سازد، آن را آپلود می‌کند، batch را ایجاد می‌کند و شناسه‌اش را برمی‌گرداند. یک worker جداگانه هم هر خط خروجی را بر اساس custom_id می‌خواند و با تیکت تطبیق می‌دهد.

مهم:هیچ‌وقت ترتیب خط‌ها را مبنای شناسایی تیکت قرار ندهید. نتیجه‌ها را همیشه با custom_id تطبیق دهید؛ چون شکست بخشی از خط‌ها و تلاش‌های دوباره، ترتیب را غیرقابل‌اعتماد می‌کند.

نمونهٔ پیاده‌سازی

import json, os, requests
api = "https://api.mahvashai.ir"
headers = {"Authorization": "Bearer " + os.environ["MAHVASH_PROJECT_KEY"]}
with open("tickets.jsonl", "w", encoding="utf-8") as target:
    for ticket in tickets.unsummarized():  # Your queue
        target.write(json.dumps({"custom_id": str(ticket.id), "method": "POST", "url": "/v1/responses",
            "body": {"model": "auto", "input": "Summarize this ticket: " + ticket.text}}) + "\n")
with open("tickets.jsonl", "rb") as source:
    uploaded = requests.post(api + "/v1/files", headers=headers,
        data={"purpose": "batch"}, files={"file": source}, timeout=120)
uploaded.raise_for_status()
batch = requests.post(api + "/v1/batches", headers=headers,
    json={"input_file_id": uploaded.json()["id"], "endpoint": "/v1/responses",
          "completion_window": "24h"}, timeout=30)
batch.raise_for_status()
jobs.save_batch_id(batch.json()["id"])  # Poll GET /v1/batches/{id} later

نمونهٔ خروجی این مرحله

{
  "id": "batch_<id>",
  "object": "batch",
  "status": "validating",
  "input_file_id": "file-<uuid>",
  "output_file_id": null
}

این فقط بخشی از response به‌عنوان نمونه است. روند کار و داده‌های مشتری در اپلیکیشن خود شما مدیریت می‌شوند.

اعمال امن نتیجه‌ها

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

تکرار و لغو

  • ممکن است batch تمام شود ولی چند خط در فایل خطا باشند. کل batch را دوباره نفرستید؛ یک فایل تازه فقط با custom_idهای ناموفق بسازید.
  • POST /v1/batches/{batch_id}/cancel کارهای در صف را متوقف می‌کند. خط‌هایی که پیش‌تر انجام شده‌اند، انجام‌شده باقی می‌مانند و هزینه‌شان محاسبه می‌شود.

همین الگو برای کسب‌وکارهای دیگر

  • نظرات محصولات — برچسب حس و موضوع برای همهٔ نظرات فروشگاه.
  • متن تماس‌ها — خلاصهٔ شبانهٔ تماس‌های دیروز.
  • محتوای کاتالوگ — بازنویسی یا ترجمهٔ انبوه توضیحات محصولات.
  • مدیریت محتوا — بررسی انبوه نظرات کاربران با /v1/moderations.
  • ایندکس جست‌وجو — ساخت embedding برای بایگانی اسناد با /v1/embeddings.