模型能力
语音转文本
通过一次 API 调用将音频文件转录为文本,或通过 WebSocket 实时流式传输音频。该 API 支持 12 种音频格式、词级时间戳、多通道转录和文本格式化。
快速开始
通过一次 API 调用转录音频文件:
curl -X POST https://api.x.ai/v1/stt \
-H "Authorization: Bearer $XAI_API_KEY" \
-F format=true \
-F language=en \
-F "keyterm=Understand The Universe" \
-F file=@audio.mp3import os
import requests
response = requests.post(
"https://api.x.ai/v1/stt",
headers={"Authorization": f"Bearer {os.environ['XAI_API_KEY']}"},
files={"file": ("audio.mp3", open("audio.mp3", "rb"), "audio/mpeg")},
data=[
("format", "true"),
("language", "en"),
("keyterm", "Understand The Universe"),
],
)
response.raise_for_status()
result = response.json()
print(result["text"])
print(f"Duration: {result['duration']}s")
for word in result.get("words", []):
print(f" {word['start']:.2f}s - {word['end']:.2f}s: {word['text']}")import fs from "fs";
const formData = new FormData();
formData.append("format", "true");
formData.append("language", "en");
formData.append("keyterm", "Understand The Universe");
formData.append("file", new Blob([fs.readFileSync("audio.mp3")]), "audio.mp3");
const response = await fetch("https://api.x.ai/v1/stt", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.XAI_API_KEY}`,
},
body: formData,
});
if (!response.ok) throw new Error(`STT error ${response.status}`);
const result = await response.json();
console.log(result.text);
console.log(`Duration: ${result.duration}s`);
for (const word of result.words ?? []) {
console.log(` ${word.start.toFixed(2)}s - ${word.end.toFixed(2)}s: ${word.text}`);
}注意:file 参数必须在多部分表单中的所有其他参数之后提供。
支持的语言
language 参数可启用以下语言的格式化。模型会以这些语言中的任意一种转录语音,而不管 language 参数的设置 — 设置该参数可将数字、货币和单位格式化为其书面形式。
| 语言 | 代码 | 语言 | 代码 | |
|---|---|---|---|---|
| 阿拉伯语 | ar | 马其顿语 | mk | |
| 捷克语 | cs | 马来语 | ms | |
| 丹麦语 | da | 波斯语 | fa | |
| 荷兰语 | nl | 波兰语 | pl | |
| 英语 | en | 葡萄牙语 | pt | |
| 菲律宾语 | fil | 罗马尼亚语 | ro | |
| 法语 | fr | 俄语 | ru | |
| 德语 | de | 西班牙语 | es | |
| 印地语 | hi | 瑞典语 | sv | |
| 印尼语 | id | 泰语 | th | |
| 意大利语 | it | 土耳其语 | tr | |
| 日语 | ja | 越南语 | vi | |
| 韩语 | ko |
请求体
请求使用 multipart/form-data。必须提供 file 或 url。
| 参数 | 类型 | 默认值 | 必需 | 描述 |
|---|---|---|---|---|
file | file | ✓† | 要转录的音频文件。最大 500 MB。参见支持的格式。必须是多部分表单中的最后一个字段。 | |
url | string | ✓† | 要下载和转录的音频文件 URL(服务器端)。 | |
audio_format | string | 原始/无头音频的格式提示:pcm、mulaw、alaw。容器格式为自动检测 — 请勿为 MP3、WAV 等设置此字段。 | ||
sample_rate | integer | 以 Hz 为单位的采样率。仅对原始音频(pcm、mulaw、alaw)必需。支持:8000、16000、22050、24000、44100、48000。 | ||
language | string | 语言代码(例如 en、fr、de)。与 format=true 一起使用以启用文本格式化。参见支持的语言。 | ||
format | boolean | false | 当为 true 时,启用逆向文本规范化 — 将口语数字/货币转换为书面形式(例如 "one hundred dollars" → "$100")。需要 language。 | |
multichannel | boolean | false | 当为 true 时,独立转录每个音频通道。结果在 channels 数组中返回。 | |
channels | integer | 音频通道数(2-8)。仅对多通道原始音频必需。容器格式为自动检测。 | ||
diarize | boolean | false | 当为 true 时,启用说话人分离。响应中的每个词都包含一个 speaker 字段(整数),用于标识检测到的说话人。 | |
keyterm | string | 用于偏向转录的关键词(例如产品名称、专有名词)。对多个词重复此字段(例如 keyterm=Understand+The+Universe)。最多 100 个词,每个最多 50 个字符。 | ||
filler_words | boolean | false | 当为 true 时,填充词(例如 "uh"、"um"、"er")包含在转录文本中。当为 false(默认)时,填充词会从转录文本和 words 数组中自动移除。 | |
vad_threshold | number | 0.5 | 语音活动门限的语音概率阈值(0.0-1.0)。得分低于阈值的音频段被视为非语音并跳过转录。较低的值可转录较安静或有噪声的语音(例如窄带电话),但可能会为背景噪声产生虚假文本。0 表示禁用门限。 |
† 必须提供 file 或 url。
可选字段应在多部分主体中的 file 之前 — 对于可流式上传的文件,在 file 之后发送的字段可能会被忽略。
带文本格式化的示例
curl -X POST https://api.x.ai/v1/stt \
-H "Authorization: Bearer $XAI_API_KEY" \
-F format=true \
-F language=en \
-F "keyterm=Understand The Universe" \
-F file=@meeting.mp3file 参数必须在多部分表单中的所有其他参数之后提供。
响应
响应包括完整转录文本、音频持续时间和词级时间戳。
{
"text": "The balance is $167,983.15.",
"language": "English",
"duration": 3.45,
"words": [
{ "text": "The", "start": 0.24, "end": 0.48 },
{ "text": "balance", "start": 0.48, "end": 0.96 },
{ "text": "is", "start": 0.96, "end": 1.12 },
{ "text": "$167,983.15.", "start": 1.12, "end": 3.20 }
]
}| 字段 | 类型 | 描述 |
|---|---|---|
text | string | 完整转录文本。 |
language | string | 检测到的语言名称(例如 "English"、"French")。 |
duration | number | 音频持续时间(秒,2位小数)。 |
words | array | 词级片段,包含 text、start、end 和 speaker(整数,仅在 diarize=true 时)。 |
channels | array | 每个通道的转录文本(仅在 multichannel=true 时)。每个条目包含 index、text 和 words。 |
支持的音频格式
容器格式(自动检测)
| 格式 | 扩展名 | 描述 |
|---|---|---|
| WAV | .wav | 波形音频 — 无损,最佳质量输入 |
| MP3 | .mp3 | MPEG 音频层 3 — 广泛支持 |
| OGG | .ogg | Ogg 容器 — 开放格式 |
| Opus | .opus | Opus 编解码器 — 低延迟,高质量 |
| FLAC | .flac | 免费无损音频编解码器 — 无损压缩 |
| AAC | .aac | 高级音频编码 |
| MP4 | .mp4 | MPEG-4 容器 |
| M4A | .m4a | MPEG-4 音频 — Apple 生态系统标准 |
| MKV | .mkv | Matroska 容器 — 支持 MP3、AAC 和 FLAC 音频编解码器 |
原始格式(需要 audio_format 和 sample_rate)
| 格式 | audio_format 值 | 描述 |
|---|---|---|
| PCM | pcm | 有符号 16 位小端序(2 字节/样本) |
| µ-law | mulaw | G.711 µ-law(1 字节/样本) |
| A-law | alaw | G.711 A-law(1 字节/样本) |
限制
- 最大文件大小: 500 MB
- 通道数: 单声道、立体声或多达 8 个通道(使用
multichannel=true) - 采样率: 8000、16000、22050、24000、44100、48000 Hz
流式语音转文本(WebSocket)
对于实时转录,请在 wss://api.x.ai/v1/stt 使用 WebSocket API。客户端将原始音频作为二进制 WebSocket 帧流式传输,并在音频处理过程中接收 JSON 转录事件。
端点: wss://api.x.ai/v1/stt
配置通过 URL 查询参数完成 — 无需设置消息。音频作为原始二进制帧发送(无 base64 编码)。
NOTE
切勿在客户端代码中暴露您的 API 密钥。 始终通过您的后代理 WebSocket 连接。
查询参数
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
sample_rate | integer | 16000 | 音频采样率(Hz)。 |
encoding | string | pcm | 音频编码:pcm、mulaw 或 alaw。 |
interim_results | boolean | false | 当为 true 时,每 ~500 毫秒发出一次部分转录,is_final=false。 |
endpointing | integer | 10 | 语句结束事件前的静音持续时间(毫秒)。范围:0-5000。0 = 在任何 VAD 静音边界触发。 |
language | string | 文本格式化的语言代码。参见支持的语言。 | |
diarize | boolean | 当为 true 时,启用说话人分离。词包含一个 speaker 字段,用于标识检测到的说话人。 | |
filler_words | boolean | false | 当为 true 时,填充词(例如 uh、um、er)包含在转录文本中。当为 false(默认)时,填充词会自动移除。 |
multichannel | boolean | false | 每通道转录。需要 channels ≥ 2。 |
channels | integer | 1 | 交错音频通道数(最多 8)。 |
keyterm | string | 用于偏向转录的关键词(例如产品名称、专有名词)。对多个词重复此参数(例如 keyterm=Understand+The+Universe)。最多 100 个词,每个最多 50 个字符。 | |
smart_turn | number | 话语结束检测阈值(0.0-1.0)。设置后,启用 Smart Turn — ML 模型在每个静音边界预测说话人是否已完成其思路。参见Smart Turn。 | |
smart_turn_timeout | integer | 强制触发 speech_final 的最大静音持续时间(毫秒),即使 Smart Turn 模型预测说话人未完成。范围:1-5000。仅在启用 smart_turn 时适用。参见Smart Turn。 | |
vad_threshold | number | 0.08 | 语音活动门限的语音概率阈值(0.0-1.0)。得分低于阈值的音频块被视为非语音并跳过转录。较低的值可转录较安静或有噪声的语音(例如窄带电话),但可能会为背景噪声产生虚假文本。0 表示禁用门限。不影响 endpointing 或 speech_final 计时。 |
服务器事件
| 事件 | 描述 |
|---|---|
transcript.created | 服务器就绪 — 在发送音频前等待此事件。 |
transcript.partial | 转录结果,包含 text、words、is_final、speech_final、start、duration。当 multichannel=true 时包含 channel_index。当启用 smart_turn 时包含 end_of_turn_confidence。 |
transcript.done | 在 audio.done 后的最终转录。duration 始终存在。当 multichannel=true 时包含 channel_index — 每个通道发送一个事件。连接在此之后关闭。 |
error | 错误,包含 message 字段。连接保持打开状态。 |
transcript.partial 事件使用 is_final 和 speech_final 来传达三种状态:
is_final | speech_final | 含义 |
|---|---|---|
false | false | 临时结果 — 文本可能会更改(仅在 interim_results=true 时) |
true | false | 块结束 — 文本已锁定,约 3 秒语音已结束。当启用 smart_turn 时,模型置信度低于阈值的静音暂停会被降级为块结束而非语句结束。 |
true | true | 语句结束 — 说话人停止,完整的拼接语句。当启用 smart_turn 时,仅在模型的话语结束置信度超过阈值或超过 smart_turn_timeout 时触发。 |
客户端消息
- 二进制帧 — 指定编码的原始音频(以实时节奏的块流式传输,例如 100 毫秒)
{"type": "finalize"}— 强制当前语句立即结束为speech_final,用于 PTT{"type": "audio.done"}— 表示音频结束,触发transcript.done
transcript.done 告诉服务器不再发送音频,并刷新剩余的转录文本并关闭 WebSocket。
按键说话示例(在按钮释放时结束,然后继续会话):
{"type": "Finalize"}每通道结束(仅多通道 — 例如通道 0 上的代理):
{"type": "Finalize", "channel": 0}多通道流式传输
当 multichannel=true 且 channels ≥ 2 时,服务器独立转录每个音频通道。发送交错的多通道 PCM(例如立体的 L,R,L,R,...)作为二进制帧,服务器去交错并并行处理每个通道。
工作原理:
transcript.created发送一次(会话级别 — 无channel_index)。transcript.partial事件包含一个channel_index字段(基于 0),标识源通道。来自不同通道的事件交错到达。transcript.done在audio.done后每个通道发送一次,每个都有自己的channel_index。- 客户端
Finalize不带channel会同时结束所有通道;{"type": "Finalize", "channel": N}仅结束通道N(基于 0)。 - 块大小应考虑所有通道 — 例如,对于 16 kHz 的立体声 PCM16,100 毫秒 = 6,400 字节(每通道 3,200 × 2 通道)。
示例 URL:
wss://api.x.ai/v1/stt?sample_rate=16000&encoding=pcm&multichannel=true&channels=2&interim_results=true典型用例: 呼叫中心录音,代理在通道 0,客户在通道 1,实现每说话人转录,无需说话人分离。
Smart Turn
Smart Turn 使用轻量级 ML 模型预测说话人在静音暂停时是否已完成其思路,减少在中句暂停时的错误端点检测(例如在听写数字或思考从句之间时)。
工作原理:
- 通过
smart_turn=<threshold>启用时,模型在每个 VAD 静音边界评估累积的音频。 - 如果话语结束置信度超过阈值,
speech_final=true正常触发。 - 如果置信度低于阈值,事件被降级为
chunk_final(is_final=true、speech_final=false)— 转录文本已锁定但语句继续。 - 每个启用 Smart Turn 的
transcript.partial事件都包含一个0.0-1.0范围的end_of_turn_confidence字段。 - 在活跃语音期间,
end_of_turn_confidence为0.0(模型仅在静音边界运行)。
| 阈值 | 行为 |
|---|---|
0.5 | 平衡 — 捕获大多数自然的话语结束 |
0.7 | 保守 — 需要更高的置信度才能结束话语,更适合听写和数字序列 |
0.9 | 非常保守 — 仅在高度置信的话语完成时结束 |
静音超时(smart_turn_timeout):
启用 Smart Turn 时,模型完全控制 speech_final 的触发时间。为防止在长时间静音时会话挂起(例如用户走开),将 smart_turn_timeout 设置为最大静音持续时间(毫秒)(1-5000)。如果模型预测"未完成"的时间超过此持续时间,speech_final 仍会作为安全网触发。
wss://api.x.ai/v1/stt?sample_rate=16000&encoding=pcm&interim_results=true&smart_turn=0.7&smart_turn_timeout=3000没有 smart_turn_timeout,模型拥有完全控制权 — speech_final 仅在置信度超过阈值时触发。
启用 Smart Turn 的示例事件:
{
"type": "transcript.partial",
"text": "I will buy two of those, please.",
"words": [...],
"is_final": true,
"speech_final": true,
"start": 0.0,
"duration": 2.4,
"end_of_turn_confidence": 0.983
}典型用例: 语音助手和对话式 AI,您希望避免在中句时打断用户。没有 Smart Turn,在听写电话号码或思考从句时的短暂暂停会触发 speech_final。有了 Smart Turn,模型会等到检测到自然的话语结束(置信度 0.95+),同时在正确抑制中句暂停时(置信度约 0.005)。
完整示例
import asyncio
import json
import os
import websockets
API_KEY = os.environ["XAI_API_KEY"]
WS_URL = "wss://api.x.ai/v1/stt?sample_rate=16000&encoding=pcm&interim_results=true&language=en&keyterm=Understand+The+Universe"
async def transcribe_stream(audio_file: str):
headers = {"Authorization": f"Bearer {API_KEY}"}
async with websockets.connect(WS_URL, additional_headers=headers) as ws:
# Wait for server ready signal
msg = json.loads(await ws.recv())
assert msg["type"] == "transcript.created"
print("Server ready")
# Read raw PCM from a WAV file (skip 44-byte header)
with open(audio_file, "rb") as f:
f.read(44) # Skip WAV header
chunk_size = 16000 * 2 // 10 # 100ms of PCM16 at 16kHz
while chunk := f.read(chunk_size):
await ws.send(chunk) # Send raw binary — no base64
await asyncio.sleep(0.1)
# Signal end of audio
await ws.send(json.dumps({"type": "audio.done"}))
# Collect events until transcript.done
async for message in ws:
event = json.loads(message)
if event["type"] == "transcript.partial":
prefix = "FINAL" if event["is_final"] else "partial"
print(f"[{prefix}] {event['text']}")
elif event["type"] == "transcript.done":
print(f"\nFull transcript: {event['text']}")
print(f"Duration: {event['duration']}s")
break
asyncio.run(transcribe_stream("audio.wav"))import fs from "fs";
import WebSocket from "ws";
const apiKey = process.env.XAI_API_KEY;
const url = "wss://api.x.ai/v1/stt?sample_rate=16000&encoding=pcm&interim_results=true&language=en&keyterm=Understand+The+Universe";
const ws = new WebSocket(url, { headers: { Authorization: `Bearer ${apiKey}` } });
ws.on("open", () => console.log("Connected"));
ws.on("message", (data) => {
const event = JSON.parse(data);
switch (event.type) {
case "transcript.created":
console.log("Server ready — streaming audio...");
// Read WAV file, skip 44-byte header, send 100ms chunks
const audio = fs.readFileSync("audio.wav").slice(44);
const chunkSize = 3200; // 100ms at 16kHz, 16-bit
let offset = 0;
const interval = setInterval(() => {
if (offset >= audio.length) {
clearInterval(interval);
ws.send(JSON.stringify({ type: "audio.done" }));
return;
}
ws.send(audio.slice(offset, offset + chunkSize));
offset += chunkSize;
}, 100);
break;
case "transcript.partial":
const prefix = event.is_final ? "FINAL" : "partial";
console.log(`[${prefix}] ${event.text}`);
break;
case "transcript.done":
console.log(`\nFull transcript: ${event.text}`);
console.log(`Duration: ${event.duration}s`);
ws.close();
break;
}
});用例
- 实时字幕 — 视频通话、会议和直播的实时字幕
- 语音助手 — 转录用户语音以用于自然语言理解流程
- 呼叫中心 — 多通道每说话人转录的实时代理辅助
- 无障碍功能 — 为听力障碍用户提供实时转录
- 语音命令 — 免提界面的低延迟语音转操作
流式 STT 技巧
- 使用 16 kHz 采样率和 PCM 编码(
sample_rate=16000&encoding=pcm)— 这是模型的原生采样率,避免服务器上的重采样 - 启用
interim_results以