控制智能体语音情绪
功能说明
在 AI 实时语音互动场景中,默认的 TTS 语音往往较为平淡,缺乏情感变化。通过控制 TTS 合成时的情绪、语调等参数,可以让 AI 的声音更富有表现力和沉浸感。
例如,在客服场景中,AI 可以根据用户的问题自动切换为温和、耐心的语气;在游戏陪玩场景中,AI 可以随着对话内容表现出兴奋、惊讶等情绪。这些能力都需要通过 TTS 合成参数来控制。
目前主要有两种控制方式:
-
特定情绪枚举:通过预定义的情绪标签(如
happy、sad、angry)控制语音情绪。这种方式由 TTS 厂商定义可用的情绪列表,开发者从中选择。 例如,MiniMax 的 Speech 系列支持高兴、悲伤、愤怒等指定情绪进行语音合成,可通过语音调试台体验。 -
自然语言描述:通过自然语言指令(如"用温柔的语气说话")控制语音风格。这种方式更加灵活,可以描述更细腻的情感变化。 例如火山豆包语音 2.0,可以填写如"用温柔的语气说话"的指令来控制合成效果,可通过查看语音指令与标签说明体验。
更多 ZEGO 目前支持的厂商及对应能力,可参考附录-支持的厂商与参数。
功能流程图
以豆包语音 2.0的自然语言描述(context_texts 标签),通过ZEGO TTS-Vendor=ByteDanceV3 调用"单向流式语音合成 WebSocket"为例。

