fix(chat): 增强回复生成的健壮性,增加超时和类型检查

在 `DefaultReplyer` 的提示词构建流程中,为并行的子任务(如记忆、工具、关系等)增加了15秒的超时机制。这可以防止因某个子任务耗时过长或卡死而导致整个回复生成过程停滞。

同时,在能量系统中增加了对计算器分数和兴趣值的类型检查,确保它们是数值类型,避免了潜在的 `TypeError` 异常,提高了系统的稳定性。
This commit is contained in:
tt-P607
2025-10-02 23:22:00 +08:00
parent 58688c5e49
commit 844d4f3362
2 changed files with 40 additions and 24 deletions

View File

@@ -94,14 +94,10 @@ class InterestEnergyCalculator(EnergyCalculator):
for msg in messages: for msg in messages:
interest_value = getattr(msg, "interest_value", None) interest_value = getattr(msg, "interest_value", None)
if interest_value is not None: if isinstance(interest_value, (int, float)):
try: if 0.0 <= interest_value <= 1.0:
interest_float = float(interest_value) total_interest += interest_value
if 0.0 <= interest_float <= 1.0: valid_messages += 1
total_interest += interest_float
valid_messages += 1
except (ValueError, TypeError):
continue
if valid_messages > 0: if valid_messages > 0:
avg_interest = total_interest / valid_messages avg_interest = total_interest / valid_messages
@@ -315,7 +311,12 @@ class EnergyManager:
weight = calculator.get_weight() weight = calculator.get_weight()
component_scores[calculator.__class__.__name__] = score # 确保 score 是 float 类型
if not isinstance(score, (int, float)):
logger.warning(f"计算器 {calculator.__class__.__name__} 返回了非数值类型: {type(score)},跳过此组件")
continue
component_scores[calculator.__class__.__name__] = float(score)
total_weight += weight total_weight += weight
logger.debug(f"{calculator.__class__.__name__} 能量: {score:.3f} (权重: {weight:.3f})") logger.debug(f"{calculator.__class__.__name__} 能量: {score:.3f} (权重: {weight:.3f})")

View File

@@ -1217,21 +1217,36 @@ class DefaultReplyer:
from src.chat.utils.prompt import Prompt from src.chat.utils.prompt import Prompt
# 并行执行六个构建任务 # 并行执行六个构建任务
task_results = await asyncio.gather( tasks = {
self._time_and_run_task( "expression_habits": asyncio.create_task(self._time_and_run_task(self.build_expression_habits(chat_talking_prompt_short, target), "expression_habits")),
self.build_expression_habits(chat_talking_prompt_short, target), "expression_habits" "relation_info": asyncio.create_task(self._time_and_run_task(self.build_relation_info(sender, target), "relation_info")),
), "memory_block": asyncio.create_task(self._time_and_run_task(self.build_memory_block(chat_talking_prompt_short, target), "memory_block")),
self._time_and_run_task(self.build_relation_info(sender, target), "relation_info"), "tool_info": asyncio.create_task(self._time_and_run_task(self.build_tool_info(chat_talking_prompt_short, sender, target, enable_tool=enable_tool), "tool_info")),
self._time_and_run_task(self.build_memory_block(chat_talking_prompt_short, target), "memory_block"), "prompt_info": asyncio.create_task(self._time_and_run_task(self.get_prompt_info(chat_talking_prompt_short, sender, target), "prompt_info")),
self._time_and_run_task( "cross_context": asyncio.create_task(self._time_and_run_task(Prompt.build_cross_context(chat_id, global_config.personality.prompt_mode, target_user_info), "cross_context")),
self.build_tool_info(chat_talking_prompt_short, sender, target, enable_tool=enable_tool), "tool_info" }
),
self._time_and_run_task(self.get_prompt_info(chat_talking_prompt_short, sender, target), "prompt_info"), # 设置超时
self._time_and_run_task( timeout = 15.0 # 秒
Prompt.build_cross_context(chat_id, global_config.personality.prompt_mode, target_user_info),
"cross_context", async def get_task_result(task_name, task):
), try:
) return await asyncio.wait_for(task, timeout=timeout)
except asyncio.TimeoutError:
logger.warning(f"构建任务{task_name}超时 ({timeout}s),使用默认值")
# 为超时任务提供默认值
default_values = {
"expression_habits": "",
"relation_info": "",
"memory_block": "",
"tool_info": "",
"prompt_info": "",
"cross_context": "",
}
logger.info(f"为超时任务 {task_name} 提供默认值")
return task_name, default_values[task_name], timeout
task_results = await asyncio.gather(*(get_task_result(name, task) for name, task in tasks.items()))
# 任务名称中英文映射 # 任务名称中英文映射
task_name_mapping = { task_name_mapping = {