diff --git a/src/plugins/built_in/kokoro_flow_chatter/config.py b/src/plugins/built_in/kokoro_flow_chatter/config.py index ee01abf77..b46a2a31d 100644 --- a/src/plugins/built_in/kokoro_flow_chatter/config.py +++ b/src/plugins/built_in/kokoro_flow_chatter/config.py @@ -158,6 +158,9 @@ class KokoroFlowChatterConfig: # LLM 配置 llm: LLMConfig = field(default_factory=LLMConfig) + # 自定义决策提示词 + custom_decision_prompt: str = "" + # 调试模式 debug: bool = False @@ -256,6 +259,10 @@ def load_config() -> KokoroFlowChatterConfig: timeout=getattr(llm_cfg, "timeout", 60.0), ) + # 自定义决策提示词配置 + if hasattr(kfc_cfg, "custom_decision_prompt"): + config.custom_decision_prompt = str(kfc_cfg.custom_decision_prompt) + except Exception as e: from src.common.logger import get_logger logger = get_logger("kfc_config") diff --git a/src/plugins/built_in/kokoro_flow_chatter/prompt/builder.py b/src/plugins/built_in/kokoro_flow_chatter/prompt/builder.py index 144d6dbb7..87528e30d 100644 --- a/src/plugins/built_in/kokoro_flow_chatter/prompt/builder.py +++ b/src/plugins/built_in/kokoro_flow_chatter/prompt/builder.py @@ -72,6 +72,9 @@ class PromptBuilder: # 1.5. 构建安全互动准则块 safety_guidelines_block = self._build_safety_guidelines_block() + # 1.6. 构建自定义决策提示词块 + custom_decision_block = self._build_custom_decision_block() + # 2. 使用 context_builder 获取关系、记忆、工具、表达习惯等 context_data = await self._build_context_data(user_name, chat_stream, user_id) relation_block = context_data.get("relation_info", f"你与 {user_name} 还不太熟悉,这是早期的交流阶段。") @@ -102,6 +105,7 @@ class PromptBuilder: user_name=user_name, persona_block=persona_block, safety_guidelines_block=safety_guidelines_block, + custom_decision_block=custom_decision_block, relation_block=relation_block, memory_block=memory_block or "(暂无相关记忆)", tool_info=tool_info or "(暂无工具信息)", @@ -232,6 +236,23 @@ class PromptBuilder: {guidelines_text} 如果遇到违反上述原则的请求,请在保持你核心人设的同时,以合适的方式进行回应。""" + def _build_custom_decision_block(self) -> str: + """ + 构建自定义决策提示词块 + + 从配置中读取 custom_decision_prompt,用于指导KFC的决策行为 + 类似于AFC的planner_custom_prompt_content + """ + from ..config import get_config + + kfc_config = get_config() + custom_prompt = getattr(kfc_config, "custom_decision_prompt", "") + + if not custom_prompt or not custom_prompt.strip(): + return "" + + return custom_prompt.strip() + def _build_combined_expression_block(self, learned_habits: str) -> str: """ 构建合并后的表达习惯块 @@ -693,8 +714,22 @@ class PromptBuilder: # 添加真正追问次数警告(只有真正发了消息才算追问) followup_count = extra_context.get("followup_count", 0) - if followup_count > 0: - timeout_context_parts.append(f"⚠️ 你已经连续追问了 {followup_count} 次,对方仍未回复。再追问可能会显得太急躁,请三思。") + if followup_count >= 2: + timeout_context_parts.append( + f"⚠️ **强烈建议**: 你已经连续追问了 {followup_count} 次,对方仍未回复。" + "**极度推荐选择 `do_nothing` 或主动结束话题**。" + "对方可能在忙或需要空间,不是所有人都能一直在线。给彼此一些空间会更好。" + ) + elif followup_count == 1: + timeout_context_parts.append( + "📝 温馨提醒:这是你第2次等待回复(已追问1次)。" + "可以再试着追问一次,但如果对方还是没回复,**强烈建议**之后选择 `do_nothing` 或结束话题。" + ) + elif followup_count == 0: + timeout_context_parts.append( + "💭 追问提示:如果对方一段时间未回复,可以适当追问一次。" + "但要记住对方可能在忙,建议最多追问2次左右,之后给对方一些空间。" + ) # 添加距离用户上次回复的时间 time_since_user_reply_str = extra_context.get("time_since_user_reply_str") diff --git a/src/plugins/built_in/kokoro_flow_chatter/prompt/prompts.py b/src/plugins/built_in/kokoro_flow_chatter/prompt/prompts.py index 4d4277c8e..6d5090360 100644 --- a/src/plugins/built_in/kokoro_flow_chatter/prompt/prompts.py +++ b/src/plugins/built_in/kokoro_flow_chatter/prompt/prompts.py @@ -24,6 +24,9 @@ kfc_MAIN_PROMPT = Prompt( # 安全互动准则 {safety_guidelines_block} +# 决策指导 +{custom_decision_block} + # 相关信息 {memory_block} diff --git a/src/plugins/built_in/kokoro_flow_chatter/prompt_modules_unified.py b/src/plugins/built_in/kokoro_flow_chatter/prompt_modules_unified.py index 1cf506097..d956169a4 100644 --- a/src/plugins/built_in/kokoro_flow_chatter/prompt_modules_unified.py +++ b/src/plugins/built_in/kokoro_flow_chatter/prompt_modules_unified.py @@ -100,6 +100,33 @@ def build_rules_module() -> str: {kfc_rules}""" +# ============================================================ +# 模块2.5: 自定义决策提示词 - 用户自定义的决策行为指导 +# ============================================================ + +def build_custom_decision_module() -> str: + """ + 构建自定义决策提示词模块 + + 允许用户通过配置文件自定义KFC的决策行为指导 + 类似于AFC的planner_custom_prompt_content + """ + from .config import get_config + + kfc_config = get_config() + custom_prompt = getattr(kfc_config, "custom_decision_prompt", "") + + # 调试输出 + logger.debug(f"[自定义决策提示词] 原始值: {repr(custom_prompt)}, 类型: {type(custom_prompt)}") + + if not custom_prompt or not custom_prompt.strip(): + logger.debug("[自定义决策提示词] 为空或仅含空白字符,跳过") + return "" + + logger.info(f"[自定义决策提示词] 已加载: {custom_prompt.strip()}") + return custom_prompt.strip() + + # ============================================================ # 模块3: 情境上下文 - 时间/场景/内在状态/关系/记忆 # ============================================================ @@ -354,6 +381,9 @@ def build_system_prompt( # 角色框架(不提AI,直接进入角色) role_frame = "你是一个真实的人,有自己的生活、想法和情绪。像平时和朋友聊天一样自然地交流。" + # 获取自定义决策提示词 + custom_decision_block = build_custom_decision_module() + # 组装各模块 modules = [ role_frame, @@ -363,6 +393,17 @@ def build_system_prompt( "", "## 2. 规则", build_rules_module(), + ] + + # 如果有自定义决策提示词,插入到规则后面 + if custom_decision_block: + modules.extend([ + "", + "## 2.5. 决策指导", + custom_decision_block, + ]) + + modules.extend([ "", "## 3. 现在的情况", build_context_module(session, chat_stream, context_data), @@ -372,7 +413,7 @@ def build_system_prompt( "", "## 5. 怎么回复", build_output_module(context_data), - ] + ]) return "\n".join(modules) diff --git a/src/plugins/built_in/kokoro_flow_chatter/unified.py b/src/plugins/built_in/kokoro_flow_chatter/unified.py index 5b34167df..6b52c1494 100644 --- a/src/plugins/built_in/kokoro_flow_chatter/unified.py +++ b/src/plugins/built_in/kokoro_flow_chatter/unified.py @@ -147,17 +147,35 @@ class UnifiedPromptGenerator: # 生成连续追问警告(使用 followup_count 作为追问计数,只有真正发消息才算) followup_count = session.waiting_config.followup_count - max_followups = 3 # 最多追问3次 + max_followups = 2 # 建议最多追问2次 if followup_count >= max_followups: - followup_warning = f"""⚠️ **重要提醒**: + followup_warning = f"""⚠️ **强烈建议**: 你已经连续追问了 {followup_count} 次,对方都没有回复。 -**强烈建议不要再发消息了**——继续追问会显得很缠人、很不尊重对方的空间。 -对方可能真的在忙,或者暂时不想回复,这都是正常的。 -请选择 `do_nothing` 继续等待,或者直接结束对话(设置 `max_wait_seconds: 0`)。""" - elif followup_count > 0: - followup_warning = f"""📝 提示:这已经是你第 {followup_count + 1} 次等待对方回复了。 -如果对方持续没有回应,可能真的在忙或不方便,不需要急着追问。""" +**极度推荐选择 `do_nothing` 或设置 `max_wait_seconds: 0` 结束这个话题**。 + +对方很可能: +- 正在忙自己的事情,没有时间回复 +- 需要一些个人空间和独处时间 +- 暂时不方便或不想聊天 + +这些都是完全正常的。不是所有人都能一直在线,每个人都有自己的生活节奏。 +继续追问很可能会让对方感到压力和不适,不如给彼此一些空间。 + +**最好的选择**: +1. 选择 `do_nothing` 安静等待对方主动联系 +2. 或者主动结束这个话题(`max_wait_seconds: 0`),让对方知道你理解他们可能在忙""" + elif followup_count == 1: + followup_warning = """📝 温馨提醒: +这是你第2次等待对方回复(已追问1次)。 +可以再试着温柔地追问一次,但要做好对方可能真的在忙的心理准备。 +如果这次之后对方还是没回复,**强烈建议**不要再继续追问了—— +选择 `do_nothing` 给对方空间,或者主动结束话题,都是尊重对方的表现。""" + elif followup_count == 0: + followup_warning = """💭 追问提示: +如果对方一段时间没回复,可以适当追问一次,用轻松的语气提醒一下。 +但要记住:不是所有人都能一直在线,对方可能在忙。 +建议最多追问2次左右,之后就给对方一些空间吧。""" else: followup_warning = "" diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index 6c3da912b..63114a01a 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -631,6 +631,13 @@ mode = "split" max_wait_seconds_default = 300 # 默认的最大等待秒数(AI发送消息后愿意等待用户回复的时间) enable_continuous_thinking = true # 是否在等待期间启用心理活动更新 +# --- 自定义决策提示词 --- +# 类似于AFC的planner_custom_prompt_content,允许用户自定义KFC的决策行为指导 +# 在unified模式下:会插入到完整提示词中,影响整体思考和回复生成 +# 在split模式下:只会插入到planner提示词中,影响决策规划,不影响replyer的回复生成 +# 留空则不生效 +custom_decision_prompt = "" + # --- 等待策略 --- [kokoro_flow_chatter.waiting] default_max_wait_seconds = 300 # LLM 未给出等待时间时的默认值