feat: 现在使用工具调用来更新关系和心情而不是固定更新

This commit is contained in:
SengokuCola
2025-04-14 00:36:33 +08:00
parent d1bbda9e60
commit 7eba42f84a
16 changed files with 551 additions and 87 deletions

View File

@@ -0,0 +1,58 @@
from src.do_tool.tool_can_use.base_tool import BaseTool, register_tool
from src.plugins.config.config import global_config
from src.common.logger import get_module_logger
from src.plugins.moods.moods import MoodManager
from src.plugins.chat_module.think_flow_chat.think_flow_generator import ResponseGenerator
from typing import Dict, Any
logger = get_module_logger("change_mood_tool")
class ChangeMoodTool(BaseTool):
"""改变心情的工具"""
name = "change_mood"
description = "根据收到的内容和自身回复的内容,改变心情,当你回复了别人的消息,你可以使用这个工具"
parameters = {
"type": "object",
"properties": {
"text": {"type": "string", "description": "引起你改变心情的文本"},
"response_set": {"type": "list", "description": "你对文本的回复"}
},
"required": ["text", "response_set"],
}
async def execute(self, function_args: Dict[str, Any],message_txt:str) -> Dict[str, Any]:
"""执行心情改变
Args:
function_args: 工具参数
message_processed_plain_text: 原始消息文本
response_set: 原始消息文本
Returns:
Dict: 工具执行结果
"""
try:
response_set = function_args.get("response_set")
message_processed_plain_text = function_args.get("text")
mood_manager = MoodManager.get_instance()
gpt = ResponseGenerator()
if response_set is None:
response_set = ["你还没有回复"]
ori_response = ",".join(response_set)
_stance, emotion = await gpt._get_emotion_tags(ori_response, message_processed_plain_text)
mood_manager.update_mood_from_emotion(emotion, global_config.mood_intensity_factor)
return {"name": "change_mood", "content": f"你的心情刚刚变化了,现在的心情是: {emotion}"}
except Exception as e:
logger.error(f"心情改变工具执行失败: {str(e)}")
return {"name": "change_mood", "content": f"心情改变失败: {str(e)}"}
# 注册工具
# register_tool(ChangeMoodTool)

View File

@@ -0,0 +1,53 @@
from src.plugins.person_info.relationship_manager import relationship_manager
from src.common.logger import get_module_logger
from src.do_tool.tool_can_use.base_tool import BaseTool
from src.plugins.chat_module.think_flow_chat.think_flow_generator import ResponseGenerator
logger = get_module_logger("relationship_tool")
class RelationshipTool(BaseTool):
name = "change_relationship"
description = "根据收到的文本和回复内容,修改与特定用户的关系值,当你回复了别人的消息,你可以使用这个工具"
parameters = {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "收到的文本"
},
"changed_value": {
"type": "number",
"description": "变更值"
},
"reason": {
"type": "string",
"description": "变更原因"
}
},
"required": ["text", "changed_value", "reason"]
}
async def execute(self, args: dict,message_txt:str) -> dict:
"""执行工具功能
Args:
args: 包含工具参数的字典
text: 原始消息文本
changed_value: 变更值
reason: 变更原因
Returns:
dict: 包含执行结果的字典
"""
try:
text = args.get("text")
changed_value = args.get("changed_value")
reason = args.get("reason")
return {"content": f"因为你刚刚因为{reason},所以你和发[{text}]这条消息的人的关系值变化为{changed_value}"}
except Exception as e:
logger.error(f"修改关系值时发生错误: {str(e)}")
return {"content": f"修改关系值失败: {str(e)}"}

View File

@@ -47,4 +47,4 @@ class CompareNumbersTool(BaseTool):
# 注册工具
register_tool(CompareNumbersTool)
# register_tool(CompareNumbersTool)

View File

@@ -51,4 +51,4 @@ class GetCurrentTaskTool(BaseTool):
# 注册工具
register_tool(GetCurrentTaskTool)
# register_tool(GetCurrentTaskTool)

View File

@@ -132,4 +132,4 @@ class SearchKnowledgeTool(BaseTool):
# 注册工具
register_tool(SearchKnowledgeTool)
# register_tool(SearchKnowledgeTool)

View File

@@ -56,4 +56,4 @@ class GetMemoryTool(BaseTool):
# 注册工具
register_tool(GetMemoryTool)
# register_tool(GetMemoryTool)

View File

