
Dify 语音助手实战STT 与 TTS 一步到位【免费下载链接】difyBuild Agentic workflows, RAG pipelines, with rich AI model and tool support on one collaborative workspace. Deploy on cloud, VPC, or self-hosted, so teams move from prototype to production without rebuilding the stack.项目地址: https://gitcode.com/GitHub_Trending/di/dify你搭好一个客服聊天应用后用户发来的往往不是一段文字而是 30 秒语音。Dify 语音助手能力就为这种场景服务把音频文件 POST 给/v1/apps/{app_id}/audio-to-text拿到识别文本交给 LLM 生成回复再把回复 POST 给/v1/apps/{app_id}/text-to-audio直接取回音频流。整条链路只需要配置两件事——模型服务商的 Speech-to-TextSTT与 Text-to-SpeechTTS默认模型以及应用侧的功能开关。一图看懂 Dify 语音功能全貌Dify 的语音实现不在应用代码里而是统一委托给ModelManager它按租户取出ModelType.SPEECH2TEXT和ModelType.TTS的默认模型实例所以换服务商时只需要改工作区模型配置应用调用代码不用动。能力边界先看这张表项目约束STT 输入格式audio/mp3、audio/mpga、audio/m4a、audio/wav、audio/amrSTT 文件大小≤ 30 MBSTT 输出JSON{text: 识别结果}TTS 输入text或message_id二选一message_id优先TTS 输出二进制音频流容器格式取决于服务商AAC / FLAC / MP3 / MP4 / OGG / WAV / WebM以响应头Content-Type为准应用适用范围基础 Chat 读应用设置Chatflow / Workflow 读功能配置speech_to_text/text_to_speech最小可运行路径最短链路三步工作区 → 模型供应商配置好服务商如 OpenAI凭证并在模型配置里指定 Speech-to-Text 与 Text-to-Speech 的默认模型如whisper-1、tts-1。应用设置中打开「语音转文字」和「文本转语音」开关Chatflow / Workflow 应用在「功能设置」里勾选对应项。带Bearer应用 API Token 调用 STT 接口这段代码演示上传一段 m4a 音频并拿到识别文本。const form new FormData(); form.append(file, new Blob([bytes], { type: audio/m4a }), voice.m4a); const res await fetch(https://host/v1/apps/{app_id}/audio-to-text, { method: POST, headers: { Authorization: Bearer ${apiKey} }, body: form, }); const { text } await res.json();⚠️ 坑上传.m4a文件时 MIME 必须是audio/m4a或audio/x-m4a其他类型会直接返回415 unsupported_audio_type与文件内容是否真的是音频无关。5 分钟配好 STTaudio-to-text 参数STT 没有模型选择参数——它固定使用租户的默认 Speech2Text 模型想换识别引擎就去模型配置页改默认模型。接口本身只有一个字段参数位置必填说明filemultipart/form-data是音频文件字段名固定为fileusermultipart 或 query视接入端终端用户标识用于计量与会话归属常见错误码audio_too_large413超过 30 MB、unsupported_audio_type415MIME 不在白名单、speech_to_text_disabled400应用未开启、provider_not_support_speech_to_text400未配置默认 STT 模型。识别结果的置信度依赖原始音频质量采样率低、带强背景音的 m4a 转码文件识别效果通常差于原生录音。拿不准时先用ffmpeg -i in.m4a -ar 16000 out.wav转成 16 kHz WAV 再上传这是成本最低的调优点。TTS 语音参数怎么选text-to-audioTTS 接口的 JSON 请求体共 4 个字段字段类型说明textstring要合成的文本voicestring音色取决于 TTS 服务商如 OpenAI 的alloy/nova/echo省略时使用应用设置里配置的音色再没有则取服务商返回的第一个音色message_idstring传历史消息 ID直接对该条回复做合成优先于text。Web 应用里消息气泡的播放按钮走的就是这条路径streamingbool兼容保留字段实际响应形态由服务商决定这段代码演示把一段文本合成为语音并直接播放。const res await fetch(https://host/v1/apps/${appId}/text-to-audio, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${apiKey} }, body: JSON.stringify({ text: 你好这里是 Dify 语音助手 }), }); new Audio(URL.createObjectURL(await res.blob())).play();⚠️ 坑成功响应是二进制音频对它调res.json()会得到乱码。按Content-Type当 blob 处理即可不同服务商返回的容器格式不同OpenAI 常见audio/mpegAzure 常见audio/ogg不要在前端硬编码.mp3后缀。音色选择建议客服与助手类场景用中性音色如alloy讲解与播报类用更有人声起伏的音色如nova同一应用内保持音色固定比追新音色更重要。端到端串联语音对话完整链路服务端也可以直接调用AudioService把两段串起来audio_service.py便于写自定义中转服务这段 Python 演示在服务端完成识别 → 回复 → 合成的完整回合。from services.audio_service import AudioService def voice_roundtrip(app_model, session, file, reply): asr AudioService.transcript_asr( app_modelapp_model, filefile, sessionsession ) return asr[text], AudioService.transcript_tts( app_modelapp_model, sessionsession, textreply, voicenova, )前端只需把上一节两个调用按顺序接上这段 JavaScript 实现一次语音问、语音答的完整交互。async function askByVoice(appId, apiKey, audioBlob, chatCompletion) { const form new FormData(); form.append(file, audioBlob, voice.m4a); const asr await fetch(/v1/apps/${appId}/audio-to-text, { method: POST, headers: { Authorization: Bearer ${apiKey} }, body: form, }).then(r r.json()); const answer await chatCompletion(appId, apiKey, asr.text); const tts await fetch(/v1/apps/${appId}/text-to-audio, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${apiKey} }, body: JSON.stringify({ text: answer }), }); new Audio(URL.createObjectURL(await tts.blob())).play(); }踩坑清单现象原因解法400speech_to_text_disabledChatflow / Workflow 应用在功能设置里未勾选 STT或 Agent 应用的 Agent Soul 未开启语音能力到对应功能设置页开启speech_to_text415unsupported_audio_type上传的 MIME 不在mp3 / mpga / m4a / wav / amr白名单内前端转码或重设type后再上传413audio_too_large文件超过 30 MB 上限压缩或分段上传长录音改走文件解析链路TTS 400provider_not_initialize工作区未配置 TTS 服务商凭证或没设默认 TTS 模型模型配置页补全凭证并指定默认模型返回音频播放无声或花屏把二进制响应当 JSON / 文本读取用blob()读取并信任响应头Content-Type而非猜测后缀⚠️ 特别注意Agent 型应用的 STT 生效配置来自 Agent Soul 与旧版应用设置的合并结果改应用设置页可能不生效需同时检查 Agent 功能配置。下一步把这条语音链路接到 Chatflow 应用做语音提问 → RAG 检索 → 语音播报的完整闭环模型侧的 Speech2Text / TTS 凭证与默认模型配置见模型供应商章节。【免费下载链接】difyBuild Agentic workflows, RAG pipelines, with rich AI model and tool support on one collaborative workspace. Deploy on cloud, VPC, or self-hosted, so teams move from prototype to production without rebuilding the stack.项目地址: https://gitcode.com/GitHub_Trending/di/dify创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考