news 2026/8/28 11:11:17

Dify 语音助手实战:STT 与 TTS 一步到位

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Dify 语音助手实战:STT 与 TTS 一步到位

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-Text(STT)与 Text-to-Speech(TTS)默认模型,以及应用侧的功能开关。

一图看懂 Dify 语音功能全貌

Dify 的语音实现不在应用代码里,而是统一委托给ModelManager:它按租户取出ModelType.SPEECH2TEXTModelType.TTS默认模型实例,所以换服务商时只需要改工作区模型配置,应用调用代码不用动。

能力边界先看这张表:

项目约束
STT 输入格式audio/mp3audio/mpgaaudio/m4aaudio/wavaudio/amr
STT 文件大小≤ 30 MB
STT 输出JSON:{"text": "识别结果"}
TTS 输入textmessage_id(二选一,message_id优先)
TTS 输出二进制音频流,容器格式取决于服务商(AAC / FLAC / MP3 / MP4 / OGG / WAV / WebM),以响应头Content-Type为准
应用适用范围基础 Chat 读应用设置;Chatflow / Workflow 读功能配置speech_to_text/text_to_speech

最小可运行路径

最短链路三步:

  1. 工作区 → 模型供应商:配置好服务商(如 OpenAI)凭证,并在模型配置里指定 Speech-to-Text 与 Text-to-Speech 的默认模型(如whisper-1tts-1)。
  2. 应用设置中打开「语音转文字」和「文本转语音」开关(Chatflow / Workflow 应用在「功能设置」里勾选对应项)。
  3. 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/m4aaudio/x-m4a,其他类型会直接返回415 unsupported_audio_type,与文件内容是否真的是音频无关。

5 分钟配好 STT:audio-to-text 参数

STT 没有模型选择参数——它固定使用租户的默认 Speech2Text 模型,想换识别引擎就去模型配置页改默认模型。接口本身只有一个字段:

参数位置必填说明
filemultipart/form-data音频文件,字段名固定为file
usermultipart 或 query视接入端终端用户标识,用于计量与会话归属

常见错误码:audio_too_large(413,超过 30 MB)、unsupported_audio_type(415,MIME 不在白名单)、speech_to_text_disabled(400,应用未开启)、provider_not_support_speech_to_text(400,未配置默认 STT 模型)。

识别结果的置信度依赖原始音频质量:采样率低、带强背景音的 m4a 转码文件,识别效果通常差于原生录音。拿不准时先用ffmpeg -i in.m4a -ar 16000 out.wav转成 16 kHz WAV 再上传,这是成本最低的调优点。

TTS 语音参数怎么选:text-to-audio

TTS 接口的 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/mpeg,Azure 常见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_model=app_model, file=file, session=session ) return asr["text"], AudioService.transcript_tts( app_model=app_model, session=session, text=reply, voice="nova", )

前端只需把上一节两个调用按顺序接上:

这段 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_text
415unsupported_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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/28 11:11:12

基于RAG与向量数据库的智能问答系统构建实战

简介&#xff1a;检索增强生成&#xff08;RAG&#xff09;技术通过将外部知识库与大语言模型结合&#xff0c;有效解决了模型幻觉与知识更新难题。其核心原理在于将文档向量化存储&#xff0c;通过语义检索匹配用户问题与相关知识片段&#xff0c;再交由大模型生成精准答案。这…

作者头像 李华
网站建设 2026/8/28 11:10:38

最小二乘法:从误差量化到多元回归,原理推导与Python实践

1. 从“猜”到“算”&#xff1a;为什么我们需要最小二乘法&#xff1f; 做数据分析、搞模型拟合&#xff0c;或者哪怕只是用Excel画条趋势线&#xff0c;你大概率都听过“最小二乘法”这个名字。它听起来像个高深的数学工具&#xff0c;但实际上&#xff0c;它的核心思想朴素得…

作者头像 李华
网站建设 2026/8/28 11:09:24

MarkItDown 使用指南:一条命令将 10 余种办公文档转为 Markdown

MarkItDown 使用指南&#xff1a;一条命令将 10 余种办公文档转为 Markdown 【免费下载链接】markitdown Python tool for converting files and office documents to Markdown. 项目地址: https://gitcode.com/GitHub_Trending/ma/markitdown 把一沓 PDF 论文、Word 报…

作者头像 李华
网站建设 2026/8/28 11:08:59

Claude Code 会话秒结束?从 Session 原理到实战排查

昨天还能正常跑的长任务&#xff0c;今天一启动就“秒结束”&#xff1b;恢复历史会话时&#xff0c;刚打印几行就被截断&#xff1b;甚至还没开始干活&#xff0c;进程就直接退出。HN 上也有人专门发帖问&#xff1a;Anyones Claude Code session finishing quickly from yest…

作者头像 李华
网站建设 2026/8/28 11:06:05

深度强化学习在移动边缘计算任务卸载与资源分配中的应用实践

简介&#xff1a;任务卸载与资源分配是分布式计算和网络优化中的核心基础问题&#xff0c;旨在解决有限计算资源在多用户、多任务场景下的高效调度挑战。其原理是通过智能决策算法&#xff0c;动态决定计算任务的执行位置&#xff08;本地或远程&#xff09;以及分配相应的CPU、…

作者头像 李华