语音(TTS / ASR / 对话闭环)

四个语音端点,全部用 Bearer API key 鉴权:

端点方向形态
POST /v1/tts文本 → 语音同步,一次回整段 mp3
POST /v1/tts/stream文本 → 语音流式,边合成边吐 PCM
POST /v1/asr语音 → 文本同步,音频字节进、文本出
POST /v1/voice语音 → 语音同步,音频进 → asr→agent→tts → 智能音频出(一趟闭环)

TTS 同步:POST /v1/tts

bash
curl "$BASE/v1/tts" \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"你好喵,今天也要加油哦"}' \
  -o hello.mp3

请求体:

字段类型必填说明
textstring要合成的文本(空白串 400)
voicestring音色 id,缺省 female-shaonv(甜美少女音)

成功响应:200,Content-Type: audio/mpeg,响应体即 mp3 字节(32kHz / 128kbps),存成文件直接可播。

错误:400(体坏 / text 空)、401、429、502「语音合成暂时不可用」(上游或配置问题)。

TTS 流式:POST /v1/tts/stream

请求体与 /v1/tts 完全相同;区别在响应:

播放示例(macOS / Linux,ffplay):

bash
curl -sN "$BASE/v1/tts/stream" \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"边合成边播放的一段话"}' \
| ffplay -autoexit -nodisp -f s16le -ar 32000 -ch_layout mono -i -

已知边界:若流已经以 200 开始、上游中途失败,流会提前结束(无带内错误事件)——请按「收到的字节即有效音频」处理。

ASR:POST /v1/asr

请求体就是原始音频字节(不是 JSON):wav / mp3 / flac / ogg 等常见格式皆可,上限 25MB

bash
curl "$BASE/v1/asr" \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @speech.wav

成功响应:

json
{"text":"识别出来的文字"}

错误:400「音频为空」、401、413「音频过大(上限 25MB)」、429、502(识别服务不可用 / 失败)。

质量说明(诚实):底层是 Workers AI Whisper,中文内容识别可用,但专有名词可能同音错(如「喵喵」→「妙妙」)、不带标点。拿来「听懂指令喂给 Agent」足够;要出版级转写请自行后处理。

语音对话(一趟闭环):POST /v1/voice

把上面三段(asr → agent → tts)在服务端串成一趟请求:你只发一次音频,直接拿回 Agent 的智能语音应答。客户端零编排、一次往返。对话端完整继承 /v1/agent 的全部能力——工具、知识库(RAG)、人格、多轮记忆、BYO 自带模型、多租户,统统继承。

bash
# 把 speech.wav 编码成 base64,POST /v1/voice,拿回 JSON
AUDIO_B64=$(base64 < speech.wav | tr -d '\n')
curl "$BASE/v1/voice" \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d "{\"audio_b64\":\"$AUDIO_B64\",\"session_id\":\"my-voice-session\"}"

请求体:

字段类型必填说明
audio_b64stringbase64 编码的音频(格式同 /v1/asr:wav/mp3/flac/ogg 等;解码后 ≤25MB)
session_idstring会话 id(同 /v1/agent:续多轮记忆;缺省 anon)
voicestring回复语音音色 id(同 /v1/tts,缺省 female-shaonv)
kbbool知识库检索开关(透传 agent;缺省按租户有无文档自动检索)
persona_idstring人格库引用 id(透传 agent;租户隔离)
skip_ttsbool跳过 TTS 合成、只回文字(缺省 false)。瘦客户端/MCU 若自走 /v1/tts/stream 取流式音频,置 true 可省一整段 mp3 的合成与传输、端到端更快;此时 audio_b64:nullaudio_format:"none"

成功响应(200):

json
{
  "asr_text": "今天天气怎么样",
  "reply_text": "喵~今天天气不错哦,适合出门晒太阳!",
  "audio_b64": "SUQzBAAAAAAA...(回复语音的 base64 mp3)",
  "audio_format": "mp3"
}

audio_b64 base64 解码即得 mp3 字节,存文件直接可播:

bash
curl -s "$BASE/v1/voice" -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d "{\"audio_b64\":\"$(base64 < speech.wav | tr -d '\n')\"}" \
| jq -r '.audio_b64' | base64 -d > reply.mp3

降级(分段不全挂):

错误:400(体坏 / audio_b64 非法 base64 / 音频为空)、401、413(解码后 >25MB)、429、502(见上)。

延迟口径(诚实):同步版延迟 = asr + agent + tts 串行之和(可观,适合「一问一答」而非「说半句就抢答」)。要更低延迟的「边说边播」,现阶段请自行用 /v1/asr + /v1/agent(SSE)+ /v1/tts/stream 三段手动串(全流式 voice 是后续升级路径)。

手动串三段(更低延迟 / 边收边播)

ASR 出文本 → 喂 /v1/agent(SSE 边收边显)→ 回复喂 /v1/tts/stream(边合成边播),三个端点串起来就是一个能听会说、低延迟的语音助手——这正是 NovaMeow 桌面客户端的做法。一趟式 /v1/voice 则适合瘦客户端(ESP32 等)/ 一问一答场景:省去客户端编排。