From 3be012f8bb3142af4fe0e86f93ab98809b5df686 Mon Sep 17 00:00:00 2001 From: tcmofashi Date: Tue, 4 Mar 2025 10:19:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=A5=9E=E7=A7=98form?= =?UTF-8?q?atter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/chat/llm_generator.py | 144 +++++++----------- src/plugins/chat/topic_identifier.py | 209 ++++----------------------- 2 files changed, 76 insertions(+), 277 deletions(-) diff --git a/src/plugins/chat/llm_generator.py b/src/plugins/chat/llm_generator.py index 0701af3e..95a936e8 100644 --- a/src/plugins/chat/llm_generator.py +++ b/src/plugins/chat/llm_generator.py @@ -23,96 +23,65 @@ class ResponseGenerator: def __init__(self): self.model_r1 = LLM_request(model=global_config.llm_reasoning, temperature=0.7) self.model_v3 = LLM_request(model=global_config.llm_normal, temperature=0.7) - self.model_r1_distill = LLM_request( - model=global_config.llm_reasoning_minor, temperature=0.7 - ) + self.model_r1_distill = LLM_request(model=global_config.llm_reasoning_minor, temperature=0.7) self.db = Database.get_instance() - self.current_model_type = "r1" # 默认使用 R1 + self.current_model_type = 'r1' # 默认使用 R1 - async def generate_response( - self, message: Message - ) -> Optional[Union[str, List[str]]]: + async def generate_response(self, message: Message) -> Optional[Union[str, List[str]]]: """根据当前模型类型选择对应的生成函数""" # 从global_config中获取模型概率值并选择模型 rand = random.random() if rand < global_config.MODEL_R1_PROBABILITY: - self.current_model_type = "r1" + self.current_model_type = 'r1' current_model = self.model_r1 - elif ( - rand - < global_config.MODEL_R1_PROBABILITY + global_config.MODEL_V3_PROBABILITY - ): - self.current_model_type = "v3" + elif rand < global_config.MODEL_R1_PROBABILITY + global_config.MODEL_V3_PROBABILITY: + self.current_model_type = 'v3' current_model = self.model_v3 else: - self.current_model_type = "r1_distill" + self.current_model_type = 'r1_distill' current_model = self.model_r1_distill - print( - f"+++++++++++++++++{global_config.BOT_NICKNAME}{self.current_model_type}思考中+++++++++++++++++" - ) - - model_response = await self._generate_response_with_model( - message, current_model - ) - + print(f"+++++++++++++++++{global_config.BOT_NICKNAME}{self.current_model_type}思考中+++++++++++++++++") + + model_response = await self._generate_response_with_model(message, current_model) + if model_response: - print(f"{global_config.BOT_NICKNAME}的回复是:{model_response}") + print(f'{global_config.BOT_NICKNAME}的回复是:{model_response}') model_response, emotion = await self._process_response(model_response) if model_response: print(f"为 '{model_response}' 获取到的情感标签为:{emotion}") - valuedict = { - "happy": 0.5, - "angry": -1, - "sad": -0.5, - "surprised": 0.5, - "disgusted": -1.5, - "fearful": -0.25, - "neutral": 0.25, + valuedict={ + 'happy':0.5,'angry':-1,'sad':-0.5,'surprised':0.5,'disgusted':-1.5,'fearful':-0.25,'neutral':0.25 } - await relationship_manager.update_relationship_value( - message.user_id, relationship_value=valuedict[emotion[0]] - ) + await relationship_manager.update_relationship_value(message.user_id, relationship_value=valuedict[emotion[0]]) return model_response, emotion return None, [] - async def _generate_response_with_model( - self, message: Message, model: LLM_request - ) -> Optional[str]: + async def _generate_response_with_model(self, message: Message, model: LLM_request) -> Optional[str]: """使用指定的模型生成回复""" sender_name = message.user_nickname or f"用户{message.user_id}" if message.user_cardname: - sender_name = ( - f"[({message.user_id}){message.user_nickname}]{message.user_cardname}" - ) - + sender_name=f"[({message.user_id}){message.user_nickname}]{message.user_cardname}" + # 获取关系值 - relationship_value = ( - relationship_manager.get_relationship(message.user_id).relationship_value - if relationship_manager.get_relationship(message.user_id) - else 0.0 - ) + relationship_value = relationship_manager.get_relationship(message.user_id).relationship_value if relationship_manager.get_relationship(message.user_id) else 0.0 if relationship_value != 0.0: - print( - f"\033[1;32m[关系管理]\033[0m 回复中_当前关系值: {relationship_value}" - ) - + print(f"\033[1;32m[关系管理]\033[0m 回复中_当前关系值: {relationship_value}") + # 构建prompt prompt, prompt_check = prompt_builder._build_prompt( message_txt=message.processed_plain_text, sender_name=sender_name, relationship_value=relationship_value, - group_id=message.group_id, + group_id=message.group_id ) # 读空气模块 if global_config.enable_kuuki_read: - content_check, reasoning_content_check = ( - await self.model_v3.generate_response(prompt_check) - ) + content_check, reasoning_content_check = await self.model_v3.generate_response(prompt_check) print(f"\033[1;32m[读空气]\033[0m 读空气结果为{content_check}") - if "yes" not in content_check.lower() and random.random() < 0.3: + if 'yes' not in content_check.lower() and random.random() < 0.3: self._save_to_db( message=message, sender_name=sender_name, @@ -121,13 +90,13 @@ class ResponseGenerator: content="", content_check=content_check, reasoning_content="", - reasoning_content_check=reasoning_content_check, + reasoning_content_check=reasoning_content_check ) return None # 生成回复 content, reasoning_content = await model.generate_response(prompt) - + # 保存到数据库 self._save_to_db( message=message, @@ -137,65 +106,52 @@ class ResponseGenerator: content=content, content_check=content_check if global_config.enable_kuuki_read else "", reasoning_content=reasoning_content, - reasoning_content_check=( - reasoning_content_check if global_config.enable_kuuki_read else "" - ), + reasoning_content_check=reasoning_content_check if global_config.enable_kuuki_read else "" ) - + return content - def _save_to_db( - self, - message: Message, - sender_name: str, - prompt: str, - prompt_check: str, - content: str, - content_check: str, - reasoning_content: str, - reasoning_content_check: str, - ): + def _save_to_db(self, message: Message, sender_name: str, prompt: str, prompt_check: str, + content: str, content_check: str, reasoning_content: str, reasoning_content_check: str): """保存对话记录到数据库""" - self.db.db.reasoning_logs.insert_one( - { - "time": time.time(), - "group_id": message.group_id, - "user": sender_name, - "message": message.processed_plain_text, - "model": self.current_model_type, - "reasoning_check": reasoning_content_check, - "response_check": content_check, - "reasoning": reasoning_content, - "response": content, - "prompt": prompt, - "prompt_check": prompt_check, - } - ) + self.db.db.reasoning_logs.insert_one({ + 'time': time.time(), + 'group_id': message.group_id, + 'user': sender_name, + 'message': message.processed_plain_text, + 'model': self.current_model_type, + 'reasoning_check': reasoning_content_check, + 'response_check': content_check, + 'reasoning': reasoning_content, + 'response': content, + 'prompt': prompt, + 'prompt_check': prompt_check + }) async def _get_emotion_tags(self, content: str) -> List[str]: """提取情感标签""" try: - prompt = f"""请从以下内容中,从"happy,angry,sad,surprised,disgusted,fearful,neutral"中选出最匹配的1个情感标签并输出 + prompt = f'''请从以下内容中,从"happy,angry,sad,surprised,disgusted,fearful,neutral"中选出最匹配的1个情感标签并输出 只输出标签就好,不要输出其他内容: 内容:{content} 输出: - """ - + ''' + content, _ = await self.model_v3.generate_response(prompt) return [content.strip()] if content else ["neutral"] - + except Exception as e: print(f"获取情感标签时出错: {e}") return ["neutral"] - + async def _process_response(self, content: str) -> Tuple[List[str], List[str]]: """处理响应内容,返回处理后的内容和情感标签""" if not content: return None, [] - + emotion_tags = await self._get_emotion_tags(content) processed_response = process_llm_response(content) - + return processed_response, emotion_tags diff --git a/src/plugins/chat/topic_identifier.py b/src/plugins/chat/topic_identifier.py index 91afe36f..5c51e0bd 100644 --- a/src/plugins/chat/topic_identifier.py +++ b/src/plugins/chat/topic_identifier.py @@ -8,8 +8,7 @@ from snownlp import SnowNLP from ..models.utils_model import LLM_request driver = get_driver() -config = driver.config - +config = driver.config class TopicIdentifier: def __init__(self): @@ -18,11 +17,11 @@ class TopicIdentifier: async def identify_topic_llm(self, text: str) -> Optional[List[str]]: """识别消息主题,返回主题列表""" - prompt = f"""判断这条消息的主题,如果没有明显主题请回复"无主题",要求:\ - 1. 主题通常2-4个字,必须简短,要求精准概括,不要太具体。\ - 2. 建议给出多个主题,之间用英文逗号分割。只输出主题本身就好,不要有前后缀。\ - 3. 这里是 - 消息内容:{text}""" + prompt = f"""判断这条消息的主题,如果没有明显主题请回复"无主题",要求: +1. 主题通常2-4个字,必须简短,要求精准概括,不要太具体。 +2. 建议给出多个主题,之间用英文逗号分割。只输出主题本身就好,不要有前后缀。 + +消息内容:{text}""" # 使用 LLM_request 类进行请求 topic, _ = await self.llm_client.generate_response(prompt) @@ -44,181 +43,25 @@ class TopicIdentifier: words = jieba.lcut(text) # 去除停用词和标点符号 stop_words = { - "的", - "了", - "和", - "是", - "就", - "都", - "而", - "及", - "与", - "这", - "那", - "但", - "然", - "却", - "因为", - "所以", - "如果", - "虽然", - "一个", - "我", - "你", - "他", - "她", - "它", - "我们", - "你们", - "他们", - "在", - "有", - "个", - "把", - "被", - "让", - "给", - "从", - "向", - "到", - "又", - "也", - "很", - "啊", - "吧", - "呢", - "吗", - "呀", - "哦", - "哈", - "么", - "嘛", - "啦", - "哎", - "唉", - "哇", - "嗯", - "哼", - "哪", - "什么", - "怎么", - "为什么", - "怎样", - "如何", - "什么样", - "这样", - "那样", - "这么", - "那么", - "多少", - "几", - "谁", - "哪里", - "哪儿", - "什么时候", - "何时", - "为何", - "怎么办", - "怎么样", - "这些", - "那些", - "一些", - "一点", - "一下", - "一直", - "一定", - "一般", - "一样", - "一会儿", - "一边", - "一起", + '的', '了', '和', '是', '就', '都', '而', '及', '与', '这', '那', '但', '然', '却', + '因为', '所以', '如果', '虽然', '一个', '我', '你', '他', '她', '它', '我们', '你们', + '他们', '在', '有', '个', '把', '被', '让', '给', '从', '向', '到', '又', '也', '很', + '啊', '吧', '呢', '吗', '呀', '哦', '哈', '么', '嘛', '啦', '哎', '唉', '哇', '嗯', + '哼', '哪', '什么', '怎么', '为什么', '怎样', '如何', '什么样', '这样', '那样', '这么', + '那么', '多少', '几', '谁', '哪里', '哪儿', '什么时候', '何时', '为何', '怎么办', + '怎么样', '这些', '那些', '一些', '一点', '一下', '一直', '一定', '一般', '一样', + '一会儿', '一边', '一起', # 添加更多量词 - "个", - "只", - "条", - "张", - "片", - "块", - "本", - "册", - "页", - "幅", - "面", - "篇", - "份", - "朵", - "颗", - "粒", - "座", - "幢", - "栋", - "间", - "层", - "家", - "户", - "位", - "名", - "群", - "双", - "对", - "打", - "副", - "套", - "批", - "组", - "串", - "包", - "箱", - "袋", - "瓶", - "罐", + '个', '只', '条', '张', '片', '块', '本', '册', '页', '幅', '面', '篇', '份', + '朵', '颗', '粒', '座', '幢', '栋', '间', '层', '家', '户', '位', '名', '群', + '双', '对', '打', '副', '套', '批', '组', '串', '包', '箱', '袋', '瓶', '罐', # 添加更多介词 - "按", - "按照", - "把", - "被", - "比", - "比如", - "除", - "除了", - "当", - "对", - "对于", - "根据", - "关于", - "跟", - "和", - "将", - "经", - "经过", - "靠", - "连", - "论", - "通过", - "同", - "往", - "为", - "为了", - "围绕", - "于", - "由", - "由于", - "与", - "在", - "沿", - "沿着", - "依", - "依照", - "以", - "因", - "因为", - "用", - "由", - "与", - "自", - "自从", + '按', '按照', '把', '被', '比', '比如', '除', '除了', '当', '对', '对于', + '根据', '关于', '跟', '和', '将', '经', '经过', '靠', '连', '论', '通过', + '同', '往', '为', '为了', '围绕', '于', '由', '由于', '与', '在', '沿', '沿着', + '依', '依照', '以', '因', '因为', '用', '由', '与', '自', '自从' } - + # 过滤掉停用词和标点符号,只保留名词和动词 filtered_words = [] for word in words: @@ -231,16 +74,16 @@ class TopicIdentifier: '≈', '∈', '∉', '⊆', '⊇', '⊂', '⊃', '∪', '∩', '∧', '∨' }: filtered_words.append(word) - + # 统计词频 word_freq = {} for word in filtered_words: word_freq[word] = word_freq.get(word, 0) + 1 - + # 按词频排序,取前3个 sorted_words = sorted(word_freq.items(), key=lambda x: x[1], reverse=True) top_words = [word for word, freq in sorted_words[:3]] - + return top_words if top_words else None def identify_topic_snownlp(self, text: str) -> Optional[List[str]]: @@ -264,4 +107,4 @@ class TopicIdentifier: print(f"\033[1;31m[错误]\033[0m SnowNLP 处理失败: {str(e)}") return None -topic_identifier = TopicIdentifier() +topic_identifier = TopicIdentifier() \ No newline at end of file