diff --git a/src/heart_flow/heartflow.py b/src/heart_flow/heartflow.py index 2d0326384..8f582fb07 100644 --- a/src/heart_flow/heartflow.py +++ b/src/heart_flow/heartflow.py @@ -6,7 +6,9 @@ from src.plugins.config.config import global_config from src.plugins.schedule.schedule_generator import bot_schedule import asyncio from src.common.logger import get_module_logger, LogConfig, HEARTFLOW_STYLE_CONFIG # noqa: E402 +from src.individuality.individuality import Individuality import time +import random heartflow_config = LogConfig( # 使用海马体专用样式 @@ -40,7 +42,6 @@ class Heartflow: self._subheartflows = {} self.active_subheartflows_nums = 0 - self.personality_info = " ".join(global_config.PROMPT_PERSONALITY) async def _cleanup_inactive_subheartflows(self): """定期清理不活跃的子心流""" @@ -81,7 +82,27 @@ class Heartflow: logger.debug("麦麦大脑袋转起来了") self.current_state.update_current_state_info() - personality_info = self.personality_info + # 开始构建prompt + prompt_personality = "你" + #person + individuality = Individuality.get_instance() + + personality_core = individuality.personality.personality_core + prompt_personality += personality_core + + personality_sides = individuality.personality.personality_sides + random.shuffle(personality_sides) + prompt_personality += f",{personality_sides[0]}" + + identity_detail = individuality.identity.identity_detail + random.shuffle(identity_detail) + prompt_personality += f",{identity_detail[0]}" + + + + personality_info = prompt_personality + + current_thinking_info = self.current_mind mood_info = self.current_state.mood related_memory_info = "memory" @@ -123,7 +144,25 @@ class Heartflow: return await self.minds_summary(sub_minds) async def minds_summary(self, minds_str): - personality_info = self.personality_info + # 开始构建prompt + prompt_personality = "你" + #person + individuality = Individuality.get_instance() + + personality_core = individuality.personality.personality_core + prompt_personality += personality_core + + personality_sides = individuality.personality.personality_sides + random.shuffle(personality_sides) + prompt_personality += f",{personality_sides[0]}" + + identity_detail = individuality.identity.identity_detail + random.shuffle(identity_detail) + prompt_personality += f",{identity_detail[0]}" + + + + personality_info = prompt_personality mood_info = self.current_state.mood prompt = "" diff --git a/src/heart_flow/observation.py b/src/heart_flow/observation.py index 09af33c41..f4a082a4e 100644 --- a/src/heart_flow/observation.py +++ b/src/heart_flow/observation.py @@ -4,7 +4,8 @@ from datetime import datetime from src.plugins.models.utils_model import LLM_request from src.plugins.config.config import global_config from src.common.database import db - +from src.individuality.individuality import Individuality +import random # 所有观察的基类 class Observation: @@ -24,7 +25,6 @@ class ChattingObservation(Observation): self.talking_message = [] self.talking_message_str = "" - self.personality_info = " ".join(global_config.PROMPT_PERSONALITY) self.name = global_config.BOT_NICKNAME self.nick_name = global_config.BOT_ALIAS_NAMES @@ -115,8 +115,30 @@ class ChattingObservation(Observation): async def update_talking_summary(self, new_messages_str): # 基于已经有的talking_summary,和新的talking_message,生成一个summary # print(f"更新聊天总结:{self.talking_summary}") + # 开始构建prompt + prompt_personality = "你" + #person + individuality = Individuality.get_instance() + + personality_core = individuality.personality.personality_core + prompt_personality += personality_core + + personality_sides = individuality.personality.personality_sides + random.shuffle(personality_sides) + prompt_personality += f",{personality_sides[0]}" + + identity_detail = individuality.identity.identity_detail + random.shuffle(identity_detail) + prompt_personality += f",{identity_detail[0]}" + + + + personality_info = prompt_personality + + + prompt = "" - prompt += f"你{self.personality_info},请注意识别你自己的聊天发言" + prompt += f"{personality_info},请注意识别你自己的聊天发言" prompt += f"你的名字叫:{self.name},你的昵称是:{self.nick_name}\n" prompt += f"你正在参与一个qq群聊的讨论,你记得这个群之前在聊的内容是:{self.observe_info}\n" prompt += f"现在群里的群友们产生了新的讨论,有了新的发言,具体内容如下:{new_messages_str}\n" diff --git a/src/heart_flow/sub_heartflow.py b/src/heart_flow/sub_heartflow.py index 1312b7aae..b6a0fb30e 100644 --- a/src/heart_flow/sub_heartflow.py +++ b/src/heart_flow/sub_heartflow.py @@ -11,6 +11,8 @@ from src.common.logger import get_module_logger, LogConfig, SUB_HEARTFLOW_STYLE_ from src.plugins.chat.utils import get_embedding from src.common.database import db from typing import Union +from src.individuality.individuality import Individuality +import random subheartflow_config = LogConfig( # 使用海马体专用样式 @@ -51,7 +53,6 @@ class SubHeartflow: if not self.current_mind: self.current_mind = "你什么也没想" - self.personality_info = " ".join(global_config.PROMPT_PERSONALITY) self.is_active = False @@ -159,6 +160,25 @@ class SubHeartflow: chat_observe_info = observation.observe_info # print(f"chat_observe_info:{chat_observe_info}") + # 开始构建prompt + prompt_personality = "你" + #person + individuality = Individuality.get_instance() + + personality_core = individuality.personality.personality_core + prompt_personality += personality_core + + personality_sides = individuality.personality.personality_sides + random.shuffle(personality_sides) + prompt_personality += f",{personality_sides[0]}" + + identity_detail = individuality.identity.identity_detail + random.shuffle(identity_detail) + prompt_personality += f",{identity_detail[0]}" + + + + # 调取记忆 related_memory = await HippocampusManager.get_instance().get_memory_from_text( text=chat_observe_info, max_memory_num=2, max_memory_length=2, max_depth=3, fast_retrieval=False @@ -184,7 +204,7 @@ class SubHeartflow: prompt = "" # prompt += f"麦麦的总体想法是:{self.main_heartflow_info}\n\n" - prompt += f"你{self.personality_info}\n" + prompt += f"{prompt_personality}\n" prompt += f"你刚刚在做的事情是:{schedule_info}\n" if related_memory_info: prompt += f"你想起来你之前见过的回忆:{related_memory_info}。\n以上是你的回忆,不一定是目前聊天里的人说的,也不一定是现在发生的事情,请记住。\n" @@ -207,6 +227,25 @@ class SubHeartflow: async def do_thinking_after_reply(self, reply_content, chat_talking_prompt): # print("麦麦回复之后脑袋转起来了") + + # 开始构建prompt + prompt_personality = "你" + #person + individuality = Individuality.get_instance() + + personality_core = individuality.personality.personality_core + prompt_personality += personality_core + + personality_sides = individuality.personality.personality_sides + random.shuffle(personality_sides) + prompt_personality += f",{personality_sides[0]}" + + identity_detail = individuality.identity.identity_detail + random.shuffle(identity_detail) + prompt_personality += f",{identity_detail[0]}" + + + current_thinking_info = self.current_mind mood_info = self.current_state.mood @@ -219,7 +258,7 @@ class SubHeartflow: prompt = "" # prompt += f"你现在正在做的事情是:{schedule_info}\n" - prompt += f"你{self.personality_info}\n" + prompt += f"{prompt_personality}\n" prompt += f"现在你正在上网,和qq群里的网友们聊天,群里正在聊的话题是:{chat_observe_info}\n" prompt += f"刚刚你的想法是{current_thinking_info}。" prompt += f"你现在看到了网友们发的新消息:{message_new_info}\n" @@ -238,12 +277,30 @@ class SubHeartflow: self.last_reply_time = time.time() async def judge_willing(self): + # 开始构建prompt + prompt_personality = "你" + #person + individuality = Individuality.get_instance() + + personality_core = individuality.personality.personality_core + prompt_personality += personality_core + + personality_sides = individuality.personality.personality_sides + random.shuffle(personality_sides) + prompt_personality += f",{personality_sides[0]}" + + identity_detail = individuality.identity.identity_detail + random.shuffle(identity_detail) + prompt_personality += f",{identity_detail[0]}" + + + # print("麦麦闹情绪了1") current_thinking_info = self.current_mind mood_info = self.current_state.mood # print("麦麦闹情绪了2") prompt = "" - prompt += f"{self.personality_info}\n" + prompt += f"{prompt_personality}\n" prompt += "现在你正在上网,和qq群里的网友们聊天" prompt += f"你现在的想法是{current_thinking_info}。" prompt += f"你现在{mood_info}。" diff --git a/src/individuality/identity.py b/src/individuality/identity.py new file mode 100644 index 000000000..287f9e5d5 --- /dev/null +++ b/src/individuality/identity.py @@ -0,0 +1,95 @@ +from dataclasses import dataclass +from typing import List + +@dataclass +class Identity: + """身份特征类""" + identity_detail: List[str] # 身份细节描述 + height: int # 身高(厘米) + weight: int # 体重(千克) + age: int # 年龄 + gender: str # 性别 + appearance: str # 外貌特征 + + _instance = None + + def __new__(cls, *args, **kwargs): + if cls._instance is None: + cls._instance = super().__new__(cls) + return cls._instance + + def __init__(self, identity_detail: List[str] = None, height: int = 0, weight: int = 0, + age: int = 0, gender: str = "", appearance: str = ""): + """初始化身份特征 + + Args: + identity_detail: 身份细节描述列表 + height: 身高(厘米) + weight: 体重(千克) + age: 年龄 + gender: 性别 + appearance: 外貌特征 + """ + if identity_detail is None: + identity_detail = [] + self.identity_detail = identity_detail + self.height = height + self.weight = weight + self.age = age + self.gender = gender + self.appearance = appearance + + @classmethod + def get_instance(cls) -> 'Identity': + """获取Identity单例实例 + + Returns: + Identity: 单例实例 + """ + if cls._instance is None: + cls._instance = cls() + return cls._instance + + @classmethod + def initialize(cls, identity_detail: List[str], height: int, weight: int, + age: int, gender: str, appearance: str) -> 'Identity': + """初始化身份特征 + + Args: + identity_detail: 身份细节描述列表 + height: 身高(厘米) + weight: 体重(千克) + age: 年龄 + gender: 性别 + appearance: 外貌特征 + + Returns: + Identity: 初始化后的身份特征实例 + """ + instance = cls.get_instance() + instance.identity_detail = identity_detail + instance.height = height + instance.weight = weight + instance.age = age + instance.gender = gender + instance.appearance = appearance + return instance + + def to_dict(self) -> dict: + """将身份特征转换为字典格式""" + return { + "identity_detail": self.identity_detail, + "height": self.height, + "weight": self.weight, + "age": self.age, + "gender": self.gender, + "appearance": self.appearance + } + + @classmethod + def from_dict(cls, data: dict) -> 'Identity': + """从字典创建身份特征实例""" + instance = cls.get_instance() + for key, value in data.items(): + setattr(instance, key, value) + return instance \ No newline at end of file diff --git a/src/individuality/individuality.py b/src/individuality/individuality.py new file mode 100644 index 000000000..899de62e7 --- /dev/null +++ b/src/individuality/individuality.py @@ -0,0 +1,77 @@ +from typing import Optional +from .personality import Personality +from .identity import Identity + +class Individuality: + """个体特征管理类""" + _instance = None + + def __new__(cls, *args, **kwargs): + if cls._instance is None: + cls._instance = super().__new__(cls) + return cls._instance + + def __init__(self): + self.personality: Optional[Personality] = None + self.identity: Optional[Identity] = None + + @classmethod + def get_instance(cls) -> 'Individuality': + """获取Individuality单例实例 + + Returns: + Individuality: 单例实例 + """ + if cls._instance is None: + cls._instance = cls() + return cls._instance + + def initialize(self, bot_nickname: str, personality_core: str, personality_sides: list, + identity_detail: list, height: int, weight: int, age: int, + gender: str, appearance: str) -> None: + """初始化个体特征 + + Args: + bot_nickname: 机器人昵称 + personality_core: 人格核心特点 + personality_sides: 人格侧面描述 + identity_detail: 身份细节描述 + height: 身高(厘米) + weight: 体重(千克) + age: 年龄 + gender: 性别 + appearance: 外貌特征 + """ + # 初始化人格 + self.personality = Personality.initialize( + bot_nickname=bot_nickname, + personality_core=personality_core, + personality_sides=personality_sides + ) + + # 初始化身份 + self.identity = Identity.initialize( + identity_detail=identity_detail, + height=height, + weight=weight, + age=age, + gender=gender, + appearance=appearance + ) + + def to_dict(self) -> dict: + """将个体特征转换为字典格式""" + return { + "personality": self.personality.to_dict() if self.personality else None, + "identity": self.identity.to_dict() if self.identity else None + } + + @classmethod + def from_dict(cls, data: dict) -> 'Individuality': + """从字典创建个体特征实例""" + instance = cls.get_instance() + if data.get("personality"): + instance.personality = Personality.from_dict(data["personality"]) + if data.get("identity"): + instance.identity = Identity.from_dict(data["identity"]) + return instance \ No newline at end of file diff --git a/src/personality/offline_llm.py b/src/individuality/offline_llm.py similarity index 100% rename from src/personality/offline_llm.py rename to src/individuality/offline_llm.py diff --git a/src/individuality/personality.py b/src/individuality/personality.py new file mode 100644 index 000000000..19aa3c212 --- /dev/null +++ b/src/individuality/personality.py @@ -0,0 +1,119 @@ +from dataclasses import dataclass +from typing import Dict, List +import os +import json +from pathlib import Path + +@dataclass +class Personality: + """人格特质类""" + openness: float # 开放性 + conscientiousness: float # 尽责性 + extraversion: float # 外向性 + agreeableness: float # 宜人性 + neuroticism: float # 神经质 + bot_nickname: str # 机器人昵称 + personality_core: str # 人格核心特点 + personality_sides: List[str] # 人格侧面描述 + + _instance = None + + def __new__(cls, *args, **kwargs): + if cls._instance is None: + cls._instance = super().__new__(cls) + return cls._instance + + def __init__(self, personality_core: str = "", personality_sides: List[str] = None): + if personality_sides is None: + personality_sides = [] + self.personality_core = personality_core + self.personality_sides = personality_sides + + @classmethod + def get_instance(cls) -> 'Personality': + """获取Personality单例实例 + + Returns: + Personality: 单例实例 + """ + if cls._instance is None: + cls._instance = cls() + return cls._instance + + def _init_big_five_personality(self): + """初始化大五人格特质""" + # 构建文件路径 + personality_file = Path("data/personality") / f"{self.bot_nickname}_personality.per" + + # 如果文件存在,读取文件 + if personality_file.exists(): + with open(personality_file, 'r', encoding='utf-8') as f: + personality_data = json.load(f) + self.openness = personality_data.get('openness', 0.5) + self.conscientiousness = personality_data.get('conscientiousness', 0.5) + self.extraversion = personality_data.get('extraversion', 0.5) + self.agreeableness = personality_data.get('agreeableness', 0.5) + self.neuroticism = personality_data.get('neuroticism', 0.5) + else: + # 如果文件不存在,根据personality_core和personality_core来设置大五人格特质 + if "活泼" in self.personality_core or "开朗" in self.personality_sides: + self.extraversion = 0.8 + self.neuroticism = 0.2 + else: + self.extraversion = 0.3 + self.neuroticism = 0.5 + + if "认真" in self.personality_core or "负责" in self.personality_sides: + self.conscientiousness = 0.9 + else: + self.conscientiousness = 0.5 + + if "友善" in self.personality_core or "温柔" in self.personality_sides: + self.agreeableness = 0.9 + else: + self.agreeableness = 0.5 + + if "创新" in self.personality_core or "开放" in self.personality_sides: + self.openness = 0.8 + else: + self.openness = 0.5 + + @classmethod + def initialize(cls, bot_nickname: str, personality_core: str, personality_sides: List[str]) -> 'Personality': + """初始化人格特质 + + Args: + bot_nickname: 机器人昵称 + personality_core: 人格核心特点 + personality_sides: 人格侧面描述 + + Returns: + Personality: 初始化后的人格特质实例 + """ + instance = cls.get_instance() + instance.bot_nickname = bot_nickname + instance.personality_core = personality_core + instance.personality_sides = personality_sides + instance._init_big_five_personality() + return instance + + def to_dict(self) -> Dict: + """将人格特质转换为字典格式""" + return { + "openness": self.openness, + "conscientiousness": self.conscientiousness, + "extraversion": self.extraversion, + "agreeableness": self.agreeableness, + "neuroticism": self.neuroticism, + "bot_nickname": self.bot_nickname, + "personality_core": self.personality_core, + "personality_sides": self.personality_sides + } + + @classmethod + def from_dict(cls, data: Dict) -> 'Personality': + """从字典创建人格特质实例""" + instance = cls.get_instance() + for key, value in data.items(): + setattr(instance, key, value) + return instance \ No newline at end of file diff --git a/src/plugins/personality_s/renqingziji_with_mymy.py b/src/individuality/renqingziji_with_mymy.py similarity index 100% rename from src/plugins/personality_s/renqingziji_with_mymy.py rename to src/individuality/renqingziji_with_mymy.py diff --git a/src/individuality/scene.py b/src/individuality/scene.py new file mode 100644 index 000000000..b94d55046 --- /dev/null +++ b/src/individuality/scene.py @@ -0,0 +1,40 @@ +import json +from typing import Dict +import os + +def load_scenes() -> Dict: + """ + 从JSON文件加载场景数据 + + Returns: + Dict: 包含所有场景的字典 + """ + current_dir = os.path.dirname(os.path.abspath(__file__)) + json_path = os.path.join(current_dir, 'template_scene.json') + + with open(json_path, 'r', encoding='utf-8') as f: + return json.load(f) + +PERSONALITY_SCENES = load_scenes() + +def get_scene_by_factor(factor: str) -> Dict: + """ + 根据人格因子获取对应的情景测试 + + Args: + factor (str): 人格因子名称 + + Returns: + Dict: 包含情景描述的字典 + """ + return PERSONALITY_SCENES.get(factor, None) + + +def get_all_scenes() -> Dict: + """ + 获取所有情景测试 + + Returns: + Dict: 所有情景测试的字典 + """ + return PERSONALITY_SCENES diff --git a/src/individuality/template_scene.json b/src/individuality/template_scene.json new file mode 100644 index 000000000..cd9ae4752 --- /dev/null +++ b/src/individuality/template_scene.json @@ -0,0 +1,112 @@ +{ + "外向性": { + "场景1": { + "scenario": "你刚刚搬到一个新的城市工作。今天是你入职的第一天,在公司的电梯里,一位同事微笑着和你打招呼:\n\n同事:「嗨!你是新来的同事吧?我是市场部的小林。」\n\n同事看起来很友善,还主动介绍说:「待会午饭时间,我们部门有几个人准备一起去楼下新开的餐厅,你要一起来吗?可以认识一下其他同事。」", + "explanation": "这个场景通过职场社交情境,观察个体对于新环境、新社交圈的态度和反应倾向。" + }, + "场景2": { + "scenario": "在大学班级群里,班长发起了一个组织班级联谊活动的投票:\n\n班长:「大家好!下周末我们准备举办一次班级联谊活动,地点在学校附近的KTV。想请大家报名参加,也欢迎大家邀请其他班级的同学!」\n\n已经有几个同学在群里积极响应,有人@你问你要不要一起参加。", + "explanation": "通过班级活动场景,观察个体对群体社交活动的参与意愿。" + }, + "场景3": { + "scenario": "你在社交平台上发布了一条动态,收到了很多陌生网友的评论和私信:\n\n网友A:「你说的这个观点很有意思!想和你多交流一下。」\n\n网友B:「我也对这个话题很感兴趣,要不要建个群一起讨论?」", + "explanation": "通过网络社交场景,观察个体对线上社交的态度。" + }, + "场景4": { + "scenario": "你暗恋的对象今天主动来找你:\n\n对方:「那个...我最近在准备一个演讲比赛,听说你口才很好。能不能请你帮我看看演讲稿,顺便给我一些建议?如果你有时间的话,可以一起吃个饭聊聊。」", + "explanation": "通过恋爱情境,观察个体在面对心仪对象时的社交表现。" + }, + "场景5": { + "scenario": "在一次线下读书会上,主持人突然点名让你分享读后感:\n\n主持人:「听说你对这本书很有见解,能不能和大家分享一下你的想法?」\n\n现场有二十多个陌生的读书爱好者,都期待地看着你。", + "explanation": "通过即兴发言场景,观察个体的社交表现欲和公众表达能力。" + } + }, + "神经质": { + "场景1": { + "scenario": "你正在准备一个重要的项目演示,这关系到你的晋升机会。就在演示前30分钟,你收到了主管发来的消息:\n\n主管:「临时有个变动,CEO也会来听你的演示。他对这个项目特别感兴趣。」\n\n正当你准备回复时,主管又发来一条:「对了,能不能把演示时间压缩到15分钟?CEO下午还有其他安排。你之前准备的是30分钟的版本对吧?」", + "explanation": "这个场景通过突发的压力情境,观察个体在面对计划外变化时的情绪反应和调节能力。" + }, + "场景2": { + "scenario": "期末考试前一天晚上,你收到了好朋友发来的消息:\n\n好朋友:「不好意思这么晚打扰你...我看你平时成绩很好,能不能帮我解答几个问题?我真的很担心明天的考试。」\n\n你看了看时间,已经是晚上11点,而你原本计划的复习还没完成。", + "explanation": "通过考试压力场景,观察个体在时间紧张时的情绪管理。" + }, + "场景3": { + "scenario": "你在社交媒体上发表的一个观点引发了争议,有不少人开始批评你:\n\n网友A:「这种观点也好意思说出来,真是无知。」\n\n网友B:「建议楼主先去补补课再来发言。」\n\n评论区里的负面评论越来越多,还有人开始人身攻击。", + "explanation": "通过网络争议场景,观察个体面对批评时的心理承受能力。" + }, + "场景4": { + "scenario": "你和恋人约好今天一起看电影,但在约定时间前半小时,对方发来消息:\n\n恋人:「对不起,我临时有点事,可能要迟到一会儿。」\n\n二十分钟后,对方又发来消息:「可能要再等等,抱歉!」\n\n电影快要开始了,但对方还是没有出现。", + "explanation": "通过恋爱情境,观察个体对不确定性的忍耐程度。" + }, + "场景5": { + "scenario": "在一次重要的小组展示中,你的组员在演示途中突然卡壳了:\n\n组员小声对你说:「我忘词了,接下来的部分是什么来着...」\n\n台下的老师和同学都在等待,气氛有些尴尬。", + "explanation": "通过公开场合的突发状况,观察个体的应急反应和压力处理能力。" + } + }, + "严谨性": { + "场景1": { + "scenario": "你是团队的项目负责人,刚刚接手了一个为期两个月的重要项目。在第一次团队会议上:\n\n小王:「老大,我觉得两个月时间很充裕,我们先做着看吧,遇到问题再解决。」\n\n小张:「要不要先列个时间表?不过感觉太详细的计划也没必要,点到为止就行。」\n\n小李:「客户那边说如果能提前完成有奖励,我觉得我们可以先做快一点的部分。」", + "explanation": "这个场景通过项目管理情境,体现个体在工作方法、计划性和责任心方面的特征。" + }, + "场景2": { + "scenario": "期末小组作业,组长让大家分工完成一份研究报告。在截止日期前三天:\n\n组员A:「我的部分大概写完了,感觉还行。」\n\n组员B:「我这边可能还要一天才能完成,最近太忙了。」\n\n组员C发来一份没有任何引用出处、可能存在抄袭的内容:「我写完了,你们看看怎么样?」", + "explanation": "通过学习场景,观察个体对学术规范和质量要求的重视程度。" + }, + "场景3": { + "scenario": "你在一个兴趣小组的群聊中,大家正在讨论举办一次线下活动:\n\n成员A:「到时候见面就知道具体怎么玩了!」\n\n成员B:「对啊,随意一点挺好的。」\n\n成员C:「人来了自然就热闹了。」", + "explanation": "通过活动组织场景,观察个体对活动计划的态度。" + }, + "场景4": { + "scenario": "你和恋人计划一起去旅游,对方说:\n\n恋人:「我们就随心而行吧!订个目的地,其他的到了再说,这样更有意思。」\n\n距离出发还有一周时间,但机票、住宿和具体行程都还没有确定。", + "explanation": "通过旅行规划场景,观察个体的计划性和对不确定性的接受程度。" + }, + "场景5": { + "scenario": "在一个重要的团队项目中,你发现一个同事的工作存在明显错误:\n\n同事:「差不多就行了,反正领导也看不出来。」\n\n这个错误可能不会立即造成问题,但长期来看可能会影响项目质量。", + "explanation": "通过工作质量场景,观察个体对细节和标准的坚持程度。" + } + }, + "开放性": { + "场景1": { + "scenario": "周末下午,你的好友小美兴致勃勃地给你打电话:\n\n小美:「我刚发现一个特别有意思的沉浸式艺术展!不是传统那种挂画的展览,而是把整个空间都变成了艺术品。观众要穿特制的服装,还要带上VR眼镜,好像还有AI实时互动!」\n\n小美继续说:「虽然票价不便宜,但听说体验很独特。网上评价两极分化,有人说是前所未有的艺术革新,也有人说是哗众取宠。要不要周末一起去体验一下?」", + "explanation": "这个场景通过新型艺术体验,反映个体对创新事物的接受程度和尝试意愿。" + }, + "场景2": { + "scenario": "在一节创意写作课上,老师提出了一个特别的作业:\n\n老师:「下周的作业是用AI写作工具协助创作一篇小说。你们可以自由探索如何与AI合作,打破传统写作方式。」\n\n班上随即展开了激烈讨论,有人认为这是对创作的亵渎,也有人对这种新形式感到兴奋。", + "explanation": "通过新技术应用场景,观察个体对创新学习方式的态度。" + }, + "场景3": { + "scenario": "在社交媒体上,你看到一个朋友分享了一种新的生活方式:\n\n「最近我在尝试'数字游牧'生活,就是一边远程工作一边环游世界。没有固定住所,住青旅或短租,认识来自世界各地的朋友。虽然有时会很不稳定,但这种自由的生活方式真的很棒!」\n\n评论区里争论不断,有人向往这种生活,也有人觉得太冒险。", + "explanation": "通过另类生活方式,观察个体对非传统选择的态度。" + }, + "场景4": { + "scenario": "你的恋人突然提出了一个想法:\n\n恋人:「我们要不要尝试一下开放式关系?就是在保持彼此关系的同时,也允许和其他人发展感情。现在国外很多年轻人都这样。」\n\n这个提议让你感到意外,你之前从未考虑过这种可能性。", + "explanation": "通过感情观念场景,观察个体对非传统关系模式的接受度。" + }, + "场景5": { + "scenario": "在一次朋友聚会上,大家正在讨论未来职业规划:\n\n朋友A:「我准备辞职去做自媒体,专门介绍一些小众的文化和艺术。」\n\n朋友B:「我想去学习生物科技,准备转行做人造肉研发。」\n\n朋友C:「我在考虑加入一个区块链创业项目,虽然风险很大。」", + "explanation": "通过职业选择场景,观察个体对新兴领域的探索意愿。" + } + }, + "宜人性": { + "场景1": { + "scenario": "在回家的公交车上,你遇到这样一幕:\n\n一位老奶奶颤颤巍巍地上了车,车上座位已经坐满了。她站在你旁边,看起来很疲惫。这时你听到前排两个年轻人的对话:\n\n年轻人A:「那个老太太好像站不稳,看起来挺累的。」\n\n年轻人B:「现在的老年人真是...我看她包里还有菜,肯定是去菜市场买完菜回来的,这么多人都不知道叫子女开车接送。」\n\n就在这时,老奶奶一个趔趄,差点摔倒。她扶住了扶手,但包里的东西洒了一些出来。", + "explanation": "这个场景通过公共场合的助人情境,体现个体的同理心和对他人需求的关注程度。" + }, + "场景2": { + "scenario": "在班级群里,有同学发起为生病住院的同学捐款:\n\n同学A:「大家好,小林最近得了重病住院,医药费很贵,家里负担很重。我们要不要一起帮帮他?」\n\n同学B:「我觉得这是他家里的事,我们不方便参与吧。」\n\n同学C:「但是都是同学一场,帮帮忙也是应该的。」", + "explanation": "通过同学互助场景,观察个体的助人意愿和同理心。" + }, + "场景3": { + "scenario": "在一个网络讨论组里,有人发布了求助信息:\n\n求助者:「最近心情很低落,感觉生活很压抑,不知道该怎么办...」\n\n评论区里已经有一些回复:\n「生活本来就是这样,想开点!」\n「你这样子太消极了,要积极面对。」\n「谁还没点烦心事啊,过段时间就好了。」", + "explanation": "通过网络互助场景,观察个体的共情能力和安慰方式。" + }, + "场景4": { + "scenario": "你的恋人向你倾诉工作压力:\n\n恋人:「最近工作真的好累,感觉快坚持不下去了...」\n\n但今天你也遇到了很多烦心事,心情也不太好。", + "explanation": "通过感情关系场景,观察个体在自身状态不佳时的关怀能力。" + }, + "场景5": { + "scenario": "在一次团队项目中,新来的同事小王因为经验不足,造成了一个严重的错误。在部门会议上:\n\n主管:「这个错误造成了很大的损失,是谁负责的这部分?」\n\n小王看起来很紧张,欲言又止。你知道是他造成的错误,同时你也是这个项目的共同负责人。", + "explanation": "通过职场情境,观察个体在面对他人过错时的态度和处理方式。" + } + } +} \ No newline at end of file diff --git a/src/main.py b/src/main.py index 14dc04355..3e657204f 100644 --- a/src/main.py +++ b/src/main.py @@ -15,6 +15,7 @@ from .plugins.config.config import global_config from .plugins.chat.bot import chat_bot from .common.logger import get_module_logger from .plugins.remote import heartbeat_thread # noqa: F401 +from .individuality.individuality import Individuality logger = get_module_logger("main") @@ -26,6 +27,7 @@ class MainSystem: self.mood_manager = MoodManager.get_instance() self.hippocampus_manager = HippocampusManager.get_instance() self._message_manager_started = False + self.individuality = Individuality.get_instance() # 使用消息API替代直接的FastAPI实例 from .plugins.message import global_api @@ -79,7 +81,7 @@ class MainSystem: # 初始化日程 bot_schedule.initialize( name=global_config.BOT_NICKNAME, - personality=global_config.PROMPT_PERSONALITY, + personality=global_config.personality_core, behavior=global_config.PROMPT_SCHEDULE_GEN, interval=global_config.SCHEDULE_DOING_UPDATE_INTERVAL, ) @@ -88,6 +90,20 @@ class MainSystem: # 启动FastAPI服务器 self.app.register_message_handler(chat_bot.message_process) + # 初始化个体特征 + self.individuality.initialize( + bot_nickname=global_config.BOT_NICKNAME, + personality_core=global_config.personality_core, + personality_sides=global_config.personality_sides, + identity_detail=global_config.identity_detail, + height=global_config.height, + weight=global_config.weight, + age=global_config.age, + gender=global_config.gender, + appearance=global_config.appearance + ) + logger.success("个体特征初始化成功") + try: # 启动心流系统 asyncio.create_task(heartflow.heartflow_start_working()) diff --git a/src/personality/personality.py b/src/personality/personality.py deleted file mode 100644 index 3977743a5..000000000 --- a/src/personality/personality.py +++ /dev/null @@ -1,32 +0,0 @@ -from dataclasses import dataclass -from typing import Dict, List - -@dataclass -class Personality: - """人格特质类""" - openness: float # 开放性 - conscientiousness: float # 尽责性 - extraversion: float # 外向性 - agreeableness: float # 宜人性 - neuroticism: float # 神经质 - bot_nickname: str # 机器人昵称 - personality_core: str # 人格核心特点 - personality_detail: List[str] # 人格细节描述 - - def to_dict(self) -> Dict: - """将人格特质转换为字典格式""" - return { - "openness": self.openness, - "conscientiousness": self.conscientiousness, - "extraversion": self.extraversion, - "agreeableness": self.agreeableness, - "neuroticism": self.neuroticism, - "bot_nickname": self.bot_nickname, - "personality_core": self.personality_core, - "personality_detail": self.personality_detail - } - - @classmethod - def from_dict(cls, data: Dict) -> 'Personality': - """从字典创建人格特质实例""" - return cls(**data) \ No newline at end of file diff --git a/src/personality/personality_gen.py b/src/personality/personality_gen.py deleted file mode 100644 index 8eaf99db0..000000000 --- a/src/personality/personality_gen.py +++ /dev/null @@ -1,186 +0,0 @@ -import os -import json -import sys -from typing import Optional, List - -sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) -from src.personality.offline_llm import LLM_request_off -from src.common.logger import get_module_logger -from src.personality.personality import Personality - -logger = get_module_logger("personality_gen") - -class PersonalityGenerator: - """人格生成器类""" - def __init__(self, bot_nickname: str): - self.bot_nickname = bot_nickname - self.llm = LLM_request_off() - self.personality: Optional[Personality] = None - self.save_path = os.path.join("data", "personality") - - # 确保保存目录存在 - os.makedirs(self.save_path, exist_ok=True) - - def personality_exists(self) -> bool: - """检查是否已存在该机器人的人格文件""" - file_path = os.path.join(self.save_path, f"{self.bot_nickname}_personality.per") - return os.path.exists(file_path) - - async def generate_personality( - self, - personality_core: str, - personality_detail: List[str], - height: int, - weight: int, - age: int, - gender: str, - appearance: str, - interests: List[str], - others: List[str] - ) -> Optional[Personality]: - """根据配置生成人格特质""" - # 检查是否已存在 - if self.personality_exists(): - logger.info(f"机器人 {self.bot_nickname} 的人格文件已存在,跳过生成") - return await self.load_personality() - - # 构建提示文本 - prompt = f"""你是一个心理学家,专职心理测量和大五人格研究。请根据以下信息分析并给出这个人的大五人格特质评分。 -每个特质的分数范围是0到1之间的小数,请确保返回标准的JSON格式。 - -机器人信息: -- 昵称:{self.bot_nickname} -- 性格核心的特质:{personality_core} -- 性格细节:{', '.join(personality_detail)} -- 身高:{height}cm -- 体重:{weight}kg -- 年龄:{age}岁 -- 性别:{gender} -- 外貌:{appearance} -- 兴趣爱好:{', '.join(interests)} -- 其他信息:{', '.join(others)} -请只返回如下JSON格式数据(不要包含任何其他文字): -{{ - "openness": 0.x, - "conscientiousness": 0.x, - "extraversion": 0.x, - "agreeableness": 0.x, - "neuroticism": 0.x -}}""" - - response, _ = await self.llm.generate_response_async(prompt) - try: - # 尝试清理响应文本,只保留JSON部分 - json_str = response.strip() - if "```json" in json_str: - json_str = json_str.split("```json")[1].split("```")[0].strip() - elif "```" in json_str: - json_str = json_str.split("```")[1].strip() - - traits = json.loads(json_str) - - # 验证所有必需的字段是否存在 - required_fields = ["openness", "conscientiousness", "extraversion", "agreeableness", "neuroticism"] - if not all(field in traits for field in required_fields): - raise ValueError("缺少必需的人格特质字段") - - # 验证数值是否在合理范围内 - for field in required_fields: - if not 0 <= traits[field] <= 1: - traits[field] = max(0, min(traits[field], 1)) - - self.personality = Personality( - **traits, - bot_nickname=self.bot_nickname - ) - await self.save_personality() - return self.personality - - except json.JSONDecodeError as e: - logger.error(f"JSON解析失败: {e}\n响应内容: {response}") - raise - except Exception as e: - logger.error(f"生成人格特质失败: {e}") - raise - - async def save_personality(self) -> None: - """保存人格特质到文件""" - if not self.personality: - raise ValueError("没有可保存的人格特质") - - file_path = os.path.join(self.save_path, f"{self.bot_nickname}_personality.per") - try: - with open(file_path, 'w', encoding='utf-8') as f: - json.dump(self.personality.to_dict(), f, ensure_ascii=False, indent=4) - logger.info(f"人格特质已保存到: {file_path}") - except Exception as e: - logger.error(f"保存人格特质失败: {e}") - raise - - async def load_personality(self) -> Optional[Personality]: - """从文件加载人格特质""" - file_path = os.path.join(self.save_path, f"{self.bot_nickname}_personality.per") - try: - if os.path.exists(file_path): - with open(file_path, 'r', encoding='utf-8') as f: - data = json.load(f) - self.personality = Personality.from_dict(data) - return self.personality - except Exception as e: - logger.error(f"加载人格特质失败: {e}") - return None - -async def main(): - """主函数,用于测试人格生成""" - # 创建人格生成器实例 - generator = PersonalityGenerator("麦麦") - - # 生成或加载人格 - personality = await generator.generate_personality( - personality_core="对世界抱着善意和好奇,愿意尝试新奇事物", - personality_detail=[ - "你会刷小红书", - "你会刷贴吧", - "学习心理学和脑科学", - "你会刷b站,对ACG文化感兴趣", - "有时候有些搞怪", - ], - height=160, - weight=45, - age=20, - gender="女", - appearance="有着橙色短发", - interests=["摄影", "绘画"], - others=["是一个大二女大学生"] - ) - - if personality: - logger.info("人格特质生成成功:") - logger.info(f"开放性: {personality.openness}") - logger.info(f"尽责性: {personality.conscientiousness}") - logger.info(f"外向性: {personality.extraversion}") - logger.info(f"宜人性: {personality.agreeableness}") - logger.info(f"神经质: {personality.neuroticism}") - else: - logger.error("人格特质生成失败") - -if __name__ == "__main__": - import asyncio - import platform - - if platform.system() == 'Windows': - # Windows平台特殊处理 - asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) - - try: - loop = asyncio.get_event_loop() - loop.run_until_complete(main()) - finally: - # 确保所有待处理的任务都完成 - pending = asyncio.all_tasks(loop) - for task in pending: - task.cancel() - - # 运行一次以处理取消的任务 - loop.run_until_complete(asyncio.gather(*pending, return_exceptions=True)) - loop.close() diff --git a/src/plugins/chat_module/reasoning_chat/reasoning_prompt_builder.py b/src/plugins/chat_module/reasoning_chat/reasoning_prompt_builder.py index 4c0f035ea..176f59b43 100644 --- a/src/plugins/chat_module/reasoning_chat/reasoning_prompt_builder.py +++ b/src/plugins/chat_module/reasoning_chat/reasoning_prompt_builder.py @@ -1,14 +1,13 @@ import random import time from typing import Optional, Union -import re -import jieba import numpy as np from ....common.database import db from ...chat.utils import get_embedding, get_recent_group_detailed_plain_text, get_recent_group_speaker from ...chat.chat_stream import chat_manager from ...moods.moods import MoodManager +from ....individuality.individuality import Individuality from ...memory_system.Hippocampus import HippocampusManager from ...schedule.schedule_generator import bot_schedule from ...config.config import global_config @@ -28,7 +27,23 @@ class PromptBuilder: ) -> tuple[str, str]: # 开始构建prompt - + prompt_personality = "你" + #person + individuality = Individuality.get_instance() + + personality_core = individuality.personality.personality_core + prompt_personality += personality_core + + personality_sides = individuality.personality.personality_sides + random.shuffle(personality_sides) + prompt_personality += f",{personality_sides[0]}" + + identity_detail = individuality.identity.identity_detail + random.shuffle(identity_detail) + prompt_personality += f",{identity_detail[0]}" + + + # 关系 who_chat_in_group = [(chat_stream.user_info.platform, chat_stream.user_info.user_id, @@ -105,20 +120,6 @@ class PromptBuilder: ) keywords_reaction_prompt += rule.get("reaction", "") + "," - # 人格选择 - personality = global_config.PROMPT_PERSONALITY - probability_1 = global_config.PERSONALITY_1 - probability_2 = global_config.PERSONALITY_2 - - personality_choice = random.random() - - if personality_choice < probability_1: # 第一种风格 - prompt_personality = personality[0] - elif personality_choice < probability_1 + probability_2: # 第二种风格 - prompt_personality = personality[1] - else: # 第三种人格 - prompt_personality = personality[2] - # 中文高手(新加的好玩功能) prompt_ger = "" if random.random() < 0.04: diff --git a/src/plugins/chat_module/think_flow_chat/think_flow_prompt_builder.py b/src/plugins/chat_module/think_flow_chat/think_flow_prompt_builder.py index d79878258..b5b01bb7b 100644 --- a/src/plugins/chat_module/think_flow_chat/think_flow_prompt_builder.py +++ b/src/plugins/chat_module/think_flow_chat/think_flow_prompt_builder.py @@ -10,7 +10,7 @@ from ...chat.utils import get_recent_group_detailed_plain_text, get_recent_group from ...chat.chat_stream import chat_manager from src.common.logger import get_module_logger from ...person_info.relationship_manager import relationship_manager - +from ....individuality.individuality import Individuality from src.heart_flow.heartflow import heartflow logger = get_module_logger("prompt") @@ -28,6 +28,20 @@ class PromptBuilder: current_mind_info = heartflow.get_subheartflow(stream_id).current_mind # 开始构建prompt + prompt_personality = "你" + #person + individuality = Individuality.get_instance() + + personality_core = individuality.personality.personality_core + prompt_personality += personality_core + + personality_sides = individuality.personality.personality_sides + random.shuffle(personality_sides) + prompt_personality += f",{personality_sides[0]}" + + identity_detail = individuality.identity.identity_detail + random.shuffle(identity_detail) + prompt_personality += f",{identity_detail[0]}" # 关系 who_chat_in_group = [(chat_stream.user_info.platform, @@ -90,20 +104,6 @@ class PromptBuilder: ) keywords_reaction_prompt += rule.get("reaction", "") + "," - # 人格选择 - personality = global_config.PROMPT_PERSONALITY - probability_1 = global_config.PERSONALITY_1 - probability_2 = global_config.PERSONALITY_2 - - personality_choice = random.random() - - if personality_choice < probability_1: # 第一种风格 - prompt_personality = personality[0] - elif personality_choice < probability_1 + probability_2: # 第二种风格 - prompt_personality = personality[1] - else: # 第三种人格 - prompt_personality = personality[2] - # 中文高手(新加的好玩功能) prompt_ger = "" if random.random() < 0.04: @@ -133,73 +133,5 @@ class PromptBuilder: return prompt - def _build_initiative_prompt_select(self, group_id, probability_1=0.8, probability_2=0.1): - current_date = time.strftime("%Y-%m-%d", time.localtime()) - current_time = time.strftime("%H:%M:%S", time.localtime()) - bot_schedule_now_time, bot_schedule_now_activity = bot_schedule.get_current_task() - prompt_date = f"""今天是{current_date},现在是{current_time},你今天的日程是: -{bot_schedule.today_schedule} -你现在正在{bot_schedule_now_activity} -""" - - chat_talking_prompt = "" - if group_id: - chat_talking_prompt = get_recent_group_detailed_plain_text( - group_id, limit=global_config.MAX_CONTEXT_SIZE, combine=True - ) - - chat_talking_prompt = f"以下是群里正在聊天的内容:\n{chat_talking_prompt}" - # print(f"\033[1;34m[调试]\033[0m 已从数据库获取群 {group_id} 的消息记录:{chat_talking_prompt}") - - # 获取主动发言的话题 - all_nodes = HippocampusManager.get_instance().memory_graph.dots - all_nodes = filter(lambda dot: len(dot[1]["memory_items"]) > 3, all_nodes) - nodes_for_select = random.sample(all_nodes, 5) - topics = [info[0] for info in nodes_for_select] - - # 激活prompt构建 - activate_prompt = "" - activate_prompt = "以上是群里正在进行的聊天。" - personality = global_config.PROMPT_PERSONALITY - prompt_personality = "" - personality_choice = random.random() - if personality_choice < probability_1: # 第一种人格 - prompt_personality = f"""{activate_prompt}你的网名叫{global_config.BOT_NICKNAME},{personality[0]}""" - elif personality_choice < probability_1 + probability_2: # 第二种人格 - prompt_personality = f"""{activate_prompt}你的网名叫{global_config.BOT_NICKNAME},{personality[1]}""" - else: # 第三种人格 - prompt_personality = f"""{activate_prompt}你的网名叫{global_config.BOT_NICKNAME},{personality[2]}""" - - topics_str = ",".join(f'"{topics}"') - prompt_for_select = ( - f"你现在想在群里发言,回忆了一下,想到几个话题,分别是{topics_str},综合当前状态以及群内气氛," - f"请你在其中选择一个合适的话题,注意只需要输出话题,除了话题什么也不要输出(双引号也不要输出)" - ) - - prompt_initiative_select = f"{prompt_date}\n{prompt_personality}\n{prompt_for_select}" - prompt_regular = f"{prompt_date}\n{prompt_personality}" - - return prompt_initiative_select, nodes_for_select, prompt_regular - - def _build_initiative_prompt_check(self, selected_node, prompt_regular): - memory = random.sample(selected_node["memory_items"], 3) - memory = "\n".join(memory) - prompt_for_check = ( - f"{prompt_regular}你现在想在群里发言,回忆了一下,想到一个话题,是{selected_node['concept']}," - f"关于这个话题的记忆有\n{memory}\n,以这个作为主题发言合适吗?请在把握群里的聊天内容的基础上," - f"综合群内的氛围,如果认为应该发言请输出yes,否则输出no,请注意是决定是否需要发言,而不是编写回复内容," - f"除了yes和no不要输出任何回复内容。" - ) - return prompt_for_check, memory - - def _build_initiative_prompt(self, selected_node, prompt_regular, memory): - prompt_for_initiative = ( - f"{prompt_regular}你现在想在群里发言,回忆了一下,想到一个话题,是{selected_node['concept']}," - f"关于这个话题的记忆有\n{memory}\n,请在把握群里的聊天内容的基础上,综合群内的氛围," - f"以日常且口语化的口吻,简短且随意一点进行发言,不要说的太有条理,可以有个性。" - f"记住不要输出多余内容(包括前后缀,冒号和引号,括号,表情,@等)" - ) - return prompt_for_initiative - prompt_builder = PromptBuilder() diff --git a/src/plugins/config/config.py b/src/plugins/config/config.py index 83314c082..125439374 100644 --- a/src/plugins/config/config.py +++ b/src/plugins/config/config.py @@ -149,20 +149,11 @@ class BotConfig: # personality personality_core = "用一句话或几句话描述人格的核心特点" # 建议20字以内,谁再写3000字小作文敲谁脑袋 - personality_detail: List[str] = field(default_factory=lambda: [ - "用一句话或几句话描述人格的一些细节", - "用一句话或几句话描述人格的一些细节", - "用一句话或几句话描述人格的一些细节", - "用一句话或几句话描述人格的一些细节", - "用一句话或几句话描述人格的一些细节" + personality_sides: List[str] = field(default_factory=lambda: [ + "用一句话或几句话描述人格的一些侧面", + "用一句话或几句话描述人格的一些侧面", + "用一句话或几句话描述人格的一些侧面" ]) - - traits: List[str] = field(default_factory=lambda: [ - "用一个词描述性格", - "用一个词描述性格", - "用一个词描述性格", - ]) - # identity identity_detail: List[str] = field(default_factory=lambda: [ "身份特点", @@ -173,11 +164,6 @@ class BotConfig: age: int = 20 # 年龄 单位岁 gender: str = "男" # 性别 appearance: str = "用几句话描述外貌特征" # 外貌特征 - interests: List[str] = field(default_factory=lambda: [ - "兴趣爱好1", - "兴趣爱好2", - "兴趣爱好3" - ]) # schedule ENABLE_SCHEDULE_GEN: bool = False # 是否启用日程生成 @@ -371,7 +357,7 @@ class BotConfig: personality_config = parent["personality"] if config.INNER_VERSION in SpecifierSet(">=1.2.4"): config.personality_core = personality_config.get("personality_core", config.personality_core) - config.personality_detail = personality_config.get("personality_detail", config.personality_detail) + config.personality_sides = personality_config.get("personality_sides", config.personality_sides) def identity(parent: dict): identity_config = parent["identity"] @@ -382,7 +368,6 @@ class BotConfig: config.age = identity_config.get("age", config.age) config.gender = identity_config.get("gender", config.gender) config.appearance = identity_config.get("appearance", config.appearance) - config.interests = identity_config.get("interests", config.interests) def schedule(parent: dict): schedule_config = parent["schedule"] diff --git a/src/plugins/personality_s/scene.py b/src/plugins/personality_s/scene.py deleted file mode 100644 index 0ce094a36..000000000 --- a/src/plugins/personality_s/scene.py +++ /dev/null @@ -1,261 +0,0 @@ -from typing import Dict - -PERSONALITY_SCENES = { - "外向性": { - "场景1": { - "scenario": """你刚刚搬到一个新的城市工作。今天是你入职的第一天,在公司的电梯里,一位同事微笑着和你打招呼: - -同事:「嗨!你是新来的同事吧?我是市场部的小林。」 - -同事看起来很友善,还主动介绍说:「待会午饭时间,我们部门有几个人准备一起去楼下新开的餐厅,你要一起来吗?可以认识一下其他同事。」""", - "explanation": "这个场景通过职场社交情境,观察个体对于新环境、新社交圈的态度和反应倾向。", - }, - "场景2": { - "scenario": """在大学班级群里,班长发起了一个组织班级联谊活动的投票: - -班长:「大家好!下周末我们准备举办一次班级联谊活动,地点在学校附近的KTV。想请大家报名参加,也欢迎大家邀请其他班级的同学!」 - -已经有几个同学在群里积极响应,有人@你问你要不要一起参加。""", - "explanation": "通过班级活动场景,观察个体对群体社交活动的参与意愿。", - }, - "场景3": { - "scenario": """你在社交平台上发布了一条动态,收到了很多陌生网友的评论和私信: - -网友A:「你说的这个观点很有意思!想和你多交流一下。」 - -网友B:「我也对这个话题很感兴趣,要不要建个群一起讨论?」""", - "explanation": "通过网络社交场景,观察个体对线上社交的态度。", - }, - "场景4": { - "scenario": """你暗恋的对象今天主动来找你: - -对方:「那个...我最近在准备一个演讲比赛,听说你口才很好。能不能请你帮我看看演讲稿,顺便给我一些建议?""" - """如果你有时间的话,可以一起吃个饭聊聊。」""", - "explanation": "通过恋爱情境,观察个体在面对心仪对象时的社交表现。", - }, - "场景5": { - "scenario": """在一次线下读书会上,主持人突然点名让你分享读后感: - -主持人:「听说你对这本书很有见解,能不能和大家分享一下你的想法?」 - -现场有二十多个陌生的读书爱好者,都期待地看着你。""", - "explanation": "通过即兴发言场景,观察个体的社交表现欲和公众表达能力。", - }, - }, - "神经质": { - "场景1": { - "scenario": """你正在准备一个重要的项目演示,这关系到你的晋升机会。""" - """就在演示前30分钟,你收到了主管发来的消息: - -主管:「临时有个变动,CEO也会来听你的演示。他对这个项目特别感兴趣。」 - -正当你准备回复时,主管又发来一条:「对了,能不能把演示时间压缩到15分钟?CEO下午还有其他安排。你之前准备的是30分钟的版本对吧?」""", - "explanation": "这个场景通过突发的压力情境,观察个体在面对计划外变化时的情绪反应和调节能力。", - }, - "场景2": { - "scenario": """期末考试前一天晚上,你收到了好朋友发来的消息: - -好朋友:「不好意思这么晚打扰你...我看你平时成绩很好,能不能帮我解答几个问题?我真的很担心明天的考试。」 - -你看了看时间,已经是晚上11点,而你原本计划的复习还没完成。""", - "explanation": "通过考试压力场景,观察个体在时间紧张时的情绪管理。", - }, - "场景3": { - "scenario": """你在社交媒体上发表的一个观点引发了争议,有不少人开始批评你: - -网友A:「这种观点也好意思说出来,真是无知。」 - -网友B:「建议楼主先去补补课再来发言。」 - -评论区里的负面评论越来越多,还有人开始人身攻击。""", - "explanation": "通过网络争议场景,观察个体面对批评时的心理承受能力。", - }, - "场景4": { - "scenario": """你和恋人约好今天一起看电影,但在约定时间前半小时,对方发来消息: - -恋人:「对不起,我临时有点事,可能要迟到一会儿。」 - -二十分钟后,对方又发来消息:「可能要再等等,抱歉!」 - -电影快要开始了,但对方还是没有出现。""", - "explanation": "通过恋爱情境,观察个体对不确定性的忍耐程度。", - }, - "场景5": { - "scenario": """在一次重要的小组展示中,你的组员在演示途中突然卡壳了: - -组员小声对你说:「我忘词了,接下来的部分是什么来着...」 - -台下的老师和同学都在等待,气氛有些尴尬。""", - "explanation": "通过公开场合的突发状况,观察个体的应急反应和压力处理能力。", - }, - }, - "严谨性": { - "场景1": { - "scenario": """你是团队的项目负责人,刚刚接手了一个为期两个月的重要项目。在第一次团队会议上: - -小王:「老大,我觉得两个月时间很充裕,我们先做着看吧,遇到问题再解决。」 - -小张:「要不要先列个时间表?不过感觉太详细的计划也没必要,点到为止就行。」 - -小李:「客户那边说如果能提前完成有奖励,我觉得我们可以先做快一点的部分。」""", - "explanation": "这个场景通过项目管理情境,体现个体在工作方法、计划性和责任心方面的特征。", - }, - "场景2": { - "scenario": """期末小组作业,组长让大家分工完成一份研究报告。在截止日期前三天: - -组员A:「我的部分大概写完了,感觉还行。」 - -组员B:「我这边可能还要一天才能完成,最近太忙了。」 - -组员C发来一份没有任何引用出处、可能存在抄袭的内容:「我写完了,你们看看怎么样?」""", - "explanation": "通过学习场景,观察个体对学术规范和质量要求的重视程度。", - }, - "场景3": { - "scenario": """你在一个兴趣小组的群聊中,大家正在讨论举办一次线下活动: - -成员A:「到时候见面就知道具体怎么玩了!」 - -成员B:「对啊,随意一点挺好的。」 - -成员C:「人来了自然就热闹了。」""", - "explanation": "通过活动组织场景,观察个体对活动计划的态度。", - }, - "场景4": { - "scenario": """你和恋人计划一起去旅游,对方说: - -恋人:「我们就随心而行吧!订个目的地,其他的到了再说,这样更有意思。」 - -距离出发还有一周时间,但机票、住宿和具体行程都还没有确定。""", - "explanation": "通过旅行规划场景,观察个体的计划性和对不确定性的接受程度。", - }, - "场景5": { - "scenario": """在一个重要的团队项目中,你发现一个同事的工作存在明显错误: - -同事:「差不多就行了,反正领导也看不出来。」 - -这个错误可能不会立即造成问题,但长期来看可能会影响项目质量。""", - "explanation": "通过工作质量场景,观察个体对细节和标准的坚持程度。", - }, - }, - "开放性": { - "场景1": { - "scenario": """周末下午,你的好友小美兴致勃勃地给你打电话: - -小美:「我刚发现一个特别有意思的沉浸式艺术展!不是传统那种挂画的展览,而是把整个空间都变成了艺术品。""" - """观众要穿特制的服装,还要带上VR眼镜,好像还有AI实时互动!」 - -小美继续说:「虽然票价不便宜,但听说体验很独特。网上评价两极分化,有人说是前所未有的艺术革新,也有人说是哗众取宠。""" - """要不要周末一起去体验一下?」""", - "explanation": "这个场景通过新型艺术体验,反映个体对创新事物的接受程度和尝试意愿。", - }, - "场景2": { - "scenario": """在一节创意写作课上,老师提出了一个特别的作业: - -老师:「下周的作业是用AI写作工具协助创作一篇小说。你们可以自由探索如何与AI合作,打破传统写作方式。」 - -班上随即展开了激烈讨论,有人认为这是对创作的亵渎,也有人对这种新形式感到兴奋。""", - "explanation": "通过新技术应用场景,观察个体对创新学习方式的态度。", - }, - "场景3": { - "scenario": """在社交媒体上,你看到一个朋友分享了一种新的生活方式: - -「最近我在尝试'数字游牧'生活,就是一边远程工作一边环游世界。""" - """没有固定住所,住青旅或短租,认识来自世界各地的朋友。虽然有时会很不稳定,但这种自由的生活方式真的很棒!」 - -评论区里争论不断,有人向往这种生活,也有人觉得太冒险。""", - "explanation": "通过另类生活方式,观察个体对非传统选择的态度。", - }, - "场景4": { - "scenario": """你的恋人突然提出了一个想法: - -恋人:「我们要不要尝试一下开放式关系?就是在保持彼此关系的同时,也允许和其他人发展感情。现在国外很多年轻人都这样。」 - -这个提议让你感到意外,你之前从未考虑过这种可能性。""", - "explanation": "通过感情观念场景,观察个体对非传统关系模式的接受度。", - }, - "场景5": { - "scenario": """在一次朋友聚会上,大家正在讨论未来职业规划: - -朋友A:「我准备辞职去做自媒体,专门介绍一些小众的文化和艺术。」 - -朋友B:「我想去学习生物科技,准备转行做人造肉研发。」 - -朋友C:「我在考虑加入一个区块链创业项目,虽然风险很大。」""", - "explanation": "通过职业选择场景,观察个体对新兴领域的探索意愿。", - }, - }, - "宜人性": { - "场景1": { - "scenario": """在回家的公交车上,你遇到这样一幕: - -一位老奶奶颤颤巍巍地上了车,车上座位已经坐满了。她站在你旁边,看起来很疲惫。这时你听到前排两个年轻人的对话: - -年轻人A:「那个老太太好像站不稳,看起来挺累的。」 - -年轻人B:「现在的老年人真是...我看她包里还有菜,肯定是去菜市场买完菜回来的,这么多人都不知道叫子女开车接送。」 - -就在这时,老奶奶一个趔趄,差点摔倒。她扶住了扶手,但包里的东西洒了一些出来。""", - "explanation": "这个场景通过公共场合的助人情境,体现个体的同理心和对他人需求的关注程度。", - }, - "场景2": { - "scenario": """在班级群里,有同学发起为生病住院的同学捐款: - -同学A:「大家好,小林最近得了重病住院,医药费很贵,家里负担很重。我们要不要一起帮帮他?」 - -同学B:「我觉得这是他家里的事,我们不方便参与吧。」 - -同学C:「但是都是同学一场,帮帮忙也是应该的。」""", - "explanation": "通过同学互助场景,观察个体的助人意愿和同理心。", - }, - "场景3": { - "scenario": """在一个网络讨论组里,有人发布了求助信息: - -求助者:「最近心情很低落,感觉生活很压抑,不知道该怎么办...」 - -评论区里已经有一些回复: -「生活本来就是这样,想开点!」 -「你这样子太消极了,要积极面对。」 -「谁还没点烦心事啊,过段时间就好了。」""", - "explanation": "通过网络互助场景,观察个体的共情能力和安慰方式。", - }, - "场景4": { - "scenario": """你的恋人向你倾诉工作压力: - -恋人:「最近工作真的好累,感觉快坚持不下去了...」 - -但今天你也遇到了很多烦心事,心情也不太好。""", - "explanation": "通过感情关系场景,观察个体在自身状态不佳时的关怀能力。", - }, - "场景5": { - "scenario": """在一次团队项目中,新来的同事小王因为经验不足,造成了一个严重的错误。在部门会议上: - -主管:「这个错误造成了很大的损失,是谁负责的这部分?」 - -小王看起来很紧张,欲言又止。你知道是他造成的错误,同时你也是这个项目的共同负责人。""", - "explanation": "通过职场情境,观察个体在面对他人过错时的态度和处理方式。", - }, - }, -} - - -def get_scene_by_factor(factor: str) -> Dict: - """ - 根据人格因子获取对应的情景测试 - - Args: - factor (str): 人格因子名称 - - Returns: - Dict: 包含情景描述的字典 - """ - return PERSONALITY_SCENES.get(factor, None) - - -def get_all_scenes() -> Dict: - """ - 获取所有情景测试 - - Returns: - Dict: 所有情景测试的字典 - """ - return PERSONALITY_SCENES diff --git a/src/plugins/schedule/schedule_generator.py b/src/plugins/schedule/schedule_generator.py index edce54b64..e8999099b 100644 --- a/src/plugins/schedule/schedule_generator.py +++ b/src/plugins/schedule/schedule_generator.py @@ -62,9 +62,7 @@ class ScheduleGenerator: self.name = name self.behavior = behavior self.schedule_doing_update_interval = interval - - for pers in personality: - self.personality += pers + "\n" + self.personality = personality async def mai_schedule_start(self): """启动日程系统,每5分钟执行一次move_doing,并在日期变化时重新检查日程""" diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index c40c03dfd..9e107a5cd 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -35,7 +35,7 @@ ban_user_id = [] #禁止回复和读取消息的QQ号 [personality] personality_core = "用一句话或几句话描述人格的核心特点" # 建议20字以内,谁再写3000字小作文敲谁脑袋 -personality_detail = [ +personality_sides = [ "用一句话或几句话描述人格的一些细节", "用一句话或几句话描述人格的一些细节", "用一句话或几句话描述人格的一些细节", diff --git a/从0.6.0升级0.6.1请先看我.txt b/从0.6.0升级0.6.1请先看我.txt new file mode 100644 index 000000000..734061c99 --- /dev/null +++ b/从0.6.0升级0.6.1请先看我.txt @@ -0,0 +1 @@ +该版本变动了人格相关设置,原有的配置内容可能被自动更新,如果你没有备份,可以在\config\old找回 \ No newline at end of file