语音回复 (Reply Audio)
给 Agent 配置了声音之后,它的每一条回复都可以被朗读出来:SDK 流式拉取音频、边收边播,并在本地缓存,重复播放不再计费。 文字、音色和模型都由平台根据 Agent 的配置决定,客户端只需要指明「朗读哪一条回复」。
前提:Agent 的所有者需要先为 Agent 配置声音。没有配置声音的 Agent,朗读请求会失败;这时建议在组件上关闭朗读按钮(
showAudioControls={false})。
在 React 组件里
<ChatBox> / <ChatWidget> 默认在每条已完成的回复上显示朗读按钮,点击即播放,再点停止;加载失败时按钮变为「重试」。
<ChatWidget agentId="…" getToken={getToken} /> {/* 默认显示朗读按钮 */}
<ChatWidget agentId="…" getToken={getToken} autoPlayAudio /> {/* 每条回复完成后自动朗读 */}
<ChatWidget agentId="…" getToken={getToken} showAudioControls={false} /> {/* 不显示朗读按钮 */}
按钮的无障碍标签可以用 audioLabels 覆盖:
<ChatBox audioLabels={{ play: '朗读', stop: '停止', loading: '加载中', error: '重试' }} />
用无头 Hook 时:
const { messages, playAudio, stopAudio, audioPlayback } = useOpenhexChat({ agentId: '…', getToken });
// audioPlayback[message.id]: 'idle' | 'loading' | 'playing' | 'error'
<button onClick={() => playAudio(message)}>朗读</button>
playAudio 只对已经完成、并且带有 replyStreamId 的 Agent 回复生效。
在 JS / TS 里
client.chat.messageAudio 拉取一条回复的完整音频,返回 Blob:
const audio = await client.chat.messageAudio(agentId, conversationId, messageId, {
onChunk: chunk => player.append(chunk), // 可选:边收边处理
});
audio.blob; // audio/mpeg
audio.billableCharacters; // 本次合成计费的字符数(可能为空)
audio.requestId; // 平台请求 id,排查问题时提供
audio.fallbackUsed; // 是否走了备用路径
| 参数 | 说明 |
|---|---|
agentId | 回复所属的 Agent |
conversationId | 回复所在的对话 |
messageId | 回复在事件流里的 id,即流式记录的 record.id(React 消息上的 replyStreamId) |
onChunk | 每收到一段音频字节时回调 |
fallback | 流式请求失败时是否改用非流式请求重试,默认 true |
signal | 取消请求 |
SDK 先请求流式接口;流式失败且你没有主动取消时,自动改走非流式接口再试一次。
本地缓存
同一条回复重复播放时,用 MessageAudioCache 避免重复请求:
import { MessageAudioCache } from '@openhex-ai/agent-sdk';
const cache = new MessageAudioCache(10); // 最多缓存 10 条,按最近使用淘汰
let blob = cache.get(messageId);
if (!blob) {
blob = (await client.chat.messageAudio(agentId, conversationId, messageId)).blob;
cache.set(messageId, blob);
}
new Audio(URL.createObjectURL(blob)).play();
React 组件内部已经这样做了。
常见错误
| 状态码 | detail | 原因 |
|---|---|---|
403 | forbidden | 当前账号 / Agent 未开放语音回复 |
404 | reply message not found | messageId 不是这个对话里该 Agent 的一条已完成回复,或这条回复没有可朗读的文本 |
413 | reply message is too long for speech synthesis | 回复超过 20000 字符 |