From 48d99defc7803413854b864cd239db2572b91868 Mon Sep 17 00:00:00 2001 From: tt-P607 <68868379+tt-P607@users.noreply.github.com> Date: Wed, 22 Oct 2025 01:39:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(tts):=20=E4=B8=BA=20TTS=20=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E5=BC=95=E5=85=A5=E6=B7=B7=E5=90=88=E6=BF=80=E6=B4=BB?= =?UTF-8?q?=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构了 TTSVoiceAction 的激活逻辑,以提升语音交互的自然度和趣味性。 此前的纯关键词触发方式较为僵硬,新的机制结合了多种判断方式,使语音回复更加智能和生动。 新的混合激活机制包含三种并行的判断方式: 1. **随机激活**: 以 55% 的概率随机触发,为对话增添惊喜感和自发性。 2. **关键词激活**: 响应用户的明确语音请求,如“发语音”、“用语音说”等。 3. **LLM 判断**: 利用大模型分析上下文,在讲故事、情感表达等适宜场景下智能激活。 任意一种方式满足条件即可触发语音回复,使机器人的回应更加人性化。 --- .../tts_voice_plugin/actions/tts_action.py | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/plugins/built_in/tts_voice_plugin/actions/tts_action.py b/src/plugins/built_in/tts_voice_plugin/actions/tts_action.py index 24a6186a6..44de6d754 100644 --- a/src/plugins/built_in/tts_voice_plugin/actions/tts_action.py +++ b/src/plugins/built_in/tts_voice_plugin/actions/tts_action.py @@ -19,18 +19,12 @@ class TTSVoiceAction(BaseAction): action_name = "tts_voice_action" action_description = "使用GPT-SoVITS将文本转换为语音并发送" - focus_activation_type = ActionActivationType.KEYWORD - normal_activation_type = ActionActivationType.KEYWORD - activation_keywords = [ - "发语音", "语音", "说句话", "用语音说", "听你", "听声音", "想你", "想听声音", - "讲个话", "说段话", "念一下", "读一下", "用嘴说", "说", "能发语音吗","亲口" - ] mode_enable = ChatMode.ALL parallel_action = False action_require = [ "当用户明确请求使用语音进行回复时,例如‘发个语音听听’、‘用语音说’等。", - "当对话内容适合用语音表达,例如讲故事、念诗、撒娇或进行角色扮演时。", + "当对话内容适合用语音表达,例如讲故事、念诗、撒嬌或进行角色扮演时。", "在表达特殊情感(如安慰、鼓励、庆祝)的场景下,可以主动使用语音来增强感染力。", "不要在日常的、简短的问答或闲聊中频繁使用语音,避免打扰用户。", "文本内容必须是纯粹的对话,不能包含任何括号或方括号括起来的动作、表情、或场景描述(例如,不要出现 '(笑)' 或 '[歪头]')", @@ -42,6 +36,39 @@ class TTSVoiceAction(BaseAction): # 关键配置项现在由 TTSService 管理 self.tts_service = get_service("tts") + async def go_activate(self, llm_judge_model=None) -> bool: + """ + 判断此 Action 是否应该被激活。 + 满足以下任一条件即可激活: + 1. 55% 的随机概率 + 2. 匹配到预设的关键词 + 3. LLM 判断当前场景适合发送语音 + """ + # 条件1: 随机激活 + if await self._random_activation(0.55): + logger.info(f"{self.log_prefix} 随机激活成功 (55%)") + return True + + # 条件2: 关键词激活 + keywords = [ + "发语音", "语音", "说句话", "用语音说", "听你", "听声音", "想你", "想听声音", + "讲个话", "说段话", "念一下", "读一下", "用嘴说", "说", "能发语音吗", "亲口" + ] + if await self._keyword_match(keywords): + logger.info(f"{self.log_prefix} 关键词激活成功") + return True + + # 条件3: LLM 判断激活 + # 注意:这里我们复用 action_require 里的描述,让 LLM 的判断更精准 + if await self._llm_judge_activation( + llm_judge_model=llm_judge_model + ): + logger.info(f"{self.log_prefix} LLM 判断激活成功") + return True + + logger.debug(f"{self.log_prefix} 所有激活条件均未满足,不激活") + return False + async def execute(self) -> tuple[bool, str]: """ 执行 Action 的核心逻辑