Merge branch 'dev' of https://github.com/MoFox-Studio/MoFox-Core into dev
This commit is contained in:
@@ -158,6 +158,9 @@ class KokoroFlowChatterConfig:
|
|||||||
# LLM 配置
|
# LLM 配置
|
||||||
llm: LLMConfig = field(default_factory=LLMConfig)
|
llm: LLMConfig = field(default_factory=LLMConfig)
|
||||||
|
|
||||||
|
# 自定义决策提示词
|
||||||
|
custom_decision_prompt: str = ""
|
||||||
|
|
||||||
# 调试模式
|
# 调试模式
|
||||||
debug: bool = False
|
debug: bool = False
|
||||||
|
|
||||||
@@ -256,6 +259,10 @@ def load_config() -> KokoroFlowChatterConfig:
|
|||||||
timeout=getattr(llm_cfg, "timeout", 60.0),
|
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:
|
except Exception as e:
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
logger = get_logger("kfc_config")
|
logger = get_logger("kfc_config")
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ class PromptBuilder:
|
|||||||
# 1.5. 构建安全互动准则块
|
# 1.5. 构建安全互动准则块
|
||||||
safety_guidelines_block = self._build_safety_guidelines_block()
|
safety_guidelines_block = self._build_safety_guidelines_block()
|
||||||
|
|
||||||
|
# 1.6. 构建自定义决策提示词块
|
||||||
|
custom_decision_block = self._build_custom_decision_block()
|
||||||
|
|
||||||
# 2. 使用 context_builder 获取关系、记忆、工具、表达习惯等
|
# 2. 使用 context_builder 获取关系、记忆、工具、表达习惯等
|
||||||
context_data = await self._build_context_data(user_name, chat_stream, user_id)
|
context_data = await self._build_context_data(user_name, chat_stream, user_id)
|
||||||
relation_block = context_data.get("relation_info", f"你与 {user_name} 还不太熟悉,这是早期的交流阶段。")
|
relation_block = context_data.get("relation_info", f"你与 {user_name} 还不太熟悉,这是早期的交流阶段。")
|
||||||
@@ -102,6 +105,7 @@ class PromptBuilder:
|
|||||||
user_name=user_name,
|
user_name=user_name,
|
||||||
persona_block=persona_block,
|
persona_block=persona_block,
|
||||||
safety_guidelines_block=safety_guidelines_block,
|
safety_guidelines_block=safety_guidelines_block,
|
||||||
|
custom_decision_block=custom_decision_block,
|
||||||
relation_block=relation_block,
|
relation_block=relation_block,
|
||||||
memory_block=memory_block or "(暂无相关记忆)",
|
memory_block=memory_block or "(暂无相关记忆)",
|
||||||
tool_info=tool_info or "(暂无工具信息)",
|
tool_info=tool_info or "(暂无工具信息)",
|
||||||
@@ -232,6 +236,23 @@ class PromptBuilder:
|
|||||||
{guidelines_text}
|
{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:
|
def _build_combined_expression_block(self, learned_habits: str) -> str:
|
||||||
"""
|
"""
|
||||||
构建合并后的表达习惯块
|
构建合并后的表达习惯块
|
||||||
@@ -693,8 +714,22 @@ class PromptBuilder:
|
|||||||
|
|
||||||
# 添加真正追问次数警告(只有真正发了消息才算追问)
|
# 添加真正追问次数警告(只有真正发了消息才算追问)
|
||||||
followup_count = extra_context.get("followup_count", 0)
|
followup_count = extra_context.get("followup_count", 0)
|
||||||
if followup_count > 0:
|
if followup_count >= 2:
|
||||||
timeout_context_parts.append(f"⚠️ 你已经连续追问了 {followup_count} 次,对方仍未回复。再追问可能会显得太急躁,请三思。")
|
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")
|
time_since_user_reply_str = extra_context.get("time_since_user_reply_str")
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ kfc_MAIN_PROMPT = Prompt(
|
|||||||
# 安全互动准则
|
# 安全互动准则
|
||||||
{safety_guidelines_block}
|
{safety_guidelines_block}
|
||||||
|
|
||||||
|
# 决策指导
|
||||||
|
{custom_decision_block}
|
||||||
|
|
||||||
# 相关信息
|
# 相关信息
|
||||||
{memory_block}
|
{memory_block}
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,33 @@ def build_rules_module() -> str:
|
|||||||
{kfc_rules}"""
|
{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: 情境上下文 - 时间/场景/内在状态/关系/记忆
|
# 模块3: 情境上下文 - 时间/场景/内在状态/关系/记忆
|
||||||
# ============================================================
|
# ============================================================
|
||||||
@@ -354,6 +381,9 @@ def build_system_prompt(
|
|||||||
# 角色框架(不提AI,直接进入角色)
|
# 角色框架(不提AI,直接进入角色)
|
||||||
role_frame = "你是一个真实的人,有自己的生活、想法和情绪。像平时和朋友聊天一样自然地交流。"
|
role_frame = "你是一个真实的人,有自己的生活、想法和情绪。像平时和朋友聊天一样自然地交流。"
|
||||||
|
|
||||||
|
# 获取自定义决策提示词
|
||||||
|
custom_decision_block = build_custom_decision_module()
|
||||||
|
|
||||||
# 组装各模块
|
# 组装各模块
|
||||||
modules = [
|
modules = [
|
||||||
role_frame,
|
role_frame,
|
||||||
@@ -363,6 +393,17 @@ def build_system_prompt(
|
|||||||
"",
|
"",
|
||||||
"## 2. 规则",
|
"## 2. 规则",
|
||||||
build_rules_module(),
|
build_rules_module(),
|
||||||
|
]
|
||||||
|
|
||||||
|
# 如果有自定义决策提示词,插入到规则后面
|
||||||
|
if custom_decision_block:
|
||||||
|
modules.extend([
|
||||||
|
"",
|
||||||
|
"## 2.5. 决策指导",
|
||||||
|
custom_decision_block,
|
||||||
|
])
|
||||||
|
|
||||||
|
modules.extend([
|
||||||
"",
|
"",
|
||||||
"## 3. 现在的情况",
|
"## 3. 现在的情况",
|
||||||
build_context_module(session, chat_stream, context_data),
|
build_context_module(session, chat_stream, context_data),
|
||||||
@@ -372,7 +413,7 @@ def build_system_prompt(
|
|||||||
"",
|
"",
|
||||||
"## 5. 怎么回复",
|
"## 5. 怎么回复",
|
||||||
build_output_module(context_data),
|
build_output_module(context_data),
|
||||||
]
|
])
|
||||||
|
|
||||||
return "\n".join(modules)
|
return "\n".join(modules)
|
||||||
|
|
||||||
|
|||||||
@@ -147,17 +147,35 @@ class UnifiedPromptGenerator:
|
|||||||
|
|
||||||
# 生成连续追问警告(使用 followup_count 作为追问计数,只有真正发消息才算)
|
# 生成连续追问警告(使用 followup_count 作为追问计数,只有真正发消息才算)
|
||||||
followup_count = session.waiting_config.followup_count
|
followup_count = session.waiting_config.followup_count
|
||||||
max_followups = 3 # 最多追问3次
|
max_followups = 2 # 建议最多追问2次
|
||||||
|
|
||||||
if followup_count >= max_followups:
|
if followup_count >= max_followups:
|
||||||
followup_warning = f"""⚠️ **重要提醒**:
|
followup_warning = f"""⚠️ **强烈建议**:
|
||||||
你已经连续追问了 {followup_count} 次,对方都没有回复。
|
你已经连续追问了 {followup_count} 次,对方都没有回复。
|
||||||
**强烈建议不要再发消息了**——继续追问会显得很缠人、很不尊重对方的空间。
|
**极度推荐选择 `do_nothing` 或设置 `max_wait_seconds: 0` 结束这个话题**。
|
||||||
对方可能真的在忙,或者暂时不想回复,这都是正常的。
|
|
||||||
请选择 `do_nothing` 继续等待,或者直接结束对话(设置 `max_wait_seconds: 0`)。"""
|
对方很可能:
|
||||||
elif followup_count > 0:
|
- 正在忙自己的事情,没有时间回复
|
||||||
followup_warning = f"""📝 提示:这已经是你第 {followup_count + 1} 次等待对方回复了。
|
- 需要一些个人空间和独处时间
|
||||||
如果对方持续没有回应,可能真的在忙或不方便,不需要急着追问。"""
|
- 暂时不方便或不想聊天
|
||||||
|
|
||||||
|
这些都是完全正常的。不是所有人都能一直在线,每个人都有自己的生活节奏。
|
||||||
|
继续追问很可能会让对方感到压力和不适,不如给彼此一些空间。
|
||||||
|
|
||||||
|
**最好的选择**:
|
||||||
|
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:
|
else:
|
||||||
followup_warning = ""
|
followup_warning = ""
|
||||||
|
|
||||||
|
|||||||
@@ -631,6 +631,13 @@ mode = "split"
|
|||||||
max_wait_seconds_default = 300 # 默认的最大等待秒数(AI发送消息后愿意等待用户回复的时间)
|
max_wait_seconds_default = 300 # 默认的最大等待秒数(AI发送消息后愿意等待用户回复的时间)
|
||||||
enable_continuous_thinking = true # 是否在等待期间启用心理活动更新
|
enable_continuous_thinking = true # 是否在等待期间启用心理活动更新
|
||||||
|
|
||||||
|
# --- 自定义决策提示词 ---
|
||||||
|
# 类似于AFC的planner_custom_prompt_content,允许用户自定义KFC的决策行为指导
|
||||||
|
# 在unified模式下:会插入到完整提示词中,影响整体思考和回复生成
|
||||||
|
# 在split模式下:只会插入到planner提示词中,影响决策规划,不影响replyer的回复生成
|
||||||
|
# 留空则不生效
|
||||||
|
custom_decision_prompt = ""
|
||||||
|
|
||||||
# --- 等待策略 ---
|
# --- 等待策略 ---
|
||||||
[kokoro_flow_chatter.waiting]
|
[kokoro_flow_chatter.waiting]
|
||||||
default_max_wait_seconds = 300 # LLM 未给出等待时间时的默认值
|
default_max_wait_seconds = 300 # LLM 未给出等待时间时的默认值
|
||||||
|
|||||||
Reference in New Issue
Block a user