feat:将action选择从处理器转变为单独阶段,增加action使用的准确性

This commit is contained in:
SengokuCola
2025-05-29 10:16:34 +08:00
parent 3cf7776966
commit b551710c13
8 changed files with 114 additions and 73 deletions

View File

@@ -16,16 +16,18 @@ from src.chat.focus_chat.info.info_base import InfoBase
from src.chat.focus_chat.info_processors.chattinginfo_processor import ChattingInfoProcessor
from src.chat.focus_chat.info_processors.mind_processor import MindProcessor
from src.chat.focus_chat.info_processors.working_memory_processor import WorkingMemoryProcessor
from src.chat.focus_chat.info_processors.action_processor import ActionProcessor
# from src.chat.focus_chat.info_processors.action_processor import ActionProcessor
from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation
from src.chat.heart_flow.observation.working_observation import WorkingMemoryObservation
from src.chat.heart_flow.observation.structure_observation import StructureObservation
from src.chat.heart_flow.observation.actions_observation import ActionObservation
from src.chat.focus_chat.info_processors.tool_processor import ToolProcessor
from src.chat.focus_chat.expressors.default_expressor import DefaultExpressor
from src.chat.focus_chat.memory_activator import MemoryActivator
from src.chat.focus_chat.info_processors.base_processor import BaseProcessor
from src.chat.focus_chat.info_processors.self_processor import SelfProcessor
from src.chat.focus_chat.planners.planner import ActionPlanner
from src.chat.focus_chat.planners.modify_actions import ActionModifier
from src.chat.focus_chat.planners.action_manager import ActionManager
from src.chat.focus_chat.working_memory.working_memory import WorkingMemory
from src.config.config import global_config
@@ -41,7 +43,7 @@ PROCESSOR_CLASSES = {
"ToolProcessor": (ToolProcessor, "tool_use_processor"),
"WorkingMemoryProcessor": (WorkingMemoryProcessor, "working_memory_processor"),
"SelfProcessor": (SelfProcessor, "self_identify_processor"),
"ActionProcessor": (ActionProcessor, "action_processor"), # 这个处理器不需要配置键名,默认启用
# "ActionProcessor": (ActionProcessor, "action_processor"), # 这个处理器不需要配置键名,默认启用
}
@@ -129,8 +131,10 @@ class HeartFChatting:
self.expressor = DefaultExpressor(chat_id=self.stream_id)
self.action_manager = ActionManager()
self.action_planner = ActionPlanner(log_prefix=self.log_prefix, action_manager=self.action_manager)
self.action_modifier = ActionModifier(action_manager=self.action_manager)
self.action_observation = ActionObservation(observe_id=self.stream_id)
self.hfcloop_observation.set_action_manager(self.action_manager)
self.action_observation.set_action_manager(self.action_manager)
self.all_observations = observations
@@ -470,6 +474,12 @@ class HeartFChatting:
with Timer("回忆", cycle_timers):
running_memorys = await self.memory_activator.activate_memory(observations)
with Timer("调整动作", cycle_timers):
# 处理特殊的观察
await self.action_modifier.modify_actions(observations=observations, running_memorys=running_memorys)
await self.action_observation.observe()
observations.append(self.action_observation)
with Timer("执行 信息处理器", cycle_timers):
all_plan_info, processor_time_costs = await self._process_processors(observations, running_memorys, cycle_timers)

View File

@@ -14,6 +14,7 @@ from .base_processor import BaseProcessor
from src.chat.focus_chat.info.mind_info import MindInfo
from typing import List, Optional
from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation
from src.chat.heart_flow.observation.actions_observation import ActionObservation
from typing import Dict
from src.chat.focus_chat.info.info_base import InfoBase
@@ -30,6 +31,8 @@ def init_prompt():
现在是{time_now}你正在上网和qq群里的网友们聊天以下是正在进行的聊天内容
{chat_observe_info}
{action_observe_info}
以下是你之前对聊天的观察和规划,你的名字是{bot_name}
{last_mind}
@@ -50,6 +53,8 @@ def init_prompt():
现在是{time_now}你正在上网和qq群里的网友们聊天以下是正在进行的聊天内容
{chat_observe_info}
{action_observe_info}
以下是你之前对聊天的观察和规划,你的名字是{bot_name}
{last_mind}
@@ -191,6 +196,8 @@ class MindProcessor(BaseProcessor):
person_list = observation.person_list
if isinstance(observation, HFCloopObservation):
hfcloop_observe_info = observation.get_observe_info()
if isinstance(observation, ActionObservation):
action_observe_info = observation.get_observe_info()
# ---------- 3. 准备个性化数据 ----------
# 获取个性化信息
@@ -211,6 +218,7 @@ class MindProcessor(BaseProcessor):
chat_observe_info=chat_observe_info,
last_mind=previous_mind,
cycle_info_block=hfcloop_observe_info,
action_observe_info=action_observe_info,
chat_target_name=chat_target_name,
)

View File

