feat(planner): 实现大小脑规划器分离以优化决策流程
将规划器(Planner)拆分为“大脑”和“小脑”两个部分,以实现更精细化的决策控制。 - **大脑(BIG_BRAIN)**: 负责宏观决策,如是否回复、是否需要@人等高层级意图。 - **小脑(SMALL_BRAIN)**: 负责具体的功能性动作执行。 此重构引入了 `PlannerType` 枚举,并更新了动作(Action)定义,允许将动作明确分配给大脑或小脑,从而提升了AI回复的逻辑性和条理性。同时,新增了 `no_action` 类型,用于在规划阶段明确表示“无动作”,提高了处理流程的清晰度。
This commit is contained in:
committed by
Windpicker-owo
parent
cfffc69e20
commit
a30652b0bc
@@ -228,6 +228,8 @@ class CycleProcessor:
|
|||||||
async def execute_action(action_info):
|
async def execute_action(action_info):
|
||||||
"""执行单个动作的通用函数"""
|
"""执行单个动作的通用函数"""
|
||||||
try:
|
try:
|
||||||
|
if action_info["action_type"] == "no_action":
|
||||||
|
return {"action_type": "no_action", "success": True, "reply_text": "", "command": ""}
|
||||||
if action_info["action_type"] == "no_reply":
|
if action_info["action_type"] == "no_reply":
|
||||||
# 直接处理no_reply逻辑,不再通过动作系统
|
# 直接处理no_reply逻辑,不再通过动作系统
|
||||||
reason = action_info.get("reasoning", "选择不回复")
|
reason = action_info.get("reasoning", "选择不回复")
|
||||||
@@ -245,7 +247,7 @@ class CycleProcessor:
|
|||||||
)
|
)
|
||||||
|
|
||||||
return {"action_type": "no_reply", "success": True, "reply_text": "", "command": ""}
|
return {"action_type": "no_reply", "success": True, "reply_text": "", "command": ""}
|
||||||
elif action_info["action_type"] != "reply":
|
elif action_info["action_type"] != "reply" and action_info["action_type"] != "no_action":
|
||||||
# 执行普通动作
|
# 执行普通动作
|
||||||
with Timer("动作执行", cycle_timers):
|
with Timer("动作执行", cycle_timers):
|
||||||
success, reply_text, command = await self._handle_action(
|
success, reply_text, command = await self._handle_action(
|
||||||
@@ -420,7 +422,7 @@ class CycleProcessor:
|
|||||||
if "reply" in available_actions:
|
if "reply" in available_actions:
|
||||||
fallback_action = "reply"
|
fallback_action = "reply"
|
||||||
elif available_actions:
|
elif available_actions:
|
||||||
fallback_action = list(available_actions.keys())
|
fallback_action = list(available_actions.keys())[0]
|
||||||
|
|
||||||
if fallback_action and fallback_action != action:
|
if fallback_action and fallback_action != action:
|
||||||
logger.info(f"{self.context.log_prefix} 使用回退动作: {fallback_action}")
|
logger.info(f"{self.context.log_prefix} 使用回退动作: {fallback_action}")
|
||||||
|
|||||||
@@ -23,7 +23,13 @@ from src.chat.utils.chat_message_builder import (
|
|||||||
from src.chat.utils.utils import get_chat_type_and_target_info
|
from src.chat.utils.utils import get_chat_type_and_target_info
|
||||||
from src.chat.planner_actions.action_manager import ActionManager
|
from src.chat.planner_actions.action_manager import ActionManager
|
||||||
from src.chat.message_receive.chat_stream import get_chat_manager
|
from src.chat.message_receive.chat_stream import get_chat_manager
|
||||||
from src.plugin_system.base.component_types import ActionInfo, ChatMode, ComponentType, ActionActivationType
|
from src.plugin_system.base.component_types import (
|
||||||
|
ActionInfo,
|
||||||
|
ChatMode,
|
||||||
|
ComponentType,
|
||||||
|
ActionActivationType,
|
||||||
|
PlannerType,
|
||||||
|
)
|
||||||
from src.plugin_system.core.component_registry import component_registry
|
from src.plugin_system.core.component_registry import component_registry
|
||||||
from src.schedule.schedule_manager import schedule_manager
|
from src.schedule.schedule_manager import schedule_manager
|
||||||
from src.mood.mood_manager import mood_manager
|
from src.mood.mood_manager import mood_manager
|
||||||
@@ -503,6 +509,9 @@ class ActionPlanner:
|
|||||||
try:
|
try:
|
||||||
sub_planner_actions: Dict[str, ActionInfo] = {}
|
sub_planner_actions: Dict[str, ActionInfo] = {}
|
||||||
for action_name, action_info in available_actions.items():
|
for action_name, action_info in available_actions.items():
|
||||||
|
if action_info.planner_type not in [PlannerType.SMALL_BRAIN, PlannerType.ALL]:
|
||||||
|
continue
|
||||||
|
|
||||||
if action_info.activation_type in [ActionActivationType.LLM_JUDGE, ActionActivationType.ALWAYS]:
|
if action_info.activation_type in [ActionActivationType.LLM_JUDGE, ActionActivationType.ALWAYS]:
|
||||||
sub_planner_actions[action_name] = action_info
|
sub_planner_actions[action_name] = action_info
|
||||||
elif action_info.activation_type == ActionActivationType.RANDOM:
|
elif action_info.activation_type == ActionActivationType.RANDOM:
|
||||||
@@ -550,10 +559,15 @@ class ActionPlanner:
|
|||||||
# --- 3. 大脑独立思考是否回复 ---
|
# --- 3. 大脑独立思考是否回复 ---
|
||||||
action, reasoning, action_data, target_message = "no_reply", "大脑初始化默认", {}, None
|
action, reasoning, action_data, target_message = "no_reply", "大脑初始化默认", {}, None
|
||||||
try:
|
try:
|
||||||
|
big_brain_actions = {
|
||||||
|
name: info
|
||||||
|
for name, info in available_actions.items()
|
||||||
|
if info.planner_type in [PlannerType.BIG_BRAIN, PlannerType.ALL]
|
||||||
|
}
|
||||||
prompt, _ = await self.build_planner_prompt(
|
prompt, _ = await self.build_planner_prompt(
|
||||||
is_group_chat=is_group_chat,
|
is_group_chat=is_group_chat,
|
||||||
chat_target_info=chat_target_info,
|
chat_target_info=chat_target_info,
|
||||||
current_available_actions={}, # 大脑不考虑具体action
|
current_available_actions=big_brain_actions,
|
||||||
mode=mode,
|
mode=mode,
|
||||||
chat_content_block_override=chat_content_block,
|
chat_content_block_override=chat_content_block,
|
||||||
message_id_list_override=message_id_list,
|
message_id_list_override=message_id_list,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from typing import Tuple, Optional, Dict, Any
|
|||||||
|
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.chat.message_receive.chat_stream import ChatStream
|
from src.chat.message_receive.chat_stream import ChatStream
|
||||||
from src.plugin_system.base.component_types import ActionActivationType, ChatMode, ActionInfo, ComponentType, ChatType
|
from src.plugin_system.base.component_types import ActionActivationType, ChatMode, ActionInfo, ComponentType, ChatType,PlannerType
|
||||||
from src.plugin_system.apis import send_api, database_api, message_api
|
from src.plugin_system.apis import send_api, database_api, message_api
|
||||||
|
|
||||||
|
|
||||||
@@ -92,6 +92,8 @@ class BaseAction(ABC):
|
|||||||
self.parallel_action: bool = getattr(self.__class__, "parallel_action", True)
|
self.parallel_action: bool = getattr(self.__class__, "parallel_action", True)
|
||||||
self.associated_types: list[str] = getattr(self.__class__, "associated_types", []).copy()
|
self.associated_types: list[str] = getattr(self.__class__, "associated_types", []).copy()
|
||||||
self.chat_type_allow: ChatType = getattr(self.__class__, "chat_type_allow", ChatType.ALL)
|
self.chat_type_allow: ChatType = getattr(self.__class__, "chat_type_allow", ChatType.ALL)
|
||||||
|
self.planner_type: PlannerType = getattr(self.__class__, "planner_type", ChatType.ALL)
|
||||||
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# 便捷属性 - 直接在初始化时获取常用聊天信息(带类型注解)
|
# 便捷属性 - 直接在初始化时获取常用聊天信息(带类型注解)
|
||||||
|
|||||||
@@ -51,6 +51,17 @@ class ChatMode(Enum):
|
|||||||
|
|
||||||
|
|
||||||
# 聊天类型枚举
|
# 聊天类型枚举
|
||||||
|
class PlannerType(Enum):
|
||||||
|
"""规划器类型枚举"""
|
||||||
|
|
||||||
|
BIG_BRAIN = "big_brain" # 大脑,负责宏观决策
|
||||||
|
SMALL_BRAIN = "small_brain" # 小脑,负责具体动作
|
||||||
|
ALL = "all" # 通用
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
|
||||||
class ChatType(Enum):
|
class ChatType(Enum):
|
||||||
"""聊天类型枚举,用于限制插件在不同聊天环境中的使用"""
|
"""聊天类型枚举,用于限制插件在不同聊天环境中的使用"""
|
||||||
|
|
||||||
@@ -140,6 +151,7 @@ class ActionInfo(ComponentInfo):
|
|||||||
mode_enable: ChatMode = ChatMode.ALL
|
mode_enable: ChatMode = ChatMode.ALL
|
||||||
parallel_action: bool = False
|
parallel_action: bool = False
|
||||||
chat_type_allow: ChatType = ChatType.ALL # 允许的聊天类型
|
chat_type_allow: ChatType = ChatType.ALL # 允许的聊天类型
|
||||||
|
planner_type: PlannerType = PlannerType.ALL
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
super().__post_init__()
|
super().__post_init__()
|
||||||
@@ -215,27 +227,7 @@ class EventInfo(ComponentInfo):
|
|||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
super().__post_init__()
|
super().__post_init__()
|
||||||
self.component_type = ComponentType.EVENT
|
self.component_type = ComponentType.EVENT_HANDLER
|
||||||
|
|
||||||
|
|
||||||
# 事件类型枚举
|
|
||||||
class EventType(Enum):
|
|
||||||
"""
|
|
||||||
事件类型枚举类
|
|
||||||
"""
|
|
||||||
|
|
||||||
ON_START = "on_start" # 启动事件,用于调用按时任务
|
|
||||||
ON_STOP = "on_stop" # 停止事件,用于调用按时任务
|
|
||||||
ON_MESSAGE = "on_message"
|
|
||||||
ON_PLAN = "on_plan"
|
|
||||||
POST_LLM = "post_llm"
|
|
||||||
AFTER_LLM = "after_llm"
|
|
||||||
POST_SEND = "post_send"
|
|
||||||
AFTER_SEND = "after_send"
|
|
||||||
UNKNOWN = "unknown" # 未知事件类型
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
return self.value
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from src.plugin_system import (
|
|||||||
)
|
)
|
||||||
from src.person_info.person_info import get_person_info_manager
|
from src.person_info.person_info import get_person_info_manager
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.plugin_system.base.component_types import ChatType
|
from src.plugin_system.base.component_types import ChatType,PlannerType
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@ class AtAction(BaseAction):
|
|||||||
activation_type = ActionActivationType.LLM_JUDGE # 消息接收时激活(?)
|
activation_type = ActionActivationType.LLM_JUDGE # 消息接收时激活(?)
|
||||||
parallel_action = False
|
parallel_action = False
|
||||||
chat_type_allow = ChatType.GROUP
|
chat_type_allow = ChatType.GROUP
|
||||||
|
planner_type = PlannerType.BIG_BRAIN
|
||||||
|
|
||||||
# === 功能描述(必须填写)===
|
# === 功能描述(必须填写)===
|
||||||
action_parameters = {"user_name": "需要艾特用户的名字", "at_message": "艾特用户时要发送的消,注意消息里不要有@"}
|
action_parameters = {"user_name": "需要艾特用户的名字", "at_message": "艾特用户时要发送的消,注意消息里不要有@"}
|
||||||
|
|||||||
Reference in New Issue
Block a user