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

pull/1002/head
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.chattinginfo_processor import ChattingInfoProcessor
from src.chat.focus_chat.info_processors.mind_processor import MindProcessor 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.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.hfcloop_observation import HFCloopObservation
from src.chat.heart_flow.observation.working_observation import WorkingMemoryObservation 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.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.info_processors.tool_processor import ToolProcessor
from src.chat.focus_chat.expressors.default_expressor import DefaultExpressor from src.chat.focus_chat.expressors.default_expressor import DefaultExpressor
from src.chat.focus_chat.memory_activator import MemoryActivator 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.base_processor import BaseProcessor
from src.chat.focus_chat.info_processors.self_processor import SelfProcessor 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.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.planners.action_manager import ActionManager
from src.chat.focus_chat.working_memory.working_memory import WorkingMemory from src.chat.focus_chat.working_memory.working_memory import WorkingMemory
from src.config.config import global_config from src.config.config import global_config
@ -41,7 +43,7 @@ PROCESSOR_CLASSES = {
"ToolProcessor": (ToolProcessor, "tool_use_processor"), "ToolProcessor": (ToolProcessor, "tool_use_processor"),
"WorkingMemoryProcessor": (WorkingMemoryProcessor, "working_memory_processor"), "WorkingMemoryProcessor": (WorkingMemoryProcessor, "working_memory_processor"),
"SelfProcessor": (SelfProcessor, "self_identify_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.expressor = DefaultExpressor(chat_id=self.stream_id)
self.action_manager = ActionManager() self.action_manager = ActionManager()
self.action_planner = ActionPlanner(log_prefix=self.log_prefix, action_manager=self.action_manager) 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 self.all_observations = observations
@ -470,6 +474,12 @@ class HeartFChatting:
with Timer("回忆", cycle_timers): with Timer("回忆", cycle_timers):
running_memorys = await self.memory_activator.activate_memory(observations) 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): with Timer("执行 信息处理器", cycle_timers):
all_plan_info, processor_time_costs = await self._process_processors(observations, running_memorys, 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 src.chat.focus_chat.info.mind_info import MindInfo
from typing import List, Optional from typing import List, Optional
from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation 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 typing import Dict
from src.chat.focus_chat.info.info_base import InfoBase from src.chat.focus_chat.info.info_base import InfoBase
@ -30,6 +31,8 @@ def init_prompt():
现在是{time_now}你正在上网和qq群里的网友们聊天以下是正在进行的聊天内容 现在是{time_now}你正在上网和qq群里的网友们聊天以下是正在进行的聊天内容
{chat_observe_info} {chat_observe_info}
{action_observe_info}
以下是你之前对聊天的观察和规划你的名字是{bot_name} 以下是你之前对聊天的观察和规划你的名字是{bot_name}
{last_mind} {last_mind}
@ -50,6 +53,8 @@ def init_prompt():
现在是{time_now}你正在上网和qq群里的网友们聊天以下是正在进行的聊天内容 现在是{time_now}你正在上网和qq群里的网友们聊天以下是正在进行的聊天内容
{chat_observe_info} {chat_observe_info}
{action_observe_info}
以下是你之前对聊天的观察和规划你的名字是{bot_name} 以下是你之前对聊天的观察和规划你的名字是{bot_name}
{last_mind} {last_mind}
@ -191,6 +196,8 @@ class MindProcessor(BaseProcessor):
person_list = observation.person_list person_list = observation.person_list
if isinstance(observation, HFCloopObservation): if isinstance(observation, HFCloopObservation):
hfcloop_observe_info = observation.get_observe_info() hfcloop_observe_info = observation.get_observe_info()
if isinstance(observation, ActionObservation):
action_observe_info = observation.get_observe_info()
# ---------- 3. 准备个性化数据 ---------- # ---------- 3. 准备个性化数据 ----------
# 获取个性化信息 # 获取个性化信息
@ -211,6 +218,7 @@ class MindProcessor(BaseProcessor):
chat_observe_info=chat_observe_info, chat_observe_info=chat_observe_info,
last_mind=previous_mind, last_mind=previous_mind,
cycle_info_block=hfcloop_observe_info, cycle_info_block=hfcloop_observe_info,
action_observe_info=action_observe_info,
chat_target_name=chat_target_name, 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.heart_flow.observation.observation import Observation
from src.chat.focus_chat.info.info_base import InfoBase from src.chat.focus_chat.info.info_base import InfoBase
from src.chat.focus_chat.info.action_info import ActionInfo 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.common.logger_manager import get_logger
from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation
from src.chat.heart_flow.observation.chatting_observation import ChattingObservation 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 typing import Dict
from src.config.config import global_config from src.config.config import global_config
import random 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对象 用于处理Observation对象将其转换为ObsInfo对象
""" """
log_prefix = "动作处理" 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, self,
observations: Optional[List[Observation]] = None, observations: Optional[List[Observation]] = None,
running_memorys: Optional[List[Dict]] = None, running_memorys: Optional[List[Dict]] = None,
**kwargs: Any, **kwargs: Any,
) -> List[InfoBase]: ):
"""处理Observation对象
Args:
infos: InfoBase对象列表
observations: 可选的Observation对象列表
**kwargs: 其他可选参数
Returns:
List[InfoBase]: 处理后的ObsInfo实例列表
"""
# print(f"observations: {observations}") # print(f"observations: {observations}")
processed_infos = [] # processed_infos = []
# 处理Observation对象 # 处理Observation对象
if observations: if observations:
action_info = ActionInfo() # action_info = ActionInfo()
all_actions = None # all_actions = None
hfc_obs = None hfc_obs = None
chat_obs = None chat_obs = None
@ -66,7 +59,7 @@ class ActionProcessor(BaseProcessor):
# 处理HFCloopObservation # 处理HFCloopObservation
if hfc_obs: if hfc_obs:
obs = hfc_obs obs = hfc_obs
all_actions = obs.all_actions all_actions = self.all_actions
action_changes = await self.analyze_loop_actions(obs) action_changes = await self.analyze_loop_actions(obs)
if action_changes["add"] or action_changes["remove"]: if action_changes["add"] or action_changes["remove"]:
# 合并动作变更 # 合并动作变更
@ -74,13 +67,13 @@ class ActionProcessor(BaseProcessor):
merged_action_changes["remove"].extend(action_changes["remove"]) merged_action_changes["remove"].extend(action_changes["remove"])
# 收集变更原因 # 收集变更原因
if action_changes["add"]: # if action_changes["add"]:
reasons.append(f"添加动作{action_changes['add']}因为检测到大量无回复") # reasons.append(f"添加动作{action_changes['add']}因为检测到大量无回复")
if action_changes["remove"]: # if action_changes["remove"]:
reasons.append(f"移除动作{action_changes['remove']}因为检测到连续回复") # reasons.append(f"移除动作{action_changes['remove']}因为检测到连续回复")
# 处理ChattingObservation # 处理ChattingObservation
if chat_obs and all_actions is not None: if chat_obs :
obs = chat_obs obs = chat_obs
# 检查动作的关联类型 # 检查动作的关联类型
chat_context = chat_manager.get_stream(obs.chat_id).context 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) merged_action_changes["remove"].extend(type_mismatched_actions)
reasons.append(f"移除动作{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中 # 如果有任何动作变更设置到action_info中
if merged_action_changes["add"] or merged_action_changes["remove"]: # if merged_action_changes["add"] or merged_action_changes["remove"]:
action_info.set_action_changes(merged_action_changes) # action_info.set_action_changes(merged_action_changes)
action_info.set_reason(" | ".join(reasons)) # 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]]: async def analyze_loop_actions(self, obs: HFCloopObservation) -> Dict[str, List[str]]:
"""分析最近的循环内容并决定动作的增减 """分析最近的循环内容并决定动作的增减

View File

@ -101,29 +101,26 @@ class ActionPlanner:
# 获取观察信息 # 获取观察信息
extra_info: list[str] = [] extra_info: list[str] = []
# 首先处理动作变更 # # 首先处理动作变更
for info in all_plan_info: # for info in all_plan_info:
if isinstance(info, ActionInfo) and info.has_changes(): # if isinstance(info, ActionInfo) and info.has_changes():
add_actions = info.get_add_actions() # add_actions = info.get_add_actions()
remove_actions = info.get_remove_actions() # remove_actions = info.get_remove_actions()
reason = info.get_reason() # reason = info.get_reason()
print(f"{self.log_prefix} 动作变更: {add_actions} {remove_actions} {reason}") # print(f"{self.log_prefix} 动作变更: {add_actions} {remove_actions} {reason}")
# 处理动作的增加 # # 处理动作的增加
for action_name in add_actions: # for action_name in add_actions:
if action_name in self.action_manager.get_registered_actions(): # if action_name in self.action_manager.get_registered_actions():
self.action_manager.add_action_to_using(action_name) # self.action_manager.add_action_to_using(action_name)
logger.debug(f"{self.log_prefix}添加动作: {action_name}, 原因: {reason}") # 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 = "" self_info = ""
@ -146,8 +143,8 @@ class ActionPlanner:
elif isinstance(info, StructuredInfo): elif isinstance(info, StructuredInfo):
structured_info = info.get_processed_info() structured_info = info.get_processed_info()
# print(f"structured_info: {structured_info}") # print(f"structured_info: {structured_info}")
elif not isinstance(info, ActionInfo): # 跳过已处理的ActionInfo # elif not isinstance(info, ActionInfo): # 跳过已处理的ActionInfo
extra_info.append(info.get_processed_info()) # extra_info.append(info.get_processed_info())
# 获取当前可用的动作 # 获取当前可用的动作
current_available_actions = self.action_manager.get_using_actions() 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.observe_id = observe_id
self.last_observe_time = datetime.now().timestamp() # 初始化为当前时间 self.last_observe_time = datetime.now().timestamp() # 初始化为当前时间
self.history_loop: List[CycleDetail] = [] self.history_loop: List[CycleDetail] = []
self.action_manager: ActionManager = None
self.all_actions = {}
def get_observe_info(self): def get_observe_info(self):
return self.observe_info return self.observe_info
@ -27,10 +24,6 @@ class HFCloopObservation:
def add_loop_info(self, loop_info: CycleDetail): def add_loop_info(self, loop_info: CycleDetail):
self.history_loop.append(loop_info) 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): async def observe(self):
recent_active_cycles: List[CycleDetail] = [] recent_active_cycles: List[CycleDetail] = []
for cycle in reversed(self.history_loop): for cycle in reversed(self.history_loop):

View File

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