ВойтиКонтактыНачать бесплатно
Reliability and Routing27 июля 2026 г.Flatkey Team

Контрольный список для production с Seedance API для команд text-to-video

Практический контрольный список для работы с заданиями Seedance text-to-video: надежные очереди, нормализованные статусы, безопасные повторные попытки, хранилище и контроль затрат.

Контрольный список для production с Seedance API для команд text-to-video

Контрольный список для production с Seedance API для команд text-to-video

Прототип Seedance API может выглядеть завершённым после одного успешного видео. Production-интеграция считается завершённой только тогда, когда ваша система способна переживать медленные задачи, дубликаты событий, смену маршрутов модели, частичные сбои и неопределённую стоимость.

Это различие важно, потому что генерация видео — не обычная функция request-response. Приложение отправляет задачу, ждёт, получает изменения статуса, сохраняет большой результат и решает, нужно ли повторять сбойную операцию. Вызов модели — лишь один этап более длинного workflow.

Этот чек-лист превращает такой workflow в production-контракт, который ваши команды продукта, платформы и финансов смогут вместе проверять.

Примечание о текущем маршруте: В общедоступном каталоге моделей Flatkey при проверке этого руководства в понедельник, 27 июля 2026 года для text-to-video и image-to-video была указана seedance-2.5, а для image-to-video — также seedance-2.0-i2v. Рассматривайте эти названия как состояние каталога, а не как постоянные константы. Перед запуском в production или изменением allowlist обязательно проверьте текущий каталог моделей Flatkey.

Краткий ответ

Не подключайте пользовательский запрос напрямую к вызову видеопровайдера. Поместите между ними надёжный слой задач.

Ваш минимальный production-путь должен быть таким:

  1. принять и проверить запрос пользователя на генерацию
  2. назначить собственный idempotency key и job ID
  3. сохранить запрос до вызова маршрута модели
  4. отправить задачу через серверный адаптер
  5. обрабатывать обновления webhook и polling идемпотентно
  6. скопировать готовые медиа в хранилище, которым вы управляете
  7. зафиксировать задержку, причину сбоя, маршрут модели и оценочную стоимость
  8. показывать стабильный статус продукта, не зависящий от формулировок провайдера

Если хотя бы одного из этих шагов нет, интеграция всё ещё может хорошо выглядеть в демо, но ею труднее безопасно управлять.

Почему production-работа с Seedance API отличается

Генерация текста часто возвращает полезный ответ за один HTTP-обмен. Генерация видео обычно ведёт себя как распределённая batch-задача. Действие пользователя может пережить запрос приложения, деплой, сессию браузера или даже временный URL, на котором в итоге окажется результат.

Практические последствия легко недооценить:

Производственная проблема Поведение прототипа Требование для production
Время отклика Заставлять браузер ждать Немедленно возвращать внутренний ID задания
Статус Показывать статус провайдера напрямую Сопоставлять состояния провайдера со своей собственной машиной состояний
Повторы Позволять пользователю нажать снова Повторять только с политикой идемпотентности
Результат Использовать возвращённый URL Копировать медиафайлы в контролируемое хранилище
Стоимость Проверить счёт позже Оценить до отправки и сверить после завершения
Изменения модели Жёстко задать один маршрут Проверять текущий каталог моделей и сохранять путь отката
Обработка сбоев Показывать «failed» Сохранять нормализованную причину и безопасное следующее действие

Цель не в том, чтобы скрыть провайдера. Цель — не дать специфичному для провайдера поведению стать постоянным контрактом вашего продукта.

1. Зафиксируйте контракт продукта до payload

Начинайте с опыта, который вы обещаете пользователям, а не с полей провайдера, доступных сегодня.

Определите:

  • принимаемые типы входных данных: только текст, изображение плюс текст или оба варианта
  • поддерживаемые соотношения сторон и диапазоны длительности
  • максимальный размер загрузки и принимаемые форматы медиа
  • проверки модерации и прав перед отправкой
  • ожидаемые обновления статуса и поведение при отмене
  • срок хранения результата
  • будет ли неудачное задание расходовать пользовательский кредит
  • что означает «retry» в продукте

Затем переведите этот контракт на текущий маршрут Seedance внутри адаптера.

Такое разделение защищает вас от двух распространённых сценариев отказа. Во-первых, обновление маршрута может добавить или переименовать параметры, не заставляя переписывать фронтенд. Во-вторых, ваше приложение может отклонять неподдерживаемые комбинации до того, как на заведомо обречённую задачу будут потрачены деньги.

2. Используйте свой собственный job ID и ключ идемпотентности