具体使用流程
context_texts 标签),通过 ZEGO TTS-Vendor=ByteDanceV3 调用"单向流式语音合成 WebSocket"为例,实现AI 自动判断并以指定语气 + 音调播报回复的效果。前提条件
- 开通 AI Agent 服务。
- 确认所使用的 TTS 模型或音色支持对应的合成参数,并且 ZEGO AI Agent 服务支持(详细见附录-支持的厂商与参数章节)。
实现流程
注册智能体 / 创建智能体实例
配置1:配置 LLMMetaInfo 提取规则
通过配置创建智能体实例接口的 AdvancedConfig.LLMMetaInfo 参数,指定如何从 LLM 文本中提取元数据。例如:
"AdvancedConfig": {
"LLMMetaInfo": {
"BeginCharacters": "[[",
"EndCharacters": "]]"
}
}无需在注册智能体或创建智能体实例时再配置 FilterText.BeginCharacters 和 FilterText.EndCharacters 参数,因为元数据及标记符号将会被从 LLM 输出文本中移除。
配置2:配置 TTSParamPaths 映射
TTS 各厂商可以通过一些参数控制合成的语音情绪效果。TTSParamPaths 是创建智能体实例时通过 AdvancedConfig 传入的映射表,这个参数控制 LLM 输出内容中如何通过元数据标志映射为 TTS 情绪控制参数。
以火山引擎 TTS(单向流式)为例:
"AdvancedConfig": {
"TTSParamPaths": {
"context_texts": "req_params.additions.context_texts",
"pitch": "req_params.additions.post_process.pitch"
}
}表示 LLM 输出为 [[{"context_texts":"用温柔的语气","pitch":"1"}]]你好 时,会将这段输出中的元数据:
{"context_texts":"用温柔的语气"}的context_texts对应的值用温柔的语气"pitch":"1"的pitch对应的值1
提取出来,作为值传给 TTS 厂商接口的 req_params.additions.context_texts 和 req_params.additions.post_process.pitch。
TTSParamPaths 的 key 可以根据业务逻辑自定义(例如将 instruction 换成 i),只需保证 LLM 输出的元数据 key 与 TTSParamPaths 中定义的 key 一致即可。配置3:让 LLM 按照指定格式输出内容
在注册智能体或创建智能体实例接口的 LLM.SystemPrompt 中提示 LLM 在回答中输出包含厂商原生参数的标签。
以下为可添加到 SystemPrompt 中的片段示例,请根据实际业务调整:
## 语音情绪控制规则
在每次回复的最前面,输出一个 JSON 标签来控制本次回复的语音情绪,格式如下:
[[{"context_texts":["此处填写期望的语气描述,如:用温柔的语气说话"],"pitch":此处填写1-5的整数}]]
说明:
- context_texts:用自然语言描述你希望本次回复的语音风格(如"温柔的语气""兴奋的语调"等)。
- pitch:音调调整,取值 1-5 的整数,数值越大音调越高;如不需要可省略该字段。
- 标签必须放在回复文本的最前面,标签内容不会被朗读。
- 紧接标签之后,正常输出回复用户的文本内容。
示例:
输入:用户说"你好"
你的输出应为:[[{"context_texts":["用温柔的语气说话"],"pitch":5}]]你好呀,很高兴见到你!触发 AI 说话
触发方式1:用户说话
用户在实时语音对话中说话,语音经 RTC 传输、ASR 转写后输入 LLM。LLM 自动生成回复并按已配置的 SystemPrompt 在句首输出 [[标签]],标签随 LLM 流式输出进入 ZEGO 处理流程,无需额外调用。
触发方式2:通过 sendAgentInstanceLLM,让 AI 主动说话
LLM 本身不支持主动输出,需开发者基于一定规则主动触发智能体说话,从而提升实时互动中的沉浸感。例如当用户 5 秒未说话时,让智能体主动搭话。
通过 sendAgentInstanceLLM 主动触发 LLM 生成回复,LLM 同样按已配置的 SystemPrompt 输出带 [[标签]] 的文本,处理流程与触发方式1一致。
调用 sendAgentInstanceLLM 接口示例:
{
"AgentInstanceId": "1907755175297171456",
"Text": "主动跟用户打个招呼吧"
}调用后 LLM 会基于上下文生成回复,并按已配置的 SystemPrompt 在回复句首输出 [[标签]],后续提取、映射、合成流程与触发方式1完全一致。
LLM SSE 数据返回示例:
data: {"id":"d7ae7c4a-1524-4fe5-9d58-e4d59b89d8f0","object":"chat.completion.chunk","created":1709899323,"model":"step-1-8k","choices":[{"index":0,"delta":{"role":"","content":"[[{\"context_texts\":[\"用温柔的语气说话\"],\"pitch\":5}]]"},"finish_reason":""}],"usage":{"prompt_tokens":83,"completion_tokens":1,"total_tokens":84}}
data: {"id":"d7ae7c4a-1524-4fe5-9d58-e4d59b89d8f0","object":"chat.completion.chunk","created":1709899323,"model":"step-1-8k","choices":[{"index":0,"delta":{"role":"","content":"您"},"finish_reason":""}],"usage":{"prompt_tokens":83,"completion_tokens":2,"total_tokens":85}}
data: {"id":"d7ae7c4a-1524-4fe5-9d58-e4d59b89d8f0","object":"chat.completion.chunk","created":1709899323,"model":"step-1-8k","choices":[{"index":0,"delta":{"role":"","content":"好"},"finish_reason":""}],"usage":{"prompt_tokens":83,"completion_tokens":3,"total_tokens":86}}
...
data: {"id":"d7ae7c4a-1524-4fe5-9d58-e4d59b89d8f0","object":"chat.completion.chunk","created":1709899323,"model":"step-1-8k","choices":[{"index":0,"delta":{"role":"","content":"。"},"finish_reason":"stop"}],"usage":{"prompt_tokens":83,"completion_tokens":150,"total_tokens":233}}
data: [DONE]触发方式3:通过 sendAgentInstanceTTS,让 AI 主动说话(可选)
除了通过 LLM 自动输出标签外,您也可以在调用 sendAgentInstanceTTS 等接口时,直接在 text 字段最前面携带标签,标签内容不会被朗读:
{
"text": "[[{\"context_texts\":[\"用温柔的语气说话\"],\"pitch\":5}]]你好"
}标签必须置于文本最前面(句首)。
ZEGO 自动处理并控制 TTS 播报
无论通过上述哪种触发方式,ZEGO AI Agent 服务都会按既定规则处理:
① 按 LLMMetaInfo 提取 [[标签]] 并移除标记 → ② 按 TTSParamPaths 把短参数名映射为厂商请求体路径 → ③ 调用第三方 TTS 按参数合成。
最终用户听到带情绪的语音,例如以"温柔的语气 + pitch=5"播报"你好"。
本示例以火山 ByteDanceV3 为例。若使用其他厂商,只需调整以下三处,其余流程(提取标签、触发方式、ZEGO 自动处理)完全不变:
- 配置2 的
TTSParamPaths映射路径 — 替换为目标厂商的参数路径,见附录《支持的厂商与参数》表"TTS 参数路径"列。例:阿里云 CosyVoice 的instruction→payload.parameters.instruction - 配置3 的
SystemPrompt提示词 — 替换为目标厂商支持的参数名和取值规则。例:MiniMax 改为输出emotion枚举;CosyVoice 改为输出instruction指令 - 触发方式3 的 text 标签(如使用直接调用 TTS)— 标签内的字段名同步替换为目标厂商的参数名即可
特殊说明
- 现在由客户自己管理传入参数的有效性。如果大模型生成或
sendAgentInstanceTTS调用传入了厂商不支持的参数值,可能导致生成的 TTS 没有声音。 - 音色/情绪列表可能会变更,请以 TTS 厂商提供的最新列表为准。
以下方案为早期实现方式,推荐使用上述基于
TTSParamPaths透传厂商原生参数的方式。
1. 指定 LLM 文本中控制情绪的内容格式
无需在注册智能体或创建智能体实例时再配置 FilterText.BeginCharacters 和 FilterText.EndCharacters 参数,因为元数据及标记符号将会被从 LLM 输出文本中移除。
通过配置创建智能体实例接口的 AdvancedConfig.LLMMetaInfo 参数,指定如何从 LLM 文本中提取控制情绪的元数据。例如:
"LLMMetaInfo" : {
"BeginCharacters": "[[",
"EndCharacters": "]]"
}2. 让 LLM 按照指定的控制情绪格式输出内容
以下示例中,提示的 emotion 选值仅仅是示例,实际 TTS 厂商支持哪些情绪就可以让 LLM 输出的文本中包含哪些情绪。但是一般都不会包含所有情绪(比如一个人工客服应用不会让它有悲伤情绪)。
以下是使用 MiniMax 和豆包语音 TTS 时,调用注册智能体和创建智能体实例接口对应的 LLM.SystemPrompt 示例,仅供参考,请根据实际需求调整:
3. 让 TTS 厂商根据情绪控制参数合成带情绪的语音
现在您可以与创建的智能体实例开始语音对话啦!当 LLM 输出的内容包含了情绪控制参数时,AI Agent 服务会自动根据这些参数调用 TTS 厂商接口,让它以丰富的语音情绪表现力与您进行互动。
附录
支持的厂商与参数
目前 ZEGO AI Agent 支持以下 TTS 厂商的情绪控制能力,不同厂商和模型支持的控制方式不同:MiniMax 和火山豆包语音 1.0 支持通过 emotion 标签指定预定义的情绪枚举;火山豆包语音 2.0 和 CosyVoice 支持通过自然语言指令(如 instruction 或 context_texts)描述语音风格。
下表列出了各厂商支持透传的参数详情,其中"TTS 参数路径"列的值即 TTSParamPaths 映射表所需填写的 value(厂商请求体的点号路径),标签中使用的短参数名则对应 TTSParamPaths 的 key。
| 厂商(TTS-Vendor) | 适用模型 | TTS 参数路径 | 类型 | 支持的厂商参数说明 | LLM 输出 | 直接调用 TTS |
|---|---|---|---|---|---|---|
火山引擎 TTS(单向流式)ByteDanceV3 | 1.0 系列 | req_params.audio_params.emotion | string | 特定情绪枚举,如 happy、sad、angry、fearful、surprised、neutral 等。查看情感参数说明 / 豆包语音合成大模型 | ✅ | ✅ |
火山引擎 TTS(单向流式)ByteDanceV3 | 1.0 系列 | req_params.audio_params.emotion_scale | number | 情绪强度 1-5 注意:仅 1.0 系列支持 | ✅ | ✅ |
火山引擎 TTS(单向流式)ByteDanceV3 | 2.0 系列 | req_params.additions.context_texts | string[] | 自然语言指令,如填写"用温柔的语气说话"、"用兴奋的语调说话"等指令控制语音风格。 查看语音指令与标签说明 / 豆包语音合成大模型 中的多情感音色 注意:仅 2.0 系列支持 | ✅ | ✅ |
火山引擎 TTS(单向流式)ByteDanceV3 | 1.0 / 2.0 | req_params.additions.post_process.pitch | int | 音调调整 | ✅ | ✅ |
火山引擎 TTS(双向流式)ByteDanceFlowing | 2.0 系列 | req_params.additions.context_texts | string[] | 自然语言指令 查看语音指令与标签说明 / 豆包语音合成大模型 中的多情感音色 注意:仅 2.0 系列支持 | ❌ | ✅ |
阿里云 CosyVoiceCosyVoice | CosyVoice | payload.parameters.instruction | string | 自然语言描述,如填写"用温柔的语气说话"、"用四川方言说话"等指令控制方言、情感、角色等。 查看指令控制说明 / CosyVoice 体验 | ✅ | ✅ |
MiniMaxMiniMax | Speech 系列 | voice_setting.emotion | string | 特定情绪枚举,如 happy、sad、angry、fearful、surprised、neutral 等。查看完整 emotion 列表 / 语音调试台 | ✅ | ❌ |
sendAgentInstanceTTS)传入标签。