Guide · 使用教程
Cartesia 实时 TTS 教程:给语音 Agent 接入流式合成、打断与成本验收
用 Cartesia Sonic 3.6 WebSocket 把增量文本转成逐块音频,完成 Python 演示、中文声线替换、用户插话取消、密钥保护及延迟与费用验收。
这篇教程把 Cartesia Sonic 3.6 当作语音 Agent 的“说话层”:上游可以是任意 LLM,本文先用三段固定文本模拟增量输出,确认 WebSocket、音频格式和播放器能正常工作,再接真实模型。最终目标是得到可播放的逐块音频,并建立延迟、打断和费用验收表。示例不需要上传真实用户录音。
开始前准备
- 创建 Cartesia 账户和 API key。在本机环境变量中设置
CARTESIA_API_KEY,不要写进网页代码、Git 仓库或截图。 - 安装 Python 3、
ffplay(FFmpeg 提供),以及官方 Python SDK:python3 -m pip install 'cartesia[websockets]'。 - 先选一个官方语音 ID。下面用官方 Sonic 3.6 文档中的英文示例声线 Skylar 测链路;做中文产品时,去 Voice Library 挑支持中文的声线,并把业务语料换成中文。Sonic 3.6 官方语言表包含
zh,但某个具体声线的实际效果仍需试听。
第一步:发出分段文本并播放音频
把下面内容保存为 cartesia_demo.py。这段代码由官方 WebSocket 模式改写,重点是 push、no_more_inputs 与逐块接收。服务器没有扬声器时,可把音频块写到文件后用同一采样率转换。
import os
import subprocess
from cartesia import Cartesia
api_key = os.environ.get("CARTESIA_API_KEY")
if not api_key:
raise RuntimeError()
client = Cartesia(api_key=api_key)
player = subprocess.Popen(
[, , , , , ,
, , , ],
stdin=subprocess.PIPE,
bufsize=,
)
:
client.tts.websocket_connect() connection:
speech = connection.context(
model_id=,
voice=,
output_format={
: ,
: ,
: ,
},
)
part [, , ]:
speech.push(part)
speech.no_more_inputs()
event speech.receive():
event. == event.audio:
player.stdin.write(event.audio)
event. == :
:
player.stdin:
player.stdin.close()
player.wait()
常见问题
- Cartesia 的 API key 可以放在浏览器吗?
- 长期 API key 不应放浏览器。官方建议客户端使用短期访问令牌,并由服务端控制签发和权限。
- 为什么示例用英文语音?
- 这是为了用官方列出的声线先验证音频链路。做中文产品时应从 Voice Library 选择合适声线,并用中文数字、人名和混合语料盲测。
- 每个 LLM token 都要马上送入 TTS 吗?
- 通常不需要。按词组或句子边界分块,平衡首音频延迟与发音自然度。
- 用户插话时只关闭 Cartesia context 够吗?
- 不够。还要停止上游 LLM,并清理播放器或电话网关中排队的旧音频。
- 为什么电话里听到杂音?
- 可能是输出编码或采样率与电话网关不一致。示例是 44.1 kHz 浮点 PCM,接 8 kHz μ-law 链路要正确转换。
- 怎么比较 Cartesia 和其他 TTS 的费用?
- 用相同业务样本统计每次成功会话的字符、credits、重试和通话链路成本,别只比较公开月费。