feat(action): 重构 Action 激活机制并添加 go_activate() 方法
引入新的 Action 激活机制,允许通过重写 go_activate() 方法来自定义激活逻辑。提供了三个工具函数: - _random_activation(): 随机概率激活 - _keyword_match(): 关键词匹配激活 - _llm_judge_activation(): LLM 智能判断激活 主要变更: - 在 BaseAction 中添加 go_activate() 抽象方法和相关工具函数 - 更新 ActionModifier 使用新的激活判断逻辑 - 在 hello_world_plugin 中添加新的激活方式示例 - 更新文档说明新的激活机制 - 保持向后兼容,旧的激活类型配置仍然可用 BREAKING CHANGE: Action 激活判断现在通过 go_activate() 方法进行,旧的激活类型字段已标记为废弃但仍然兼容
This commit is contained in:
@@ -196,6 +196,8 @@ class ActionModifier:
|
||||
) -> list[tuple[str, str]]:
|
||||
"""
|
||||
根据激活类型过滤,返回需要停用的动作列表及原因
|
||||
|
||||
新的实现:调用每个 Action 类的 go_activate 方法来判断是否激活
|
||||
|
||||
Args:
|
||||
actions_with_info: 带完整信息的动作字典
|
||||
@@ -205,56 +207,72 @@ class ActionModifier:
|
||||
List[Tuple[str, str]]: 需要停用的 (action_name, reason) 元组列表
|
||||
"""
|
||||
deactivated_actions = []
|
||||
|
||||
# 分类处理不同激活类型的actions
|
||||
llm_judge_actions = {}
|
||||
|
||||
|
||||
# 获取 Action 类注册表
|
||||
from src.plugin_system.core.component_registry import component_registry
|
||||
from src.plugin_system.base.component_types import ComponentType
|
||||
|
||||
actions_to_check = list(actions_with_info.items())
|
||||
random.shuffle(actions_to_check)
|
||||
|
||||
|
||||
# 创建并行任务列表
|
||||
activation_tasks = []
|
||||
task_action_names = []
|
||||
|
||||
for action_name, action_info in actions_to_check:
|
||||
activation_type = action_info.activation_type or action_info.focus_activation_type
|
||||
|
||||
if activation_type == ActionActivationType.ALWAYS:
|
||||
continue # 总是激活,无需处理
|
||||
|
||||
elif activation_type == ActionActivationType.RANDOM:
|
||||
probability = action_info.random_activation_probability
|
||||
probability = action_info.random_activation_probability
|
||||
if random.random() >= probability:
|
||||
reason = f"RANDOM类型未触发(概率{probability})"
|
||||
deactivated_actions.append((action_name, reason))
|
||||
logger.debug(f"{self.log_prefix}未激活动作: {action_name},原因: {reason}")
|
||||
|
||||
elif activation_type == ActionActivationType.KEYWORD:
|
||||
if not self._check_keyword_activation(action_name, action_info, chat_content):
|
||||
keywords = action_info.activation_keywords
|
||||
reason = f"关键词未匹配(关键词: {keywords})"
|
||||
deactivated_actions.append((action_name, reason))
|
||||
logger.debug(f"{self.log_prefix}未激活动作: {action_name},原因: {reason}")
|
||||
|
||||
elif activation_type == ActionActivationType.LLM_JUDGE:
|
||||
llm_judge_actions[action_name] = action_info
|
||||
|
||||
elif activation_type == ActionActivationType.NEVER:
|
||||
reason = "激活类型为never"
|
||||
deactivated_actions.append((action_name, reason))
|
||||
logger.debug(f"{self.log_prefix}未激活动作: {action_name},原因: 激活类型为never")
|
||||
|
||||
else:
|
||||
logger.warning(f"{self.log_prefix}未知的激活类型: {activation_type},跳过处理")
|
||||
|
||||
# 并行处理LLM_JUDGE类型
|
||||
if llm_judge_actions:
|
||||
llm_results = await self._process_llm_judge_actions_parallel(
|
||||
llm_judge_actions,
|
||||
chat_content,
|
||||
)
|
||||
for action_name, should_activate in llm_results.items():
|
||||
if not should_activate:
|
||||
reason = "LLM判定未激活"
|
||||
deactivated_actions.append((action_name, reason))
|
||||
logger.debug(f"{self.log_prefix}未激活动作: {action_name},原因: {reason}")
|
||||
# 获取 Action 类
|
||||
action_class = component_registry.get_component_class(action_name, ComponentType.ACTION)
|
||||
if not action_class:
|
||||
logger.warning(f"{self.log_prefix}未找到 Action 类: {action_name},默认不激活")
|
||||
deactivated_actions.append((action_name, "未找到 Action 类"))
|
||||
continue
|
||||
|
||||
# 创建一个临时实例来调用 go_activate 方法
|
||||
# 注意:这里只是为了调用 go_activate,不需要完整的初始化
|
||||
try:
|
||||
# 创建一个最小化的实例
|
||||
action_instance = object.__new__(action_class)
|
||||
# 设置必要的属性
|
||||
action_instance.action_name = action_name
|
||||
action_instance.log_prefix = self.log_prefix
|
||||
# 设置聊天内容,用于激活判断
|
||||
action_instance._activation_chat_content = chat_content
|
||||
|
||||
# 调用 go_activate 方法(不再需要传入 chat_content)
|
||||
task = action_instance.go_activate(
|
||||
llm_judge_model=self.llm_judge,
|
||||
)
|
||||
activation_tasks.append(task)
|
||||
task_action_names.append(action_name)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix}创建 Action 实例 {action_name} 失败: {e}")
|
||||
deactivated_actions.append((action_name, f"创建实例失败: {e}"))
|
||||
|
||||
# 并行执行所有激活判断
|
||||
if activation_tasks:
|
||||
logger.debug(f"{self.log_prefix}并行执行激活判断,任务数: {len(activation_tasks)}")
|
||||
try:
|
||||
task_results = await asyncio.gather(*activation_tasks, return_exceptions=True)
|
||||
|
||||
# 处理结果
|
||||
for action_name, result in zip(task_action_names, task_results, strict=False):
|
||||
if isinstance(result, Exception):
|
||||
logger.error(f"{self.log_prefix}激活判断 {action_name} 时出错: {result}")
|
||||
deactivated_actions.append((action_name, f"激活判断出错: {result}"))
|
||||
elif not result:
|
||||
# go_activate 返回 False,不激活
|
||||
deactivated_actions.append((action_name, "go_activate 返回 False"))
|
||||
logger.debug(f"{self.log_prefix}未激活动作: {action_name},原因: go_activate 返回 False")
|
||||
else:
|
||||
# go_activate 返回 True,激活
|
||||
logger.debug(f"{self.log_prefix}激活动作: {action_name}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix}并行激活判断失败: {e}")
|
||||
# 如果并行执行失败,为所有任务默认不激活
|
||||
for action_name in task_action_names:
|
||||
deactivated_actions.append((action_name, f"并行判断失败: {e}"))
|
||||
|
||||
return deactivated_actions
|
||||
|
||||
|
||||
Reference in New Issue
Block a user