@@ -83,7 +83,7 @@ class ChatBot:
|
|||||||
chat_stream=chat,
|
chat_stream=chat,
|
||||||
)
|
)
|
||||||
await relationship_manager.update_relationship_value(
|
await relationship_manager.update_relationship_value(
|
||||||
chat_stream=chat, relationship_value=0.5
|
chat_stream=chat, relationship_value=0
|
||||||
)
|
)
|
||||||
|
|
||||||
await message.process()
|
await message.process()
|
||||||
@@ -255,20 +255,11 @@ class ChatBot:
|
|||||||
)
|
)
|
||||||
message_manager.add_message(bot_message)
|
message_manager.add_message(bot_message)
|
||||||
|
|
||||||
emotion = await self.gpt._get_emotion_tags(raw_content)
|
# 获取立场和情感标签,更新关系值
|
||||||
logger.debug(f"为 '{response}' 获取到的情感标签为:{emotion}")
|
stance, emotion = await self.gpt._get_emotion_tags(raw_content, message.processed_plain_text)
|
||||||
valuedict = {
|
logger.debug(f"为 '{response}' 立场为:{stance} 获取到的情感标签为:{emotion}")
|
||||||
"happy": 0.5,
|
await relationship_manager.calculate_update_relationship_value(chat_stream=chat, label=emotion, stance=stance)
|
||||||
"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]]
|
|
||||||
)
|
|
||||||
# 使用情绪管理器更新情绪
|
# 使用情绪管理器更新情绪
|
||||||
self.mood_manager.update_mood_from_emotion(
|
self.mood_manager.update_mood_from_emotion(
|
||||||
emotion[0], global_config.mood_intensity_factor
|
emotion[0], global_config.mood_intensity_factor
|
||||||
|
|||||||
@@ -63,25 +63,19 @@ class ResponseGenerator:
|
|||||||
|
|
||||||
async def _generate_response_with_model(self, message: MessageThinking, model: LLM_request) -> Optional[str]:
|
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}"
|
sender_name = ""
|
||||||
if message.chat_stream.user_info.user_cardname:
|
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}"
|
sender_name = f"[({message.chat_stream.user_info.user_id}){message.chat_stream.user_info.user_nickname}]{message.chat_stream.user_info.user_cardname}"
|
||||||
|
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}"
|
||||||
relationship_value = (
|
else:
|
||||||
relationship_manager.get_relationship(message.chat_stream).relationship_value
|
sender_name = f"用户({message.chat_stream.user_info.user_id})"
|
||||||
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
|
|
||||||
|
|
||||||
# 构建prompt
|
# 构建prompt
|
||||||
prompt, prompt_check = await prompt_builder._build_prompt(
|
prompt, prompt_check = await prompt_builder._build_prompt(
|
||||||
|
message.chat_stream,
|
||||||
message_txt=message.processed_plain_text,
|
message_txt=message.processed_plain_text,
|
||||||
sender_name=sender_name,
|
sender_name=sender_name,
|
||||||
relationship_value=relationship_value,
|
|
||||||
stream_id=message.chat_stream.stream_id,
|
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:
|
try:
|
||||||
prompt = f"""请从以下内容中,从"happy,angry,sad,surprised,disgusted,fearful,neutral"中选出最匹配的1个情感标签并输出
|
# 构建提示词,结合回复内容、被回复的内容以及立场分析
|
||||||
只输出标签就好,不要输出其他内容:
|
prompt = f"""
|
||||||
内容:{content}
|
请根据以下对话内容,完成以下任务:
|
||||||
输出:
|
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 [
|
result, _ = await self.model_v25.generate_response(prompt)
|
||||||
"happy",
|
result = result.strip()
|
||||||
"angry",
|
|
||||||
"sad",
|
# 解析模型输出的结果
|
||||||
"surprised",
|
if "-" in result:
|
||||||
"disgusted",
|
stance, emotion = result.split("-", 1)
|
||||||
"fearful",
|
valid_stances = ["supportive", "opposed", "neutrality"]
|
||||||
"neutral",
|
valid_emotions = [
|
||||||
]:
|
"happy", "angry", "sad", "surprised", "disgusted", "fearful", "neutral"
|
||||||
return [content]
|
]
|
||||||
|
if stance in valid_stances and emotion in valid_emotions:
|
||||||
|
return stance, emotion # 返回有效的立场-情绪组合
|
||||||
else:
|
else:
|
||||||
return ["neutral"]
|
return "neutrality", "neutral" # 默认返回中立-中性
|
||||||
|
else:
|
||||||
|
return "neutrality", "neutral" # 格式错误时返回默认值
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"获取情感标签时出错: {e}")
|
print(f"获取情感标签时出错: {e}")
|
||||||
return ["neutral"]
|
return "neutrality", "neutral" # 出错时返回默认值
|
||||||
|
|
||||||
async def _process_response(self, content: str) -> Tuple[List[str], List[str]]:
|
async def _process_response(self, content: str) -> Tuple[List[str], List[str]]:
|
||||||
"""处理响应内容,返回处理后的内容和情感标签"""
|
"""处理响应内容,返回处理后的内容和情感标签"""
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ from ..memory_system.memory import hippocampus, memory_graph
|
|||||||
from ..moods.moods import MoodManager
|
from ..moods.moods import MoodManager
|
||||||
from ..schedule.schedule_generator import bot_schedule
|
from ..schedule.schedule_generator import bot_schedule
|
||||||
from .config import global_config
|
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 .chat_stream import chat_manager
|
||||||
|
from .relationship_manager import relationship_manager
|
||||||
from src.common.logger import get_module_logger
|
from src.common.logger import get_module_logger
|
||||||
|
|
||||||
logger = get_module_logger("prompt")
|
logger = get_module_logger("prompt")
|
||||||
@@ -21,34 +22,36 @@ class PromptBuilder:
|
|||||||
self.prompt_built = ""
|
self.prompt_built = ""
|
||||||
self.activate_messages = ""
|
self.activate_messages = ""
|
||||||
|
|
||||||
async def _build_prompt(
|
async def _build_prompt(self,
|
||||||
self,
|
chat_stream,
|
||||||
message_txt: str,
|
message_txt: str,
|
||||||
sender_name: str = "某人",
|
sender_name: str = "某人",
|
||||||
relationship_value: float = 0.0,
|
stream_id: Optional[int] = None) -> tuple[str, str]:
|
||||||
stream_id: Optional[int] = None,
|
|
||||||
) -> tuple[str, str]:
|
|
||||||
"""构建prompt
|
"""构建prompt
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message_txt: 消息文本
|
message_txt: 消息文本
|
||||||
sender_name: 发送者昵称
|
sender_name: 发送者昵称
|
||||||
relationship_value: 关系值
|
# relationship_value: 关系值
|
||||||
group_id: 群组ID
|
group_id: 群组ID
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: 构建好的prompt
|
str: 构建好的prompt
|
||||||
"""
|
"""
|
||||||
# 先禁用关系
|
# 关系(载入当前聊天记录里部分人的关系)
|
||||||
if 0 > 30:
|
who_chat_in_group = [chat_stream]
|
||||||
relation_prompt = "关系特别特别好,你很喜欢喜欢他"
|
who_chat_in_group += get_recent_group_speaker(
|
||||||
relation_prompt_2 = "热情发言或者回复"
|
stream_id,
|
||||||
elif 0 < -20:
|
(chat_stream.user_info.user_id, chat_stream.user_info.platform),
|
||||||
relation_prompt = "关系很差,你很讨厌他"
|
limit=global_config.MAX_CONTEXT_SIZE
|
||||||
relation_prompt_2 = "骂他"
|
)
|
||||||
else:
|
relation_prompt = ""
|
||||||
relation_prompt = "关系一般"
|
for person in who_chat_in_group:
|
||||||
relation_prompt_2 = "发言或者回复"
|
relation_prompt += relationship_manager.build_relationship_info(person)
|
||||||
|
|
||||||
|
relation_prompt_all = (
|
||||||
|
f"{relation_prompt}关系等级越大,关系越好,请分析聊天记录,根据你和说话者{sender_name}的关系和态度进行回复,明确你的立场和情感。"
|
||||||
|
)
|
||||||
|
|
||||||
# 开始构建prompt
|
# 开始构建prompt
|
||||||
|
|
||||||
@@ -70,10 +73,10 @@ class PromptBuilder:
|
|||||||
)
|
)
|
||||||
chat_stream = chat_manager.get_stream(stream_id)
|
chat_stream = chat_manager.get_stream(stream_id)
|
||||||
if chat_stream.group_info:
|
if chat_stream.group_info:
|
||||||
chat_talking_prompt = f"以下是群里正在聊天的内容:\n{chat_talking_prompt}"
|
chat_talking_prompt = chat_talking_prompt
|
||||||
else:
|
else:
|
||||||
chat_in_group = False
|
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}")
|
# print(f"\033[1;34m[调试]\033[0m 已从数据库获取群 {group_id} 的消息记录:{chat_talking_prompt}")
|
||||||
|
|
||||||
# 使用新的记忆获取方法
|
# 使用新的记忆获取方法
|
||||||
@@ -123,10 +126,7 @@ class PromptBuilder:
|
|||||||
probability_3 = global_config.PERSONALITY_3
|
probability_3 = global_config.PERSONALITY_3
|
||||||
|
|
||||||
personality_choice = random.random()
|
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: # 第一种人格
|
if personality_choice < probability_1: # 第一种人格
|
||||||
prompt_personality = personality[0]
|
prompt_personality = personality[0]
|
||||||
elif personality_choice < probability_1 + probability_2: # 第二种人格
|
elif personality_choice < probability_1 + probability_2: # 第二种人格
|
||||||
@@ -143,15 +143,6 @@ class PromptBuilder:
|
|||||||
if random.random() < 0.01:
|
if random.random() < 0.01:
|
||||||
prompt_ger += "你喜欢用文言文"
|
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()
|
start_time = time.time()
|
||||||
|
|
||||||
@@ -176,7 +167,7 @@ class PromptBuilder:
|
|||||||
`<UserMessage>`
|
`<UserMessage>`
|
||||||
{message_txt}
|
{message_txt}
|
||||||
`</UserMessage>`\
|
`</UserMessage>`\
|
||||||
引起了你的注意,你和ta{relation_prompt},{mood_prompt},你想要{relation_prompt_2}。
|
引起了你的注意,{relation_prompt_all}{mood_prompt}
|
||||||
|
|
||||||
`<MainRule>`
|
`<MainRule>`
|
||||||
你的网名叫{global_config.BOT_NICKNAME},你还有很多别名:{"/".join(global_config.BOT_ALIAS_NAMES)},{prompt_personality}。
|
你的网名叫{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_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 = f"{prompt_info}\n{prompt_date}\n{chat_talking_prompt}\n{prompt_personality_check}"
|
||||||
prompt_check_if_response = ""
|
|
||||||
|
|
||||||
|
prompt_check_if_response = ""
|
||||||
return prompt, 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):
|
def _build_initiative_prompt_select(self, group_id, probability_1=0.8, probability_2=0.1):
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from src.common.logger import get_module_logger
|
|||||||
from ...common.database import db
|
from ...common.database import db
|
||||||
from .message_base import UserInfo
|
from .message_base import UserInfo
|
||||||
from .chat_stream import ChatStream
|
from .chat_stream import ChatStream
|
||||||
|
import math
|
||||||
|
|
||||||
logger = get_module_logger("rel_manager")
|
logger = get_module_logger("rel_manager")
|
||||||
|
|
||||||
@@ -251,5 +252,100 @@ class RelationshipManager:
|
|||||||
else:
|
else:
|
||||||
return "某人"
|
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()
|
relationship_manager = RelationshipManager()
|
||||||
|
|||||||
@@ -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
|
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]:
|
def split_into_sentences_w_remove_punctuation(text: str) -> List[str]:
|
||||||
"""将文本分割成句子,但保持书名号中的内容完整
|
"""将文本分割成句子,但保持书名号中的内容完整
|
||||||
Args:
|
Args:
|
||||||
|
|||||||
Reference in New Issue
Block a user