如何在 Dify.AI 搭建"听懂又会说"的语音助手: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
Dify.AI 是一个 LLM 应用开发平台,除了文本对话,它内置了语音转文字(Speech-to-Text,STT)和文字转语音(Text-to-Speech,TTS)两条链路,让你的应用既能"听懂"用户,也能"开口"回答。本文面向刚接手 Dify.AI 语音助手搭建的新手开发者,从真实客服场景出发,讲清最短上手路径、两个接口的参数细节,以及上线前最容易踩的四个坑,全程只需 30 分钟。
🎙️ 从一个客服电话开始:为什么应用需要"耳朵"和"嗓子"
想象一个电商客服机器人。用户在电话里说:"我上周买的耳机,什么时候发货?" 这时系统要完成三件事:先把这段话变成文本(STT),交给大模型理解并生成回答,再把回答念出来(TTS)。少了第一步,机器人"聋";少了第三步,机器人像复读机,体验大打折扣。
Dify.AI 把这两步做成了应用级的能力开关:STT 挂在语音输入上,TTS 挂在每条回复上。你不需要自己写音频处理代码,只需要配置模型提供商、打开两个开关,然后调用两个 HTTP 接口。
⚡ 最短路径:从 0 到出声的 5 步
- 准备模型。在工作区的"模型供应商"里配置一家提供语音能力的提供商并填入 API Key。STT 和 TTS 可以来自同一家(如 OpenAI),也可以分开配。
- 打开 STT 开关。进入目标应用(聊天、聊天流或工作流模式均可)的"功能设置",启用语音转文字。
- 打开 TTS 开关并选音色。启用文字转语音,再从该提供商提供的音色列表里挑一个,例如
nova。 - 发布应用,拿到该应用的访问地址。
- 前端接线:录音上传走
/audio-to-text,回复播放走/text-to-audio,代码见第四节。
最小可用配置长这样(应用功能设置中要生效的两个字段):
{ "speech_to_text": { "enabled": true }, "text_to_speech": { "enabled": true, "voice": "nova" } }后端会按这套配置校验请求:开关未打开时直接返回"STT/TTS 未启用"错误,不会白跑模型调用。
🎧 STT 与 TTS 详解:格式、上限与音色
语音转文字(STT):接口与限制
STT 的入口是POST /audio-to-text,以 multipart 表单提交,字段名为file,成功返回一个包含text字段的 JSON。它只接受音频文件的 MIME 类型,且大小卡在 30MB,这两条规则在 api/services/audio_service.py 中硬编码校验。
| 项目 | 说明 |
|---|---|
| 请求方式 | POST /audio-to-text,multipart/form-data,字段file |
| 支持格式 | mp3、m4a、wav、amr、mpga |
| 文件大小上限 | 30MB(超出返回 413) |
| 常用提供商 | OpenAI(Whisper)、Azure、Google、阿里云 |
| 典型报错 | 415 格式不支持、"STT 未启用"、"提供商未配置该能力" |
文字转语音(TTS):给回复配上声音
TTS 的入口是POST /text-to-audio,JSON 请求体包含三个字段:
| 字段 | 必填 | 作用 |
|---|---|---|
text | 二选一 | 要合成的文本 |
message_id | 二选一 | 传某条历史消息的 ID,服务端直接取该消息的回复来合成,免去重复传文本 |
voice | 否 | 音色;不传时自动取该提供商音色列表的第一个 |
以 OpenAI TTS 为例,可选音色大致是这一档(不同提供商列表不同,以模型供应商页面实际显示为准):
| 音色 | 风格 | 适合场景 |
|---|---|---|
| alloy | 中性 | 通用播报 |
| nova | 明快 | 客服、导购等友好交互 |
| echo / onyx | 男性 | 资讯、严肃内容 |
| fable / shimmer | 女性 / 中性 | 故事、创意内容 |
注意 TTS 的返回体不是 JSON,而是音频流本身(MIME 由实际返回的音频容器决定),前端拿 blob 直接播放即可。
🔧 完整示例:一个会听的客服助手
整条链路按时序展开是这样的:
后端侧不需要你新写接口,AudioService已经把两步都封装好了(见api/controllers/web/audio.py),如果要在自定义后端中复用,核心就是这两行:
text = AudioService.transcript_asr(app_model=app, file=upload)["text"] audio = AudioService.transcript_tts(app_model=app, session=session, message_id=msg_id, voice="nova")前端侧,录音结束后的处理逻辑:
const stt = await fetch(`${base}/audio-to-text`, { method: "POST", body: fd }); const text = (await stt.json()).text; // 先走正常聊天拿到 message_id,再合成语音 const tts = await fetch(`${base}/text-to-audio`, { method: "POST", body: JSON.stringify({ message_id, voice: "nova" }) }); new Audio(URL.createObjectURL(await tts.blob())).play();🚧 避坑清单:上线前对一遍
| 症状 | 对策 |
|---|---|
| 识别结果不准、整句丢失 | 先确认录音没被压缩到失真;嘈杂环境加前端降噪;录音语言与 STT 模型不匹配时换支持该语言的模型 |
| 合成语音听着"播音腔"不自然 | 换音色,客服场景nova通常比默认第一个音色自然;长文本拆短句分段合成,语气更连贯 |
| 中文应用接英文用户,识别成乱码 | 在 STT 提供商处选择多语言模型,或在应用提示词中声明用户语言,让模型按正确语言转写 |
| 用户觉得"反应慢半拍" | 限制单次录音时长(10 秒内);TTS 返回后先建 Audio 对象再等 blob 加载完;对延迟敏感的场景考虑流式播放而非整段下载 |
另外两个高频错误码值得记住:415是文件格式不在白名单,413是超过 30MB,都发生在调用模型之前,属于客户端可自助解决的问题。
✅ 边界与方向
需要说明的是,Dify.AI 目前的语音链路是"先上传、再合成"的请求-响应模式,还没有实时的双向音频流,想做"边说边听"的通话体验,需要自己在外部叠一层音频通道。演进方向上,情感化合成、跨语言实时对话和专属音色克隆是社区最关心的能力,建议关注版本更新。如果你正准备做一个能听能说的助手应用,按本文的五步路径配置一遍,今天就能听到第一声回复。
【免费下载链接】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),仅供参考