文档 · 语音合成

一个音色,而且一直是那个音色

语音合成只有一个别名 auto/tts,走 POST /v1/audio/speech。它背后有两个模型,切换条件只有一个:当前模型在上游被下线了。响应慢不换,被限流也不换。下面先讲它返回什么——和你想的可能不一样。

怎么调

curl https://tokenexchage.com/v1/audio/speech \
  -H "Authorization: Bearer sk-你的key" \
  -H "Content-Type: application/json" \
  -d '{"model":"auto/tts","input":"把这句话读出来。","voice":"zhimao"}'

返回的是 JSON,不是音频:

{
  "object":     "audio.speech",
  "url":        "https://dashscope-result-….oss-cn-beijing.aliyuncs.com/…",
  "expires_at": "2026-09-28T12:40:00Z",
  "format":     "wav"
}

趁 url 还没过期把它拉下来,或者转存到你自己控制的地方。那是对象存储的临时链接,不是永久 CDN 地址。

import requests

r = requests.post(
    "https://tokenexchage.com/v1/audio/speech",
    headers={"Authorization": "Bearer sk-你的key"},
    json={"model": "auto/tts",
          "input": "把这句话读出来。",
          "voice": "zhimao"},
).json()

audio = requests.get(r["url"]).content
open("out." + (r["format"] or "wav"), "wb").write(audio)

为什么不套 OpenAI 的形状

OpenAI 的 /v1/audio/speech 是在同一个连接上把音频字节流吐回来。我们不这么做,原因值得说清楚。

别名背后的模型返回的是一个临时地址。真要给你字节流,网关就得自己把音频拉下来再吐出去——意味着每一秒生成的音频都要在本机过两遍。对一个免费开放的功能,这笔带宽花得毫无意义。

所以形状是混合的:保持 JSON,把地址提到顶层,把格式标出来。这是整套接口里唯一一处我们明知偏离 OpenAI 契约的地方,写成文档而不是糊过去。

如果你现在的代码就是在调 OpenAI 的语音接口,需要改的只有一处:从返回值里读 url,而不是消费流。请求路径、鉴权头、model / input / voice 三个字段,全都不变。

别名会做什么、不会做什么

上游发生什么你会得到
模型被下线(404 / 410)列表里的下一个模型接手
超时报错。还是同一个模型
被限流报错。还是同一个模型
上游 5xx报错。还是同一个模型

换 TTS 模型不会让输出「变差一点」——它会变成另一样东西。音色不同,节奏不同。如果你在做一套四十集的音频,中途静默换人不是次品,是一整套得重做。

模型退役是唯一一种「换掉比失败好」的情况,因为不换就什么都没有。所以只有这一种情况会往下走。

这条规则适用于这里所有非对话别名。它和池化路由的做法正好相反,也是向量那个别名只有一个候选的原因。

参数

字段必填说明
model是写 auto/tts;也可以直接写具体模型名
input是要读出来的文字
voice否默认 zhimao

请求体上限 25 MB,超了在任何上游调用之前就返 413。Content-Type: multipart/form-data 也收,和 JSON 走同一个处理函数。

其他能力

同一套命名,一个能力一个别名,都在 /v1/models 里:

asr

auto/asr

语音转文字

embedding

auto/embed

1024 维向量,单候选

rerank

auto/rerank

按相关度重排检索结果

image

auto/image

文生图

video

auto/video

文生视频,异步