@@ -21,7 +21,7 @@ class ToolUser:
model=global_config.llm_heartflow, temperature=0.2, max_tokens=1000, request_type="tool_use"
)
async def _build_tool_prompt(self, message_txt: str, sender_name: str, chat_stream: ChatStream):
async def _build_tool_prompt(self, message_txt: str, sender_name: str, chat_stream: ChatStream, reply_message:str = ""):
"""构建工具使用的提示词
Args:
@@ -45,9 +45,11 @@ class ToolUser:
prompt = ""
prompt += "你正在思考如何回复群里的消息。\n"
prompt += f"你注意到{sender_name}刚刚说:{message_txt}\n"
if reply_message:
prompt += f"你刚刚回复的内容是:{reply_message}\n"
prompt += f"注意你就是{bot_name}{bot_name}指的就是你。"
prompt += "你现在需要对群里的聊天内容进行回复,现在请你思考,你是否需要额外的信息,或者一些工具来帮你回复,不要使用危险功能(比如文件操作或者系统操作爬虫),比如回忆或者搜寻已有的知识,或者了解你现在正在做什么,请输出你需要的工具,或者你需要的额外信息。"
prompt += "你现在需要对群里的聊天内容进行回复,现在选择工具来对消息和你的回复进行处理,你是否需要额外的信息,或者进行一些动作,比如回忆或者搜寻已有的知识,改变关系和情感,或者了解你现在正在做什么,请输出你需要的工具,或者你需要的额外信息。"
return prompt
def _define_tools(self):
@@ -81,10 +83,26 @@ class ToolUser:
# 执行工具
result = await tool_instance.execute(function_args, message_txt)
if result:
# 根据工具名称确定类型标签
tool_type = ""
if "memory" in function_name.lower():
tool_type = "memory"
elif "schedule" in function_name.lower() or "task" in function_name.lower():
tool_type = "schedule"
elif "knowledge" in function_name.lower():
tool_type = "knowledge"
elif "change_relationship" in function_name.lower():
tool_type = "change_relationship"
elif "change_mood" in function_name.lower():
tool_type = "change_mood"
else:
tool_type = "other"
return {
"tool_call_id": tool_call["id"],
"role": "tool",
"name": function_name,
"type": tool_type,
"content": result["content"],
}
return None
@@ -101,7 +119,7 @@ class ToolUser:
chat_stream: 聊天流对象
Returns:
dict: 工具使用结果
dict: 工具使用结果,包含结构化的信息
"""
try:
# 构建提示词
@@ -109,6 +127,7 @@ class ToolUser:
# 定义可用工具
tools = self._define_tools()
logger.trace(f"工具定义: {tools}")
# 使用llm_model_tool发送带工具定义的请求
payload = {
@@ -119,7 +138,7 @@ class ToolUser:
"temperature": 0.2,
}
logger.debug(f"发送工具调用请求,模型: {self.llm_model_tool.model_name}")
logger.trace(f"发送工具调用请求,模型: {self.llm_model_tool.model_name}")
# 发送请求获取模型是否需要调用工具
response = await self.llm_model_tool._execute_request(
endpoint="/chat/completions", payload=payload, prompt=prompt
@@ -128,36 +147,50 @@ class ToolUser:
# 根据返回值数量判断是否有工具调用
if len(response) == 3:
content, reasoning_content, tool_calls = response
logger.info(f"工具思考: {tool_calls}")
# logger.info(f"工具思考: {tool_calls}")
# logger.debug(f"工具思考: {content}")
# 检查响应中工具调用是否有效
if not tool_calls:
logger.info("模型返回了空的tool_calls列表")
logger.debug("模型返回了空的tool_calls列表")
return {"used_tools": False}
logger.info(f"模型请求调用{len(tool_calls)}个工具")
tool_calls_str = ""
for tool_call in tool_calls:
tool_calls_str += f"{tool_call['function']['name']}\n"
logger.info(f"模型请求调用{len(tool_calls)}个工具: {tool_calls_str}")
tool_results = []
collected_info = ""
structured_info = {
"memory": [],
"schedule": [],
"knowledge": [],
"change_relationship": [],
"change_mood": [],
"other": []
}
# 执行所有工具调用
for tool_call in tool_calls:
result = await self._execute_tool_call(tool_call, message_txt)
if result:
tool_results.append(result)
# 将工具结果添加到收集的信息
collected_info += f"\n{result['name']}返回结果: {result['content']}\n"
# 将工具结果添加到对应类型的列表
structured_info[result["type"]].append({
"name": result["name"],
"content": result["content"]
})
# 如果有工具结果,直接返回收集的信息
if collected_info:
logger.info(f"工具调用收集到信息: {collected_info}")
# 如果有工具结果,返回结构化的信息
if any(structured_info.values()):
logger.info(f"工具调用收集到结构化信息: {json.dumps(structured_info, ensure_ascii=False)}")
return {
"used_tools": True,
"collected_info": collected_info,
"structured_info": structured_info
}
else:
# 没有工具调用
content, reasoning_content = response
logger.info("模型没有请求调用任何工具")
logger.debug("模型没有请求调用任何工具")
# 如果没有工具调用或处理失败,直接返回原始思考
return {

82
src/heart_flow/README.md Normal file
View File

@@ -0,0 +1,82 @@
# 心流系统 (Heart Flow System)
心流系统是一个模拟AI机器人内心思考和情感流动的核心系统。它通过多层次的心流结构使AI能够对外界信息进行观察、思考和情感反应从而产生更自然的对话和行为。
## 系统架构
### 1. 主心流 (Heartflow)
- 位于 `heartflow.py`
- 作为整个系统的主控制器
- 负责管理和协调多个子心流
- 维护AI的整体思维状态
- 定期进行全局思考更新
### 2. 子心流 (SubHeartflow)
- 位于 `sub_heartflow.py`
- 处理具体的对话场景(如群聊)
- 维护特定场景下的思维状态
- 通过观察者模式接收和处理信息
- 能够进行独立的思考和回复判断
### 3. 观察系统 (Observation)
- 位于 `observation.py`
- 负责收集和处理外部信息
- 支持多种观察类型(如聊天观察)
- 对信息进行实时总结和更新
## 主要功能
### 思维系统
- 定期进行思维更新
- 维护短期记忆和思维连续性
- 支持多层次的思维处理
### 情感系统
- 情绪状态管理
- 回复意愿判断
- 情感因素影响决策
### 交互系统
- 群聊消息处理
- 多场景并行处理
- 智能回复生成
## 工作流程
1. 主心流启动并创建必要的子心流
2. 子心流通过观察者接收外部信息
3. 系统进行信息处理和思维更新
4. 根据情感状态和思维结果决定是否回复
5. 生成合适的回复并更新思维状态
## 使用说明
### 创建新的子心流
```python
heartflow = Heartflow()
subheartflow = heartflow.create_subheartflow(chat_id)
```
### 添加观察者
```python
observation = ChattingObservation(chat_id)
subheartflow.add_observation(observation)
```
### 启动心流系统
```python
await heartflow.heartflow_start_working()
```
## 配置说明
系统的主要配置参数:
- `sub_heart_flow_stop_time`: 子心流停止时间
- `sub_heart_flow_freeze_time`: 子心流冻结时间
- `heart_flow_update_interval`: 心流更新间隔
## 注意事项
1. 子心流会在长时间不活跃后自动清理
2. 需要合理配置更新间隔以平衡性能和响应速度
3. 观察系统会限制消息处理数量以避免过载

View File

@@ -18,7 +18,6 @@ import random
from src.plugins.chat.chat_stream import ChatStream
from src.plugins.person_info.relationship_manager import relationship_manager
from src.plugins.chat.utils import get_recent_group_speaker
from src.do_tool.tool_use import ToolUser
from ..plugins.utils.prompt_builder import Prompt, global_prompt_manager
subheartflow_config = LogConfig(
@@ -32,7 +31,7 @@ logger = get_module_logger("subheartflow", config=subheartflow_config)
def init_prompt():
prompt = ""
# prompt += f"麦麦的总体想法是:{self.main_heartflow_info}\n\n"
prompt += "{collected_info}\n"
prompt += "{extra_info}\n"
prompt += "{relation_prompt_all}\n"
prompt += "{prompt_personality}\n"
prompt += "刚刚你的想法是{current_thinking_info}。如果有新的内容,记得转换话题\n"
@@ -47,6 +46,7 @@ def init_prompt():
Prompt(prompt, "sub_heartflow_prompt_before")
prompt = ""
# prompt += f"你现在正在做的事情是:{schedule_info}\n"
prompt += "{extra_info}\n"
prompt += "{prompt_personality}\n"
prompt += "现在你正在上网和qq群里的网友们聊天群里正在聊的话题是{chat_observe_info}\n"
prompt += "刚刚你的想法是{current_thinking_info}"
@@ -97,7 +97,7 @@ class SubHeartflow:
self.bot_name = global_config.BOT_NICKNAME
self.tool_user = ToolUser()
def add_observation(self, observation: Observation):
"""添加一个新的observation对象到列表中如果已存在相同id的observation则不添加"""
@@ -151,25 +151,14 @@ class SubHeartflow:
observation = self.observations[0]
await observation.observe()
async def do_thinking_before_reply(self, message_txt: str, sender_name: str, chat_stream: ChatStream):
async def do_thinking_before_reply(self, message_txt: str, sender_name: str, chat_stream: ChatStream, extra_info: str):
current_thinking_info = self.current_mind
mood_info = self.current_state.mood
# mood_info = "你很生气,很愤怒"
observation = self.observations[0]
chat_observe_info = observation.observe_info
# print(f"chat_observe_info{chat_observe_info}")
# 首先尝试使用工具获取更多信息
tool_result = await self.tool_user.use_tool(message_txt, sender_name, chat_stream)
# 如果工具被使用且获得了结果,将收集到的信息合并到思考中
collected_info = ""
if tool_result.get("used_tools", False):
logger.info("使用工具收集了信息")
# 如果有收集到的信息,将其添加到当前思考中
if "collected_info" in tool_result:
collected_info = tool_result["collected_info"]
# 开始构建prompt
prompt_personality = f"你的名字是{self.bot_name},你"
@@ -226,7 +215,7 @@ class SubHeartflow:
# prompt += f"记得结合上述的消息,生成内心想法,文字不要浮夸,注意你就是{self.bot_name}{self.bot_name}指的就是你。"
prompt = (await global_prompt_manager.get_prompt_async("sub_heartflow_prompt_before")).format(
collected_info,
extra_info,
relation_prompt_all,
prompt_personality,
current_thinking_info,
@@ -250,7 +239,7 @@ class SubHeartflow:
logger.info(f"麦麦的思考前脑内状态:{self.current_mind}")
return self.current_mind, self.past_mind
async def do_thinking_after_reply(self, reply_content, chat_talking_prompt):
async def do_thinking_after_reply(self, reply_content, chat_talking_prompt, extra_info):
# print("麦麦回复之后脑袋转起来了")
# 开始构建prompt
@@ -277,20 +266,15 @@ class SubHeartflow:
message_new_info = chat_talking_prompt
reply_info = reply_content
# schedule_info = bot_schedule.get_current_num_task(num=1, time_info=False)
# prompt = ""
# # prompt += f"你现在正在做的事情是:{schedule_info}\n"
# prompt += f"{prompt_personality}\n"
# prompt += f"现在你正在上网和qq群里的网友们聊天群里正在聊的话题是{chat_observe_info}\n"
# prompt += f"刚刚你的想法是{current_thinking_info}。"
# prompt += f"你现在看到了网友们发的新消息:{message_new_info}\n"
# prompt += f"你刚刚回复了群友们:{reply_info}"
# prompt += f"你现在{mood_info}"
# prompt += "现在你接下去继续思考,产生新的想法,记得保留你刚刚的想法,不要分点输出,输出连贯的内心独白"
# prompt += "不要太长,但是记得结合上述的消息,要记得你的人设,关注聊天和新内容,关注你回复的内容,不要思考太多:"
prompt = (await global_prompt_manager.get_prompt_async("sub_heartflow_prompt_after")).format(
prompt_personality, chat_observe_info, current_thinking_info, message_new_info, reply_info, mood_info
extra_info,
prompt_personality,
chat_observe_info,
current_thinking_info,
message_new_info,
reply_info,
mood_info,
)
try:

View File

@@ -21,6 +21,7 @@ from ...person_info.relationship_manager import relationship_manager
from ...chat.message_buffer import message_buffer
from src.plugins.respon_info_catcher.info_catcher import info_catcher_manager
from ...utils.timer_calculater import Timer
from src.do_tool.tool_use import ToolUser
# 定义日志配置
chat_config = LogConfig(
@@ -37,6 +38,7 @@ class ThinkFlowChat:
self.gpt = ResponseGenerator()
self.mood_manager = MoodManager.get_instance()
self.mood_manager.start_mood_update()
self.tool_user = ToolUser()
async def _create_thinking_message(self, message, chat, userinfo, messageinfo):
"""创建思考消息"""
@@ -110,14 +112,10 @@ class ThinkFlowChat:
"""处理表情包"""
if random() < global_config.emoji_chance:
emoji_raw = await emoji_manager.get_emoji_for_text(response)
# print("11111111111111")
# logger.info(emoji_raw)
if emoji_raw:
emoji_path, description = emoji_raw
emoji_cq = image_path_to_base64(emoji_path)
# logger.info(emoji_cq)
thinking_time_point = round(message.message_info.time, 2)
message_segment = Seg(type="emoji", data=emoji_cq)
@@ -136,19 +134,9 @@ class ThinkFlowChat:
is_emoji=True,
)
# logger.info("22222222222222")
message_manager.add_message(bot_message)
async def _update_using_response(self, message, response_set):
"""更新心流状态"""
stream_id = message.chat_stream.stream_id
chat_talking_prompt = ""
if stream_id:
chat_talking_prompt = get_recent_group_detailed_plain_text(
stream_id, limit=global_config.MAX_CONTEXT_SIZE, combine=True
)
await heartflow.get_subheartflow(stream_id).do_thinking_after_reply(response_set, chat_talking_prompt)
async def _update_relationship(self, message: MessageRecv, response_set):
"""更新关系情绪"""
@@ -224,13 +212,6 @@ class ThinkFlowChat:
logger.info("触发缓冲,已炸飞消息列")
return
# 计算回复意愿
# current_willing_old = willing_manager.get_willing(chat_stream=chat)
# # current_willing_new = (heartflow.get_subheartflow(chat.stream_id).current_state.willing - 5) / 4
# # current_willing = (current_willing_old + current_willing_new) / 2
# # 有点bug
# current_willing = current_willing_old
# 获取回复概率
is_willing = False
if reply_probability != 1:
@@ -266,7 +247,7 @@ class ThinkFlowChat:
except Exception as e:
logger.error(f"心流创建思考消息失败: {e}")
logger.debug(f"创建捕捉器thinking_id:{thinking_id}")
logger.trace(f"创建捕捉器thinking_id:{thinking_id}")
info_catcher = info_catcher_manager.get_info_catcher(thinking_id)
info_catcher.catch_decide_to_response(message)
@@ -279,7 +260,72 @@ class ThinkFlowChat:
logger.error(f"心流观察失败: {e}")
info_catcher.catch_after_observe(timing_results["观察"])
# 思考前使用工具
update_relationship = ""
try:
with Timer("思考前使用工具", timing_results):
tool_result = await self.tool_user.use_tool(message.processed_plain_text, message.message_info.user_info.user_nickname, chat)
# 如果工具被使用且获得了结果,将收集到的信息合并到思考中
collected_info = ""
if tool_result.get("used_tools", False):
# 如果有收集到的结构化信息,将其格式化后添加到当前思考中
if "structured_info" in tool_result:
info = tool_result["structured_info"]
# 处理记忆信息
if info["memory"]:
collected_info += "\n记忆相关信息:\n"
for mem in info["memory"]:
collected_info += f"- {mem['name']}: {mem['content']}\n"
# 处理日程信息
if info["schedule"]:
collected_info += "\n日程相关信息:\n"
for sch in info["schedule"]:
collected_info += f"- {sch['name']}: {sch['content']}\n"
# 处理知识信息
if info["knowledge"]:
collected_info += "\n知识相关信息:\n"
for know in info["knowledge"]:
collected_info += f"- {know['name']}: {know['content']}\n"
# 处理关系信息
if info["change_relationship"]:
collected_info += "\n关系相关信息:\n"
for rel in info["change_relationship"]:
collected_info += f"- {rel['name']}: {rel['content']}\n"
# print("11111111111111111111111111111")
update_relationship += rel["content"]
# print(f"11111111111111111111111111111{update_relationship}")
# 处理心情信息
if info["change_mood"]:
collected_info += "\n心情相关信息:\n"
for mood in info["change_mood"]:
collected_info += f"- {mood['name']}: {mood['content']}\n"
# 处理其他信息
if info["other"]:
collected_info += "\n其他相关信息:\n"
for other in info["other"]:
collected_info += f"- {other['name']}: {other['content']}\n"
except Exception as e:
logger.error(f"思考前工具调用失败: {e}")
logger.error(traceback.format_exc())
if update_relationship:
# ori_response = ",".join(response_set)
# print("22222222222222222222222222222")
stance, emotion = await self.gpt._get_emotion_tags_with_reason("你还没有回复", message.processed_plain_text,update_relationship)
await relationship_manager.calculate_update_relationship_value(
chat_stream=message.chat_stream, label=emotion, stance=stance
)
print("33333333333333333333333333333")
# 思考前脑内状态
try:
with Timer("思考前脑内状态", timing_results):
@@ -289,6 +335,7 @@ class ThinkFlowChat:
message_txt=message.processed_plain_text,
sender_name=message.message_info.user_info.user_nickname,
chat_stream=chat,
extra_info=collected_info
)
except Exception as e:
logger.error(f"心流思考前脑内状态失败: {e}")
@@ -323,19 +370,80 @@ class ThinkFlowChat:
except Exception as e:
logger.error(f"心流处理表情包失败: {e}")
# 更新心流
try:
with Timer("更新心流", timing_results):
await self._update_using_response(message, response_set)
except Exception as e:
logger.error(f"心流更新失败: {e}")
# 更新关系情绪
# 思考后使用工具
try:
with Timer("更新关系情绪", timing_results):
await self._update_relationship(message, response_set)
with Timer("思考后使用工具", timing_results):
tool_result = await self.tool_user.use_tool(message.processed_plain_text, message.message_info.user_info.user_nickname, chat)
# 如果工具被使用且获得了结果,将收集到的信息合并到思考中
collected_info = ""
if tool_result.get("used_tools", False):
# 如果有收集到的结构化信息,将其格式化后添加到当前思考中
if "structured_info" in tool_result:
info = tool_result["structured_info"]
# 处理记忆信息
if info["memory"]:
collected_info += "\n记忆相关信息:\n"
for mem in info["memory"]:
collected_info += f"- {mem['name']}: {mem['content']}\n"
# 处理日程信息
if info["schedule"]:
collected_info += "\n日程相关信息:\n"
for sch in info["schedule"]:
collected_info += f"- {sch['name']}: {sch['content']}\n"
# 处理知识信息
if info["knowledge"]:
collected_info += "\n知识相关信息:\n"
for know in info["knowledge"]:
collected_info += f"- {know['name']}: {know['content']}\n"
# 处理关系信息
if info["change_relationship"]:
collected_info += "\n关系相关信息:\n"
for rel in info["change_relationship"]:
collected_info += f"- {rel['name']}: {rel['content']}\n"
# 处理心情信息
if info["change_mood"]:
collected_info += "\n心情相关信息:\n"
for mood in info["change_mood"]:
collected_info += f"- {mood['name']}: {mood['content']}\n"
# 处理其他信息
if info["other"]:
collected_info += "\n其他相关信息:\n"
for other in info["other"]:
collected_info += f"- {other['name']}: {other['content']}\n"
except Exception as e:
logger.error(f"心流更新关系情绪失败: {e}")
logger.error(f"思考后工具调用失败: {e}")
logger.error(traceback.format_exc())
# 更新关系
if info["change_relationship"]:
ori_response = ",".join(response_set)
stance, emotion = await self.gpt._get_emotion_tags(ori_response, message.processed_plain_text,info["change_relationship"]["content"])
await relationship_manager.calculate_update_relationship_value(
chat_stream=message.chat_stream, label=emotion, stance=stance
)
try:
with Timer("思考后脑内状态更新", timing_results):
stream_id = message.chat_stream.stream_id
chat_talking_prompt = ""
if stream_id:
chat_talking_prompt = get_recent_group_detailed_plain_text(
stream_id, limit=global_config.MAX_CONTEXT_SIZE, combine=True
)
await heartflow.get_subheartflow(stream_id).do_thinking_after_reply(response_set, chat_talking_prompt,collected_info)
except Exception as e:
logger.error(f"心流思考后脑内状态更新失败: {e}")
# 回复后处理
await willing_manager.after_generate_reply_handle(message.message_info.message_id)

View File

@@ -225,6 +225,58 @@ class ResponseGenerator:
except Exception as e:
logger.debug(f"获取情感标签时出错: {e}")
return "中立", "平静" # 出错时返回默认值
async def _get_emotion_tags_with_reason(self, content: str, processed_plain_text: str, reason: str):
"""提取情感标签,结合立场和情绪"""
try:
# 构建提示词,结合回复内容、被回复的内容以及立场分析
prompt = f"""
请严格根据以下对话内容,完成以下任务:
1. 判断回复者对被回复者观点的直接立场:
- "支持":明确同意或强化被回复者观点
- "反对":明确反驳或否定被回复者观点
- "中立":不表达明确立场或无关回应
2. 从"开心,愤怒,悲伤,惊讶,平静,害羞,恐惧,厌恶,困惑"中选出最匹配的1个情感标签
3. 按照"立场-情绪"的格式直接输出结果,例如:"反对-愤怒"
4. 考虑回复者的人格设定为{global_config.personality_core}
对话示例:
被回复「A就是笨」
回复「A明明很聪明」 → 反对-愤怒
当前对话:
被回复:「{processed_plain_text}
回复:「{content}
原因:「{reason}
输出要求:
- 只需输出"立场-情绪"结果,不要解释
- 严格基于文字直接表达的对立关系判断
"""
# 调用模型生成结果
result, _, _ = await self.model_sum.generate_response(prompt)
result = result.strip()
# 解析模型输出的结果
if "-" in result:
stance, emotion = result.split("-", 1)
valid_stances = ["支持", "反对", "中立"]
valid_emotions = ["开心", "愤怒", "悲伤", "惊讶", "害羞", "平静", "恐惧", "厌恶", "困惑"]
if stance in valid_stances and emotion in valid_emotions:
return stance, emotion # 返回有效的立场-情绪组合
else:
logger.debug(f"无效立场-情感组合:{result}")
return "中立", "平静" # 默认返回中立-平静
else:
logger.debug(f"立场-情感格式错误:{result}")
return "中立", "平静" # 格式错误时返回默认值
except Exception as e:
logger.debug(f"获取情感标签时出错: {e}")
return "中立", "平静" # 出错时返回默认值
async def _process_response(self, content: str) -> List[str]:
"""处理响应内容,返回处理后的内容和情感标签"""

View File

@@ -436,7 +436,7 @@ class Hippocampus:
activation_values[neighbor] = new_activation
visited_nodes.add(neighbor)
nodes_to_process.append((neighbor, new_activation, current_depth + 1))
logger.debug(
logger.trace(
f"节点 '{neighbor}' 被激活,激活值: {new_activation:.2f} (通过 '{current_node}' 连接,强度: {strength}, 深度: {current_depth + 1})"
) # noqa: E501
@@ -1144,7 +1144,7 @@ class Hippocampus:
activation_values[neighbor] = new_activation
visited_nodes.add(neighbor)
nodes_to_process.append((neighbor, new_activation, current_depth + 1))
logger.debug(
logger.trace(
f"节点 '{neighbor}' 被激活,激活值: {new_activation:.2f} (通过 '{current_node}' 连接,强度: {strength}, 深度: {current_depth + 1})"
) # noqa: E501

View File

@@ -98,7 +98,7 @@ class LLM_request:
"timestamp": datetime.now(),
}
db.llm_usage.insert_one(usage_data)
logger.debug(
logger.trace(
f"Token使用情况 - 模型: {self.model_name}, "
f"用户: {user_id}, 类型: {request_type}, "
f"提示词: {prompt_tokens}, 完成: {completion_tokens}, "

View File

@@ -117,7 +117,7 @@ class PersonInfoManager:
return document[field_name]
else:
default_value = copy.deepcopy(person_info_default[field_name])
logger.debug(f"获取{person_id}{field_name}失败,已返回默认值{default_value}")
logger.trace(f"获取{person_id}{field_name}失败,已返回默认值{default_value}")
return default_value
async def get_values(self, person_id: str, field_names: list) -> dict:

View File

@@ -75,7 +75,7 @@ class RelationshipManager:
else:
return mood_value / coefficient
async def calculate_update_relationship_value(self, chat_stream: ChatStream, label: str, stance: str) -> None:
async def calculate_update_relationship_value(self, chat_stream: ChatStream, label: str, stance: str) -> tuple:
"""计算并变更关系值
新的关系值变更计算方式:
将关系值限定在-1000到1000
@@ -84,6 +84,10 @@ class RelationshipManager:
2.关系越差,改善越难,关系越好,恶化越容易
3.人维护关系的精力往往有限,所以当高关系值用户越多,对于中高关系值用户增长越慢
4.连续正面或负面情感会正反馈
返回:
用户昵称,变更值,变更后关系等级
"""
stancedict = {
"支持": 0,
@@ -147,6 +151,7 @@ class RelationshipManager:
level_num = self.calculate_level_num(old_value + value)
relationship_level = ["厌恶", "冷漠", "一般", "友好", "喜欢", "暧昧"]
logger.info(
f"用户: {chat_stream.user_info.user_nickname}"
f"当前关系: {relationship_level[level_num]}, "
f"关系值: {old_value:.2f}, "
f"当前立场情感: {stance}-{label}, "
@@ -154,6 +159,95 @@ class RelationshipManager:
)
await person_info_manager.update_one_field(person_id, "relationship_value", old_value + value, data)
return chat_stream.user_info.user_nickname,value,relationship_level[level_num]
async def calculate_update_relationship_value_with_reason(self, chat_stream: ChatStream, label: str, stance: str, reason: str) -> tuple:
"""计算并变更关系值
新的关系值变更计算方式:
将关系值限定在-1000到1000
对于关系值的变更,期望:
1.向两端逼近时会逐渐减缓
2.关系越差,改善越难,关系越好,恶化越容易
3.人维护关系的精力往往有限,所以当高关系值用户越多,对于中高关系值用户增长越慢
4.连续正面或负面情感会正反馈
返回:
用户昵称,变更值,变更后关系等级
"""
stancedict = {
"支持": 0,
"中立": 1,
"反对": 2,
}
valuedict = {
"开心": 1.5,
"愤怒": -2.0,
"悲伤": -0.5,
"惊讶": 0.6,
"害羞": 2.0,
"平静": 0.3,
"恐惧": -1.5,
"厌恶": -1.0,
"困惑": 0.5,
}
person_id = person_info_manager.get_person_id(chat_stream.user_info.platform, chat_stream.user_info.user_id)
data = {
"platform": chat_stream.user_info.platform,
"user_id": chat_stream.user_info.user_id,
"nickname": chat_stream.user_info.user_nickname,
"konw_time": int(time.time()),
}
old_value = await person_info_manager.get_value(person_id, "relationship_value")
old_value = self.ensure_float(old_value, person_id)
if old_value > 1000:
old_value = 1000
elif old_value < -1000:
old_value = -1000
value = valuedict[label]
if old_value >= 0:
if valuedict[label] >= 0 and stancedict[stance] != 2:
value = value * math.cos(math.pi * old_value / 2000)
if old_value > 500:
rdict = await person_info_manager.get_specific_value_list("relationship_value", lambda x: x > 700)
high_value_count = len(rdict)
if old_value > 700:
value *= 3 / (high_value_count + 2) # 排除自己
else:
value *= 3 / (high_value_count + 3)
elif valuedict[label] < 0 and stancedict[stance] != 0:
value = value * math.exp(old_value / 2000)
else:
value = 0
elif old_value < 0:
if valuedict[label] >= 0 and stancedict[stance] != 2:
value = value * math.exp(old_value / 2000)
elif valuedict[label] < 0 and stancedict[stance] != 0:
value = value * math.cos(math.pi * old_value / 2000)
else:
value = 0
self.positive_feedback_sys(label, stance)
value = self.mood_feedback(value)
level_num = self.calculate_level_num(old_value + value)
relationship_level = ["厌恶", "冷漠", "一般", "友好", "喜欢", "暧昧"]
logger.info(
f"用户: {chat_stream.user_info.user_nickname}"
f"当前关系: {relationship_level[level_num]}, "
f"关系值: {old_value:.2f}, "
f"当前立场情感: {stance}-{label}, "
f"变更: {value:+.5f}"
)
await person_info_manager.update_one_field(person_id, "relationship_value", old_value + value, data)
return chat_stream.user_info.user_nickname,value,relationship_level[level_num]
async def build_relationship_info(self, person) -> str:
person_id = person_info_manager.get_person_id(person[0], person[1])

View File

@@ -189,7 +189,7 @@ pri_out = 16 #模型的输出价格(非必填,可以记录消耗)
#非推理模型
[model.llm_normal] #V3 回复模型1 主要回复模型
[model.llm_normal] #V3 回复模型1 主要回复模型默认temp 0.2 如果你使用的是老V3或者其他模型请自己修改代码中的temp参数
name = "Pro/deepseek-ai/DeepSeek-V3"
provider = "SILICONFLOW"
pri_in = 2 #模型的输入价格(非必填,可以记录消耗)