feat:重写关系模块的逻辑和关系结构

This commit is contained in:
SengokuCola
2025-06-07 01:03:00 +08:00
parent 3c955c8a34
commit e032f44643
10 changed files with 1354 additions and 555 deletions

View File

@@ -16,29 +16,19 @@ class ImpressionUpdateTask(AsyncTask):
def __init__(self):
super().__init__(
task_name="impression_update",
wait_before_start=5, # 启动后等待10秒
run_interval=20, # 每1分钟运行一次
wait_before_start=5,
run_interval=global_config.relationship.build_relationship_interval,
)
async def run(self):
try:
if random.random() < 0.1:
# 获取最近10分钟的消息
current_time = int(time.time())
start_time = current_time - 6000 # 10分钟前
# 取一个月内任意一个小时的时间段
else:
now = int(time.time())
# 30天前的时间戳
month_ago = now - 90 * 24 * 60 * 60
# 随机选择一个小时的起点
random_start = random.randint(month_ago, now - 3600)
start_time = random_start
current_time = random_start + 3600 # 一个小时后
# 获取最近的消息
current_time = int(time.time())
start_time = current_time - 360000 # 1小时前
# 获取所有消息
messages = get_raw_msg_by_timestamp(timestamp_start=start_time, timestamp_end=current_time, limit=100)
messages = get_raw_msg_by_timestamp(timestamp_start=start_time, timestamp_end=current_time, limit=200)
if not messages:
logger.info("没有找到需要处理的消息")
return
@@ -54,8 +44,6 @@ class ImpressionUpdateTask(AsyncTask):
# 处理每个聊天组
for chat_id, msgs in chat_messages.items():
# logger.info(f"处理聊天组 {chat_id}, 消息数: {len(msgs)}")
# 获取chat_stream
chat_stream = chat_manager.get_stream(chat_id)
if not chat_stream:
@@ -64,15 +52,39 @@ class ImpressionUpdateTask(AsyncTask):
# 找到bot的消息
bot_messages = [msg for msg in msgs if msg["user_nickname"] == global_config.bot.nickname]
logger.debug(f"找到 {len(bot_messages)} 条bot消息")
if not bot_messages:
logger.info(f"聊天组 {chat_id} 没有bot消息跳过处理")
continue
# 按时间排序所有消息
sorted_messages = sorted(msgs, key=lambda x: x["time"])
# 找到第一条和最后一条bot消息
first_bot_msg = bot_messages[0]
last_bot_msg = bot_messages[-1]
# 获取第一条bot消息前15条消息
first_bot_index = sorted_messages.index(first_bot_msg)
start_index = max(0, first_bot_index - 15)
# 获取最后一条bot消息后15条消息
last_bot_index = sorted_messages.index(last_bot_msg)
end_index = min(len(sorted_messages), last_bot_index + 16)
# 获取相关消息
relevant_messages = sorted_messages[start_index:end_index]
# 统计用户发言权重
user_weights = defaultdict(lambda: {"weight": 0, "messages": [], "middle_time": 0})
user_weights = defaultdict(lambda: {"weight": 0, "messages": []})
if not bot_messages:
# 如果没有bot消息所有消息权重都为1
logger.info("没有找到bot消息所有消息权重设为1")
for msg in msgs:
# 计算权重
for bot_msg in bot_messages:
bot_time = bot_msg["time"]
context_messages = [msg for msg in relevant_messages if abs(msg["time"] - bot_time) <= 600] # 前后10分钟
logger.debug(f"Bot消息 {bot_time} 的上下文消息数: {len(context_messages)}")
for msg in context_messages:
if msg["user_nickname"] == global_config.bot.nickname:
continue
@@ -81,43 +93,15 @@ class ImpressionUpdateTask(AsyncTask):
logger.warning(f"未找到用户 {msg['user_nickname']} 的person_id")
continue
user_weights[person_id]["weight"] += 1
# 在bot消息附近的发言权重加倍
if abs(msg["time"] - bot_time) <= 120: # 前后2分钟
user_weights[person_id]["weight"] += 2
logger.debug(f"用户 {msg['user_nickname']} 在bot消息附近发言权重+2")
else:
user_weights[person_id]["weight"] += 1
logger.debug(f"用户 {msg['user_nickname']} 发言,权重+1")
user_weights[person_id]["messages"].append(msg)
else:
# 有bot消息时的原有逻辑
for bot_msg in bot_messages:
# 获取bot消息前后的消息
bot_time = bot_msg["time"]
context_messages = [msg for msg in msgs if abs(msg["time"] - bot_time) <= 600] # 前后10分钟
logger.debug(f"Bot消息 {bot_time} 的上下文消息数: {len(context_messages)}")
# 计算权重
for msg in context_messages:
if msg["user_nickname"] == global_config.bot.nickname:
continue
person_id = person_info_manager.get_person_id(msg["chat_info_platform"], msg["user_id"])
if not person_id:
logger.warning(f"未找到用户 {msg['user_nickname']} 的person_id")
continue
# 在bot消息附近的发言权重加倍
if abs(msg["time"] - bot_time) <= 120: # 前后2分钟
user_weights[person_id]["weight"] += 2
logger.debug(f"用户 {msg['user_nickname']} 在bot消息附近发言权重+2")
else:
user_weights[person_id]["weight"] += 1
logger.debug(f"用户 {msg['user_nickname']} 发言,权重+1")
user_weights[person_id]["messages"].append(msg)
# 计算每个用户的中间时间
for _, data in user_weights.items():
if data["messages"]:
sorted_messages = sorted(data["messages"], key=lambda x: x["time"])
middle_index = len(sorted_messages) // 2
data["middle_time"] = sorted_messages[middle_index]["time"]
logger.debug(f"用户 {sorted_messages[0]['user_nickname']} 中间时间: {data['middle_time']}")
# 按权重排序
sorted_users = sorted(user_weights.items(), key=lambda x: x[1]["weight"], reverse=True)
@@ -126,12 +110,29 @@ class ImpressionUpdateTask(AsyncTask):
f"用户权重排序: {[(msg[1]['messages'][0]['user_nickname'], msg[1]['weight']) for msg in sorted_users]}"
)
# 随机选择三个用户
# 选择最多5个用户
selected_users = []
if len(sorted_users) > 3:
# 使用权重作为概率进行随机选择
if len(sorted_users) > 5:
# 使用权重作为概率进行随机选择,确保不重复
weights = [user[1]["weight"] for user in sorted_users]
selected_indices = random.choices(range(len(sorted_users)), weights=weights, k=3)
total_weight = sum(weights)
# 计算每个用户的概率
probabilities = [w/total_weight for w in weights]
# 使用累积概率进行选择
selected_indices = []
remaining_indices = list(range(len(sorted_users)))
for _ in range(5):
if not remaining_indices:
break
# 计算剩余索引的累积概率
remaining_probs = [probabilities[i] for i in remaining_indices]
# 归一化概率
remaining_probs = [p/sum(remaining_probs) for p in remaining_probs]
# 选择索引
chosen_idx = random.choices(remaining_indices, weights=remaining_probs, k=1)[0]
selected_indices.append(chosen_idx)
remaining_indices.remove(chosen_idx)
selected_users = [sorted_users[i] for i in selected_indices]
logger.info(
f"开始进一步了解这些用户: {[msg[1]['messages'][0]['user_nickname'] for msg in selected_users]}"
@@ -145,9 +146,22 @@ class ImpressionUpdateTask(AsyncTask):
# 更新选中用户的印象
for person_id, data in selected_users:
user_nickname = data["messages"][0]["user_nickname"]
platform = data["messages"][0]["chat_info_platform"]
user_id = data["messages"][0]["user_id"]
cardname = data["messages"][0]["user_cardname"]
is_known = await relationship_manager.is_known_some_one(platform, user_id)
if not is_known:
logger.info(f"首次认识用户: {user_nickname}")
await relationship_manager.first_knowing_some_one(platform, user_id, user_nickname, cardname)
logger.info(f"开始更新用户 {user_nickname} 的印象")
await relationship_manager.update_person_impression(
person_id=person_id, chat_id=chat_id, reason="", timestamp=data["middle_time"]
person_id=person_id,
timestamp=last_bot_msg["time"],
bot_engaged_messages=relevant_messages
)
logger.debug("印象更新任务执行完成")