@ai-sdk/fal 演进全解析:AI SDK 图像、视频、语音与转录提供方的版本脉络与源码实践
【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/ai
@ai-sdk/fal是 AI SDK(The AI Toolkit for TypeScript)中对接 fal.ai 生成式媒体平台的官方提供方包,当前版本为 3.0.40。本文以该包的 CHANGELOG.md 为脉络主线,结合 包源码、官方文档 与 README,系统梳理其从 0.0.1 到 3.0.40 的功能演进、核心模型能力与安全加固细节。读完本文,你将理解 fal 提供方的实例化配置方式、图像/视频/语音/转录四类模型的底层实现,以及视频异步流水线(poll / webhook)、URL 安全校验、凭据同源保护等关键机制。
版本主线:从 fal.ai 接入到 AI SDK v7 预发布
@ai-sdk/fal的演进与 AI SDK 主版本升级保持同步,CHANGELOG 记录了完整的发布序列:
| 版本阶段 | 关键里程碑 | 对应 AI SDK 版本 |
|---|---|---|
0.0.1~0.1.4 | 首个 fal.ai 提供方(e671e31),图像模型支持加入 provider 规范,FAL_KEY环境变量回退 | AI SDK 4.x |
1.0.0~1.0.13 | AI SDK 5:图像设置移入 generate options,新增transcribe,支持 Flux Kontext 模型,ImageModelV1重命名为ImageModelV2 | AI SDK 5 |
2.0.0~2.0.25 | AI SDK 6 beta:Provider-V3、图像编辑、speech / transcription v3 规范、图像模型改为 V3、providerOptions schema 化(弃用 snake_case) | AI SDK 6 |
3.0.0~3.0.40 | AI SDK v7 预发布:ESM-only、Node 22+、视频异步 API、URL 安全校验、工作流序列化 | AI SDK 7 |
从依赖声明看,@ai-sdk/fal仅直接依赖@ai-sdk/provider与@ai-sdk/provider-utils两个 workspace 包(见 package.json),版本变化大多来自这两个底层包的迭代;但其中也穿插了大量 fal 特有的功能变更,是理解该提供方能力边界的第一手资料。
提供方实例与配置:createFal 的完整参数体系
fal 提供方的入口是createFal工厂函数与默认实例fal,两者均在 fal-provider.ts 中定义。官方文档(10-fal.mdx)给出的定制化示例:
import { createFal } from '@ai-sdk/fal'; const fal = createFal({ apiKey: 'your-api-key', // 可选,默认取 FAL_API_KEY 环境变量,回退到 FAL_KEY baseURL: 'custom-url', // 可选 headers: { /* 自定义请求头 */ }, // 可选 });配置项说明(对应FalProviderSettings接口)
- apiKey
string:以Authorization: Key <apiKey>请求头发送。源码中的loadFalApiKey依次检查显式 apiKey 参数 →process.env.FAL_API_KEY→process.env.FAL_KEY(后者由 0.1.4 版本引入,见 CHANGELOG56c6d8b)。在无process的环境(如部分 Edge Runtime)中,只能通过apiKey参数显式传入,环境变量不可用。 - baseURL
string:API 调用前缀,默认https://fal.run。源码通过withoutTrailingSlash去除尾部斜杠后再拼接模型路径。 - headers
Record<string, string>:附加自定义请求头,与Authorization头合并。 - fetch
FetchFunction:自定义 fetch 实现,可用于请求拦截、测试桩等。
模型工厂方法
从源码可见,FalProvider实现ProviderV4接口(specificationVersion: 'v4'),提供以下工厂:
fal.image(modelId)/fal.imageModel(modelId)→ImageModelV4图像生成fal.video(modelId)/fal.videoModel(modelId)→Experimental_VideoModelV4视频生成(实验性 API)fal.speech(modelId)→SpeechModelV4语音合成fal.transcription(modelId)→TranscriptionModelV4语音转录fal.languageModel()/fal.embeddingModel()抛NoSuchModelError(fal 不提供文本与向量模型)
视频模型在提交时会将模型 ID 归一化(去掉fal-ai/前缀)并拼接到https://queue.fal.run/fal-ai/队列端点(见 fal-video-model.ts)。
图像生成:从 ImageModelV2 到 V4 的能力跃迁
AI SDK 5:设置移入 generate options(1.0.0,变更516be5b)
1.0.0 做了一次重大 API 重构:图像模型不再有构造函数级 settings,maxImagesPerCall直接传给generateImage(),其余设置经providerOptions[provider]传入。CHANGELOG 中的前后对照:
// 之前 await generateImage({ model: luma.image("photon-flash-1", { maxImagesPerCall: 5, pollIntervalMillis: 500, }), prompt, n: 10, }); // 之后 await generateImage({ model: luma.image("photon-flash-1"), prompt, n: 10, maxImagesPerCall: 5, providerOptions: { luma: { pollIntervalMillis: 5 }, }, });同期变更还包括:ImageModelV1重命名为ImageModelV2(9301f86)、specificationVersion由 v1 升为 v2(d9209ca)、新增transcribe(d8aeaef)、支持 Flux Kontext 模型(b248983)、为图像响应设置.providerMetaData(3d1dcca)、内部改用 Zod 4(d1a034f)。
AI SDK 6:providerOptions schema 化与 camelCase 化(2.0.0)
547145a变更创建了 fal providerOptions 的 schema,并弃用 snake_case 参数、改为 camelCase 选项。这一设计延续至今:在 fal-image-model.ts 中,parseProviderOptions用falImageModelOptionsSchema校验参数,随后通过fieldMapping把 camelCase 键映射回 fal API 需要的 snake_case 字段:
| providerOptions(camelCase) | 映射到 API 的字段(snake_case) |
|---|---|
imageUrl | image_url |
maskUrl | mask_url |
guidanceScale | guidance_scale |
numInferenceSteps | num_inference_steps |
enableSafetyChecker | enable_safety_checker |
outputFormat | output_format |
syncMode | sync_mode |
safetyTolerance | safety_tolerance |
如果检测到弃用的 snake_case 键,模型会向调用方推送 warning,提示'xxx' (use 'xxxYyy')形式的迁移建议。useMultipleImages为 SDK 内部开关,不会发送给 API。
图像编辑与多图输入
图像编辑能力在 2.0.0 中加入(9061dc0: feat: image editing),并在 2.0.5 扩展为支持多个 image URL 输入(e3419db)。当前源码逻辑:
prompt.images中的文件(URL / base64 /Uint8Array/ArrayBuffer/Buffer)会被convertImageModelFileToDataUri转为 data URI;- 默认写入
image_url(单图编辑);若设置providerOptions.fal.useMultipleImages = true,则写入image_urls数组,适配fal-ai/flux-2/edit等多图模型; - 传入多图但未开启该开关时,仅使用第一张图并产生一条 warning;
prompt.mask会写入mask_url,用于局部重绘(inpainting)。
getArgs同时处理size与aspectRatio:size按宽x高拆分,aspectRatio经convertAspectRatioToSize映射为 fal 的尺寸枚举(如1:1→square_hd、16:9→landscape_16_9、4:3→landscape_4_3),16:10、21:9等比例则映射为具体宽高(如2560x1080)。
响应处理与 providerMetadata
图像响应的解析兼容两种 fal 返回形态:images数组或单个image对象(部分模型如 easel-avatar 只返回单图),通过 zod union 统一为数组(见 fal-image-model.ts 中的falImageResponseSchema)。生成的图片由 SDK 下载为Uint8Array,同时把 fal 返回的content_type、file_name、file_size、width、height、NSFW 标记等归一化写入providerMetadata.fal.images。早期版本还针对响应兼容性做过专门修复:1.0.1处理null的file_name/file_size,1.0.2处理空timings对象,1.0.11处理null的宽高值。
官方文档提供了常见模型清单(节选,见 10-fal.mdx):fal-ai/flux/dev、fal-ai/flux-pro/kontext、fal-ai/flux-lora、fal-ai/ideogram/character、fal-ai/qwen-image、fal-ai/omnigen-v2、fal-ai/recraft/v3/text-to-image等。常用 providerOptions 还包括strength(与输入图差异程度)、enableSafetyChecker、acceleration(none/regular/high)、safetyTolerance(1-6,1 最严格)。
视频生成:异步流水线(doStart / doStatus / Webhook)
3.0.20 是视频能力的关键里程碑(变更79e133c):实验性视频模型接口VideoModelV4允许模型实现doStart、doStatus、handleWebhookOption(替代或补充doGenerate),上层experimental_generateVideo新增poll与webhook选项来编排完成时机;轮询配置还支持自定义 delay 实现,以便与持久化工作流(durable workflow)兼容。
底层调用链(fal-video-model.ts)
fal 的视频实现采用"提交-轮询"两段式状态机:
- doStart:将 prompt、image、aspectRatio、duration、seed 及 fal 特有参数(
loop、motion_strength、resolution、negative_prompt、prompt_optimizer等,均经 camelCase 校验后映射)组装为请求体,POST 到https://queue.fal.run/fal-ai/<modelId>。若传入 webhook,会以?fal_webhook=<encoded>追加到队列 URL。响应中的response_url与submit_url随operation一并返回。 - doStatus:轮询
response_url。fal 返回detail: 'Request is still in progress'时映射为status: 'pending';其他 API 错误映射为status: 'error';成功则buildResult产出status: 'completed'与videos: [{ type: 'url', url, mediaType }],并把宽高、时长、fps、seed、timings、NSFW 等信息写入providerMetadata.fal.videos。 - handleWebhookOption:将 AI SDK 的 webhook 选项包装为 fal 的
fal_webhook参数,同时透传{ webhookUrl, received }。
注意视频模型为实验性 API(类型名为Experimental_VideoModelV4),maxVideosPerCall固定为 1,即 fal 视频模型一次只生成一个视频。doStart/doStatus从 v3.0.20 起才被 fal 提供方支持,此前(2.0.18 起)只有同步的experimental_generateVideo基础支持(53f6731),2.0.19 又加入了全局默认视频模型解析(7168375)。
语音与转录:speech 与 transcription 模型
语音合成(SpeechModelV4)
fal.speech(modelId)对接 fal 文本转语音端点,2.0.0 引入 speech model v3 规范(046aa3b),1.0.4 已加入 speech 模型支持(d583b84)。官方文档列出的模型包括fal-ai/minimax/speech-02-hd、fal-ai/minimax/voice-clone、fal-ai/dia-tts等。providerOptions 支持voice_setting(含voice_id、speed0.5-2.0、vol0-10、pitch-12-12、emotion枚举、english_normalization)、audio_setting、language_boost、pronunciation_dict等(详见 10-fal.mdx)。
转录(TranscriptionModelV4)
fal.transcription(modelId)在 1.0.0 加入(d8aeaef),2.0.0 升级到 transcription model v3 规范(21e20c0)。模型 ID 无需fal-ai/前缀,例如fal.transcription('wizper')。providerOptions 支持:
- language
string:音频语言,默认'en',设为null时自动检测; - diarize
boolean:说话人分离,默认true; - chunkLevel
'segment' | 'word':返回的切块粒度,默认'segment'; - version
string:Whisper large 变体版本,默认'3'; - batchSize
number:并行处理的音频块数,默认64; - numSpeakers
number:说话人数,缺省自动检测。
3.0.6 进一步引入实验性流式转录支持(5c5c0f5),覆盖 OpenAIgpt-realtime-whisper与 xAI WebSocket STT 等场景,底层接口升级为TranscriptionModelV4。包内提供了转录相关测试快照与 fixtures(见 fal-transcription-model.test.ts、fixtures/fal-transcription-queue.json),可据此观察请求/响应契约。
安全加固:URL 校验与凭据同源保护
3.x 系列针对"提供方响应中携带的 URL"做了系统性安全加固,这是 CHANGELOG 中最值得关注的安全主题。
3.0.10:getFromApi 的 validateUrl 机制(变更4be62c1)
getFromApi新增validateUrl标志,所有 AI SDK 提供方在调用点显式声明信任决策(缺省等价false,即不校验,保证既有调用方继续编译)。置为true时,URL 会经fetchWithValidatedRedirects处理——与downloadBlob相同的守卫逻辑:
- 拒绝私有地址(private)、回环(loopback)、link-local 目标;
- 对每一次重定向跳转重新校验;
- 剥离代理 / metadata / cookie 请求头;
- 跨域重定向时丢弃除 user-agent 外的所有调用方请求头(自定义 API key 头与
Authorization一样不得跟随跳转离开源域); - 被拦截的 URL 抛
DownloadError。
该机制在 fal 提供方的图像下载与视频状态轮询调用点启用(因为 URL 来自提供方响应体);而由开发者配置端点构造的 URL 传validateUrl: false,不受影响。CHANGELOG 还补充了validateDownloadUrl的地址段覆盖(IPv4 组播224.0.0.0/4、TEST-NET 文档段192.0.2.0/24等、IPv6 文档段2001:db8::/32与3fff::/20),且仅跟随 fetch 规范重定向状态码 301/302/303/307/308。
同时新增两个可选参数:
- credentialedOrigin:仅当 URL 与该 origin 同源时才携带调用方请求头,防止 API key 被发送到响应指定的异源主机;
- trustedOrigin:与开发者配置的提供方端点同源的 URL(含重定向跳转)豁免目标校验,使自托管 / localhost 部署中"响应 URL 回指配置主机"的场景保持可用,其余跳转仍全部校验。
守卫只做字符串 / 字面量检查,不解析 DNS;解析后指向私有地址的主机名与 DNS rebinding 不在其范围内,处理不可信 URL 的服务端部署需在网络层约束(或注入固定解析 IP 的 Nodefetch)。完整设计见 contributing/secure-url-handling.md。
3.0.0:仅向同源响应 URL 发送凭据(变更aeda373)
此前多个提供方客户端会跟随响应体中的 URL(如polling_url、urls.get、result_url、result.sample、video.uri)并复用认证请求头或追加?key=<API_KEY>。由于未校验响应 URL 的主机,长期有效的 API key 会被发送到响应点名的任意主机(良性场景是 CDN,恶意场景则是被篡改的响应指向攻击者主机),造成凭据外泄。修复方案是在@ai-sdk/provider-utils新增isSameOrigin辅助函数,@ai-sdk/black-forest-labs、@ai-sdk/fireworks、@ai-sdk/replicate、@ai-sdk/gladia、@ai-sdk/fal、@ai-sdk/google六个包中的相关 fetch 仅在目标 URL 与配置的 API origin 同源时附加凭据,异源请求不携带。
fal 提供方的对应落地可见于源码调用点:图像下载使用validateUrl: true+trustedOrigin: this.config.baseURL(见 fal-image-model.ts 的downloadImage),视频状态轮询使用validateUrl: true+credentialedOrigin: submitUrl+trustedOrigin: submitUrl(见 fal-video-model.ts 的fetchStatus),与 CHANGELOG 描述完全吻合。
工程化演进:ESM-only、Node 版本与工作流序列化
3.0.0:ESM-only 与 Node 22+
ef992f8从所有包中移除 CommonJS 导出,全部包转为 ESM-only("type": "module"),使用require()的消费方必须切换到 ESMimport语法。7fc6bd6将最低 Node.js 版本提升到 22,官方支持 22、24、26。这两个约束都固化在 package.json 中("type": "module"、"engines": { "node": ">=22" })。
04e9009统一了各提供方的代码模式并重命名部分导出符号;所有被重命名的外部导出符号都保留了废弃别名,旧名称继续可用(例如FalImageModelOptions同时以FalImageProviderOptions别名导出,见 index.ts)。38fc777为提供方 README 增加 AI Gateway 提示,1cad0ab(2.0.0)起在 user-agent 头中携带提供方版本号(ai-sdk/fal/<VERSION>)。
工作流序列化(变更b3976a2)
所有提供方模型支持跨工作流步骤边界(workflow step boundary)的序列化:
@ai-sdk/provider-utils新增serializeModel()辅助函数,仅提取模型实例中可序列化的属性(过滤函数及包含函数的对象),第三方提供方作者也可借此为自己的模型添加工作流支持;- 所有提供方模型类都包含
WORKFLOW_SERIALIZE与WORKFLOW_DESERIALIZE静态方法; - provider 配置类型中的
headers改为可选(非破坏性),便于模型在步骤边界反序列化时由外部单独提供认证。
fal 提供方的FalImageModel即实现了这一对静态方法(见 fal-image-model.ts),配合serializeModelOptions完成配置提取与重建。
快速上手与进一步阅读
安装与基础使用(详见 README.md):
npm i @ai-sdk/falimport { fal } from '@ai-sdk/fal'; import { generateImage } from 'ai'; import fs from 'fs'; const { image } = await generateImage({ model: fal.image('fal-ai/flux/schnell'), prompt: 'A cat wearing a intricate robe', }); const filename = `image-${Date.now()}.png`; fs.writeFileSync(filename, image.uint8Array); console.log(`Image saved to ${filename}`);需要继续深入源码的读者可重点阅读以下文件:
- 提供方与配置:fal-provider.ts、fal-config.ts
- 图像模型与选项:fal-image-model.ts、fal-image-model-options.ts
- 视频模型与选项:fal-video-model.ts、fal-video-model-options.ts
- 语音与转录:fal-speech-model.ts、fal-transcription-model.ts
- 错误处理:fal-error.ts
- 测试佐证:fal-provider.test.ts、fal-image-model.test.ts、fal-video-model.test.ts
- 官方文档:content/providers/01-ai-sdk-providers/10-fal.mdx
使用前提说明:本文所述能力以当前仓库@ai-sdk/fal3.0.40 为准;视频生成与流式转录接口在 CHANGELOG 中标注为实验性(experimental),后续版本可能存在 API 调整;视频模型maxVideosPerCall固定为 1,运行时需 Node.js 22 及以上,消费方须使用 ESM 导入。
【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/ai
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考