AI SDK Fish Audio 语音提供方:@ai-sdk/fish-audio 版本演进与语音合成/转录实战指南
AI SDK Fish Audio 语音提供方ai-sdk/fish-audio 版本演进与语音合成/转录实战指南【免费下载链接】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/fish-audio包的 CHANGELOG 为脉络骨架梳理该提供方从 3.0.0 首次引入语音合成TTS与语音转录ASR能力到 3.0.17 的完整版本演进并结合仓库内的 官方文档、包内 README 与全部源码实现深入讲解 Fish Audio 提供方的实例配置、语音生成、多说话人对话、语音转录等完整使用方案。读完本文你将能基于 AI SDK 直接调用 Fish Audio 的 S1/S2 系列语音模型与transcribe-1转录模型构建可投入实战的中文语音应用。一、版本演进概览从 3.0.0 到 3.0.17打开 packages/fish-audio/CHANGELOG.md可以看到该包的全部版本记录其演进脉络清晰分两类1.1 Major Changes3.0.0 引入语音能力在 3.0.0 版本中唯一的 Major Change 记录为e1f9b02: feat(fish-audio): add Fish Audio provider with speech and transcription models这是整个包的核心定位——Fish Audio 提供方同时承载两类能力speech语音合成 / Text-to-Speech调用 Fish Audio TTS 端点支持 S1 与 S2 系列模型transcription语音转录 / Speech-to-Text调用 Fish Audio ASR 端点支持transcribe-1模型。这与包内 README 开头对包的描述完全一致contains speech generation (S1 and S2 models) and speech-to-text transcription support。1.2 Patch Changes与底层依赖保持同步从 3.0.1 到 3.0.17包持续发布 Patch 版本内容全部为依赖更新Updated dependencies主要涉及两个工作区包ai-sdk/provider从 4.0.6 逐步升级至 4.0.13提供ProviderV4、SpeechModelV4、TranscriptionModelV4等核心接口类型ai-sdk/provider-utils从 5.0.23 逐步升级至 5.0.39提供postJsonToApi、postFormDataToApi、loadApiKey、withUserAgentSuffix等底层工具函数。从 package.json 的依赖声明可以看出ai-sdk/fish-audio的运行时依赖仅有上述两个包且都以workspace:*方式引用与主仓库保持同源构建。这种薄封装设计意味着Fish Audio 提供方本身不携带任何网络请求库全部 HTTP 能力复用 AI SDK 的 provider-utils 基础设施。二、安装与包结构2.1 安装方式Fish Audio 提供方以独立 npm 模块ai-sdk/fish-audio发布包内脚本提供了完整的构建、测试与发布链路npm i ai-sdk/fish-audio从 package.json 可见包要求 Node.js22以 ESM 形式导出type: module并声明zod^3.25.76 || ^4.1.8为 peer dependency——provider options 的运行时校验正是通过 zod schema 完成的。2.2 源码文件布局包的src目录结构清晰每个模块职责单一文件职责fish-audio-provider.tsProvider 实例工厂createFishAudio与默认实例fishAudiofish-audio-config.tsProvider 内部配置类型provider 名、URL 构造、headers、fetchfish-audio-speech-model.ts语音合成模型实现SpeechModelV4fish-audio-speech-model-options.ts语音合成 provider options 的 zod schemafish-audio-speech-options.ts语音模型 ID 与 voice ID 类型fish-audio-transcription-model.ts语音转录模型实现TranscriptionModelV4fish-audio-transcription-model-options.ts语音转录 provider options 的 zod schemafish-audio-transcription-options.ts转录模型 ID 类型fish-audio-error.ts统一错误响应处理index.ts公共导出入口此外包内还配有fish-audio-provider.test.ts、fish-audio-speech-model.test.ts、fish-audio-transcription-model.test.ts等测试文件见 vitest.node.config.js 与 vitest.edge.config.js分 Node 与 Edge 两套环境运行可作深入阅读的验证入口。三、Provider 实例默认实例与自定义配置3.1 使用默认实例与 AI SDK 其他提供方一致包直接导出默认实例fishAudioimport { fishAudio } from ai-sdk/fish-audio;从 fish-audio-provider.ts 源码可见默认实例即createFishAudio()的空参数调用API Key 从环境变量FISH_AUDIO_API_KEY读取。3.2 自定义实例 createFishAudio需要定制时可导入createFishAudio创建带配置的实例import { createFishAudio } from ai-sdk/fish-audio; const fishAudio createFishAudio({ // custom settings, e.g. fetch: customFetch, });3.3 全部配置项说明结合 源码中FishAudioProviderSettings接口与官方文档支持以下可选配置apiKeystring通过Authorization: Bearer key头发送的 API Key默认读取FISH_AUDIO_API_KEY环境变量baseURLstringAPI 请求的基础地址默认https://api.fish.audio。源码中通过options.baseURL?.replace(/\/$/, )去除末尾斜杠随后拼接/v1/tts、/v1/asr等路径headersRecordstring, string附加的自定义请求头会被合并进所有请求fetch(input, init) PromiseResponse自定义 fetch 实现可用于拦截请求或提供测试替身默认使用全局fetch。3.4 鉴权与 UA 细节从源码看getHeaders的实现非常值得一提const getHeaders () withUserAgentSuffix( { Authorization: Bearer ${loadApiKey({ apiKey: options.apiKey, environmentVariableName: FISH_AUDIO_API_KEY, description: Fish Audio, })}, ...options.headers, }, ai-sdk/fish-audio/${VERSION}, );即每次请求自动附带Authorization头并通过withUserAgentSuffix在 User-Agent 上追加ai-sdk/fish-audio/版本号标识便于服务端统计与排障。其中VERSION来自 version.ts由构建期注入的__PACKAGE_VERSION__生成。3.5 未支持的能力显式报错FishAudioProvider实现了ProviderV4接口但 Fish Audio 不提供语言、嵌入、图像模型因此源码中languageModel、embeddingModel、imageModel三个方法会直接抛出NoSuchModelError并附上明确的错误信息如 Fish Audio does not provide language models。这保证了接口完整性的同时让误用者在第一时间获得清晰反馈。四、语音合成Speech Models 实战语音合成通过.speech()工厂方法创建模型底层调用 Fish Audio 的文本转语音端点对应源码 fish-audio-speech-model.ts 中的POST /v1/tts。4.1 最小示例import { fishAudio } from ai-sdk/fish-audio; import { generateSpeech } from ai; const { audio } await generateSpeech({ model: fishAudio.speech(s1), text: Hello from Fish Audio!, });4.2 支持的模型 ID从 fish-audio-speech-options.ts 源码看FishAudioSpeechModelId为以下联合类型模型 ID说明s1经典单说话人模型忽略normalizeLoudnesss2-pro支持多说话人对话支持normalizeLoudnesss2.1-proFish Audio 推荐的默认模型支持多说话人与normalizeLoudnesss2.1-pro-free免费开发者档位不保证首音频延迟与数据处理时效生产环境优先选用s2.1-pro注模型 ID 通过modelHTTP 请求头而非请求体字段发送给 Fish Audio这一点在源码doGenerate的headers: combineHeaders(..., { model: this.modelId }, ...)处有明确注释与实现。4.3 选择音色voice 与 referenceIdvoice选项接受 Fish Audio 音色模型 IDreference_id可从 Fish Audio 音色库或自己上传的模型中选取省略则使用默认音色const { audio } await generateSpeech({ model: fishAudio.speech(s1), text: Hello from Fish Audio!, voice: 933563129e564b19a115bedd57b7406a, outputFormat: opus, speed: 1.1, });音色列表不在 AI SDK 语音模型规范内需要直接调用 Fish Audio 的模型列表接口获取。按官方文档给出的方式const response await fetch( https://api.fish.audio/model?page_size20sort_bytask_count, { headers: { Authorization: Bearer ${process.env.FISH_AUDIO_API_KEY} } }, ); const { items } await response.json(); // 每个 item 的 _id 即可以传入 voice 的值可追加selftrue只列出自己上传的模型或用languageen、tagnarration做过滤。4.4 Provider Options 完整参数表以下参数通过providerOptions.fishAudio传入均经 fish-audio-speech-model-options.ts 中的 zod schema 校验后映射为 Fish Audio API 字段参数类型/取值说明referenceIdstring | string[]音色模型 ID单个 ID 选一个说话人数组启用多说话人对话S2-Pro 模型优先级高于顶层voicesampleRatenumber正整数输出采样率Hz缺省回退到格式默认值wav/pcm/mp3为 44100opus为 48000mp3Bitrate64 \| 128 \| 192mp3 输出码率kbps其他格式忽略opusBitrate-1000 \| 24000 \| 32000 \| 48000 \| 64000opus 输出码率bps-1000表示自动其他格式忽略latencylow \| normal \| balanced延迟/质量权衡normal质量最佳balanced降低延迟low最快volumenumber音量偏移dB负值更安静normalizeLoudnessboolean响度归一化S2 家族s2-pro、s2.1-pro支持s1上会被忽略并发出警告temperaturenumber0~1控制表现力值越大变化越丰富topPnumber0~1核采样多样性控制chunkLengthnumber100~300文本切分块大小minChunkLengthnumber0~100触发新分块的最小字符数normalizeboolean中英文文本归一化对数字稳定性有帮助maxNewTokensnumber正整数每个文本块生成的最大音频 token 数repetitionPenaltynumber大于 1.0 的值抑制重复音频模式conditionOnPreviousChunksboolean复用前序音频作为上下文以保持跨块音色一致earlyStopThresholdnumber0~1批处理中的早停阈值featuresstring[]透传给推理后端的请求级标志如[quality-guard]这些参数在 fish-audio-speech-model.ts 的getArgs中被逐一映射为请求体的 snake_case 字段如sample_rate、mp3_bitrate、condition_on_previous_chunks等并放入prosody对象中提交。4.5 多说话人对话S2-Pro 模型支持多说话人对话通过referenceId传入音色数组并在文本中用|speaker:N|标记轮次N为数组下标const { audio } await generateSpeech({ model: fishAudio.speech(s2-pro), text: |speaker:0|Hello!|speaker:1|Hi there!, providerOptions: { fishAudio: { referenceId: [ 933563129e564b19a115bedd57b7406a, bf322df2096a46f18c579d0baa36f41d, ], }, }, });这正是 3.0.0 版本引入的 speech 能力的进阶用法也解释了为什么referenceId在源码中被设计为z.union([z.string(), z.array(z.string())])——数组形态专为多说话人场景服务。4.6 输出格式与行为约束支持wav、pcm、mp3、opus四种输出格式其他值回退为mp3并产生警告源码中resolveFormat函数与SUPPORTED_FORMATS常量即此逻辑Fish Audio 会根据输入文本与所选音色自动推断语言没有语言参数因此 AI SDK 的language与instructions选项均不被支持传入会产生警告关于speed顶层speed选项映射为prosody.speed源码限定合法区间为 0.5~2.0MIN_SPEED/MAX_SPEED超出范围会被忽略并告警当前不支持Fish Audio 的 TTS-live WebSocket 流式端点也不支持通过references内联零样本音色克隆其需要 MessagePack 请求体。正确做法是先把参考音频上传到 Fish Audio再把其reference_id通过voice或referenceId传入。4.7 模型能力矩阵模型多说话人备注s1不支持忽略normalizeLoudnesss2-pro支持支持normalizeLoudnesss2.1-pro支持推荐默认支持normalizeLoudnesss2.1-pro-free不支持免费开发档无首音频延迟与数据处理保障五、语音转录Transcription Models 实战语音转录通过.transcription()工厂方法创建模型底层调用 Fish Audio 语音转文本端点对应源码 fish-audio-transcription-model.ts 中的POST /v1/asr。5.1 最小示例import { fishAudio } from ai-sdk/fish-audio; import { transcribe } from ai; import { readFile } from node:fs/promises; const result await transcribe({ model: fishAudio.transcription(), audio: await readFile(audio.mp3), });result包含text、segments、language等字段。5.2 模型 ID 的特殊语义transcribe-1是转录模型的唯一 ID。但需要注意当前 Fish Audio 的 ASR 端点不暴露模型选择器只服务单一模型因此 fish-audio-transcription-options.ts 中明确注释——该 ID 仅是路由标签不会发送到 API。这与 TTS 端点通过model请求头选模型的机制不同/v1/asr目前没有该头Fish Audio 计划后续增加更多 ASR 模型并会参照 TTS 端点改用modelHTTP 头选择。5.3 Provider Options转录模型仅有两个 provider options经 fish-audio-transcription-model-options.ts 的 zod schema 校验languagestring音频语言提示。它只是提示——Fish Audio 会将其传给模型但自动检测是权威的并会覆盖它因此既不改变转录文本也不改变上报的语言ignoreTimestampsboolean是否跳过精确时间戳。对应 Fish Audio 的ignore_timestamps参数其 API 默认值为true本提供方将其默认值设为false以保证segments被填充。Fish Audio 文档指出对短于 30 秒的音频会产生额外延迟成本若可接受牺牲 segments可设为true换取更低延迟。const result await transcribe({ model: fishAudio.transcription(), audio: await readFile(audio.mp3), providerOptions: { fishAudio: { language: en, ignoreTimestamps: false, }, }, });从源码看ignoreTimestamps在请求中始终以字符串形式追加到 FormDataString(fishAudioOptions?.ignoreTimestamps ?? false)而language仅在显式传入时追加音频文件则封装为File并以推断出的扩展名基于 mediaType命名。5.4 语言检测结果result.language上报检测到的语言为 ISO-639-1 两位字母代码如en永远是两位代码而非en-US这类 localeFish Audio 未检测出语言时为undefined人类可读的语言名如English通过 provider metadata 提供console.log(result.language); // en console.log(result.providerMetadata?.fishAudio?.language); // English源码中language_code虽未出现在 Fish Audio 文档化的响应 schema 中但实际会返回并反映的是检测到的语言而非请求的语言providerMetadata.fishAudio.language是展示用名称其确切形式不保证因此任何程序化逻辑都应基于result.language判断不要对其匹配或分支。5.5 分段结果与时长segments由响应中的segments数组映射而来每项包含text、startSecond、endSecond源码中从start/end秒值转换。将ignoreTimestamps设为true时Fish Audio 会返回空的segments数组因此本提供方默认请求时间戳。此外result.durationInSeconds取自响应中的duration字段。5.6 转录模型能力模型转录时长分段语言transcribe-1支持支持支持支持六、错误处理与底层调用链6.1 统一错误响应解析Fish Audio 的文档化错误响应为{ status, message }结构如 401 无权限、402 未付费。fish-audio-error.ts 通过createJsonErrorResponseHandler注册了该 schemaexport const fishAudioErrorDataSchema z.object({ status: z.number().nullish(), message: z.string().nullish(), });解析失败时错误信息回退为Unknown Fish Audio error。TTS 与 ASR 两个模型共用这一错误处理器。6.2 请求链路语音合成doGenerate调用postJsonToApiURL 为{baseURL}/v1/tts请求体为 JSON成功响应由createBinaryResponseHandler()处理直接返回二进制音频字节流result.audio以及可观测的request、response元数据时间戳、模型 ID、响应头与原始响应体语音转录doGenerate调用postFormDataToApiURL 为{baseURL}/v1/asr请求体为multipart/form-data成功响应由 zod schemafishAudioTranscriptionResponseSchema解析为 JSON。两个模型类都实现了SpeechModelV4/TranscriptionModelV4的specificationVersion v4并提供了WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE静态方法说明它们可被 AI SDK 的 workflow 能力序列化与反序列化借助serializeModelOptions。七、工程化与发布细节构建使用tsup打包见 tsup.config.tsprepack阶段会把官方文档 190-fish-audio.mdx 复制进包内docs/目录随包发布postpack后清理测试pnpm test会先后运行 Node 与 Edge 两套 vitest 配置vitest.node.config.js、vitest.edge.config.js确保提供方在服务端与边缘运行时环境行为一致版本策略以 CHANGELOG 为准当前最新版本为 3.0.17与ai-sdk/provider4.0.13、ai-sdk/provider-utils5.0.39对齐版本号由构建期注入见 version.ts便于发布流程自动维护。八、实战要点小结起步最快路径npm i ai-sdk/fish-audio设置环境变量FISH_AUDIO_API_KEY直接导入默认实例fishAudio语音合成选型生产环境优先s2.1-pro需要多说话人对话时使用s2-pro/s2.1-pro并配合referenceId数组与|speaker:N|标记开发试玩可用s2.1-pro-free音色管理先通过 Fish Audio 的模型列表接口查询reference_id再通过顶层voice或 provider optionreferenceId传入需要克隆音色时先上传参考音频再引用其 ID转录注意点默认已开启时间戳ignoreTimestamps: false短音频如需更低延迟可显式开启true但会失去segments程序化语言判断一律使用result.languageISO-639-1 代码展示场景才用providerMetadata.fishAudio.language边界认知不支持流式 TTS、不支持language/instructionsTTS参数、不支持的输出格式会回退 mp3 并告警——这些行为均由源码中的warnings机制显式上报可作为运行时诊断依据。如需进一步阅读实现细节可从 fish-audio-provider.ts 入手配合官方文档 190-fish-audio.mdx 与各模型测试文件逐层深入。【免费下载链接】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),仅供参考