diff --git a/src/plugins/chat/bot.py b/src/plugins/chat/bot.py
index 794e3ac22..685fb0ea9 100644
--- a/src/plugins/chat/bot.py
+++ b/src/plugins/chat/bot.py
@@ -83,7 +83,7 @@ class ChatBot:
chat_stream=chat,
)
await relationship_manager.update_relationship_value(
- chat_stream=chat, relationship_value=0.5
+ chat_stream=chat, relationship_value=0
)
await message.process()
@@ -255,20 +255,11 @@ class ChatBot:
)
message_manager.add_message(bot_message)
- emotion = await self.gpt._get_emotion_tags(raw_content)
- logger.debug(f"为 '{response}' 获取到的情感标签为:{emotion}")
- valuedict = {
- "happy": 0.5,
- "angry": -1,
- "sad": -0.5,
- "surprised": 0.2,
- "disgusted": -1.5,
- "fearful": -0.7,
- "neutral": 0.1,
- }
- await relationship_manager.update_relationship_value(
- chat_stream=chat, relationship_value=valuedict[emotion[0]]
- )
+ # 获取立场和情感标签,更新关系值
+ stance, emotion = await self.gpt._get_emotion_tags(raw_content, message.processed_plain_text)
+ logger.debug(f"为 '{response}' 立场为:{stance} 获取到的情感标签为:{emotion}")
+ await relationship_manager.calculate_update_relationship_value(chat_stream=chat, label=emotion, stance=stance)
+
# 使用情绪管理器更新情绪
self.mood_manager.update_mood_from_emotion(
emotion[0], global_config.mood_intensity_factor
diff --git a/src/plugins/chat/llm_generator.py b/src/plugins/chat/llm_generator.py
index 5fb400b10..192399134 100644
--- a/src/plugins/chat/llm_generator.py
+++ b/src/plugins/chat/llm_generator.py
@@ -63,25 +63,19 @@ class ResponseGenerator:
async def _generate_response_with_model(self, message: MessageThinking, model: LLM_request) -> Optional[str]:
"""使用指定的模型生成回复"""
- sender_name = message.chat_stream.user_info.user_nickname or f"用户{message.chat_stream.user_info.user_id}"
- if message.chat_stream.user_info.user_cardname:
+ sender_name = ""
+ if message.chat_stream.user_info.user_cardname and message.chat_stream.user_info.user_nickname:
sender_name = f"[({message.chat_stream.user_info.user_id}){message.chat_stream.user_info.user_nickname}]{message.chat_stream.user_info.user_cardname}"
-
- # 获取关系值
- relationship_value = (
- relationship_manager.get_relationship(message.chat_stream).relationship_value
- if relationship_manager.get_relationship(message.chat_stream)
- else 0.0
- )
- if relationship_value != 0.0:
- # print(f"\033[1;32m[关系管理]\033[0m 回复中_当前关系值: {relationship_value}")
- pass
+ elif message.chat_stream.user_info.user_nickname:
+ sender_name = f"({message.chat_stream.user_info.user_id}){message.chat_stream.user_info.user_nickname}"
+ else:
+ sender_name = f"用户({message.chat_stream.user_info.user_id})"
# 构建prompt
prompt, prompt_check = await prompt_builder._build_prompt(
+ message.chat_stream,
message_txt=message.processed_plain_text,
sender_name=sender_name,
- relationship_value=relationship_value,
stream_id=message.chat_stream.stream_id,
)
@@ -151,32 +145,48 @@ class ResponseGenerator:
}
)
- async def _get_emotion_tags(self, content: str) -> List[str]:
- """提取情感标签"""
+ async def _get_emotion_tags(
+ self, content: str, processed_plain_text: str
+ ):
+ """提取情感标签,结合立场和情绪"""
try:
- prompt = f"""请从以下内容中,从"happy,angry,sad,surprised,disgusted,fearful,neutral"中选出最匹配的1个情感标签并输出
- 只输出标签就好,不要输出其他内容:
- 内容:{content}
- 输出:
+ # 构建提示词,结合回复内容、被回复的内容以及立场分析
+ prompt = f"""
+ 请根据以下对话内容,完成以下任务:
+ 1. 判断回复者的立场是"supportive"(支持)、"opposed"(反对)还是"neutrality"(中立)。
+ 2. 从"happy,angry,sad,surprised,disgusted,fearful,neutral"中选出最匹配的1个情感标签。
+ 3. 按照"立场-情绪"的格式输出结果,例如:"supportive-happy"。
+
+ 被回复的内容:
+ {processed_plain_text}
+
+ 回复内容:
+ {content}
+
+ 请分析回复者的立场和情感倾向,并输出结果:
"""
- content, _ = await self.model_v25.generate_response(prompt)
- content = content.strip()
- if content in [
- "happy",
- "angry",
- "sad",
- "surprised",
- "disgusted",
- "fearful",
- "neutral",
- ]:
- return [content]
+
+ # 调用模型生成结果
+ result, _ = await self.model_v25.generate_response(prompt)
+ result = result.strip()
+
+ # 解析模型输出的结果
+ if "-" in result:
+ stance, emotion = result.split("-", 1)
+ valid_stances = ["supportive", "opposed", "neutrality"]
+ valid_emotions = [
+ "happy", "angry", "sad", "surprised", "disgusted", "fearful", "neutral"
+ ]
+ if stance in valid_stances and emotion in valid_emotions:
+ return stance, emotion # 返回有效的立场-情绪组合
+ else:
+ return "neutrality", "neutral" # 默认返回中立-中性
else:
- return ["neutral"]
+ return "neutrality", "neutral" # 格式错误时返回默认值
except Exception as e:
print(f"获取情感标签时出错: {e}")
- return ["neutral"]
+ return "neutrality", "neutral" # 出错时返回默认值
async def _process_response(self, content: str) -> Tuple[List[str], List[str]]:
"""处理响应内容,返回处理后的内容和情感标签"""
diff --git a/src/plugins/chat/prompt_builder.py b/src/plugins/chat/prompt_builder.py
index 8a7bf9c6b..fe9badb52 100644
--- a/src/plugins/chat/prompt_builder.py
+++ b/src/plugins/chat/prompt_builder.py
@@ -7,8 +7,9 @@ from ..memory_system.memory import hippocampus, memory_graph
from ..moods.moods import MoodManager
from ..schedule.schedule_generator import bot_schedule
from .config import global_config
-from .utils import get_embedding, get_recent_group_detailed_plain_text
+from .utils import get_embedding, get_recent_group_detailed_plain_text, get_recent_group_speaker
from .chat_stream import chat_manager
+from .relationship_manager import relationship_manager
from src.common.logger import get_module_logger
logger = get_module_logger("prompt")
@@ -21,34 +22,36 @@ class PromptBuilder:
self.prompt_built = ""
self.activate_messages = ""
- async def _build_prompt(
- self,
- message_txt: str,
- sender_name: str = "某人",
- relationship_value: float = 0.0,
- stream_id: Optional[int] = None,
- ) -> tuple[str, str]:
+ async def _build_prompt(self,
+ chat_stream,
+ message_txt: str,
+ sender_name: str = "某人",
+ stream_id: Optional[int] = None) -> tuple[str, str]:
"""构建prompt
Args:
message_txt: 消息文本
sender_name: 发送者昵称
- relationship_value: 关系值
+ # relationship_value: 关系值
group_id: 群组ID
Returns:
str: 构建好的prompt
"""
- # 先禁用关系
- if 0 > 30:
- relation_prompt = "关系特别特别好,你很喜欢喜欢他"
- relation_prompt_2 = "热情发言或者回复"
- elif 0 < -20:
- relation_prompt = "关系很差,你很讨厌他"
- relation_prompt_2 = "骂他"
- else:
- relation_prompt = "关系一般"
- relation_prompt_2 = "发言或者回复"
+ # 关系(载入当前聊天记录里部分人的关系)
+ who_chat_in_group = [chat_stream]
+ who_chat_in_group += get_recent_group_speaker(
+ stream_id,
+ (chat_stream.user_info.user_id, chat_stream.user_info.platform),
+ limit=global_config.MAX_CONTEXT_SIZE
+ )
+ relation_prompt = ""
+ for person in who_chat_in_group:
+ relation_prompt += relationship_manager.build_relationship_info(person)
+
+ relation_prompt_all = (
+ f"{relation_prompt}关系等级越大,关系越好,请分析聊天记录,根据你和说话者{sender_name}的关系和态度进行回复,明确你的立场和情感。"
+ )
# 开始构建prompt
@@ -70,10 +73,10 @@ class PromptBuilder:
)
chat_stream = chat_manager.get_stream(stream_id)
if chat_stream.group_info:
- chat_talking_prompt = f"以下是群里正在聊天的内容:\n{chat_talking_prompt}"
+ chat_talking_prompt = chat_talking_prompt
else:
chat_in_group = False
- chat_talking_prompt = f"以下是你正在和{sender_name}私聊的内容:\n{chat_talking_prompt}"
+ chat_talking_prompt = chat_talking_prompt
# print(f"\033[1;34m[调试]\033[0m 已从数据库获取群 {group_id} 的消息记录:{chat_talking_prompt}")
# 使用新的记忆获取方法
@@ -123,10 +126,7 @@ class PromptBuilder:
probability_3 = global_config.PERSONALITY_3
personality_choice = random.random()
- if chat_in_group:
- prompt_in_group = f"你正在浏览{chat_stream.platform}群"
- else:
- prompt_in_group = f"你正在{chat_stream.platform}上和{sender_name}私聊"
+
if personality_choice < probability_1: # 第一种人格
prompt_personality = personality[0]
elif personality_choice < probability_1 + probability_2: # 第二种人格
@@ -143,15 +143,6 @@ class PromptBuilder:
if random.random() < 0.01:
prompt_ger += "你喜欢用文言文"
- # 合并prompt
- # prompt = ""
- # prompt += f"{prompt_info}\n"
- # prompt += f"{prompt_date}\n"
- # prompt += f"{chat_talking_prompt}\n"
- # prompt += f"{prompt_personality}\n"
- # prompt += f"{prompt_ger}\n"
- # prompt += f"{extra_info}\n"
-
# 知识构建
start_time = time.time()
@@ -176,7 +167,7 @@ class PromptBuilder:
``
{message_txt}
``\
-引起了你的注意,你和ta{relation_prompt},{mood_prompt},你想要{relation_prompt_2}。
+引起了你的注意,{relation_prompt_all}{mood_prompt}
``
你的网名叫{global_config.BOT_NICKNAME},你还有很多别名:{"/".join(global_config.BOT_ALIAS_NAMES)},{prompt_personality}。
@@ -198,8 +189,8 @@ class PromptBuilder:
# prompt_personality_check = f"""你的网名叫{global_config.BOT_NICKNAME},{personality[2]}, 你正在浏览qq群,{promt_info_prompt} {activate_prompt_check} {extra_check_info}"""
#
# prompt_check_if_response = f"{prompt_info}\n{prompt_date}\n{chat_talking_prompt}\n{prompt_personality_check}"
+
prompt_check_if_response = ""
-
return prompt, prompt_check_if_response
def _build_initiative_prompt_select(self, group_id, probability_1=0.8, probability_2=0.1):
diff --git a/src/plugins/chat/relationship_manager.py b/src/plugins/chat/relationship_manager.py
index 937f5d7ce..39e4bce1b 100644
--- a/src/plugins/chat/relationship_manager.py
+++ b/src/plugins/chat/relationship_manager.py
@@ -5,6 +5,7 @@ from src.common.logger import get_module_logger
from ...common.database import db
from .message_base import UserInfo
from .chat_stream import ChatStream
+import math
logger = get_module_logger("rel_manager")
@@ -250,6 +251,101 @@ class RelationshipManager:
return user_info.user_nickname or user_info.user_cardname or "某人"
else:
return "某人"
+
+ async def calculate_update_relationship_value(self,
+ chat_stream: ChatStream,
+ label: str,
+ stance: str) -> None:
+ """计算变更关系值
+ 新的关系值变更计算方式:
+ 将关系值限定在-1000到1000
+ 对于关系值的变更,期望:
+ 1.向两端逼近时会逐渐减缓
+ 2.关系越差,改善越难,关系越好,恶化越容易
+ 3.人维护关系的精力往往有限,所以当高关系值用户越多,对于中高关系值用户增长越慢
+ """
+ stancedict = {
+ "supportive": 0,
+ "neutrality": 1,
+ "opposed": 2,
+ }
+
+ valuedict = {
+ "happy": 1.5,
+ "angry": -3.0,
+ "sad": -1.5,
+ "surprised": 0.6,
+ "disgusted": -4.5,
+ "fearful": -2.1,
+ "neutral": 0.3,
+ }
+ if self.get_relationship(chat_stream):
+ old_value = self.get_relationship(chat_stream).relationship_value
+ else:
+ return
+
+ 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:
+ high_value_count = 0
+ for key, relationship in self.relationships.items():
+ if relationship.relationship_value >= 850:
+ high_value_count += 1
+ value *= 3/(high_value_count + 3)
+ elif valuedict[label] < 0 and stancedict[stance] != 0:
+ value = value*math.exp(old_value/1000)
+ else:
+ value = 0
+ elif old_value < 0:
+ if valuedict[label] >= 0 and stancedict[stance] != 2:
+ value = value*math.exp(old_value/1000)
+ elif valuedict[label] < 0 and stancedict[stance] != 0:
+ value = value*math.cos(math.pi*old_value/2000)
+ else:
+ value = 0
+
+ logger.info(f"[关系变更] 立场:{stance} 标签:{label} 关系值:{value}")
+
+ await self.update_relationship_value(
+ chat_stream=chat_stream, relationship_value=value
+ )
+
+ def build_relationship_info(self,person) -> str:
+ relationship_value = relationship_manager.get_relationship(person).relationship_value
+ if -1000 <= relationship_value < -227:
+ level_num = 0
+ elif -227 <= relationship_value < -73:
+ level_num = 1
+ elif -76 <= relationship_value < 227:
+ level_num = 2
+ elif 227 <= relationship_value < 587:
+ level_num = 3
+ elif 587 <= relationship_value < 900:
+ level_num = 4
+ elif 900 <= relationship_value <= 1000:
+ level_num = 5
+ else:
+ level_num = 5 if relationship_value > 1000 else 0
+
+ relationship_level = ["厌恶", "冷漠", "一般", "友好", "喜欢", "暧昧"]
+ relation_prompt2_list = [
+ "冷漠回应或直接辱骂", "冷淡回复",
+ "保持理性", "愿意回复",
+ "积极回复", "无条件支持",
+ ]
+ if person.user_info.user_cardname:
+ return (f"你对昵称为'[({person.user_info.user_id}){person.user_info.user_nickname}]{person.user_info.user_cardname}'的用户的态度为{relationship_level[level_num]},"
+ f"回复态度为{relation_prompt2_list[level_num]},关系等级为{level_num}。")
+ else:
+ return (f"你对昵称为'({person.user_info.user_id}){person.user_info.user_nickname}'的用户的态度为{relationship_level[level_num]},"
+ f"回复态度为{relation_prompt2_list[level_num]},关系等级为{level_num}。")
relationship_manager = RelationshipManager()
diff --git a/src/plugins/chat/utils.py b/src/plugins/chat/utils.py
index 29f10fc20..ad8d41a68 100644
--- a/src/plugins/chat/utils.py
+++ b/src/plugins/chat/utils.py
@@ -197,6 +197,35 @@ def get_recent_group_detailed_plain_text(chat_stream_id: int, limit: int = 12, c
return message_detailed_plain_text_list
+def get_recent_group_speaker(chat_stream_id: int, sender, limit: int = 12) -> list:
+ # 获取当前群聊记录内发言的人
+ recent_messages = list(db.messages.find(
+ {"chat_id": chat_stream_id},
+ {
+ "chat_info": 1,
+ "user_info": 1,
+ }
+ ).sort("time", -1).limit(limit))
+
+ if not recent_messages:
+ return []
+
+ who_chat_in_group = [] # ChatStream列表
+
+ duplicate_removal = []
+ for msg_db_data in recent_messages:
+ user_info = UserInfo.from_dict(msg_db_data["user_info"])
+ if (user_info.user_id, user_info.platform) != sender \
+ and (user_info.user_id, user_info.platform) != (global_config.BOT_QQ, "qq") \
+ and (user_info.user_id, user_info.platform) not in duplicate_removal \
+ and len(duplicate_removal) < 5: # 排除重复,排除消息发送者,排除bot(此处bot的平台强制为了qq,可能需要更改),限制加载的关系数目
+
+ duplicate_removal.append((user_info.user_id, user_info.platform))
+ chat_info = msg_db_data.get("chat_info", {})
+ who_chat_in_group.append(ChatStream.from_dict(chat_info))
+ return who_chat_in_group
+
+
def split_into_sentences_w_remove_punctuation(text: str) -> List[str]:
"""将文本分割成句子,但保持书名号中的内容完整
Args: