SEEDANCE25APIINDEPENDENT
现场笔记 / 集成

Seedance 2.5 激活清单:正式流量前的证据核对

由契约快照、适配层、模拟状态机、安全门和回退路由组成的 API 上线后灰度验证流程

官方 Seedance 2.5 API 与 EvoLink 通道均已上线。开发者现在可以选择 workflow 模型 ID、定义服务商适配层、提交异步任务、测试典型故障,并保留 Seedance 2.0 回退。

但不能把接入本身称为“生产就绪”。在用自己的账户完成真实冒烟调用之前,团队没有任何证据能够说明自身工作负载的实际输出质量、排队时间、计费和失败行为。正确目标是:通道已上线,按清单逐项取得证据后再放量。

核验快照(2026 年 8 月 7 日):官方开发者 API 与 EvoLink 通道均已上线。通道提供三个 workflow ID、4–30 秒、480p/720p 与 R2V 参考素材分配;当前价格和账号限制以控制台为准。Seedance25API 的集成 Schema 是独立辅助,本站不隶属于字节跳动。

本文负责什么,API 参考负责什么

API 快速入门负责维护准确字段、接口示例和当前请求 Schema;本文负责围绕这些定义建立工程流程。

问题负责页面
目前可以验证哪种真实调用模式?API 快速入门,以及其中引用的 2.5 与任务文档
Agent 可以载入哪种结构?集成 Schema
如何生成带类型的客户端?本文
如何在不产生真实费用的情况下测试?本文
如何处理 Schema 变化?本文
哪些请求可以回退到 2.0?本文和 2.5 vs 2.0 决策指南
最终真实价格是多少?价格页面和服务商控制台

明确分开这些职责,可以避免博客变成一份很快过期的 API 文档副本。

从固定契约快照到本地韧性测试、可观测性、熔断和合格回退的 Seedance 2.5 API 上线后灰度验证流程

首先定义生产验证边界

把下面这段说明写进项目 README 或架构决策记录:

已完成本地测试:请求验证、规划类型生成、模拟任务生命周期、
错误映射、回退策略、日志以及回调幂等。

尚未在自有账户上真实验证:账户权限、服务商计费、
输出质量、延迟、参考素材读取、
回调送达以及生产环境限流。

这条边界会改变验收标准。持续集成流程应该在不发起付费调用的情况下通过;生产放量前的检查则必须采用失败关闭策略,所有仅能在线验证的项目确认前不得放行。

第一步:保存集成 Schema 快照并进行版本管理

不要在每次生产构建时都从持续变化的远程 URL 生成客户端代码。应下载一份经过审核的快照或将其纳入项目,记录哈希值,并通过受控变更更新。

curl -fsSL https://seedance25api.io/openapi.json \
  -o contracts/seedance-2.5.openapi.json

shasum -a 256 contracts/seedance-2.5.openapi.json

这份集成 Schema 描述以下内容:

  • 线上通道的 POST /v1/videos/generations 创建任务操作;
  • 通过 GET /v1/tasks/{task_id} 轮询任务状态;
  • 必填的 model(三个正式 workflow ID 之一)和 prompt
  • 可选字段,以通道正式文档为最终依据;
  • 通道当前采用的任务状态词汇:pendingprocessingcompletedfailed
  • 用于本地韧性测试的代表性错误。

已验证的线上基线是:Seedance 2.5 与 2.0 均通过 POST /v1/videos/generations 创建任务、通过 GET /v1/tasks/{task_id} 查询任务(Bearer 鉴权,/v1 前缀必须存在)。固定本地 Schema 可以让团队评审本地集成契约的变化,又不会误把它当成服务商权威定义。

第二步:生成类型,但保持领域类型独立

从快照生成传输层类型:

npx openapi-typescript@7 contracts/seedance-2.5.openapi.json \
  -o src/generated/seedance-transport.ts

不要让生成类型成为应用的领域模型。契约变化时,自动生成的传输层代码也会变化;审核状态、参考素材用途、通过验收的输出等产品概念,则应该保存在稳定的应用类型中。

export type VideoRequest = {
  prompt: string;
  durationSeconds: number;
  quality?: string;
  references: Array<{
    type: "image" | "video" | "audio";
    url: string;
    role: string;
  }>;
};

export type VideoJob = {
  id: string;
  state: "queued" | "running" | "generated" | "failed";
  outputUrl?: string;
  errorCode?: string;
};

适配层负责把稳定的领域类型映射到服务商当前的传输结构。

第三步:把路由能力保存在配置中

通道当前提供三个正式模型 ID:seedance-2.5-text-to-videoseedance-2.5-image-to-videoseedance-2.5-reference-to-video。仍应把模型 ID 和路由能力集中保存在配置里,不要让它们散落在界面组件、数据库记录、测试和工作进程代码中。

type RouteConfig = {
  baseUrl: string;
  model: string;
  maxDuration?: number;
  qualities?: string[];
  maxImages?: number;
  maxVideos?: number;
  maxAudio?: number;
  enabled: boolean;
};

export const seedance25: RouteConfig = {
  baseUrl: process.env.EVOLINK_BASE_URL ?? "https://api.evolink.ai/v1",
  model: process.env.SEEDANCE_25_MODEL ?? "seedance-2.5-text-to-video",
  maxDuration: process.env.SEEDANCE_25_MAX_DURATION
    ? Number(process.env.SEEDANCE_25_MAX_DURATION)
    : undefined,
  qualities: process.env.SEEDANCE_25_QUALITIES?.split(","),
  maxImages: undefined,
  maxVideos: undefined,
  maxAudio: undefined,
  enabled: process.env.SEEDANCE_25_ENABLED === "true",
};

默认 model 就是正式 ID,enabled 只由 SEEDANCE_25_ENABLED 开关决定。如果应用其他位置仍可能绕过开关提交任务,还应增加启动时断言。时长和画质等限制应从通道正式文档取值(当前记录为 4–30 秒、480p/720p),并在开启流量前重新运行验证和冒烟测试。

第四步:在请求到达服务商前完成验证

客户端控件可以改善使用体验,服务端验证则负责保护成本和可靠性。

export function validateRequest(input: VideoRequest, route: RouteConfig) {
  const errors: string[] = [];

  if (!input.prompt.trim()) errors.push("prompt is required");
  if (route.maxDuration && input.durationSeconds > route.maxDuration) {
    errors.push(`duration must be at most ${route.maxDuration}`);
  }
  if (input.quality && route.qualities && !route.qualities.includes(input.quality)) {
    errors.push(`quality ${input.quality} is not enabled for this route`);
  }

  const count = (type: VideoRequest["references"][number]["type"]) =>
    input.references.filter((r) => r.type === type).length;

  if (route.maxImages && count("image") > route.maxImages) errors.push("too many image references");
  if (route.maxVideos && count("video") > route.maxVideos) errors.push("too many video references");
  if (route.maxAudio && count("audio") > route.maxAudio) errors.push("too many audio references");

  return errors;
}

URL 是否可访问、媒体元数据、授权状态和签名 URL 有效期都需要单独检查。即使 URL 字符串格式正确,也可能在服务商读取前过期。

第五步:用本地模拟覆盖完整的异步生命周期

本地模拟仅用于韧性测试——线上通道已可直接调用,模拟测试数据不能代替真实调用。有效的模拟必须带状态。它应该先返回任务 ID,再按顺序改变状态,而不是立即返回一个已完成的视频。

{
  "create": { "id": "mock-job-001", "status": "pending" },
  "poll_sequence": [
    { "id": "mock-job-001", "status": "pending", "progress": 0 },
    { "id": "mock-job-001", "status": "processing", "progress": 40 },
    {
      "id": "mock-job-001",
      "status": "completed",
      "progress": 100,
      "results": ["https://example.invalid/mock-output.mp4"]
    }
  ]
}

示例 URL 使用保留的 .invalid 域名,避免测试程序意外下载无关文件。

为每种重要结果准备测试数据:

测试数据应用的预期行为
200 create在开始轮询前持久化服务商任务 ID
400 invalid request显示具体字段的修正提示;绝不原样重试
401 invalid key停止调用并要求人工修复密钥配置
429 rate limited使用有次数上限并带随机抖动的退避
模拟的 503 unavailable打开路由熔断,并判断请求是否符合回退条件
completed保存输出、用量和原始响应,然后进入人工审核
failed保存失败原因;不能标记为传输成功
重复回调返回成功,但不能重复执行状态变化

还要模拟任务一直停留在 processing,直到超过应用的截止时间。服务商任务可能仍在继续,但面向用户的操作必须进入清晰的超时状态,并允许之后恢复查询。

第六步:测试适配层 Schema,并立即对线上通道做契约测试

第一项 Schema 测试应证明应用请求能够通过固定版本的集成 Schema。第二项应证明所有任务状态都能正确映射。第三项应在 Schema 意外变化时失败。通道官方文档仍是契约差异的权威来源。

通道已上线,服务商契约测试现在就可以做:用自有密钥对线上通道提交小规模冒烟任务(4 秒、480p),核对真实响应结构、状态词汇和错误语义,在把生产流量导入之前完成这一步。

import assert from "node:assert/strict";

const mapped = mapProviderJob({
  id: "mock-job-001",
  status: "processing",
  progress: 40,
});

assert.deepEqual(mapped, {
  id: "mock-job-001",
  state: "running",
  outputUrl: undefined,
  errorCode: undefined,
});

可以在持续集成中增加一个步骤,比较已审核的契约快照与新下载的版本,但不要自动覆盖:

curl -fsSL https://seedance25api.io/openapi.json \
  -o /tmp/seedance-2.5.latest.json

diff -u contracts/seedance-2.5.openapi.json \
  /tmp/seedance-2.5.latest.json

出现差异意味着需要评审,并不等于一定存在破坏性变更。描述文字更新可能没有影响;必填字段、枚举值、状态或响应结构变化,则可能需要同步更新代码和测试数据。

第七步:按失败类型设计重试

“重试三次”不是完整策略。不同失败类型需要不同处理方式。

失败类型是否重试策略
收到响应前网络超时视情况而定在幂等保护下重试,或先对账再重新提交
400修正请求
401修复密钥或权限
429遵循服务商指引,使用指数退避和随机抖动
模拟的 503有限重试打开熔断,稍后重试或使用符合条件的回退路由
任务状态为 failed有条件只有在理解失败原因且策略允许时重试
轮询超时继续轮询同一任务,不能创建重复任务

如果服务商没有提供幂等键,应用需要维护自己的提交记录。服务商受理请求后发生网络超时尤其危险:盲目重新提交可能创建两个需要计费的任务。

第八步:明确判断能否回退

Seedance 2.0 仅作为回滚方案保留,但回退绝不是替换一个字符串。按 2.5 规划的请求可能超过 2.0 的时长或参考素材限制。

function canFallbackToSeedance20(input: VideoRequest) {
  return (
    input.durationSeconds <= 15 &&
    input.references.filter((r) => r.type === "image").length <= 9 &&
    input.references.filter((r) => r.type === "video").length <= 3 &&
    input.references.filter((r) => r.type === "audio").length <= 3
  );
}

上述限制来自所引用的 EvoLink 2.0 公开指南,但仍应与当前启用的路由再次核对。如果请求不符合回退条件,应让用户选择:缩短视频、移除参考素材、等待 2.5 路由恢复,或选择另一条已验证路由。静默截断请求不是安全的回退方式。

第九步:提前记录放量时需要的证据

