Ця стаття зосереджена на двох останніх категоріях: опитування TaskHandle асинхронних завдань та деталі, пастки і міжмовні відмінності потокових відповідей чату.
I. TaskHandle — єдина абстракція асинхронних завдань
Усі три SDK обгортають асинхронні завдання вTaskHandle, надаючи однакові 4 методи:
Два способи виклику для створення завдання
Кожен асинхронний ресурс (images.generate / video.generate / audio.generate) має параметр wait:
wait=False(за замовчуванням): негайно повертаєTaskHandle, бізнес-код сам вирішує, коли опитувати.wait=True: SDK внутрішньо викликаєhandle.wait(), функція повертає відповідь після завершення. Використовуйте лише тоді, коли ви впевнені, що цільовий API обов’язково поверне полеstatus: succeeded— деякі постачальники не дотримуються цієї угоди, що призведе до того, щоwaitбуде продовжуватися доmax_wait, перш ніж викинеTimeoutError.
Різниця в одиницях (⚠️ Обов’язково до прочитання)
Одиниціpoll_interval та max_wait відрізняються в трьох мовах, що є поширеною проблемою при міжмовній міграції:
Якщо ви спробуєте перевести{ pollInterval: 3000 }з TS як секунди в Pythonpoll_interval=3000, SDK чекатиме 50 хвилин, перш ніж опитувати вдруге.
Приклад: Явне опитування Midjourney на Python
images.generate(..., wait=False)передаєpromptдо Midjourney API, негайно отримуючиhandle, не блокуючи.handle.wait(poll_interval=3.0, max_wait=180.0)внутрішньо кожні 3 секунди виконує POST запит до/midjourney/tasks, покиstatusне зміниться наsucceededабоfailed, або загальний час не перевищить 180 секунд, викинувшиTimeoutError.- Після завершення
result["response"]["data"]зазвичай містить 4 зображення (за замовчуванням Midjourney 2x2 grid).
Приклад: Явне опитування Midjourney на TypeScript
Вибір між синхронним генеруванням та асинхронними завданнями
Якщо ваш постачальник сам по собі є синхронним (NanoBanana / Flux / Seedream), не передавайтеwait:
task_id + /tasks, це синхронне генерування; у відповіді синхронного генерування поле data вже містить остаточний результат.
Внутрішній протокол TaskHandle
ВикликTaskHandle.get() виглядає так:
response — безпосередньо читаючи верхній рівень status, тому перехід між новими та старими відповідями не вплине на бізнес-код.
II. SSE потокова відповідь (chat.completions)
chat.completions.create(stream=True) є наразі єдиним потоковим інтерфейсом у SDK (потоки аудіо / відео ще не підтримуються). Стилі ітерації трьох мов є рідними:
TypeScript
Python
Go
Структура потоку chunk
Кожен chunk є OpenAI-суміснимchat.completion.chunk:
- Перший chunk зазвичай має
delta.role: "assistant", алеcontentпорожній. - Середні chunk містять
delta.content, які можна безпосередньо з’єднувати. - Останній chunk має
deltaпорожнім,finish_reasonєstop/length/content_filter.
Скасування на півдорозі
Передчасне скасування вже нарахованих токенів — токени, згенеровані до моменту скасування, все ще будуть нараховані.
Три, тайм-аут і повторна спроба
Три SDK ділять одну і ту ж стратегію повторних спроб:
Щоб вимкнути повторні спроби: передати
max_retries=0 / maxRetries: 0 / WithMaxRetries(0) під час створення клієнта.
Опитування асинхронних завдань (TaskHandle) не підлягає впливу max_retries — його цикл є бізнес-рівнем, а не HTTP-рівнем, контролюється max_wait.
Чотири, поширені пастки
- Синхронному провайдеру не передавати
wait: NanoBanana / Flux / Seedream є синхронними, примусовеwait=Trueзмусить SDK опитувати інтерфейсtasks, який взагалі не оновлюється. - Різниця в одиницях TaskHandle: Python — секунди, TS — мілісекунди, при переносі між мовами обов’язково перераховуйте.
wait=Trueвсе ще може викликатиTimeoutError: відповідь повинна відповідатиstatus in ('succeeded','failed'), щоб вийти з циклу; якщо провайдер використовує інші назви полів, бізнес-код повинен самостійноhandle.get()розпарсити.- Потокове скасування: токени, згенеровані до скасування, вже нараховані.
- Повторне використання клієнта в одному процесі: SDK має власний пул з’єднань, часте
new AceDataCloud()/AceDataCloud()може зробити TLS-рукопожаття вузьким місцем.