@@ -2,7 +2,7 @@ from typing import List, Optional, Any
from src.chat.heart_flow.observation.observation import Observation
from src.chat.focus_chat.info.info_base import InfoBase
from src.chat.focus_chat.info.action_info import ActionInfo
from .base_processor import BaseProcessor
from ..info_processors.base_processor import BaseProcessor
from src.common.logger_manager import get_logger
from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation
from src.chat.heart_flow.observation.chatting_observation import ChattingObservation
@@ -10,45 +10,38 @@ from src.chat.message_receive.chat_stream import chat_manager
from typing import Dict
from src.config.config import global_config
import random
from src.chat.focus_chat.planners.action_manager import ActionManager
logger = get_logger("processor")
logger = get_logger("action_manager")
class ActionProcessor(BaseProcessor):
class ActionModifier():
"""动作处理器
用于处理Observation对象将其转换为ObsInfo对象
"""
log_prefix = "动作处理"
def __init__(self):
def __init__(self, action_manager: ActionManager):
"""初始化观察处理器"""
super().__init__()
self.action_manager = action_manager
self.all_actions = self.action_manager.get_registered_actions()
async def process_info(
async def modify_actions(
self,
observations: Optional[List[Observation]] = None,
running_memorys: Optional[List[Dict]] = None,
**kwargs: Any,
) -> List[InfoBase]:
"""处理Observation对象
Args:
infos: InfoBase对象列表
observations: 可选的Observation对象列表
**kwargs: 其他可选参数
Returns:
List[InfoBase]: 处理后的ObsInfo实例列表
"""
):
# print(f"observations: {observations}")
processed_infos = []
# processed_infos = []
# 处理Observation对象
if observations:
action_info = ActionInfo()
all_actions = None
# action_info = ActionInfo()
# all_actions = None
hfc_obs = None
chat_obs = None
@@ -66,7 +59,7 @@ class ActionProcessor(BaseProcessor):
# 处理HFCloopObservation
if hfc_obs:
obs = hfc_obs
all_actions = obs.all_actions
all_actions = self.all_actions
action_changes = await self.analyze_loop_actions(obs)
if action_changes["add"] or action_changes["remove"]:
# 合并动作变更
@@ -74,13 +67,13 @@ class ActionProcessor(BaseProcessor):
merged_action_changes["remove"].extend(action_changes["remove"])
# 收集变更原因
if action_changes["add"]:
reasons.append(f"添加动作{action_changes['add']}因为检测到大量无回复")
if action_changes["remove"]:
reasons.append(f"移除动作{action_changes['remove']}因为检测到连续回复")
# if action_changes["add"]:
# reasons.append(f"添加动作{action_changes['add']}因为检测到大量无回复")
# if action_changes["remove"]:
# reasons.append(f"移除动作{action_changes['remove']}因为检测到连续回复")
# 处理ChattingObservation
if chat_obs and all_actions is not None:
if chat_obs :
obs = chat_obs
# 检查动作的关联类型
chat_context = chat_manager.get_stream(obs.chat_id).context
@@ -98,14 +91,23 @@ class ActionProcessor(BaseProcessor):
merged_action_changes["remove"].extend(type_mismatched_actions)
reasons.append(f"移除动作{type_mismatched_actions}因为关联类型不匹配")
for action_name in merged_action_changes["add"]:
if action_name in self.action_manager.get_registered_actions():
self.action_manager.add_action_to_using(action_name)
logger.debug(f"{self.log_prefix} 添加动作: {action_name}, 原因: {reasons}")
for action_name in merged_action_changes["remove"]:
self.action_manager.remove_action_from_using(action_name)
logger.debug(f"{self.log_prefix} 移除动作: {action_name}, 原因: {reasons}")
# 如果有任何动作变更设置到action_info中
if merged_action_changes["add"] or merged_action_changes["remove"]:
action_info.set_action_changes(merged_action_changes)
action_info.set_reason(" | ".join(reasons))
# if merged_action_changes["add"] or merged_action_changes["remove"]:
# action_info.set_action_changes(merged_action_changes)
# action_info.set_reason(" | ".join(reasons))
processed_infos.append(action_info)
# processed_infos.append(action_info)
return processed_infos
# return processed_infos
async def analyze_loop_actions(self, obs: HFCloopObservation) -> Dict[str, List[str]]:
"""分析最近的循环内容并决定动作的增减

View File

@@ -101,29 +101,26 @@ class ActionPlanner:
# 获取观察信息
extra_info: list[str] = []
# 首先处理动作变更
for info in all_plan_info:
if isinstance(info, ActionInfo) and info.has_changes():
add_actions = info.get_add_actions()
remove_actions = info.get_remove_actions()
reason = info.get_reason()
print(f"{self.log_prefix} 动作变更: {add_actions} {remove_actions} {reason}")
# # 首先处理动作变更
# for info in all_plan_info:
# if isinstance(info, ActionInfo) and info.has_changes():
# add_actions = info.get_add_actions()
# remove_actions = info.get_remove_actions()
# reason = info.get_reason()
# print(f"{self.log_prefix} 动作变更: {add_actions} {remove_actions} {reason}")
# 处理动作的增加
for action_name in add_actions:
if action_name in self.action_manager.get_registered_actions():
self.action_manager.add_action_to_using(action_name)
logger.debug(f"{self.log_prefix}添加动作: {action_name}, 原因: {reason}")
# # 处理动作的增加
# for action_name in add_actions:
# if action_name in self.action_manager.get_registered_actions():
# self.action_manager.add_action_to_using(action_name)
# logger.debug(f"{self.log_prefix}添加动作: {action_name}, 原因: {reason}")
# # 处理动作的移除
# for action_name in remove_actions:
# self.action_manager.remove_action_from_using(action_name)
# logger.debug(f"{self.log_prefix}移除动作: {action_name}, 原因: {reason}")
# 处理动作的移除
for action_name in remove_actions:
self.action_manager.remove_action_from_using(action_name)
logger.debug(f"{self.log_prefix}移除动作: {action_name}, 原因: {reason}")
# 如果当前选择的动作被移除了更新为no_reply
if action in remove_actions:
action = "no_reply"
reasoning = f"之前选择的动作{action}已被移除,原因: {reason}"
# 继续处理其他信息
self_info = ""
@@ -146,8 +143,8 @@ class ActionPlanner:
elif isinstance(info, StructuredInfo):
structured_info = info.get_processed_info()
# print(f"structured_info: {structured_info}")
elif not isinstance(info, ActionInfo): # 跳过已处理的ActionInfo
extra_info.append(info.get_processed_info())
# elif not isinstance(info, ActionInfo): # 跳过已处理的ActionInfo
# extra_info.append(info.get_processed_info())
# 获取当前可用的动作
current_available_actions = self.action_manager.get_using_actions()

View File

@@ -0,0 +1,36 @@
# 定义了来自外部世界的信息
# 外部世界可以是某个聊天 不同平台的聊天 也可以是任意媒体
from datetime import datetime
from src.common.logger_manager import get_logger
from src.chat.focus_chat.planners.action_manager import ActionManager
logger = get_logger("observation")
# 特殊的观察,专门用于观察动作
# 所有观察的基类
class ActionObservation:
def __init__(self, observe_id):
self.observe_info = ""
self.observe_id = observe_id
self.last_observe_time = datetime.now().timestamp() # 初始化为当前时间
self.action_manager: ActionManager = None
self.all_actions = {}
self.all_using_actions = {}
def get_observe_info(self):
return self.observe_info
def set_action_manager(self, action_manager: ActionManager):
self.action_manager = action_manager
self.all_actions = self.action_manager.get_registered_actions()
async def observe(self):
action_info_block = ""
self.all_using_actions = self.action_manager.get_using_actions()
for action_name, action_info in self.all_using_actions.items():
action_info_block += f"\n{action_name}: {action_info.get('description', '')}"
action_info_block += f"\n注意,除了上面动作选项之外,你在群聊里不能做其他任何事情,这是你能力的边界\n"
self.observe_info = action_info_block

View File

@@ -17,9 +17,6 @@ class HFCloopObservation:
self.observe_id = observe_id
self.last_observe_time = datetime.now().timestamp() # 初始化为当前时间
self.history_loop: List[CycleDetail] = []
self.action_manager: ActionManager = None
self.all_actions = {}
def get_observe_info(self):
return self.observe_info
@@ -27,10 +24,6 @@ class HFCloopObservation:
def add_loop_info(self, loop_info: CycleDetail):
self.history_loop.append(loop_info)
def set_action_manager(self, action_manager: ActionManager):
self.action_manager = action_manager
self.all_actions = self.action_manager.get_registered_actions()
async def observe(self):
recent_active_cycles: List[CycleDetail] = []
for cycle in reversed(self.history_loop):

View File

@@ -2,14 +2,16 @@ HOST=127.0.0.1
PORT=8000
#key and url
CHAT_ANY_WHERE_BASE_URL=https://api.chatanywhere.tech/v1
SILICONFLOW_BASE_URL=https://api.siliconflow.cn/v1/
DEEP_SEEK_BASE_URL=https://api.deepseek.com/v1
CHAT_ANY_WHERE_BASE_URL=https://api.chatanywhere.tech/v1
xxxxxxx_BASE_URL=https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# 定义你要用的api的key(需要去对应网站申请哦)
DEEP_SEEK_KEY=
CHAT_ANY_WHERE_KEY=
SILICONFLOW_KEY=
xxxxxxx_KEY=
# 定义日志相关配置
@@ -22,8 +24,8 @@ CONSOLE_LOG_LEVEL=INFO
# 自定义日志的默认文件输出日志级别
FILE_LOG_LEVEL=DEBUG
# 原生日志的控制台输出日志级别nonebot就是这一类
# 原生日志的控制台输出日志级别
DEFAULT_CONSOLE_LOG_LEVEL=SUCCESS
# 原生日志的默认文件输出日志级别nonebot就是这一类
# 原生日志的默认文件输出日志级别
DEFAULT_FILE_LOG_LEVEL=DEBUG

View File

@@ -1,7 +0,0 @@
from src.config.config import global_config
class TestConfig:
def test_load(self):
config = global_config
print(config)