This commit is contained in:
SengokuCola
2025-04-29 23:47:37 +08:00
parent be84017972
commit 8dcfe04642
10 changed files with 41 additions and 35 deletions

View File

@@ -1,6 +1,7 @@
import difflib
import random
def ji_suan_xiang_si_du(wen_ben_yi: str, wen_ben_er: str) -> float:
"""
计算两个文本字符串的相似度。
@@ -17,6 +18,7 @@ def ji_suan_xiang_si_du(wen_ben_yi: str, wen_ben_er: str) -> float:
xiang_si_bi_lv = xu_lie_pi_pei_qi.ratio()
return xiang_si_bi_lv
def ji_suan_ti_huan_gai_lv(xiang_si_du: float) -> float:
"""
根据相似度计算替换的概率。
@@ -34,11 +36,12 @@ def ji_suan_ti_huan_gai_lv(xiang_si_du: float) -> float:
elif 0.4 < xiang_si_du <= 0.6:
# p = 3.5 * s - 1.4 (线性方程 y - 0 = (0.7-0)/(0.6-0.4) * (x - 0.4))
gai_lv = 3.5 * xiang_si_du - 1.4
return max(0.0, gai_lv) # 确保概率不小于0
return max(0.0, gai_lv) # 确保概率不小于0
elif 0.6 < xiang_si_du < 0.9:
# p = s + 0.1 (线性方程 y - 0.7 = (1-0.7)/(0.9-0.6) * (x - 0.6))
gai_lv = xiang_si_du + 0.1
return min(1.0, max(0.0, gai_lv)) # 确保概率在 0 和 1 之间
return min(1.0, max(0.0, gai_lv)) # 确保概率在 0 和 1 之间
# 获取用户输入
shu_ru_yi = "豆豆刚刚回复了我的问候 现在可以等待对方的回应 不需要再主动发言 目前情绪满足 不需要使用工具"
@@ -67,7 +70,7 @@ if random.random() < ti_huan_gai_lv:
# 更新下一个非匹配部分的起始位置
last_match_end_in_b = j + n
jie_guo = "".join(qu_chong_hou_de_er).strip() # 去除首尾空白
jie_guo = "".join(qu_chong_hou_de_er).strip() # 去除首尾空白
if jie_guo:
# 定义词语列表
@@ -78,9 +81,9 @@ if random.random() < ti_huan_gai_lv:
# 根据概率决定是否添加词语
qian_zhui_str = ""
if random.random() < 0.3: # 30% 概率添加语气词
if random.random() < 0.3: # 30% 概率添加语气词
qian_zhui_str += random.choice(yu_qi_ci_liebiao)
if random.random() < 0.7: # 70% 概率添加转折/承接词
if random.random() < 0.7: # 70% 概率添加转折/承接词
qian_zhui_str += random.choice(zhuan_jie_ci_liebiao)
# 组合最终结果

View File

