better:更好的重新思考修复复读,记录循环信息,拆分模型配置
This commit is contained in:
@@ -192,7 +192,6 @@ class BotConfig:
|
|||||||
reply_trigger_threshold: float = 3.0 # 心流聊天触发阈值,越低越容易触发
|
reply_trigger_threshold: float = 3.0 # 心流聊天触发阈值,越低越容易触发
|
||||||
probability_decay_factor_per_second: float = 0.2 # 概率衰减因子,越大衰减越快
|
probability_decay_factor_per_second: float = 0.2 # 概率衰减因子,越大衰减越快
|
||||||
default_decay_rate_per_second: float = 0.98 # 默认衰减率,越大衰减越慢
|
default_decay_rate_per_second: float = 0.98 # 默认衰减率,越大衰减越慢
|
||||||
initial_duration: int = 60 # 初始持续时间,越大心流聊天持续的时间越长
|
|
||||||
|
|
||||||
# sub_heart_flow_update_interval: int = 60 # 子心流更新频率,间隔 单位秒
|
# sub_heart_flow_update_interval: int = 60 # 子心流更新频率,间隔 单位秒
|
||||||
# sub_heart_flow_freeze_time: int = 120 # 子心流冻结时间,超过这个时间没有回复,子心流会冻结,间隔 单位秒
|
# sub_heart_flow_freeze_time: int = 120 # 子心流冻结时间,超过这个时间没有回复,子心流会冻结,间隔 单位秒
|
||||||
@@ -286,11 +285,11 @@ class BotConfig:
|
|||||||
vlm: Dict[str, str] = field(default_factory=lambda: {})
|
vlm: Dict[str, str] = field(default_factory=lambda: {})
|
||||||
moderation: Dict[str, str] = field(default_factory=lambda: {})
|
moderation: Dict[str, str] = field(default_factory=lambda: {})
|
||||||
|
|
||||||
# 实验性
|
|
||||||
llm_observation: Dict[str, str] = field(default_factory=lambda: {})
|
llm_observation: Dict[str, str] = field(default_factory=lambda: {})
|
||||||
llm_sub_heartflow: Dict[str, str] = field(default_factory=lambda: {})
|
llm_sub_heartflow: Dict[str, str] = field(default_factory=lambda: {})
|
||||||
llm_heartflow: Dict[str, str] = field(default_factory=lambda: {})
|
llm_heartflow: Dict[str, str] = field(default_factory=lambda: {})
|
||||||
llm_tool_use: Dict[str, str] = field(default_factory=lambda: {})
|
llm_tool_use: Dict[str, str] = field(default_factory=lambda: {})
|
||||||
|
llm_plan: Dict[str, str] = field(default_factory=lambda: {})
|
||||||
|
|
||||||
api_urls: Dict[str, str] = field(default_factory=lambda: {})
|
api_urls: Dict[str, str] = field(default_factory=lambda: {})
|
||||||
|
|
||||||
@@ -448,7 +447,6 @@ class BotConfig:
|
|||||||
config.default_decay_rate_per_second = heartflow_config.get(
|
config.default_decay_rate_per_second = heartflow_config.get(
|
||||||
"default_decay_rate_per_second", config.default_decay_rate_per_second
|
"default_decay_rate_per_second", config.default_decay_rate_per_second
|
||||||
)
|
)
|
||||||
config.initial_duration = heartflow_config.get("initial_duration", config.initial_duration)
|
|
||||||
|
|
||||||
def willing(parent: dict):
|
def willing(parent: dict):
|
||||||
willing_config = parent["willing"]
|
willing_config = parent["willing"]
|
||||||
@@ -489,6 +487,7 @@ class BotConfig:
|
|||||||
"llm_tool_use",
|
"llm_tool_use",
|
||||||
"llm_observation",
|
"llm_observation",
|
||||||
"llm_sub_heartflow",
|
"llm_sub_heartflow",
|
||||||
|
"llm_plan",
|
||||||
"llm_heartflow",
|
"llm_heartflow",
|
||||||
"llm_PFC_action_planner",
|
"llm_PFC_action_planner",
|
||||||
"llm_PFC_chat",
|
"llm_PFC_chat",
|
||||||
|
|||||||
@@ -230,8 +230,8 @@ class BackgroundTaskManager:
|
|||||||
if await self.subheartflow_manager.stop_subheartflow(flow_id, f"定期清理: {reason}"):
|
if await self.subheartflow_manager.stop_subheartflow(flow_id, f"定期清理: {reason}"):
|
||||||
stopped_count += 1
|
stopped_count += 1
|
||||||
logger.info(f"[Background Task Cleanup] Cleanup cycle finished. Stopped {stopped_count} inactive flows.")
|
logger.info(f"[Background Task Cleanup] Cleanup cycle finished. Stopped {stopped_count} inactive flows.")
|
||||||
else:
|
# else:
|
||||||
logger.debug("[Background Task Cleanup] Cleanup cycle finished. No inactive flows found.")
|
# logger.debug("[Background Task Cleanup] Cleanup cycle finished. No inactive flows found.")
|
||||||
|
|
||||||
async def _perform_logging_work(self):
|
async def _perform_logging_work(self):
|
||||||
"""执行一轮状态日志记录。"""
|
"""执行一轮状态日志记录。"""
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from src.do_tool.tool_use import ToolUser
|
|||||||
from src.plugins.utils.json_utils import safe_json_dumps, normalize_llm_response, process_llm_tool_calls
|
from src.plugins.utils.json_utils import safe_json_dumps, normalize_llm_response, process_llm_tool_calls
|
||||||
from src.heart_flow.chat_state_info import ChatStateInfo
|
from src.heart_flow.chat_state_info import ChatStateInfo
|
||||||
from src.plugins.chat.chat_stream import chat_manager
|
from src.plugins.chat.chat_stream import chat_manager
|
||||||
|
from src.plugins.heartFC_chat.heartFC_Cycleinfo import CycleInfo
|
||||||
|
|
||||||
subheartflow_config = LogConfig(
|
subheartflow_config = LogConfig(
|
||||||
console_format=SUB_HEARTFLOW_STYLE_CONFIG["console_format"],
|
console_format=SUB_HEARTFLOW_STYLE_CONFIG["console_format"],
|
||||||
@@ -23,12 +24,12 @@ def init_prompt():
|
|||||||
prompt = ""
|
prompt = ""
|
||||||
prompt += "{extra_info}\n"
|
prompt += "{extra_info}\n"
|
||||||
prompt += "{prompt_personality}\n"
|
prompt += "{prompt_personality}\n"
|
||||||
prompt += "刚刚你的内心想法是:{current_thinking_info}\n"
|
prompt += "{last_loop_prompt}\n"
|
||||||
prompt += "-----------------------------------\n"
|
prompt += "-----------------------------------\n"
|
||||||
prompt += "现在是{time_now},你正在上网,和qq群里的网友们聊天,以下是正在进行的聊天内容:\n{chat_observe_info}\n"
|
prompt += "现在是{time_now},你正在上网,和qq群里的网友们聊天,以下是正在进行的聊天内容:\n{chat_observe_info}\n"
|
||||||
prompt += "\n你现在{mood_info}\n"
|
prompt += "\n你现在{mood_info}\n"
|
||||||
prompt += "现在请你生成你的内心想法,要求思考群里正在进行的话题,之前大家聊过的话题,群里成员的关系。"
|
prompt += "现在请你,阅读群里正在进行的聊天内容,思考群里的正在进行的话题,分析群里成员与你的关系。"
|
||||||
prompt += "请你思考,要不要对群里的话题进行回复,以及如何对群聊内容进行回复\n"
|
prompt += "请你思考,生成你的内心想法,包括你的思考,要不要对群里的话题进行回复,以及如何对群聊内容进行回复\n"
|
||||||
prompt += "回复的要求是:不要总是重复自己提到过的话题,如果你要回复,最好只回复一个人的一个话题\n"
|
prompt += "回复的要求是:不要总是重复自己提到过的话题,如果你要回复,最好只回复一个人的一个话题\n"
|
||||||
prompt += "如果最后一条消息是你自己发的,观察到的内容只有你自己的发言,并且之后没有人回复你,不要回复。"
|
prompt += "如果最后一条消息是你自己发的,观察到的内容只有你自己的发言,并且之后没有人回复你,不要回复。"
|
||||||
prompt += "如果聊天记录中最新的消息是你自己发送的,并且你还想继续回复,你应该紧紧衔接你发送的消息,进行话题的深入,补充,或追问等等。"
|
prompt += "如果聊天记录中最新的消息是你自己发送的,并且你还想继续回复,你应该紧紧衔接你发送的消息,进行话题的深入,补充,或追问等等。"
|
||||||
@@ -39,6 +40,12 @@ def init_prompt():
|
|||||||
|
|
||||||
Prompt(prompt, "sub_heartflow_prompt_before")
|
Prompt(prompt, "sub_heartflow_prompt_before")
|
||||||
|
|
||||||
|
prompt = ""
|
||||||
|
prompt += "刚刚你的内心想法是:{current_thinking_info}\n"
|
||||||
|
prompt += "{if_replan_prompt}\n"
|
||||||
|
|
||||||
|
Prompt(prompt, "last_loop")
|
||||||
|
|
||||||
|
|
||||||
class SubMind:
|
class SubMind:
|
||||||
def __init__(self, subheartflow_id: str, chat_state: ChatStateInfo, observations: Observation):
|
def __init__(self, subheartflow_id: str, chat_state: ChatStateInfo, observations: Observation):
|
||||||
@@ -58,7 +65,7 @@ class SubMind:
|
|||||||
self.past_mind = []
|
self.past_mind = []
|
||||||
self.structured_info = {}
|
self.structured_info = {}
|
||||||
|
|
||||||
async def do_thinking_before_reply(self):
|
async def do_thinking_before_reply(self, last_cycle: CycleInfo):
|
||||||
"""
|
"""
|
||||||
在回复前进行思考,生成内心想法并收集工具调用结果
|
在回复前进行思考,生成内心想法并收集工具调用结果
|
||||||
|
|
||||||
@@ -122,6 +129,20 @@ class SubMind:
|
|||||||
("继续生成你在这个聊天中的想法,进行深入思考", 0.1),
|
("继续生成你在这个聊天中的想法,进行深入思考", 0.1),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
#上一次决策信息
|
||||||
|
last_action = last_cycle.action_type
|
||||||
|
last_reasoning = last_cycle.reasoning
|
||||||
|
is_replan = last_cycle.replanned
|
||||||
|
if is_replan:
|
||||||
|
if_replan_prompt = f"但是你有了上述想法之后,有了新消息,你决定重新思考后,你做了:{last_action}\n因为:{last_reasoning}\n"
|
||||||
|
else:
|
||||||
|
if_replan_prompt = f"出于这个想法,你刚才做了:{last_action}\n因为:{last_reasoning}\n"
|
||||||
|
|
||||||
|
last_loop_prompt = (await global_prompt_manager.get_prompt_async("last_loop")).format(
|
||||||
|
current_thinking_info=current_thinking_info,
|
||||||
|
if_replan_prompt=if_replan_prompt
|
||||||
|
)
|
||||||
|
|
||||||
# 加权随机选择思考指导
|
# 加权随机选择思考指导
|
||||||
hf_do_next = local_random.choices(
|
hf_do_next = local_random.choices(
|
||||||
[option[0] for option in hf_options], weights=[option[1] for option in hf_options], k=1
|
[option[0] for option in hf_options], weights=[option[1] for option in hf_options], k=1
|
||||||
@@ -133,11 +154,11 @@ class SubMind:
|
|||||||
extra_info="", # 可以在这里添加额外信息
|
extra_info="", # 可以在这里添加额外信息
|
||||||
prompt_personality=prompt_personality,
|
prompt_personality=prompt_personality,
|
||||||
bot_name=individuality.personality.bot_nickname,
|
bot_name=individuality.personality.bot_nickname,
|
||||||
current_thinking_info=current_thinking_info,
|
|
||||||
time_now=time_now,
|
time_now=time_now,
|
||||||
chat_observe_info=chat_observe_info,
|
chat_observe_info=chat_observe_info,
|
||||||
mood_info=mood_info,
|
mood_info=mood_info,
|
||||||
hf_do_next=hf_do_next,
|
hf_do_next=hf_do_next,
|
||||||
|
last_loop_prompt=last_loop_prompt
|
||||||
)
|
)
|
||||||
|
|
||||||
# logger.debug(f"[{self.subheartflow_id}] 心流思考提示词构建完成")
|
# logger.debug(f"[{self.subheartflow_id}] 心流思考提示词构建完成")
|
||||||
|
|||||||
70
src/plugins/heartFC_chat/heartFC_Cycleinfo.py
Normal file
70
src/plugins/heartFC_chat/heartFC_Cycleinfo.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import time
|
||||||
|
from typing import List, Optional, Dict, Any
|
||||||
|
|
||||||
|
class CycleInfo:
|
||||||
|
"""循环信息记录类"""
|
||||||
|
def __init__(self, cycle_id: int):
|
||||||
|
self.cycle_id = cycle_id
|
||||||
|
self.start_time = time.time()
|
||||||
|
self.end_time: Optional[float] = None
|
||||||
|
self.action_taken = False
|
||||||
|
self.action_type = "unknown"
|
||||||
|
self.reasoning = ""
|
||||||
|
self.timers: Dict[str, float] = {}
|
||||||
|
self.thinking_id = ""
|
||||||
|
self.replanned = False
|
||||||
|
|
||||||
|
# 添加响应信息相关字段
|
||||||
|
self.response_info: Dict[str, Any] = {
|
||||||
|
"response_text": [], # 回复的文本列表
|
||||||
|
"emoji_info": "", # 表情信息
|
||||||
|
"anchor_message_id": "", # 锚点消息ID
|
||||||
|
"reply_message_ids": [], # 回复消息ID列表
|
||||||
|
"sub_mind_thinking": "", # 子思维思考内容
|
||||||
|
}
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
|
"""将循环信息转换为字典格式"""
|
||||||
|
return {
|
||||||
|
"cycle_id": self.cycle_id,
|
||||||
|
"start_time": self.start_time,
|
||||||
|
"end_time": self.end_time,
|
||||||
|
"action_taken": self.action_taken,
|
||||||
|
"action_type": self.action_type,
|
||||||
|
"reasoning": self.reasoning,
|
||||||
|
"timers": self.timers,
|
||||||
|
"thinking_id": self.thinking_id,
|
||||||
|
"response_info": self.response_info
|
||||||
|
}
|
||||||
|
|
||||||
|
def complete_cycle(self):
|
||||||
|
"""完成循环,记录结束时间"""
|
||||||
|
self.end_time = time.time()
|
||||||
|
|
||||||
|
def set_action_info(self, action_type: str, reasoning: str, action_taken: bool):
|
||||||
|
"""设置动作信息"""
|
||||||
|
self.action_type = action_type
|
||||||
|
self.reasoning = reasoning
|
||||||
|
self.action_taken = action_taken
|
||||||
|
|
||||||
|
def set_thinking_id(self, thinking_id: str):
|
||||||
|
"""设置思考消息ID"""
|
||||||
|
self.thinking_id = thinking_id
|
||||||
|
|
||||||
|
def set_response_info(self,
|
||||||
|
response_text: Optional[List[str]] = None,
|
||||||
|
emoji_info: Optional[str] = None,
|
||||||
|
anchor_message_id: Optional[str] = None,
|
||||||
|
reply_message_ids: Optional[List[str]] = None,
|
||||||
|
sub_mind_thinking: Optional[str] = None):
|
||||||
|
"""设置响应信息"""
|
||||||
|
if response_text is not None:
|
||||||
|
self.response_info["response_text"] = response_text
|
||||||
|
if emoji_info is not None:
|
||||||
|
self.response_info["emoji_info"] = emoji_info
|
||||||
|
if anchor_message_id is not None:
|
||||||
|
self.response_info["anchor_message_id"] = anchor_message_id
|
||||||
|
if reply_message_ids is not None:
|
||||||
|
self.response_info["reply_message_ids"] = reply_message_ids
|
||||||
|
if sub_mind_thinking is not None:
|
||||||
|
self.response_info["sub_mind_thinking"] = sub_mind_thinking
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
from typing import List, Optional, Dict, Any, Set, Deque
|
import random # <-- 添加导入
|
||||||
|
from typing import List, Optional, Dict, Any, Deque
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from src.plugins.chat.message import MessageRecv, BaseMessageInfo, MessageThinking, MessageSending
|
from src.plugins.chat.message import MessageRecv, BaseMessageInfo, MessageThinking, MessageSending
|
||||||
from src.plugins.chat.message import MessageSet, Seg # Local import needed after move
|
from src.plugins.chat.message import MessageSet, Seg # Local import needed after move
|
||||||
@@ -23,6 +24,7 @@ from src.heart_flow.observation import Observation
|
|||||||
from src.plugins.heartFC_chat.heartflow_prompt_builder import global_prompt_manager
|
from src.plugins.heartFC_chat.heartflow_prompt_builder import global_prompt_manager
|
||||||
import contextlib
|
import contextlib
|
||||||
from src.plugins.utils.chat_message_builder import num_new_messages_since
|
from src.plugins.utils.chat_message_builder import num_new_messages_since
|
||||||
|
from src.plugins.heartFC_chat.heartFC_Cycleinfo import CycleInfo
|
||||||
# --- End import ---
|
# --- End import ---
|
||||||
|
|
||||||
|
|
||||||
@@ -139,75 +141,6 @@ class SenderError(HeartFCError):
|
|||||||
"""发送器异常"""
|
"""发送器异常"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CycleInfo:
|
|
||||||
"""循环信息记录类"""
|
|
||||||
def __init__(self, cycle_id: int):
|
|
||||||
self.cycle_id = cycle_id
|
|
||||||
self.start_time = time.time()
|
|
||||||
self.end_time: Optional[float] = None
|
|
||||||
self.action_taken = False
|
|
||||||
self.action_type = "unknown"
|
|
||||||
self.reasoning = ""
|
|
||||||
self.timers: Dict[str, float] = {}
|
|
||||||
self.thinking_id = ""
|
|
||||||
|
|
||||||
# 添加响应信息相关字段
|
|
||||||
self.response_info: Dict[str, Any] = {
|
|
||||||
"response_text": [], # 回复的文本列表
|
|
||||||
"emoji_info": "", # 表情信息
|
|
||||||
"anchor_message_id": "", # 锚点消息ID
|
|
||||||
"reply_message_ids": [], # 回复消息ID列表
|
|
||||||
"sub_mind_thinking": "", # 子思维思考内容
|
|
||||||
}
|
|
||||||
|
|
||||||
def to_dict(self) -> Dict[str, Any]:
|
|
||||||
"""将循环信息转换为字典格式"""
|
|
||||||
return {
|
|
||||||
"cycle_id": self.cycle_id,
|
|
||||||
"start_time": self.start_time,
|
|
||||||
"end_time": self.end_time,
|
|
||||||
"action_taken": self.action_taken,
|
|
||||||
"action_type": self.action_type,
|
|
||||||
"reasoning": self.reasoning,
|
|
||||||
"timers": self.timers,
|
|
||||||
"thinking_id": self.thinking_id,
|
|
||||||
"response_info": self.response_info
|
|
||||||
}
|
|
||||||
|
|
||||||
def complete_cycle(self):
|
|
||||||
"""完成循环,记录结束时间"""
|
|
||||||
self.end_time = time.time()
|
|
||||||
|
|
||||||
def set_action_info(self, action_type: str, reasoning: str, action_taken: bool):
|
|
||||||
"""设置动作信息"""
|
|
||||||
self.action_type = action_type
|
|
||||||
self.reasoning = reasoning
|
|
||||||
self.action_taken = action_taken
|
|
||||||
|
|
||||||
def set_thinking_id(self, thinking_id: str):
|
|
||||||
"""设置思考消息ID"""
|
|
||||||
self.thinking_id = thinking_id
|
|
||||||
|
|
||||||
def set_response_info(self,
|
|
||||||
response_text: Optional[List[str]] = None,
|
|
||||||
emoji_info: Optional[str] = None,
|
|
||||||
anchor_message_id: Optional[str] = None,
|
|
||||||
reply_message_ids: Optional[List[str]] = None,
|
|
||||||
sub_mind_thinking: Optional[str] = None):
|
|
||||||
"""设置响应信息"""
|
|
||||||
if response_text is not None:
|
|
||||||
self.response_info["response_text"] = response_text
|
|
||||||
if emoji_info is not None:
|
|
||||||
self.response_info["emoji_info"] = emoji_info
|
|
||||||
if anchor_message_id is not None:
|
|
||||||
self.response_info["anchor_message_id"] = anchor_message_id
|
|
||||||
if reply_message_ids is not None:
|
|
||||||
self.response_info["reply_message_ids"] = reply_message_ids
|
|
||||||
if sub_mind_thinking is not None:
|
|
||||||
self.response_info["sub_mind_thinking"] = sub_mind_thinking
|
|
||||||
|
|
||||||
|
|
||||||
class HeartFChatting:
|
class HeartFChatting:
|
||||||
"""
|
"""
|
||||||
管理一个连续的Plan-Replier-Sender循环
|
管理一个连续的Plan-Replier-Sender循环
|
||||||
@@ -244,8 +177,7 @@ class HeartFChatting:
|
|||||||
|
|
||||||
# LLM规划器配置
|
# LLM规划器配置
|
||||||
self.planner_llm = LLMRequest(
|
self.planner_llm = LLMRequest(
|
||||||
model=global_config.llm_normal,
|
model=global_config.llm_plan,
|
||||||
temperature=global_config.llm_normal["temp"],
|
|
||||||
max_tokens=1000,
|
max_tokens=1000,
|
||||||
request_type="action_planning", # 用于动作规划
|
request_type="action_planning", # 用于动作规划
|
||||||
)
|
)
|
||||||
@@ -352,7 +284,7 @@ class HeartFChatting:
|
|||||||
# 记录规划开始时间点
|
# 记录规划开始时间点
|
||||||
planner_start_db_time = time.time()
|
planner_start_db_time = time.time()
|
||||||
|
|
||||||
# 执行规划阶段
|
# 主循环:思考->决策->执行
|
||||||
action_taken, thinking_id = await self._think_plan_execute_loop(
|
action_taken, thinking_id = await self._think_plan_execute_loop(
|
||||||
cycle_timers, planner_start_db_time
|
cycle_timers, planner_start_db_time
|
||||||
)
|
)
|
||||||
@@ -436,29 +368,34 @@ class HeartFChatting:
|
|||||||
) -> tuple[bool, str]:
|
) -> tuple[bool, str]:
|
||||||
"""执行规划阶段"""
|
"""执行规划阶段"""
|
||||||
try:
|
try:
|
||||||
# 获取子思维思考结果
|
# think:思考
|
||||||
current_mind = ""
|
current_mind = await self._get_submind_thinking(cycle_timers)
|
||||||
with Timer("思考", cycle_timers):
|
# 记录子思维思考内容
|
||||||
current_mind = await self._get_submind_thinking()
|
if self._current_cycle:
|
||||||
# 记录子思维思考内容
|
self._current_cycle.set_response_info(sub_mind_thinking=current_mind)
|
||||||
if self._current_cycle:
|
|
||||||
self._current_cycle.set_response_info(sub_mind_thinking=current_mind)
|
|
||||||
|
|
||||||
# 执行规划
|
# plan:决策
|
||||||
with Timer("决策", cycle_timers):
|
with Timer("决策", cycle_timers):
|
||||||
planner_result = await self._planner(current_mind, cycle_timers)
|
planner_result = await self._planner(current_mind, cycle_timers)
|
||||||
|
|
||||||
|
action = planner_result.get("action", "error")
|
||||||
|
reasoning = planner_result.get("reasoning", "未提供理由")
|
||||||
|
|
||||||
|
self._current_cycle.set_action_info(action, reasoning, False)
|
||||||
|
|
||||||
# 在获取规划结果后检查新消息
|
# 在获取规划结果后检查新消息
|
||||||
if await self._check_new_messages(planner_start_db_time):
|
if await self._check_new_messages(planner_start_db_time):
|
||||||
# 更新循环信息
|
if random.random() < 0.3:
|
||||||
logger.info(f"{self.log_prefix} 思考到一半,检测到新消息,重新思考")
|
logger.info(f"{self.log_prefix} 看到了新消息,麦麦决定重新观察和规划...")
|
||||||
self._current_cycle.set_action_info("new_messages", "检测到新消息", False)
|
# 重新规划
|
||||||
return False, "new_messages"
|
with Timer("重新决策", cycle_timers):
|
||||||
|
self._current_cycle.replanned = True
|
||||||
|
planner_result = await self._planner(current_mind, cycle_timers, is_re_planned=True)
|
||||||
|
logger.info(f"{self.log_prefix} 重新规划完成.")
|
||||||
|
|
||||||
# 解析规划结果
|
# 解析规划结果
|
||||||
action = planner_result.get("action", "error")
|
action = planner_result.get("action", "error")
|
||||||
reasoning = planner_result.get("reasoning", "未提供理由")
|
reasoning = planner_result.get("reasoning", "未提供理由")
|
||||||
|
|
||||||
# 更新循环信息
|
# 更新循环信息
|
||||||
self._current_cycle.set_action_info(action, reasoning, True)
|
self._current_cycle.set_action_info(action, reasoning, True)
|
||||||
|
|
||||||
@@ -467,7 +404,7 @@ class HeartFChatting:
|
|||||||
logger.error(f"{self.log_prefix} LLM失败: {reasoning}")
|
logger.error(f"{self.log_prefix} LLM失败: {reasoning}")
|
||||||
return False, ""
|
return False, ""
|
||||||
|
|
||||||
# 根据动作类型执行对应处理
|
# execute:执行
|
||||||
with Timer("执行", cycle_timers):
|
with Timer("执行", cycle_timers):
|
||||||
return await self._handle_action(action, reasoning, planner_result.get("emoji_query", ""), cycle_timers, planner_start_db_time)
|
return await self._handle_action(action, reasoning, planner_result.get("emoji_query", ""), cycle_timers, planner_start_db_time)
|
||||||
|
|
||||||
@@ -699,7 +636,7 @@ class HeartFChatting:
|
|||||||
logger.info(f"{log_prefix} Sleep interrupted, loop likely cancelling.")
|
logger.info(f"{log_prefix} Sleep interrupted, loop likely cancelling.")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
async def _get_submind_thinking(self) -> str:
|
async def _get_submind_thinking(self, cycle_timers: dict) -> str:
|
||||||
"""
|
"""
|
||||||
获取子思维的思考结果
|
获取子思维的思考结果
|
||||||
|
|
||||||
@@ -707,27 +644,38 @@ class HeartFChatting:
|
|||||||
str: 思考结果,如果思考失败则返回错误信息
|
str: 思考结果,如果思考失败则返回错误信息
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
observation = self.observations[0]
|
with Timer("观察", cycle_timers):
|
||||||
await observation.observe()
|
observation = self.observations[0]
|
||||||
current_mind, _past_mind = await self.sub_mind.do_thinking_before_reply()
|
await observation.observe()
|
||||||
return current_mind
|
|
||||||
|
# 获取上一个循环的信息
|
||||||
|
last_cycle = self._cycle_history[-1] if self._cycle_history else None
|
||||||
|
|
||||||
|
with Timer("思考", cycle_timers):
|
||||||
|
# 获取上一个循环的动作
|
||||||
|
# 传递上一个循环的信息给 do_thinking_before_reply
|
||||||
|
current_mind, _past_mind = await self.sub_mind.do_thinking_before_reply(
|
||||||
|
last_cycle=last_cycle
|
||||||
|
)
|
||||||
|
return current_mind
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix}[SubMind] 思考失败: {e}")
|
logger.error(f"{self.log_prefix}[SubMind] 思考失败: {e}")
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
return "[思考时出错]"
|
return "[思考时出错]"
|
||||||
|
|
||||||
async def _planner(self, current_mind: str, cycle_timers: dict) -> Dict[str, Any]:
|
async def _planner(self, current_mind: str, cycle_timers: dict, is_re_planned: bool = False) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
规划器 (Planner): 使用LLM根据上下文决定是否和如何回复。
|
规划器 (Planner): 使用LLM根据上下文决定是否和如何回复。
|
||||||
|
|
||||||
参数:
|
参数:
|
||||||
current_mind: 子思维的当前思考结果
|
current_mind: 子思维的当前思考结果
|
||||||
"""
|
"""
|
||||||
logger.info(f"{self.log_prefix}[Planner] 开始执行规划器")
|
logger.info(f"{self.log_prefix}[Planner] 开始{'重新' if is_re_planned else ''}执行规划器")
|
||||||
|
|
||||||
# 获取观察信息
|
# 获取观察信息
|
||||||
observation = self.observations[0]
|
observation = self.observations[0]
|
||||||
# await observation.observe()
|
if is_re_planned:
|
||||||
|
observation.observe()
|
||||||
observed_messages = observation.talking_message
|
observed_messages = observation.talking_message
|
||||||
observed_messages_str = observation.talking_message_str
|
observed_messages_str = observation.talking_message_str
|
||||||
|
|
||||||
@@ -740,11 +688,18 @@ class HeartFChatting:
|
|||||||
try:
|
try:
|
||||||
# 构建提示词
|
# 构建提示词
|
||||||
with Timer("构建提示词", cycle_timers):
|
with Timer("构建提示词", cycle_timers):
|
||||||
|
if is_re_planned:
|
||||||
|
replan_prompt = await self._build_replan_prompt(
|
||||||
|
self._current_cycle.action, self._current_cycle.reasoning
|
||||||
|
)
|
||||||
|
prompt = replan_prompt
|
||||||
|
else:
|
||||||
|
replan_prompt = ""
|
||||||
prompt = await self._build_planner_prompt(
|
prompt = await self._build_planner_prompt(
|
||||||
observed_messages_str, current_mind, self.sub_mind.structured_info
|
observed_messages_str, current_mind, self.sub_mind.structured_info, replan_prompt
|
||||||
)
|
)
|
||||||
payload = {
|
payload = {
|
||||||
"model": self.planner_llm.model_name,
|
"model": global_config.llm_plan["name"],
|
||||||
"messages": [{"role": "user", "content": prompt}],
|
"messages": [{"role": "user", "content": prompt}],
|
||||||
"tools": self.action_manager.get_planner_tool_definition(),
|
"tools": self.action_manager.get_planner_tool_definition(),
|
||||||
"tool_choice": {"type": "function", "function": {"name": "decide_reply_action"}},
|
"tool_choice": {"type": "function", "function": {"name": "decide_reply_action"}},
|
||||||
@@ -905,8 +860,18 @@ class HeartFChatting:
|
|||||||
|
|
||||||
logger.info(f"{self.log_prefix} HeartFChatting关闭完成")
|
logger.info(f"{self.log_prefix} HeartFChatting关闭完成")
|
||||||
|
|
||||||
|
async def _build_replan_prompt(
|
||||||
|
self, action: str, reasoning: str
|
||||||
|
) -> str:
|
||||||
|
"""构建 Replanner LLM 的提示词"""
|
||||||
|
prompt = (await global_prompt_manager.get_prompt_async("replan_prompt")).format(
|
||||||
|
action=action,
|
||||||
|
reasoning=reasoning,
|
||||||
|
)
|
||||||
|
return prompt
|
||||||
|
|
||||||
async def _build_planner_prompt(
|
async def _build_planner_prompt(
|
||||||
self, observed_messages_str: str, current_mind: Optional[str], structured_info: Dict[str, Any]
|
self, observed_messages_str: str, current_mind: Optional[str], structured_info: Dict[str, Any], replan_prompt: str
|
||||||
) -> str:
|
) -> str:
|
||||||
"""构建 Planner LLM 的提示词"""
|
"""构建 Planner LLM 的提示词"""
|
||||||
|
|
||||||
@@ -937,6 +902,7 @@ class HeartFChatting:
|
|||||||
structured_info_block=structured_info_block,
|
structured_info_block=structured_info_block,
|
||||||
chat_content_block=chat_content_block,
|
chat_content_block=chat_content_block,
|
||||||
current_mind_block=current_mind_block,
|
current_mind_block=current_mind_block,
|
||||||
|
replan=replan_prompt,
|
||||||
)
|
)
|
||||||
|
|
||||||
return prompt
|
return prompt
|
||||||
|
|||||||
@@ -49,12 +49,11 @@ class HeartFCGenerator:
|
|||||||
|
|
||||||
arousal_multiplier = MoodManager.get_instance().get_arousal_multiplier()
|
arousal_multiplier = MoodManager.get_instance().get_arousal_multiplier()
|
||||||
|
|
||||||
with Timer() as t_generate_response:
|
current_model = self.model_normal
|
||||||
current_model = self.model_normal
|
current_model.temperature = global_config.llm_normal["temp"] * arousal_multiplier # 激活度越高,温度越高
|
||||||
current_model.temperature = global_config.llm_normal["temp"] * arousal_multiplier # 激活度越高,温度越高
|
model_response = await self._generate_response_with_model(
|
||||||
model_response = await self._generate_response_with_model(
|
structured_info, current_mind_info, reason, message, current_model, thinking_id
|
||||||
structured_info, current_mind_info, reason, message, current_model, thinking_id
|
)
|
||||||
)
|
|
||||||
|
|
||||||
if model_response:
|
if model_response:
|
||||||
model_processed_response = await self._process_response(model_response)
|
model_processed_response = await self._process_response(model_response)
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ def init_prompt():
|
|||||||
{chat_content_block}
|
{chat_content_block}
|
||||||
看了以上内容,你产生的内心想法是:
|
看了以上内容,你产生的内心想法是:
|
||||||
{current_mind_block}
|
{current_mind_block}
|
||||||
|
{replan}
|
||||||
请结合你的内心想法和观察到的聊天内容,分析情况并使用 'decide_reply_action' 工具来决定你的最终行动。
|
请结合你的内心想法和观察到的聊天内容,分析情况并使用 'decide_reply_action' 工具来决定你的最终行动。
|
||||||
注意你必须参考以下决策依据来选择工具:
|
注意你必须参考以下决策依据来选择工具:
|
||||||
1. 如果聊天内容无聊、与你无关、或者你的内心想法认为不适合回复(例如在讨论你不懂或不感兴趣的话题),选择 'no_reply'。
|
1. 如果聊天内容无聊、与你无关、或者你的内心想法认为不适合回复(例如在讨论你不懂或不感兴趣的话题),选择 'no_reply'。
|
||||||
@@ -64,6 +65,8 @@ def init_prompt():
|
|||||||
"planner_prompt",
|
"planner_prompt",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Prompt("你原本打算{action},因为:{reasoning},但是你看到了新的消息,你决定重新决定行动。", "replan_prompt")
|
||||||
|
|
||||||
Prompt("你正在qq群里聊天,下面是群里在聊的内容:", "chat_target_group1")
|
Prompt("你正在qq群里聊天,下面是群里在聊的内容:", "chat_target_group1")
|
||||||
Prompt("和群里聊天", "chat_target_group2")
|
Prompt("和群里聊天", "chat_target_group2")
|
||||||
Prompt("你正在和{sender_name}聊天,这是你们之前聊的内容:", "chat_target_private1")
|
Prompt("你正在和{sender_name}聊天,这是你们之前聊的内容:", "chat_target_private1")
|
||||||
@@ -86,7 +89,7 @@ def init_prompt():
|
|||||||
你的网名叫{bot_name},有人也叫你{bot_other_names},{prompt_personality}。
|
你的网名叫{bot_name},有人也叫你{bot_other_names},{prompt_personality}。
|
||||||
你正在{chat_target_2},现在请你读读之前的聊天记录,{mood_prompt},然后给出日常且口语化的回复,平淡一些,
|
你正在{chat_target_2},现在请你读读之前的聊天记录,{mood_prompt},然后给出日常且口语化的回复,平淡一些,
|
||||||
尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。{prompt_ger}
|
尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。{prompt_ger}
|
||||||
请回复的平淡一些,简短一些,说中文,不要刻意突出自身学科背景,尽量不要说你说过的话
|
请回复的平淡一些,简短一些,说中文,不要刻意突出自身学科背景,不要浮夸,平淡一些 ,不要重复自己说过的话。
|
||||||
请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出回复内容。
|
请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出回复内容。
|
||||||
{moderation_prompt}不要输出多余内容(包括前后缀,冒号和引号,括号(),表情包,at或 @等 )。,只输出回复内容""",
|
{moderation_prompt}不要输出多余内容(包括前后缀,冒号和引号,括号(),表情包,at或 @等 )。,只输出回复内容""",
|
||||||
"reasoning_prompt_main",
|
"reasoning_prompt_main",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[inner]
|
[inner]
|
||||||
version = "1.4.2"
|
version = "1.5.0"
|
||||||
|
|
||||||
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
||||||
#如果你想要修改配置文件,请在修改后将version的值进行变更
|
#如果你想要修改配置文件,请在修改后将version的值进行变更
|
||||||
@@ -81,12 +81,8 @@ model_normal_probability = 0.3 # 麦麦回答时选择一般模型 模型的概
|
|||||||
reply_trigger_threshold = 3.0 # 心流聊天触发阈值,越低越容易进入心流聊天
|
reply_trigger_threshold = 3.0 # 心流聊天触发阈值,越低越容易进入心流聊天
|
||||||
probability_decay_factor_per_second = 0.2 # 概率衰减因子,越大衰减越快,越高越容易退出心流聊天
|
probability_decay_factor_per_second = 0.2 # 概率衰减因子,越大衰减越快,越高越容易退出心流聊天
|
||||||
default_decay_rate_per_second = 0.98 # 默认衰减率,越大衰减越快,越高越难进入心流聊天
|
default_decay_rate_per_second = 0.98 # 默认衰减率,越大衰减越快,越高越难进入心流聊天
|
||||||
initial_duration = 60 # 初始持续时间,越大心流聊天持续的时间越长
|
|
||||||
|
|
||||||
sub_heart_flow_stop_time = 500 # 子心流停止时间,超过这个时间没有回复,子心流会停止,间隔 单位秒
|
sub_heart_flow_stop_time = 500 # 子心流停止时间,超过这个时间没有回复,子心流会停止,间隔 单位秒
|
||||||
# sub_heart_flow_update_interval = 60
|
|
||||||
# sub_heart_flow_freeze_time = 100
|
|
||||||
# heart_flow_update_interval = 600
|
|
||||||
|
|
||||||
observation_context_size = 20 # 心流观察到的最长上下文大小,超过这个值的上下文会被压缩
|
observation_context_size = 20 # 心流观察到的最长上下文大小,超过这个值的上下文会被压缩
|
||||||
compressed_length = 5 # 不能大于observation_context_size,心流上下文压缩的最短压缩长度,超过心流观察到的上下文长度,会压缩,最短压缩长度为5
|
compressed_length = 5 # 不能大于observation_context_size,心流上下文压缩的最短压缩长度,超过心流观察到的上下文长度,会压缩,最短压缩长度为5
|
||||||
@@ -247,6 +243,29 @@ provider = "SILICONFLOW"
|
|||||||
pri_in = 0.35
|
pri_in = 0.35
|
||||||
pri_out = 0.35
|
pri_out = 0.35
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[model.llm_observation] #观察模型,压缩聊天内容,建议用免费的
|
||||||
|
# name = "Pro/Qwen/Qwen2.5-7B-Instruct"
|
||||||
|
name = "Qwen/Qwen2.5-7B-Instruct"
|
||||||
|
provider = "SILICONFLOW"
|
||||||
|
pri_in = 0
|
||||||
|
pri_out = 0
|
||||||
|
|
||||||
|
[model.llm_sub_heartflow] #子心流:激情水群时,生成麦麦的内心想法
|
||||||
|
name = "Qwen/Qwen2.5-72B-Instruct"
|
||||||
|
provider = "SILICONFLOW"
|
||||||
|
pri_in = 4.13
|
||||||
|
pri_out = 4.13
|
||||||
|
temp = 0.7 #模型的温度,新V3建议0.1-0.3
|
||||||
|
|
||||||
|
|
||||||
|
[model.llm_plan] #决策模型:激情水群时,负责决定麦麦该做什么
|
||||||
|
name = "Qwen/Qwen2.5-32B-Instruct"
|
||||||
|
provider = "SILICONFLOW"
|
||||||
|
pri_in = 1.26
|
||||||
|
pri_out = 1.26
|
||||||
|
|
||||||
#嵌入模型
|
#嵌入模型
|
||||||
|
|
||||||
[model.embedding] #嵌入
|
[model.embedding] #嵌入
|
||||||
@@ -255,26 +274,6 @@ provider = "SILICONFLOW"
|
|||||||
pri_in = 0
|
pri_in = 0
|
||||||
pri_out = 0
|
pri_out = 0
|
||||||
|
|
||||||
[model.llm_observation] #观察模型,建议用免费的:建议使用qwen2.5 7b
|
|
||||||
# name = "Pro/Qwen/Qwen2.5-7B-Instruct"
|
|
||||||
name = "Qwen/Qwen2.5-7B-Instruct"
|
|
||||||
provider = "SILICONFLOW"
|
|
||||||
pri_in = 0
|
|
||||||
pri_out = 0
|
|
||||||
|
|
||||||
[model.llm_sub_heartflow] #子心流:建议使用V3级别
|
|
||||||
name = "Pro/deepseek-ai/DeepSeek-V3"
|
|
||||||
provider = "SILICONFLOW"
|
|
||||||
pri_in = 2
|
|
||||||
pri_out = 8
|
|
||||||
temp = 0.2 #模型的温度,新V3建议0.1-0.3
|
|
||||||
|
|
||||||
[model.llm_heartflow] #心流:建议使用qwen2.5 32b
|
|
||||||
# name = "Pro/Qwen/Qwen2.5-7B-Instruct"
|
|
||||||
name = "Qwen/Qwen2.5-32B-Instruct"
|
|
||||||
provider = "SILICONFLOW"
|
|
||||||
pri_in = 1.26
|
|
||||||
pri_out = 1.26
|
|
||||||
|
|
||||||
#私聊PFC:需要开启PFC功能,默认三个模型均为硅基流动v3,如果需要支持多人同时私聊或频繁调用,建议把其中的一个或两个换成官方v3或其它模型,以免撞到429
|
#私聊PFC:需要开启PFC功能,默认三个模型均为硅基流动v3,如果需要支持多人同时私聊或频繁调用,建议把其中的一个或两个换成官方v3或其它模型,以免撞到429
|
||||||
|
|
||||||
@@ -300,3 +299,14 @@ name = "Pro/deepseek-ai/DeepSeek-V3"
|
|||||||
provider = "SILICONFLOW"
|
provider = "SILICONFLOW"
|
||||||
pri_in = 2
|
pri_in = 2
|
||||||
pri_out = 8
|
pri_out = 8
|
||||||
|
|
||||||
|
|
||||||
|
#此模型暂时没有使用!!
|
||||||
|
#此模型暂时没有使用!!
|
||||||
|
#此模型暂时没有使用!!
|
||||||
|
[model.llm_heartflow] #心流
|
||||||
|
# name = "Pro/Qwen/Qwen2.5-7B-Instruct"
|
||||||
|
name = "Qwen/Qwen2.5-32B-Instruct"
|
||||||
|
provider = "SILICONFLOW"
|
||||||
|
pri_in = 1.26
|
||||||
|
pri_out = 1.26
|
||||||
@@ -63,35 +63,43 @@ async def test_with_tool_calls():
|
|||||||
# 简单的测试提示词
|
# 简单的测试提示词
|
||||||
prompt = "请分析当前天气情况,并查询今日历史上的重要事件。并且3.9和3.11谁比较大?请使用适当的工具来获取这些信息。"
|
prompt = "请分析当前天气情况,并查询今日历史上的重要事件。并且3.9和3.11谁比较大?请使用适当的工具来获取这些信息。"
|
||||||
prompt = """
|
prompt = """
|
||||||
你的名字是麦麦,你包容开放,情绪敏感,有时候有些搞怪幽默, 是一个学习心理学和脑科学的女大学生,现在在读大二,你会刷贴吧,有时候会想瑟瑟,喜欢刷小红书
|
你的名字是麦麦,你包容开放,情绪敏感,有时候有些搞怪幽默, 是一个学习心理学和脑科学的女大学生,现在在读大二,你会刷贴吧,有时候会喜欢说一些奇怪的话,喜欢刷小红书
|
||||||
-----------------------------------
|
刚刚你的内心想法是:漂移菌提到罐罐被吃完了,可以顺着这个梗继续玩一下,比如假装委屈"那今晚的加班费是不是也要被吃掉了"或者"猫娘罢工警告"。不过薯薯和薯宝之前已经接了不少梗,漂移菌刚刚也参与了,可能话题热度还在,可以再互动一下。如果没人接话,或许可以问问大家有没有遇到过类似"代码写完但奖励被吃掉"的搞笑职场经历,换个轻松的话题方向。
|
||||||
现在是2025-04-24 12:37:00,你正在上网,和qq群里的网友们聊天,群里正在聊的话题是:
|
|
||||||
2025-04-24 12:33:00既文横 说:这条调试消息是napcat控制台输出的,还是麦麦log输出的;
|
|
||||||
2025-04-24 12:33:23麦麦(你) 说:应该是napcat吧;
|
|
||||||
2025-04-24 12:33:24麦麦(你) 说:[表达了:害羞、害羞。];
|
|
||||||
2025-04-24 12:33:25兔伽兔伽 说:就打开麦麦的那个终端发的呀;
|
|
||||||
2025-04-24 12:33:45既文横 说:那应该不是napcat输出的,是麦麦输出的消息,怀疑版本问题;
|
|
||||||
2025-04-24 12:34:02兔伽兔伽 说:版本05.15;
|
|
||||||
2025-04-24 12:34:07麦麦(你) 说:话说你们最近刷贴吧看到那个猫猫头表情包了吗;
|
|
||||||
2025-04-24 12:34:07麦麦(你) 说:笑死;
|
|
||||||
2025-04-24 12:34:08麦麦(你) 说:[表达了:惊讶、搞笑。];
|
|
||||||
2025-04-24 12:34:14兔伽兔伽 说:只开一个终端;
|
|
||||||
2025-04-24 12:35:45兔伽兔伽 说:回复既文横的消息(怀疑版本问题),说:因为之前你连模型的那个我用的了;
|
|
||||||
2025-04-24 12:35:56麦麦(你) 说:那个猫猫头真的魔性;
|
|
||||||
2025-04-24 12:35:56麦麦(你) 说:我存了一堆;
|
|
||||||
2025-04-24 12:35:56麦麦(你) 说:[表达了:温馨、宠爱];
|
|
||||||
2025-04-24 12:36:03小千石 说:麦麦3.8和3.11谁大;
|
|
||||||
|
|
||||||
--- 以上消息已读 (标记时间: 2025-04-24 12:36:43) ---
|
暂时不需要使用工具。
|
||||||
--- 请关注你上次思考之后以下的新消息---
|
-----------------------------------
|
||||||
2025-04-24 12:36:53墨墨 说:[表情包:开心、满足。];
|
现在是2025-04-25 17:38:37,你正在上网,和qq群里的网友们聊天,以下是正在进行的聊天内容:
|
||||||
|
2025-04-25 17:34:08麦麦(你) 说:[表达了:顽皮、嬉戏。];
|
||||||
|
2025-04-25 17:34:39漂移菌 说:@麦麦。(id:3936257206) 你是一只猫娘;
|
||||||
|
2025-04-25 17:34:42薯宝 说:🤣;
|
||||||
|
2025-04-25 17:34:43麦麦(你) 说:行啊 工资分我一半;
|
||||||
|
2025-04-25 17:34:43麦麦(你) 说:我帮你写bug;
|
||||||
|
2025-04-25 17:34:43麦麦(你) 说:[表达了:悲伤、绝望、无奈、无力];
|
||||||
|
2025-04-25 17:34:53薯薯 说:?;
|
||||||
|
2025-04-25 17:35:03既文横 说:麦麦,你是一只猫娘程序员,猫娘是不需要工资;
|
||||||
|
2025-04-25 17:35:20薯宝 说:[图片:图片内容:一只卡通风格的灰色猫咪,眼睛闭着,表情显得很平静。图片下方有"死了"两个字。
|
||||||
|
|
||||||
|
图片含义猜测:这可能是一个幽默的表达,用来形容某人或某事处于非常平静的状态,仿佛已经"死"了一样。] hfc这周,真能出来吗...;
|
||||||
|
2025-04-25 17:35:34薯宝 说:[表情包:搞笑、滑稽、讽刺、幽默];
|
||||||
|
2025-04-25 17:36:25麦麦(你) 说:喵喵;
|
||||||
|
2025-04-25 17:36:25麦麦(你) 说:代码写完了;
|
||||||
|
2025-04-25 17:36:25麦麦(你) 说:罐罐拿来;
|
||||||
|
2025-04-25 17:36:25麦麦(你) 说:[表达了:悲伤、绝望、无奈、无力];
|
||||||
|
2025-04-25 17:36:41薯薯 说:好可爱;
|
||||||
|
2025-04-25 17:37:05薯薯 说:脑补出来认真营业了一天等待主人发放奖励的小猫咪;
|
||||||
|
2025-04-25 17:37:25薯宝 说:敷衍营业(bushi);
|
||||||
|
2025-04-25 17:37:54漂移菌 说:回复麦麦。的消息(罐罐拿来),说:猫娘我昨晚上太饿吃完了;
|
||||||
|
|
||||||
|
--- 以上消息已读 (标记时间: 2025-04-25 17:37:54) ---
|
||||||
|
--- 以下新消息未读---
|
||||||
|
2025-04-25 17:38:29麦麦(你) 说:那今晚的猫条是不是也要被克扣了(盯——);
|
||||||
|
2025-04-25 17:38:29麦麦(你) 说:[表达了:幽默,自嘲,无奈,父子关系,编程笑话];
|
||||||
|
|
||||||
你现在当前心情:平静。
|
你现在当前心情:平静。
|
||||||
现在请你根据刚刚的想法继续思考,思考时可以想想如何对群聊内容进行回复,要不要对群里的话题进行回复,关注新话题,可以适当转换话题,大家正在说的话才是聊天的主题。
|
现在请你生成你的内心想法,要求思考群里正在进行的话题,之前大家聊过的话题,群里成员的关系。请你思考,要不要对群里的话题进行回复,以及如何对群聊内容进行回复
|
||||||
回复的要求是:平淡一些,简短一些,说中文,如果你要回复,最好只回复一个人的一个话题
|
回复的要求是:不要总是重复自己提到过的话题,如果你要回复,最好只回复一个人的一个话题
|
||||||
请注意不要输出多余内容(包括前后缀,冒号和引号,括号, 表情,等),不要带有括号和动作描写。不要回复自己的发言,尽量不要说你说过的话。
|
如果最后一条消息是你自己发的,观察到的内容只有你自己的发言,并且之后没有人回复你,不要回复。如果聊天记录中最新的消息是你自己发送的,并且你还想继续回复,你应该紧紧衔接你发送的消息,进行话题的深入,补充,或追问等等。请注意不要输出多余内容(包括前后缀,冒号和引号,括号, 表情,等),不要回复自己的发言
|
||||||
现在请你继续生成你在这个聊天中的想法,在原来想法的基础上继续思考,不要分点输出,生成内心想法,文字不要浮夸
|
现在请你先输出想法,生成你在这个聊天中的想法,在原来的想法上尝试新的话题,不要分点输出,文字不要浮夸在输出完想法后,请你思考应该使用什么工具。工具可以帮你取得一些你不知道的信息,或者进行一些操作。如果你需要做某件事,来对消息和你的回复进行处理,请使用工具。"""
|
||||||
在输出完想法后,请你思考应该使用什么工具,如果你需要做某件事,来对消息和你的回复进行处理,请使用工具。"""
|
|
||||||
|
|
||||||
# 发送带有工具调用的请求
|
# 发送带有工具调用的请求
|
||||||
response = await llm_model.generate_response_tool_async(prompt=prompt, tools=tools)
|
response = await llm_model.generate_response_tool_async(prompt=prompt, tools=tools)
|
||||||
@@ -145,7 +153,7 @@ async def test_without_tool_calls():
|
|||||||
# 简单的测试提示词(与工具调用相同,以便公平比较)
|
# 简单的测试提示词(与工具调用相同,以便公平比较)
|
||||||
prompt = """
|
prompt = """
|
||||||
你的名字是麦麦,你包容开放,情绪敏感,有时候有些搞怪幽默, 是一个学习心理学和脑科学的女大学生,现在在读大二,你会刷贴吧,有时候会喜欢说一些奇怪的话,喜欢刷小红书
|
你的名字是麦麦,你包容开放,情绪敏感,有时候有些搞怪幽默, 是一个学习心理学和脑科学的女大学生,现在在读大二,你会刷贴吧,有时候会喜欢说一些奇怪的话,喜欢刷小红书
|
||||||
刚刚你的内心想法是:漂移菌提到罐罐被吃完了,可以顺着这个梗继续玩一下,比如假装委屈“那今晚的加班费是不是也要被吃掉了”或者“猫娘罢工警告”。不过薯薯和薯宝之前已经接了不少梗,漂移菌刚刚也参与了,可能话题热度还在,可以再互动一下。如果没人接话,或许可以问问大家有没有遇到过类似“代码写完但奖励被吃掉”的搞笑职场经历,换个轻松的话题方向。
|
刚刚你的内心想法是:漂移菌提到罐罐被吃完了,可以顺着这个梗继续玩一下,比如假装委屈"那今晚的加班费是不是也要被吃掉了"或者"猫娘罢工警告"。不过薯薯和薯宝之前已经接了不少梗,漂移菌刚刚也参与了,可能话题热度还在,可以再互动一下。如果没人接话,或许可以问问大家有没有遇到过类似"代码写完但奖励被吃掉"的搞笑职场经历,换个轻松的话题方向。
|
||||||
|
|
||||||
暂时不需要使用工具。
|
暂时不需要使用工具。
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
@@ -158,9 +166,9 @@ async def test_without_tool_calls():
|
|||||||
2025-04-25 17:34:43麦麦(你) 说:[表达了:悲伤、绝望、无奈、无力];
|
2025-04-25 17:34:43麦麦(你) 说:[表达了:悲伤、绝望、无奈、无力];
|
||||||
2025-04-25 17:34:53薯薯 说:?;
|
2025-04-25 17:34:53薯薯 说:?;
|
||||||
2025-04-25 17:35:03既文横 说:麦麦,你是一只猫娘程序员,猫娘是不需要工资;
|
2025-04-25 17:35:03既文横 说:麦麦,你是一只猫娘程序员,猫娘是不需要工资;
|
||||||
2025-04-25 17:35:20薯宝 说:[图片:图片内容:一只卡通风格的灰色猫咪,眼睛闭着,表情显得很平静。图片下方有“死了”两个字。
|
2025-04-25 17:35:20薯宝 说:[图片:图片内容:一只卡通风格的灰色猫咪,眼睛闭着,表情显得很平静。图片下方有"死了"两个字。
|
||||||
|
|
||||||
图片含义猜测:这可能是一个幽默的表达,用来形容某人或某事处于非常平静的状态,仿佛已经“死”了一样。] hfc这周,真能出来吗...;
|
图片含义猜测:这可能是一个幽默的表达,用来形容某人或某事处于非常平静的状态,仿佛已经"死"了一样。] hfc这周,真能出来吗...;
|
||||||
2025-04-25 17:35:34薯宝 说:[表情包:搞笑、滑稽、讽刺、幽默];
|
2025-04-25 17:35:34薯宝 说:[表情包:搞笑、滑稽、讽刺、幽默];
|
||||||
2025-04-25 17:36:25麦麦(你) 说:喵喵;
|
2025-04-25 17:36:25麦麦(你) 说:喵喵;
|
||||||
2025-04-25 17:36:25麦麦(你) 说:代码写完了;
|
2025-04-25 17:36:25麦麦(你) 说:代码写完了;
|
||||||
@@ -181,7 +189,6 @@ async def test_without_tool_calls():
|
|||||||
回复的要求是:不要总是重复自己提到过的话题,如果你要回复,最好只回复一个人的一个话题
|
回复的要求是:不要总是重复自己提到过的话题,如果你要回复,最好只回复一个人的一个话题
|
||||||
如果最后一条消息是你自己发的,观察到的内容只有你自己的发言,并且之后没有人回复你,不要回复。如果聊天记录中最新的消息是你自己发送的,并且你还想继续回复,你应该紧紧衔接你发送的消息,进行话题的深入,补充,或追问等等。请注意不要输出多余内容(包括前后缀,冒号和引号,括号, 表情,等),不要回复自己的发言
|
如果最后一条消息是你自己发的,观察到的内容只有你自己的发言,并且之后没有人回复你,不要回复。如果聊天记录中最新的消息是你自己发送的,并且你还想继续回复,你应该紧紧衔接你发送的消息,进行话题的深入,补充,或追问等等。请注意不要输出多余内容(包括前后缀,冒号和引号,括号, 表情,等),不要回复自己的发言
|
||||||
现在请你先输出想法,生成你在这个聊天中的想法,在原来的想法上尝试新的话题,不要分点输出,文字不要浮夸在输出完想法后,请你思考应该使用什么工具。工具可以帮你取得一些你不知道的信息,或者进行一些操作。如果你需要做某件事,来对消息和你的回复进行处理,请使用工具。"""
|
现在请你先输出想法,生成你在这个聊天中的想法,在原来的想法上尝试新的话题,不要分点输出,文字不要浮夸在输出完想法后,请你思考应该使用什么工具。工具可以帮你取得一些你不知道的信息,或者进行一些操作。如果你需要做某件事,来对消息和你的回复进行处理,请使用工具。"""
|
||||||
|
|
||||||
# 发送不带工具调用的请求
|
# 发送不带工具调用的请求
|
||||||
response, reasoning_content = await llm_model.generate_response_async(prompt)
|
response, reasoning_content = await llm_model.generate_response_async(prompt)
|
||||||
|
|
||||||
@@ -194,6 +201,69 @@ async def test_without_tool_calls():
|
|||||||
return result_info
|
return result_info
|
||||||
|
|
||||||
|
|
||||||
|
async def run_alternating_tests(iterations=5):
|
||||||
|
"""
|
||||||
|
交替运行两种测试方法,每种方法运行指定次数
|
||||||
|
|
||||||
|
参数:
|
||||||
|
iterations: 每种测试方法运行的次数
|
||||||
|
|
||||||
|
返回:
|
||||||
|
包含两种测试方法结果的元组
|
||||||
|
"""
|
||||||
|
print(f"开始交替测试(每种方法{iterations}次)...")
|
||||||
|
|
||||||
|
# 初始化结果列表
|
||||||
|
times_without_tools = []
|
||||||
|
times_with_tools = []
|
||||||
|
responses_without_tools = []
|
||||||
|
responses_with_tools = []
|
||||||
|
|
||||||
|
for i in range(iterations):
|
||||||
|
print(f"\n第 {i + 1}/{iterations} 轮交替测试")
|
||||||
|
|
||||||
|
# 不使用工具的测试
|
||||||
|
print("\n 执行不使用工具调用的测试...")
|
||||||
|
start_time = time.time()
|
||||||
|
response = await test_without_tool_calls()
|
||||||
|
end_time = time.time()
|
||||||
|
elapsed = end_time - start_time
|
||||||
|
times_without_tools.append(elapsed)
|
||||||
|
responses_without_tools.append(response)
|
||||||
|
print(f" - 耗时: {elapsed:.2f}秒")
|
||||||
|
|
||||||
|
# 使用工具的测试
|
||||||
|
print("\n 执行使用工具调用的测试...")
|
||||||
|
start_time = time.time()
|
||||||
|
response = await test_with_tool_calls()
|
||||||
|
end_time = time.time()
|
||||||
|
elapsed = end_time - start_time
|
||||||
|
times_with_tools.append(elapsed)
|
||||||
|
responses_with_tools.append(response)
|
||||||
|
print(f" - 耗时: {elapsed:.2f}秒")
|
||||||
|
|
||||||
|
# 计算统计数据
|
||||||
|
results_without_tools = {
|
||||||
|
"平均耗时": statistics.mean(times_without_tools),
|
||||||
|
"最短耗时": min(times_without_tools),
|
||||||
|
"最长耗时": max(times_without_tools),
|
||||||
|
"标准差": statistics.stdev(times_without_tools) if len(times_without_tools) > 1 else 0,
|
||||||
|
"所有耗时": times_without_tools,
|
||||||
|
"响应结果": responses_without_tools,
|
||||||
|
}
|
||||||
|
|
||||||
|
results_with_tools = {
|
||||||
|
"平均耗时": statistics.mean(times_with_tools),
|
||||||
|
"最短耗时": min(times_with_tools),
|
||||||
|
"最长耗时": max(times_with_tools),
|
||||||
|
"标准差": statistics.stdev(times_with_tools) if len(times_with_tools) > 1 else 0,
|
||||||
|
"所有耗时": times_with_tools,
|
||||||
|
"响应结果": responses_with_tools,
|
||||||
|
}
|
||||||
|
|
||||||
|
return results_without_tools, results_with_tools
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
"""主测试函数"""
|
"""主测试函数"""
|
||||||
print("=" * 50)
|
print("=" * 50)
|
||||||
@@ -201,15 +271,10 @@ async def main():
|
|||||||
print("=" * 50)
|
print("=" * 50)
|
||||||
|
|
||||||
# 设置测试迭代次数
|
# 设置测试迭代次数
|
||||||
iterations = 3
|
iterations = 10
|
||||||
|
|
||||||
# 测试不使用工具调用
|
# 执行交替测试
|
||||||
results_without_tools = await run_test("不使用工具调用", test_without_tool_calls, iterations)
|
results_without_tools, results_with_tools = await run_alternating_tests(iterations)
|
||||||
|
|
||||||
print("\n" + "-" * 50 + "\n")
|
|
||||||
|
|
||||||
# 测试使用工具调用
|
|
||||||
results_with_tools = await run_test("使用工具调用", test_with_tool_calls, iterations)
|
|
||||||
|
|
||||||
# 显示结果比较
|
# 显示结果比较
|
||||||
print("\n" + "=" * 50)
|
print("\n" + "=" * 50)
|
||||||
|
|||||||
Reference in New Issue
Block a user