现在就准备好结构化日志字段:

internal_request_id
provider_route
model_id
contract_version
provider_job_id
submit_attempt
http_status
provider_state
duration_requested
reference_counts
created_at / completed_at
usage_or_cost
output_url_expiry
review_outcome
fallback_route

不要在日志中记录 Bearer Token;敏感的签名 URL 也必须脱敏。日志应该能够回答错误究竟发生在输入验证、鉴权、容量、生成、结果获取还是人工拒绝阶段。

生产放量前验证清单

即使软件已经通过契约测试,仍然需要真实环境证据。按以下顺序检查:

  1. 在服务商文档中确认所选 workflow 模型 ID 和当前账户权限。
  2. 用服务商正式 Schema 核对本地快照,并评审每一项差异。
  3. 创建一个时长短、风险低的冒烟任务。
  4. 验证返回的每一种状态以及结果文件访问。
  5. 确认成功任务的账单记录,并单独调查失败任务如何计费。
  6. 测试限流和暂时不可用处理,同时避免形成重试风暴。
  7. 如果启用回调,验证回调鉴权、重复通知和到达顺序。
  8. 运行已经冻结的工作负载评测集。
  9. 只对少量符合条件的任务开启灰度。
  10. 确认紧急开关能够把流量切回已验证路由。

只有应用行为与服务商行为相符,集成才可以开始小流量灰度;只有输出验收率、成本、延迟和错误率全部达标,才能扩大生产流量。

推荐的下一步

固定机器可读的集成 Schema,生成类型并测试异步状态机。使用 API 快速入门中的 live 2.5 示例,参照智能体指南安全交接密钥;只有请求符合回滚条件时,才使用 Seedance 2.0。

即使 Seedance 2.5 的最终字段发生变化,这些工作仍然有价值。适配层负责隔离变化,任务、审核、日志和评测系统都可以保留。

来源

核验说明:线上基线已经对照通道的 Seedance 2.5、2.0 和任务详情文档检查。本地 OpenAPI 文件是由本站编写的集成辅助材料;当前价格与账号限制以 EvoLink 控制台为准。

Q&A快速解答
Q.01还没开始导入生产流量,开发者可以先集成 Seedance 2.5 吗?
可以使用本站集成 Schema 准备服务商适配层、输入验证、异步状态机、错误处理、可观测性和回退机制。EvoLink 通道已上线;生产就绪仍需用自有输入验证质量、延迟、实际成本和失败行为。
Q.02应该把 Seedance 2.5 模型 ID 写死吗?
不应该写死在代码里。应把模型 ID 和路由能力保存在配置中,由显式开关控制启用。通道当前提供三个正式模型 ID:seedance-2.5-text-to-video、seedance-2.5-image-to-video 和 seedance-2.5-reference-to-video。
Q.03本地模拟应该覆盖哪些情况?
至少应模拟任务创建、等待、处理、完成、失败、无效请求、缺少密钥、限流、服务不可用、重复轮询以及回调重复到达。这些是系统韧性测试;正式错误码和响应结构以通道官方文档为准。
Q.04通过本地 Schema 测试就意味着集成可以投入生产吗?
不意味着。本地测试只能证明应用能够处理当前规划结构和模拟的状态变化。达到生产就绪还需要取得服务商正式 Schema,并完成真实鉴权、计费、结果获取、延迟、失败场景和质量测试。
Q.05为什么使用 Seedance 2.0 作为回退路由?
Seedance 2.0 仅作为回滚方案保留:当 2.5 路由异常时,可以把符合条件的任务切回这条已有文档的路由。回退必须按资格判断,因为并非所有按 2.5 设计的请求都能安全转换为 2.0 请求。
Q.06通道已经上线,为什么还要模拟 HTTP 503?
无论使用哪家服务商,视频应用都应能够承受上游偶发故障。应把 503 测试数据视为韧性测试;真实错误响应以通道文档和线上观测为准。