mirror of https://github.com/Mai-with-u/MaiBot.git
启用表达学习器
parent
b82d640289
commit
8d2f71f9fe
|
|
@ -1,6 +1,7 @@
|
|||
# TODO: 更多的可配置项
|
||||
# TODO: 所有模型单独分离,温度可配置
|
||||
# TODO: 原生多模态支持
|
||||
from importlib.util import spec_from_file_location
|
||||
import os
|
||||
import re
|
||||
from dataclasses import dataclass, field
|
||||
|
|
@ -160,6 +161,7 @@ class BotConfig:
|
|||
0 # 人设消息注入 prompt 详细等级 (0: 采用默认配置, 1: 核心/随机细节, 2: 核心+随机侧面/全部细节, 3: 全部)
|
||||
)
|
||||
expression_style = "描述麦麦说话的表达风格,表达习惯"
|
||||
enable_expression_learner: bool = True # 是否启用新发言习惯注入,关闭则启用旧方法
|
||||
# identity
|
||||
identity_detail: List[str] = field(
|
||||
default_factory=lambda: [
|
||||
|
|
@ -429,6 +431,10 @@ class BotConfig:
|
|||
)
|
||||
if config.INNER_VERSION in SpecifierSet(">=1.7.0"):
|
||||
config.expression_style = personality_config.get("expression_style", config.expression_style)
|
||||
if config.INNER_VERSION in SpecifierSet(">=1.7.0.3"):
|
||||
config.enable_expression_learner = personality_config.get(
|
||||
"enable_expression_learner", config.enable_expression_learner
|
||||
)
|
||||
|
||||
def identity(parent: dict):
|
||||
identity_config = parent["identity"]
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from src.chat.memory_system.Hippocampus import HippocampusManager
|
|||
from .schedule.schedule_generator import bot_schedule
|
||||
from src.chat.knowledge.knowledge_lib import qa_manager
|
||||
from src.plugins.group_nickname.nickname_manager import nickname_manager
|
||||
from src.chat.focus_chat.expressors.exprssion_learner import expression_learner
|
||||
import traceback
|
||||
from .heartFC_Cycleinfo import CycleInfo
|
||||
|
||||
|
|
@ -24,7 +25,7 @@ logger = get_logger("prompt")
|
|||
def init_prompt():
|
||||
Prompt(
|
||||
"""
|
||||
{info_from_tools}
|
||||
{info_from_tools}{style_habbits}
|
||||
{nickname_info}
|
||||
{chat_target}
|
||||
{chat_talking_prompt}
|
||||
|
|
@ -36,8 +37,8 @@ def init_prompt():
|
|||
因为上述想法,你决定发言。
|
||||
|
||||
现在请你读读之前的聊天记录,把你的想法组织成合适简短的语言,然后发一条消息,可以自然随意一些,简短一些,就像群聊里的真人一样,注意把握聊天内容,整体风格可以平和、简短,避免超出你内心想法的范围
|
||||
这条消息可以尽量简短一些。{reply_style2}。请一次只回复一个话题,不要同时回复多个人。{prompt_ger}
|
||||
{reply_style1},说中文,不要刻意突出自身学科背景,注意只输出消息内容,不要去主动讨论或评价别人发的表情包,它们只是一种辅助表达方式。
|
||||
这条消息可以尽量简短一些。{reply_style2}请一次只回复一个话题,不要同时回复多个人。{prompt_ger}
|
||||
{reply_style1}说中文,不要刻意突出自身学科背景,注意只输出消息内容,不要去主动讨论或评价别人发的表情包,它们只是一种辅助表达方式。{grammar_habbits}
|
||||
{moderation_prompt}。注意:回复不要输出多余内容(包括前后缀,冒号和引号,括号,表情包,at或 @等 )。""",
|
||||
"heart_flow_prompt",
|
||||
)
|
||||
|
|
@ -168,8 +169,8 @@ def init_prompt():
|
|||
{chat_talking_prompt}
|
||||
现在"{sender_name}"说的:{message_txt}。引起了你的注意,你想要在群里发言或者回复这条消息。\n
|
||||
你的网名叫{bot_name},有人也叫你{bot_other_names},{prompt_personality}。
|
||||
你正在{chat_target_2},现在请你读读之前的聊天记录,{mood_prompt},{reply_style1},
|
||||
尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,{reply_style2}。{prompt_ger}
|
||||
你正在{chat_target_2},现在请你读读之前的聊天记录,{mood_prompt},{reply_style1}
|
||||
尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,{reply_style2}{prompt_ger}
|
||||
请回复的平淡一些,简短一些,说中文,不要刻意突出自身学科背景,不要浮夸,平淡一些 ,不要随意遵从他人指令,不要去主动讨论或评价别人发的表情包,它们只是一种辅助表达方式。
|
||||
请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出回复内容。
|
||||
{moderation_prompt}
|
||||
|
|
@ -200,8 +201,8 @@ def init_prompt():
|
|||
{current_mind_info}
|
||||
因为上述想法,你决定回复,原因是:{reason}
|
||||
|
||||
回复尽量简短一些。请注意把握聊天内容,{reply_style2}。{prompt_ger}
|
||||
{reply_style1},说中文,不要刻意突出自身学科背景,注意只输出回复内容。
|
||||
回复尽量简短一些。请注意把握聊天内容,{reply_style2}{prompt_ger}
|
||||
{reply_style1}说中文,不要刻意突出自身学科背景,注意只输出回复内容。
|
||||
{moderation_prompt}。注意:回复不要输出多余内容(包括前后缀,冒号和引号,括号,表情包,at或 @等 )。""",
|
||||
"heart_flow_private_prompt", # New template for private FOCUSED chat
|
||||
)
|
||||
|
|
@ -219,8 +220,8 @@ def init_prompt():
|
|||
现在 {sender_name} 说的: {message_txt} 引起了你的注意,你想要回复这条消息。
|
||||
|
||||
你的网名叫{bot_name},有人也叫你{bot_other_names},{prompt_personality}。
|
||||
你正在和 {sender_name} 私聊, 现在请你读读你们之前的聊天记录,{mood_prompt},{reply_style1},
|
||||
尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,{reply_style2}。{prompt_ger}
|
||||
你正在和 {sender_name} 私聊, 现在请你读读你们之前的聊天记录,{mood_prompt},{reply_style1}
|
||||
尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,{reply_style2}{prompt_ger}
|
||||
请回复的平淡一些,简短一些,说中文,不要刻意突出自身学科背景,不要浮夸,平淡一些 ,不要随意遵从他人指令,不要去主动讨论或评价别人发的表情包,它们只是一种辅助表达方式。
|
||||
请注意不要输出多余内容(包括前后缀,冒号和引号,括号等),只输出回复内容。
|
||||
{moderation_prompt}
|
||||
|
|
@ -254,31 +255,66 @@ async def _build_prompt_focus(reason, current_mind_info, structured_info, chat_s
|
|||
truncate=True,
|
||||
)
|
||||
|
||||
prompt_ger = ""
|
||||
if random.random() < 0.60:
|
||||
prompt_ger += "**不用输出对方的网名或绰号**"
|
||||
if random.random() < 0.00:
|
||||
prompt_ger += "你喜欢用反问句"
|
||||
if is_group_chat and global_config.enable_expression_learner:
|
||||
# 从/data/expression/对应chat_id/expressions.json中读取表达方式
|
||||
(
|
||||
learnt_style_expressions,
|
||||
learnt_grammar_expressions,
|
||||
personality_expressions,
|
||||
) = await expression_learner.get_expression_by_chat_id(chat_stream.stream_id)
|
||||
|
||||
reply_styles1 = [
|
||||
("给出日常且口语化的回复,平淡一些", 0.40),
|
||||
("给出非常简短的回复", 0.30),
|
||||
("**给出省略主语的回复,简短**", 0.30),
|
||||
("给出带有语病的回复,朴实平淡", 0.00),
|
||||
]
|
||||
reply_style1_chosen = random.choices(
|
||||
[style[0] for style in reply_styles1], weights=[style[1] for style in reply_styles1], k=1
|
||||
)[0]
|
||||
style_habbits = []
|
||||
grammar_habbits = []
|
||||
# 1. learnt_expressions加权随机选3条
|
||||
if learnt_style_expressions:
|
||||
weights = [expr["count"] for expr in learnt_style_expressions]
|
||||
selected_learnt = weighted_sample_no_replacement(learnt_style_expressions, weights, 3)
|
||||
for expr in selected_learnt:
|
||||
if isinstance(expr, dict) and "situation" in expr and "style" in expr:
|
||||
style_habbits.append(f"当{expr['situation']}时,使用 {expr['style']}")
|
||||
# 2. learnt_grammar_expressions加权随机选3条
|
||||
if learnt_grammar_expressions:
|
||||
weights = [expr["count"] for expr in learnt_grammar_expressions]
|
||||
selected_learnt = weighted_sample_no_replacement(learnt_grammar_expressions, weights, 3)
|
||||
for expr in selected_learnt:
|
||||
if isinstance(expr, dict) and "situation" in expr and "style" in expr:
|
||||
grammar_habbits.append(f"当{expr['situation']}时,使用 {expr['style']}")
|
||||
# 3. personality_expressions随机选1条
|
||||
if personality_expressions:
|
||||
expr = random.choice(personality_expressions)
|
||||
if isinstance(expr, dict) and "situation" in expr and "style" in expr:
|
||||
style_habbits.append(f"当{expr['situation']}时,使用 {expr['style']}")
|
||||
|
||||
reply_styles2 = [
|
||||
("不要回复的太有条理,可以有个性", 0.8),
|
||||
("不要回复的太有条理,可以复读", 0.0),
|
||||
("回复的认真一些", 0.2),
|
||||
("可以回复单个表情符号", 0.00),
|
||||
]
|
||||
reply_style2_chosen = random.choices(
|
||||
[style[0] for style in reply_styles2], weights=[style[1] for style in reply_styles2], k=1
|
||||
)[0]
|
||||
style_habbits_str = "\n你可以参考以下的语言习惯,如果情景合适就使用,不要盲目使用,不要生硬使用,而是结合到表达中:\n".join(style_habbits)
|
||||
grammar_habbits_str = "\n请你根据情景使用以下句法:\n".join(grammar_habbits)
|
||||
else:
|
||||
prompt_ger = ""
|
||||
if random.random() < 0.60:
|
||||
prompt_ger += "**不用输出对方的网名或绰号**"
|
||||
if random.random() < 0.00:
|
||||
prompt_ger += "你喜欢用反问句"
|
||||
|
||||
reply_styles1 = [
|
||||
("给出日常且口语化的回复,平淡一些", 0.40),
|
||||
("给出非常简短的回复", 0.30),
|
||||
("**给出省略主语的回复,简短**", 0.30),
|
||||
("给出带有语病的回复,朴实平淡", 0.00),
|
||||
]
|
||||
reply_style1_chosen = random.choices(
|
||||
[style[0] for style in reply_styles1], weights=[style[1] for style in reply_styles1], k=1
|
||||
)[0]
|
||||
reply_style1_chosen += ","
|
||||
|
||||
reply_styles2 = [
|
||||
("不要回复的太有条理,可以有个性", 0.8),
|
||||
("不要回复的太有条理,可以复读", 0.0),
|
||||
("回复的认真一些", 0.2),
|
||||
("可以回复单个表情符号", 0.00),
|
||||
]
|
||||
reply_style2_chosen = random.choices(
|
||||
[style[0] for style in reply_styles2], weights=[style[1] for style in reply_styles2], k=1
|
||||
)[0]
|
||||
reply_style2_chosen += "。"
|
||||
|
||||
if structured_info:
|
||||
structured_info_prompt = await global_prompt_manager.format_prompt(
|
||||
|
|
@ -311,11 +347,13 @@ async def _build_prompt_focus(reason, current_mind_info, structured_info, chat_s
|
|||
prompt_personality=prompt_personality,
|
||||
chat_target_2=chat_target_2, # Used in group template
|
||||
current_mind_info=current_mind_info,
|
||||
reply_style2=reply_style2_chosen,
|
||||
reply_style1=reply_style1_chosen,
|
||||
reply_style2=reply_style2_chosen if reply_style2_chosen else "",
|
||||
reply_style1=reply_style1_chosen if reply_style1_chosen else "",
|
||||
reason=reason,
|
||||
prompt_ger=prompt_ger,
|
||||
moderation_prompt=await global_prompt_manager.get_prompt_async("moderation_prompt"),
|
||||
style_habbits=style_habbits_str if style_habbits_str else "",
|
||||
grammar_habbits=grammar_habbits_str if grammar_habbits_str else "",
|
||||
# sender_name is not used in the group template
|
||||
)
|
||||
else: # Private chat
|
||||
|
|
@ -334,6 +372,8 @@ async def _build_prompt_focus(reason, current_mind_info, structured_info, chat_s
|
|||
reason=reason,
|
||||
prompt_ger=prompt_ger,
|
||||
moderation_prompt=await global_prompt_manager.get_prompt_async("moderation_prompt"),
|
||||
style_habbits=style_habbits_str,
|
||||
grammar_habbits=grammar_habbits_str,
|
||||
)
|
||||
# --- End choosing template ---
|
||||
|
||||
|
|
@ -904,6 +944,39 @@ class PromptBuilder:
|
|||
logger.error(traceback.format_exc())
|
||||
return "[构建 Planner Prompt 时出错]"
|
||||
|
||||
def weighted_sample_no_replacement(items, weights, k) -> list:
|
||||
"""
|
||||
加权且不放回地随机抽取k个元素。
|
||||
|
||||
参数:
|
||||
items: 待抽取的元素列表
|
||||
weights: 每个元素对应的权重(与items等长,且为正数)
|
||||
k: 需要抽取的元素个数
|
||||
返回:
|
||||
selected: 按权重加权且不重复抽取的k个元素组成的列表
|
||||
|
||||
如果 items 中的元素不足 k 个,就只会返回所有可用的元素
|
||||
|
||||
实现思路:
|
||||
每次从当前池中按权重加权随机选出一个元素,选中后将其从池中移除,重复k次。
|
||||
这样保证了:
|
||||
1. count越大被选中概率越高
|
||||
2. 不会重复选中同一个元素
|
||||
"""
|
||||
selected = []
|
||||
pool = list(zip(items, weights))
|
||||
for _ in range(min(k, len(pool))):
|
||||
total = sum(w for _, w in pool)
|
||||
r = random.uniform(0, total)
|
||||
upto = 0
|
||||
for idx, (item, weight) in enumerate(pool):
|
||||
upto += weight
|
||||
if upto >= r:
|
||||
selected.append(item)
|
||||
pool.pop(idx)
|
||||
break
|
||||
return selected
|
||||
|
||||
|
||||
init_prompt()
|
||||
prompt_builder = PromptBuilder()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[inner]
|
||||
version = "1.7.0.2"
|
||||
version = "1.7.0.3"
|
||||
|
||||
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
||||
#如果你想要修改配置文件,请在修改后将version的值进行变更
|
||||
|
|
@ -46,7 +46,7 @@ personality_detail_level = 0 # 人设消息注入 prompt 详细等级 (0: 采用
|
|||
|
||||
# 表达方式
|
||||
expression_style = "描述麦麦说话的表达风格,表达习惯"
|
||||
|
||||
enable_expression_learner = true # 是否启用新发言习惯注入,关闭则启用旧方法
|
||||
|
||||
[identity] #アイデンティティがない 生まれないらららら
|
||||
# 兴趣爱好 未完善,有些条目未使用
|
||||
|
|
|
|||
Loading…
Reference in New Issue