问题描述
同时开启流式输出与 TTS 语音回复时,TTS 永远不会触发,trigger_probability 形同虚设:
配置状态:
provider_settings.streaming_response = true
- 已配置 TTS provider,
provider_tts_settings.enable = true
provider_tts_settings.trigger_probability 为任意值(默认 1.0 也一样)
实际现象:
- 所有回复均以流式文字逐条发出,从不被转换为语音
- 无论
trigger_probability 设为多少,等效触发概率都是 0
- 目前唯一的解法是全局关闭流式输出——该点对用户不可见,也无任何文档或界面提示
代码定位(基于当前 master):
- 文字转语音只在一个地方发生:
astrbot/core/pipeline/result_decorate/stage.py 的 TTS 块。而流式结果会整体跳过该阶段——STREAMING_RESULT 在 stage.py:134 直接 return;STREAMING_FINISH 也在 stage.py:191-193「流式输出不执行下面的逻辑」处 return。
- 而决定是否流式的是 agent 子阶段(
InternalAgentSubStage / ThirdPartyAgentSubStage),它们只看 provider_settings.streaming_response 与消息级 enable_streaming,从不参考 provider_tts_settings——本该转语音的回复被静默地流式发出,绕过了唯一的 TTS 代码路径。
本机实测(Docker v4.26.8 + NapCat):上述配置下连续发送普通消息,100% 得到流式文字回复;将流式输出关闭后,TTS 立即按 trigger_probability 正常工作。
如何复现
- 配置任意 TTS provider,开启
provider_tts_settings.enable,trigger_probability 设为 1.0(或 0.99)。
- 保持
provider_settings.streaming_response = true(默认即为开)。
- 向机器人发送任意消息:回复始终为流式文字,从不出现语音。
- 关闭
provider_settings.streaming_response 后重发:TTS 按概率正常触发。
期望行为
- 流式输出开启时,
trigger_probability 的掷骰应被尊重:命中的回复完整生成后转为语音发出,未命中的保持流式文字(与关闭流式时的行为一致)。
trigger_probability = 0 时恢复「全部流式文字」的旧行为;未配置 TTS provider 时无任何变化。
- 命中转语音时,文字是否随语音一同发送,仍由
provider_tts_settings.dual_output 决定,语义不变。
相关 issue
已有修复
修复 PR:#9986。思路为「每条回复只掷一次骰子」:
- 在两个 agent 子阶段判定本条回复将流式输出时,按
trigger_probability 掷骰;命中且会话有可用 TTS provider 时打 tts_forced 标记并把该回复切换为非流式,使其流经 ResultDecorateStage 完成转语音;
- live 模式有自带的流式 TTS 管线(
run_live_agent),已排除;
- 仅在确实存在可用 TTS provider 时才强制非流式,TTS 配置错误不会顺带拖垮正常流式。
已在 v4.26.8(Docker)+ NapCat 上实测 0.99 / 0.5 / 0 三档概率与两条 agent 路径,ruff format / check 通过。愿意根据 review 意见继续修改。
环境
- AstrBot 版本:v4.26.8
- 操作系统:Linux
- 部署方式:Docker(astrbot 容器 + napcat 容器)
- 使用的消息平台适配器:Onebot v11(NapCat)
错误日志
本问题非崩溃类,无报错日志。佐证方式为「该出现却没有出现的日志」:走 TTS 的回复在日志中会出现 TTS request / TTS result 两行(stage.py 内 logger.info),而流式回复全程不会出现。
配置证据(cmd_config.json 实际值,v4.26.8 部署):
provider_tts_settings: {"enable": true, "provider_id": "stepfun_tts", "dual_output": false, "use_file_service": false, "trigger_probability": 1.0}
provider_settings.streaming_response: true
provider_settings.unsupported_streaming_strategy: realtime_segmenting
日志证据(同一次部署,连续多条回复;docker logs --tail 2000 中 TTS request 出现 0 次):
[19:59:45.144] [Core] [WARN] [v4.26.8] [result_decorate.stage:187]: Plugins that depend on the pre-send event hook may not work correctly when streaming output is enabled.
[20:00:38.309] [Core] [INFO] [respond.stage:223]: Applying streaming output (塔菲).
[20:00:57.168] [Core] [WARN] [v4.26.8] [result_decorate.stage:187]: Plugins that depend on the pre-send event hook may not work correctly when streaming output is enabled.
[20:02:04.266] [Core] [WARN] [v4.26.8] [result_decorate.stage:187]: Plugins that depend on the pre-send event hook may not work correctly when streaming output is enabled.
[20:35:19.613] [Core] [INFO] [respond.stage:223]: Applying streaming output (塔菲).
[20:35:40.134] [Core] [WARN] [v4.26.8] [result_decorate.stage:187]: Plugins that depend on the pre-send event hook may not work correctly when streaming output is enabled.
$ docker logs --tail 2000 astrbot | grep -c "TTS request"
0
检查清单
问题描述
同时开启流式输出与 TTS 语音回复时,TTS 永远不会触发,
trigger_probability形同虚设:配置状态:
provider_settings.streaming_response = trueprovider_tts_settings.enable = trueprovider_tts_settings.trigger_probability为任意值(默认 1.0 也一样)实际现象:
trigger_probability设为多少,等效触发概率都是 0代码定位(基于当前 master):
astrbot/core/pipeline/result_decorate/stage.py的 TTS 块。而流式结果会整体跳过该阶段——STREAMING_RESULT在stage.py:134直接 return;STREAMING_FINISH也在stage.py:191-193「流式输出不执行下面的逻辑」处 return。InternalAgentSubStage/ThirdPartyAgentSubStage),它们只看provider_settings.streaming_response与消息级enable_streaming,从不参考provider_tts_settings——本该转语音的回复被静默地流式发出,绕过了唯一的 TTS 代码路径。本机实测(Docker v4.26.8 + NapCat):上述配置下连续发送普通消息,100% 得到流式文字回复;将流式输出关闭后,TTS 立即按
trigger_probability正常工作。如何复现
provider_tts_settings.enable,trigger_probability设为 1.0(或 0.99)。provider_settings.streaming_response = true(默认即为开)。provider_settings.streaming_response后重发:TTS 按概率正常触发。期望行为
trigger_probability的掷骰应被尊重:命中的回复完整生成后转为语音发出,未命中的保持流式文字(与关闭流式时的行为一致)。trigger_probability = 0时恢复「全部流式文字」的旧行为;未配置 TTS provider 时无任何变化。provider_tts_settings.dual_output决定,语义不变。相关 issue
trigger_probability配置的功能 PR(本 issue 的问题即该配置在流式下完全失效)。已有修复
修复 PR:#9986。思路为「每条回复只掷一次骰子」:
trigger_probability掷骰;命中且会话有可用 TTS provider 时打tts_forced标记并把该回复切换为非流式,使其流经ResultDecorateStage完成转语音;run_live_agent),已排除;已在 v4.26.8(Docker)+ NapCat 上实测 0.99 / 0.5 / 0 三档概率与两条 agent 路径,ruff format / check 通过。愿意根据 review 意见继续修改。
环境
错误日志
本问题非崩溃类,无报错日志。佐证方式为「该出现却没有出现的日志」:走 TTS 的回复在日志中会出现
TTS request/TTS result两行(stage.py内 logger.info),而流式回复全程不会出现。配置证据(
cmd_config.json实际值,v4.26.8 部署):provider_tts_settings: {"enable": true, "provider_id": "stepfun_tts", "dual_output": false, "use_file_service": false, "trigger_probability": 1.0}
provider_settings.streaming_response: true
provider_settings.unsupported_streaming_strategy: realtime_segmenting
日志证据(同一次部署,连续多条回复;
docker logs --tail 2000中TTS request出现 0 次):检查清单