@@ -185,7 +185,7 @@ class BotConfig:
reply_trigger_threshold: float = 3.0 # 心流聊天触发阈值,越低越容易触发
probability_decay_factor_per_second: float = 0.2 # 概率衰减因子,越大衰减越快
default_decay_rate_per_second: float = 0.98 # 默认衰减率,越大衰减越慢
allow_focus_mode: bool = True # 是否允许子心流进入 FOCUSED 状态
allow_focus_mode: bool = True # 是否允许子心流进入 FOCUSED 状态
# sub_heart_flow_update_interval: int = 60 # 子心流更新频率,间隔 单位秒
# sub_heart_flow_freeze_time: int = 120 # 子心流冻结时间,超过这个时间没有回复,子心流会冻结,间隔 单位秒
@@ -417,6 +417,7 @@ class BotConfig:
config.model_normal_probability = response_config.get(
"model_normal_probability", config.model_normal_probability
)
def heartflow(parent: dict):
heartflow_config = parent["heartflow"]
config.sub_heart_flow_stop_time = heartflow_config.get(

View File

@@ -160,8 +160,6 @@ class ChattingObservation(Observation):
# print(f"self.11111person_list: {self.person_list}")
logger.trace(
f"Chat {self.chat_id} - 压缩早期记忆:{self.mid_memory_info}\n现在聊天内容:{self.talking_message_str}"
)

View File

@@ -16,7 +16,6 @@ import difflib
from src.plugins.person_info.relationship_manager import relationship_manager
logger = get_logger("sub_heartflow")
@@ -60,6 +59,7 @@ def calculate_similarity(text_a: str, text_b: str) -> float:
matcher = difflib.SequenceMatcher(None, text_a, text_b)
return matcher.ratio()
def calculate_replacement_probability(similarity: float) -> float:
"""
根据相似度计算替换的概率。
@@ -139,7 +139,6 @@ class SubMind:
# 获取个性化信息
individuality = Individuality.get_instance()
relation_prompt = ""
print(f"person_list: {person_list}")
for person in person_list:
@@ -302,7 +301,7 @@ class SubMind:
logger.warning(f"{self.log_prefix} LLM返回空结果思考失败。")
# ---------- 6. 应用概率性去重和修饰 ----------
new_content = content # 保存 LLM 直接输出的结果
new_content = content # 保存 LLM 直接输出的结果
try:
similarity = calculate_similarity(previous_mind, new_content)
replacement_prob = calculate_replacement_probability(similarity)
@@ -319,11 +318,13 @@ class SubMind:
if similarity == 1.0:
logger.debug(f"{self.log_prefix} 想法完全重复 (相似度 1.0),执行特殊处理...")
# 随机截取大约一半内容
if len(new_content) > 1: # 避免内容过短无法截取
split_point = max(1, len(new_content) // 2 + random.randint(-len(new_content)//4, len(new_content)//4))
if len(new_content) > 1: # 避免内容过短无法截取
split_point = max(
1, len(new_content) // 2 + random.randint(-len(new_content) // 4, len(new_content) // 4)
)
truncated_content = new_content[:split_point]
else:
truncated_content = new_content # 如果只有一个字符或者为空,就不截取了
truncated_content = new_content # 如果只有一个字符或者为空,就不截取了
# 添加语气词和转折/承接词
yu_qi_ci = random.choice(yu_qi_ci_liebiao)
@@ -347,21 +348,21 @@ class SubMind:
if deduplicated_content:
# 根据概率决定是否添加词语
prefix_str = ""
if random.random() < 0.3: # 30% 概率添加语气词
if random.random() < 0.3: # 30% 概率添加语气词
prefix_str += random.choice(yu_qi_ci_liebiao)
if random.random() < 0.7: # 70% 概率添加转折/承接词
if random.random() < 0.7: # 70% 概率添加转折/承接词
prefix_str += random.choice(zhuan_jie_ci_liebiao)
# 组合最终结果
if prefix_str:
content = f"{prefix_str}{deduplicated_content}" # 更新 content
content = f"{prefix_str}{deduplicated_content}" # 更新 content
logger.debug(f"{self.log_prefix} 去重并添加引导词后: {content}")
else:
content = deduplicated_content # 更新 content
content = deduplicated_content # 更新 content
logger.debug(f"{self.log_prefix} 去重后 (未添加引导词): {content}")
else:
logger.warning(f"{self.log_prefix} 去重后内容为空保留原始LLM输出: {new_content}")
content = new_content # 保留原始 content
content = new_content # 保留原始 content
else:
logger.debug(f"{self.log_prefix} 未执行概率性去重 (概率: {replacement_prob:.2f})")
# content 保持 new_content 不变

View File

@@ -266,9 +266,9 @@ class SubHeartflowManager:
# --- 新增:检查是否允许进入 FOCUS 模式 --- #
if not global_config.allow_focus_mode:
if int(time.time()) % 60 == 0: # 每60秒输出一次日志避免刷屏
if int(time.time()) % 60 == 0: # 每60秒输出一次日志避免刷屏
logger.debug(f"{log_prefix} 配置不允许进入 FOCUSED 状态 (allow_focus_mode=False)")
return # 如果不允许,直接返回
return # 如果不允许,直接返回
# --- 结束新增 ---
logger.debug(f"{log_prefix} 当前状态 ({current_state.value}) 开始尝试提升到FOCUSED状态")

View File

@@ -143,9 +143,9 @@ class PersonInfoManager:
parsed_json = json.loads(text)
# 如果解析结果是列表,尝试取第一个元素
if isinstance(parsed_json, list):
if parsed_json: # 检查列表是否为空
if parsed_json: # 检查列表是否为空
parsed_json = parsed_json[0]
else: # 如果列表为空,重置为 None走后续逻辑
else: # 如果列表为空,重置为 None走后续逻辑
parsed_json = None
# 确保解析结果是字典
if isinstance(parsed_json, dict):
@@ -156,7 +156,7 @@ class PersonInfoManager:
pass
except Exception as e:
logger.warning(f"尝试直接解析JSON时发生意外错误: {e}")
pass # 继续尝试其他方法
pass # 继续尝试其他方法
# 如果直接解析失败或结果不是字典
try:
@@ -165,7 +165,7 @@ class PersonInfoManager:
matches = re.findall(json_pattern, text)
if matches:
parsed_obj = json.loads(matches[0])
if isinstance(parsed_obj, dict): # 确保是字典
if isinstance(parsed_obj, dict): # 确保是字典
return parsed_obj
# 如果上面都失败了,尝试提取键值对

View File

@@ -348,7 +348,10 @@ async def build_readable_messages(
messages_before_mark, replace_bot_name, merge_messages, timestamp_mode, truncate
)
formatted_after, _ = await _build_readable_messages_internal(
messages_after_mark, replace_bot_name, merge_messages, timestamp_mode,
messages_after_mark,
replace_bot_name,
merge_messages,
timestamp_mode,
)
readable_read_mark = translate_timestamp_to_human_readable(read_mark, mode=timestamp_mode)