Каждому запросу нужны два идентификатора:

  • product job ID: стабильный идентификатор, отображаемый во всей вашей системе
  • idempotency key: идентификатор, используемый для предотвращения случайной дублирующей отправки

Не используйте ID задачи провайдера в качестве первичного ключа. Он не существует до отправки, и он может измениться, если вы намеренно отправите запрос повторно через другой маршрут.

Простая запись о запросе может выглядеть так:

type VideoJob = {
  id: string;
  idempotencyKey: string;
  accountId: string;
  requestedModel: string;
  resolvedModel: string | null;
  providerTaskId: string | null;
  status: "accepted" | "queued" | "running" | "succeeded" | "failed" | "cancelled";
  attempt: number;
  outputUrl: string | null;
  failureCode: string | null;
  createdAt: string;
  updatedAt: string;
};

Создавайте эту запись до вызова внешнего API. Если приложение аварийно завершит работу после отправки, но до сохранения ответа, ключ идемпотентности даст вам способ выполнить сверку вместо того, чтобы вслепую списывать средства за ещё одну генерацию.

3. Поместите Seedance за один серверный адаптер

Держите построение запросов, специфичное для провайдера, в одном модуле. Остальная часть продукта должна отправлять нормализованную команду, например:

type GenerateVideoCommand = {
  prompt: string;
  sourceImageUrl?: string;
  aspectRatio: "16:9" | "9:16" | "1:1";
  durationSeconds: number;
  qualityProfile: "draft" | "standard" | "high";
};

Адаптер отвечает за:

  • сопоставление qualityProfile с доступной на текущий момент моделью и настройками
  • добавление аутентификации на стороне сервера
  • преобразование ваших вариантов соотношения сторон и длительности в актуальную схему API
  • отправку задачи
  • нормализацию ошибок провайдера
  • сохранение ID задачи провайдера
  • передачу достаточного объёма метаданных для анализа затрат и надёжности

Flatkey даёт командам один API-ключ, стабильную конечную точку маршрутизатора, общий баланс и централизованную видимость использования по семействам моделей. Для команд, которые уже используют этот уровень доступа, держите асинхронную логику, специфичную для Seedance, в адаптере, а не разбрасывайте предположения о маршрутах по всей кодовой базе. В более раннем руководстве по стабильному совместимому с OpenAI базовому URL для команд Seedance API этот интерфейс раздела описан подробнее.

4. Представьте рабочий процесс как конечный автомат

Не допускайте, чтобы произвольные строки статуса попадали в логику продукта. Нормализуйте их.

stateDiagram-v2
    [*] --> accepted
    accepted --> queued: submit accepted
    accepted --> failed: validation or submit error
    queued --> running: provider starts work
    queued --> failed: terminal provider error
    running --> succeeded: output verified
    running --> failed: terminal provider error
    accepted --> cancelled: cancelled before submit
    queued --> cancelled: cancellation confirmed
    succeeded --> [*]
    failed --> [*]
    cancelled --> [*]

Разрешайте только переходы вперёд, если только вы не запускаете явный процесс восстановления. Позднее событие running не должно перезаписывать задачу, уже помеченную как succeeded. Дублирующийся webhook succeeded не должен вызывать два копирования в хранилище или два уведомления клиенту.

Сохраняйте сырое событие провайдера отдельно для отладки, но решения в продукте принимайте на основе нормализованного состояния.

5. Используйте webhooks и polling вместе

Webhooks эффективны, но они не гарантируют, что ваше приложение обработает каждое событие ровно один раз и в правильном порядке. Polling медленнее, но он полезен для сверки.

Используйте оба:

  • путь webhook: обновления статуса с низкой задержкой
  • путь polling: плановое восстановление для задач, которые давно не менялись

Ваш обработчик webhook должен:

  1. аутентифицировать callback, когда активный API поддерживает проверку подлинности
  2. разобрать событие без выполнения тяжёлой работы inline
  3. записать отпечаток события в таблицу дедупликации
  4. поставить обработку в очередь
  5. быстро вернуть успешный ответ

Ваш worker для сверки должен опрашивать только те задачи, которые всё ещё находятся в не терминальном состоянии после разумной задержки. Добавьте jitter, чтобы деплой не приводил к тысячам проверок статуса в один и тот же момент.

Специфичные для провайдера поля webhook и query могут меняться. Проверяйте их по актуальной официальной API-документации во время реализации, а не копируйте старый payload из блог-поста.

6. Принимайте решения о повторе по классу сбоя

«Повторять неудачные задания» — это не политика. Это риск затрат.

Нормализуйте ошибки в классы:

Класс сбоя Примеры Действие по умолчанию
Проверка валидности Неподдерживаемые размеры, отсутствует изображение, некорректная длительность Не повторять; вернуть исправляемую продуктовую ошибку
Аутентификация Истекший или недействительный ключ Приостановить отправку и оповестить оператора
Ограничение по скорости или емкости Троттлинг, временная нагрузка на очередь Повторять с экспоненциальным backoff и jitter
Транспорт Таймаут до подтвержденного task ID Сверить по idempotency key перед повторной отправкой
Терминальный сбой провайдера Отказ по safety, сбой генерации Не повторять автоматически, если только провайдер не пометил это как retryable
Обработка результата Временный сбой загрузки или хранения Повторить копирование, а не генерацию

Последнее различие особенно важно. Если видео было успешно сгенерировано, но копирование в ваше хранилище не удалось, повторная генерация создаст лишние расходы и может дать другой результат.

Задайте бюджет повторов для каждого задания. Разумная политика может разрешать больше проверок статуса и попыток копирования в хранилище, чем отправок на генерацию.

7. Копируйте результаты в хранилище, которое вы контролируете

Рассматривайте любой URL результата, размещенный у провайдера, как временную точку передачи, а не как ваш постоянный продуктовый asset.

После успешного завершения задания:

  1. проверьте, что ответ содержит ожидаемый media type
  2. скачайте файл с ограничением по размеру и времени
  3. проверьте, что файл не пустой и явно не обрезан
  4. вычислите checksum
  5. скопируйте его в ваше object storage
  6. сохраните duration, dimensions, codec и size
  7. переведите продуктовое задание в succeeded только после того, как доступна долговременная копия

Если ваш продукт позволяет пользователям скачать исходный asset провайдера до завершения копирования, представляйте это как отдельное временное состояние. Не обещайте постоянство без явного подтверждения.

8. Добавьте контроль затрат до запуска функции

Видео-задания достаточно дорогие, поэтому продуктовые ограничения должны существовать еще до публичного запуска.

Как минимум определите:

  • лимит расходов на ключ или на команду
  • allowlist моделей для application key
  • максимум одновременных заданий на аккаунт
  • максимальную длительность и профиль качества по тарифу
  • дневной лимит отправки для новых или ненадежных аккаунтов
  • circuit breaker, когда растет частота ошибок или стоимость успешного результата

Публичная документация Flatkey описывает лимиты на уровне ключа, необязательные allowlist моделей и видимость использования через Usage & Logs или ledger API. Используйте эти механизмы как защитный барьер на уровне доступа, а затем добавьте продуктовые квоты на основе ваших собственных тарифов и риска злоупотреблений.

Перед включением нового маршрута сравните текущий каталог и цены Flatkey. Не встраивайте числовую цену из этой статьи в логику приложения; цены и доступность маршрутов — это обновляемые данные.

9. Измеряйте весь job, а не только задержку API

Для асинхронного workflow Seedance API успешная отправка запроса все равно может привести к плохому пользовательскому опыту.

Отслеживайте как минимум:

  • коэффициент успешного принятия запросов
  • время ожидания в очереди
  • время генерации
  • общее время до устойчивого результата
  • коэффициент успешности по разрешенной модели
  • коэффициент отказов по нормализованному классу ошибки
  • задержку доставки webhook
  • коэффициент восстановления при polling
  • коэффициент отказов при копировании в хранилище
  • стоимость на один отправленный job
  • стоимость на один успешный устойчивый результат
  • количество предотвращенных дублирующих отправок

Используйте перцентили, а не только средние значения. Медианное время генерации может выглядеть нормально, в то время как самые медленные десять процентов jobs создают большую часть обращений в поддержку.

Также отдельно фиксируйте requestedModel и resolvedModel. Это делает изменения маршрута заметными и дает вам доказательства для решений об откате.

10. Вводите изменения моделей как миграции

Изменение каталога — это не просто замена строки. Относитесь к нему как к обновлению зависимости.

Перед переносом production-трафика на новый маршрут Seedance:

  1. подтвердите текущий маршрут в live-каталоге моделей
  2. сравните поддерживаемые входные данные и ограничения на выход
  3. запустите фиксированный набор оценок для ваших распространенных типов prompt
  4. сравните коэффициент успешности, задержку, приемлемость результата и стоимость
  5. проверьте webhook, polling и нормализацию ошибок
  6. проведите canary для небольшой доли трафика
  7. сохраните маршрут для отката до тех пор, пока canary не станет стабильным
  8. обновите allowlist моделей и операционный runbook

Если ваше приложение предоставляет настройку «качество», сопоставляйте ее с профилем возможностей, а не с постоянным ID модели. Это позволит изменить базовый маршрут без поломки API продукта.

Контрольный список готовности к production

Используйте этот список как gate для запуска.

Запрос и доступ

  • [ ] API-ключи остаются на стороне сервера
  • [ ] ключ приложения имеет лимит расходов и allowlist моделей
  • [ ] каждый запрос имеет внутренний job ID и idempotency key
  • [ ] входные данные проверяются до отправки
  • [ ] текущий маршрут модели Seedance проверяется в live-каталоге

Асинхронное выполнение

  • [ ] специфичная для провайдера логика находится в одном адаптере
  • [ ] product status используют нормализованный state machine
  • [ ] события webhook аутентифицируются, когда это поддерживается, и дедуплицируются
  • [ ] polling согласует устаревшие non-terminal jobs
  • [ ] поздние или дублирующиеся события не могут отменить terminal states

Надежность и стоимость

  • [ ] поведение retry зависит от класса ошибки
  • [ ] retries генерации имеют строгий бюджет
  • [ ] retries копирования результата не регенерируют успешные видео
  • [ ] ограничения на concurrency и дневное число jobs соблюдаются
  • [ ] circuit breaker может приостановить деградирующий маршрут

Выходные данные и observability

  • [ ] успешное медиа скопировано в контролируемое хранилище
  • [ ] метаданные и контрольная сумма результата сохранены
  • [ ] запрошенные и разрешённые ID моделей залогированы
  • [ ] стоимость одного успешного долговременно сохраняемого результата измеряется
  • [ ] у операторов есть runbook для зависших, неудачных и дублированных заданий

Где подходит Flatkey

Flatkey не устраняет необходимость в асинхронном слое видеозаданий. Он снижает объём работ по доступу и управлению вокруг этого слоя: одна учётная запись, один баланс, контроль API-ключей, стабильная поверхность роутера, живой каталог моделей и централизованные записи об использовании.

Для первой интеграции начните с более общего Seedance API quickstart для product-команд text-to-video. Когда функциональность приближается к production, примените этот контрольный список к слоям очереди, состояния, повторных попыток, хранения и наблюдаемости вокруг вызова модели.

Если ваша команда решает, какой текущий маршрут и какие контроли использования подходят для запуска, проверьте живые модели и цены перед утверждением production-конфигурации.

Часто задаваемые вопросы

Seedance API синхронный или асинхронный?

Рассматривайте генерацию видео как асинхронное задание. Ваш продукт должен отправлять работу, возвращать свой собственный ID задания и обрабатывать обновления статуса через webhooks и/или polling в соответствии с текущей API-документацией.

Стоит ли использовать ID задачи провайдера как первичный ключ в базе данных?

Нет. Создайте свой собственный стабильный ID задания до отправки. Сохраните ID задачи провайдера как внешний reference, чтобы можно было сопоставлять, повторно отправлять или менять маршруты без изменения product-идентификатора.

Нужны ли мне и webhooks, и polling?

Для устойчивой production-системы — да. Webhooks дают быстрые обновления; polling позволяет восстановить задания, чьи события были задержаны, пропущены или не обработаны.

Когда безопасно повторять неудачное задание Seedance?

Повторяйте только после классификации сбоя. Сбои из-за нехватки ресурсов и сети могут допускать повтор. Ошибки валидации, аутентификации, безопасности или другие окончательные сбои обычно требуют изменения конфигурации или действий пользователя. Если отправка превысила тайм-аут, выполните сопоставление по idempotency key перед отправкой ещё одного платного задания.

Должен ли я хранить сгенерированное видео самостоятельно?

Да. Копируйте завершённый результат в хранилище, которое вы контролируете, проверяйте файл и сохраняйте его метаданные. URL-адреса результатов, размещённые у провайдера, не следует считать постоянным product-хранилищем, если текущие условия явно не гарантируют такое поведение.

Как следует обрабатывать новую версию модели Seedance?

Относитесь к этому как к миграции: проверьте текущий каталог, запустите фиксированный набор оценок, сравните качество, задержку, отказы и стоимость, направьте трафик через canary и сохраняйте маршрут отката, пока изменение не стабилизируется.

Какую модель Seedance следует жёстко зашить в коде?

Избегайте постоянного жесткого закрепления модели на основе статичной статьи. Сопоставляйте профиль возможностей продукта с моделью, указанной в текущем каталоге моделей Flatkey, и храните выбранный маршрут в конфигурации, чтобы операторы могли безопасно его менять.