اگر امروز در حال ساخت یک اپلیکیشن تولید ویدیو هستید، باید بدانید که یک درخواست API استاندارد شما را ناامید خواهد کرد؛ زیرا تولید ویدیو توسط هوش مصنوعی دقایق زمان میبرد، نه میلیثانیهها. برای بقا در برابر این تأخیر (Latency)، توسعهدهندگان باید یک صف پردازش (Job Queue) مستحکم پیاده کنند که درخواست کاربر را از زمان پردازش مدل جدا (Decouple) کند. این چالش مدیریت تأخیر، در مدلهای زبانی نیز به شدت احساس میشود؛ چنانکه پیشتر بررسی کردیم چگونه استفاده از SSE و کشینگ معنایی میتواند تأخیرها را به زیر یک ثانیه برساند. این یک درخواست HTTP معمولی نیست؛ بکاند باید ورودی را اعتبارسنجی کند، یک «کار» (Job) ایجاد کند، آن را به ارائهدهنده ارسال کند، برای تکمیل آن نظارت (Poll) داشته باشد و شکستها را مدیریت نماید.
این تغییر معماری حیاتی است زیرا گردشکارهای ویدیو شامل حداقل شش مرحله مجزا هستند: اعتبارسنجی پرامپت، تأیید داراییها (Assets)، ایجاد رکورد داخلی، ارسال به ارائهدهنده، نظارت بر نتایج و نرمالسازی رابط کاربری (UI Normalization). بدون یک لایه سازگارساز (Adapter Layer) ساختاریافته، جزئیات فنی و رفتارهای خاص یک API شخص ثالث میتواند به کل کد شما نفوذ کند و با رشد سیستم، بدهی فنی (Technical Debt) عظیمی ایجاد نماید.
طبق راهنمای فنی منتشر شده در ۲۰ ژوئن ۲۰۲۶ در وبسایت dev.to، راهکار این مسئله تعریف یک قرارداد محصول داخلی (Internal Product Contract) سختگیرانه است. با استفاده از نوع VideoJob در زبان TypeScript، میتوان وضعیتهایی مانند queued (در صف)، running (در حال اجرا)، delayed (با تأخیر) و failed (شکستخورده) را ردیابی کرد، بدون اینکه مهم باشد کدام ارائهدهنده در حال انجام محاسبات سنگین است.
قراردادِ کار (Job Contract)
برای اینکه دادههای خاص هر ارائهدهنده (Provider-specific payloads) به برنامه نفوذ نکند، یک قرارداد دقیق تعریف کنید. نوع VideoJob باید موارد زیر را ردیابی کند:
- متادادههای اصلی: شامل
id،userId(شناسه کاربر)،modelوprompt. - محدودیتهای فنی: نسبت ابعاد یا aspectRatio (که محدود به گزینههای «16:9»، «9:16» یا «1:1» است) و مدتزمان به ثانیه (
durationSeconds). - ردیابی وضعیت: وضعیت یا
status(با استفاده از نوعJobStatus) و یک شناسه اختیاری برای تسک ارائهدهنده (providerTaskId). - خروجیها و شکستها: آدرس
outputUrlبرای رندرهای موفق و یک کد خطایVideoJobErrorCodeبرای موارد شکست.
مکانیزم آداپتور ارائهدهنده
برای پایداری سیستم، شما باید یک اینترفیس VideoProvider پیاده کنید. این کار تضمین میکند که Worker اصلیِ صف فقط با مجموعهای از متدهای استاندارد تعامل داشته باشد:
- submit(job): کار را ارسال کرده و یک شناسه تسک منحصربهفرد از سوی ارائهدهنده برمیگرداند.
- poll(taskId): وضعیت را چک کرده و یک نتیجه نرمالشده (در حال اجرا، موفق یا شکست) برمیگرداند.
- normalizeError(error): خطاهای مبهم ارائهدهنده را به کدهای داخلی تبدیل میکند؛ کدهایی مانند
provider_timeout(اتمام زمان)،moderation_rejected(رد شده توسط نظارت)،asset_fetch_failed(شکست در دریافت دارایی)،provider_rate_limited(محدودیت نرخ درخواست) یاoutput_missing(فقدان خروجی).
اعتبارسنجی و پردازش بهینه
پیش از صرف اعتبارهای گرانقیمت محاسباتی (Compute Credits)، سیستم باید «بررسیهای ارزان» (Cheap Checks) را انجام دهد. برای مثال، یک تابع validateVideoJob باید فوراً پرامپتهای خالی یا مدتزمانهایی که خارج از بازه ۱ تا ۱۰ ثانیه هستند را رد کند. در یک محیط عملیاتی (Production)، این مرحله اعتبارسنجی همچنین باید اعتبار کاربر (Credits)، در دسترس بودن مدل، قوانین ایمنی و محدودیتهای فایلهای آپلود شده را بررسی کند.
پس از اعتبارسنجی، تابع Worker چرخه حیات را مدیریت میکند. این تابع، کار را از وضعیت validating به running منتقل کرده و سپس وارد یک حلقه نظارت (Polling Loop) میشود. برای جلوگیری از معلق ماندن ابدی کارها، Worker باید از یک برنامه خواب تدریجی (Graduated Sleep Schedule) شامل ۵، ۱۰، ۱۵، ۳۰ و ۶۰ ثانیه استفاده کند تا در نهایت، اگر پاسخی دریافت نشد، کار را به وضعیت delayed ببرد تا یک Worker بازیابی مجزا آن را مدیریت کند.
ماندگاری و بازیابی
در یک دموی ساده، توابع ماندگاری (Persistence) مانند markStatus، saveProviderTaskId، markSucceeded و markFailed ممکن است صرفاً از لاگهای کنسول استفاده کنند. اما در یک ساختار حرفهای، این توابع باید ذخیرهسازهای بادوام (Durable Storage) را بهروزرسانی کنند و قابلیت تکرار (Retry) داشته باشند. رفتار حیاتی در اینجا، انتقال قطعی به وضعیت delayed است؛ این کار مانع از آن میشود که سیستم برای همیشه سعی کند یک پروسه متوقف شده یا «آویزان» را نظارت کند.
برای کسانی که ابزارهای خاصی را یکپارچه میکنند، این راهنما پیشنهاد میکند برای نقشهبرداری صحیح از محدودیتهای مدتزمان، رفتار نظارت، الزامات داراییهای ورودی و نسبتهای ابعاد در آداپتور، به مستندات Seedance API نوشتهی LumiYing مراجعه کنند.
نقشهبرداری وضعیت برای کاربر
این رویکرد تمرکز توسعهدهنده را از مدیریت فراخوانیهای API به مدیریت انتقال وضعیتها (State Transitions) تغییر میدهد. با نرمالسازی دستهبندی خطاها، تعداد تیکتهای پشتیبانی کاهش مییابد. رابط کاربری (UI) هرگز نباید خطاهای خام ارائهدهنده را نمایش دهد، بلکه باید وضعیتهای داخلی را به پیامهای شفاف تبدیل کند:
- queued $
ightarrow$ «ویدیوی شما در صف انتظار است.» - running $
ightarrow$ «ویدیوی شما در حال تولید است.» - delayed $
ightarrow$ «پردازش بیش از حد معمول زمان برد. ما همچنان در حال بررسی هستیم.» - moderation_rejected $
ightarrow$ «این درخواست قابل پردازش نیست. لطفاً پرامپت یا فایلها را تغییر دهید.» - asset_fetch_failed $
ightarrow$ «ما نتوانستیم فایل ورودی را بخوانیم. لطفاً آن را دوباره آپلود کنید.» - provider_timeout $
ightarrow$ «پاسخ ارائهدهنده در زمان مقرر ارسال نشد.»
توسعهدهندگان باید در گام بعدی ارزیابی کنند که چگونه یک Worker بازیابی مجزا برای کارهای وضعیت delayed پیاده کنند تا اطمینان حاصل شود که هیچ درخواست کاربری برای همیشه در فضای مجازی گم نمیشود.
گام بعدی شما
- پیادهسازی یک Worker بازیابی مجزا برای مدیریت کارهای وضعیت
delayedتا هیچ درخواستی برای همیشه گم نشود. - تعریف یک لایه کشینگ برای نتایج تکراری جهت کاهش هزینههای استنتاج.
- بررسی مکانیزم Webhookها برای جایگزینی حلقههای Polling و کاهش فشار روی سرور.
اما داستان مدیریت زیرساختی این تحول حتی پیچیدهتر است — به تحلیل ما دربارهی بهینهسازی هزینه استنتاج در مقیاس بالا مراجعه کنید.




گفتگو