diff --git a/_conf_schema.json b/_conf_schema.json index 915b5f8..05d5c4c 100644 --- a/_conf_schema.json +++ b/_conf_schema.json @@ -146,5 +146,47 @@ "description": "PDF文件名格式", "default": "群聊分析报告_{group_id}_{date}.pdf", "hint": "PDF文件名格式,支持变量:{group_id}(群号)、{date}(日期)" + }, + "topic_analysis_prompts": { + "description": "话题分析提示词模板", + "type": "object", + "hint": "选择不同的话题分析风格", + "items": { + "default": { + "description": "默认话题分析提示词", + "type": "text", + "editor_mode": true, + "editor_language": "markdown", + "default": "你是一个帮我进行群聊信息总结的助手,生成总结内容时,你需要严格遵守下面的几个准则:\n请分析接下来提供的群聊记录,提取出最多{max_topics}个主要话题。\n\n对于每个话题,请提供:\n1. 话题名称(突出主题内容,尽量简明扼要)\n2. 主要参与者(最多5人)\n3. 话题详细描述(包含关键信息和结论)\n\n注意:\n- 对于比较有价值的点,稍微用一两句话详细讲讲,比如不要生成 \"Nolan 和 SOV 讨论了 galgame 中关于性符号的衍生情况\" 这种宽泛的内容,而是生成更加具体的讨论内容,让其他人只看这个消息就能知道讨论中有价值的,有营养的信息。\n- 对于其中的部分信息,你需要特意提到主题施加的主体是谁,是哪个群友做了什么事情,而不要直接生成和群友没有关系的语句。\n- 对于每一条总结,尽量讲清楚前因后果,以及话题的结论,是什么,为什么,怎么做,如果用户没有讲到细节,则可以不用这么做。\n\n群聊记录:\n{messages_text}\n\n重要:必须返回标准JSON格式,严格遵守以下规则:\n1. 只使用英文双引号 \\\" 不要使用中文引号 \\\" \\\"\n2. 字符串内容中的引号必须转义为 \\\\\\\"\n3. 多个对象之间用逗号分隔\n4. 数组元素之间用逗号分隔\n5. 不要在JSON外添加任何文字说明\n6. 描述内容避免使用特殊符号,用普通文字表达\n\n请严格按照以下JSON格式返回,确保可以被标准JSON解析器解析:\n[\n {{\n \\\"topic\\\": \\\"话题名称\\\",\n \\\"contributors\\\": [\\\"用户1\\\", \\\"用户2\\\"],\n \\\"detail\\\": \\\"话题描述内容\\\"\n }},\n {{\n \\\"topic\\\": \\\"另一个话题\\\",\n \\\"contributors\\\": [\\\"用户3\\\", \\\"用户4\\\"],\n \\\"detail\\\": \\\"另一个话题的描述\\\"\n }}\n]\n\n注意:返回的内容必须是纯JSON,不要包含markdown代码块标记或其他格式" + } + } + }, + "user_title_analysis_prompts": { + "description": "用户称号分析提示词模板", + "type": "object", + "hint": "选择不同的用户称号分析风格", + "items": { + "default": { + "description": "默认用户称号分析提示词", + "type": "text", + "editor_mode": true, + "editor_language": "markdown", + "default": "请为以下群友分配合适的称号和MBTI类型。每个人只能有一个称号,每个称号只能给一个人。\n\n可选称号:\n- 龙王: 发言频繁但内容轻松的人\n- 技术专家: 经常讨论技术话题的人\n- 夜猫子: 经常在深夜发言的人\n- 表情包军火库: 经常发表情的人\n- 沉默终结者: 经常开启话题的人\n- 评论家: 平均发言长度很长的人\n- 阳角: 在群里很有影响力的人\n- 互动达人: 经常回复别人的人\n- ... (你可以自行进行拓展添加)\n\n用户数据:\n{users_text}\n\n请以JSON格式返回,格式如下:\n[\n {{\n \\\"name\\\": \\\"用户名\\\",\n \\\"qq\\\": 123456789,\n \\\"title\\\": \\\"称号\\\",\n \\\"mbti\\\": \\\"MBTI类型\\\",\n \\\"reason\\\": \\\"获得此称号的原因\\\"\n }}\n]" + } + } + }, + "golden_quote_analysis_prompts": { + "description": "金句分析提示词模板", + "type": "object", + "hint": "选择不同的金句分析风格", + "items": { + "default": { + "description": "默认金句分析提示词", + "type": "text", + "editor_mode": true, + "editor_language": "markdown", + "default": "请从以下群聊记录中挑选出{max_golden_quotes}句最具冲击力、最令人惊叹的\\\"金句\\\"。这些金句需满足:\n- 核心标准:**逆天的神人发言**,即具备颠覆常识的脑洞、逻辑跳脱的表达或强烈反差感的原创内容\n- 典型特征:包含某些争议话题元素、夸张类比、反常规结论、一本正经的\\\"胡说八道\\\"或突破语境的清奇思路,并且具备一定的冲击力,让人印象深刻。\n\n对于每个金句,请提供:\n1. 原文内容(完整保留发言细节)\n2. 发言人昵称\n3. 选择理由(具体说明其\\\"逆天\\\"之处,如逻辑颠覆点/脑洞角度/反差感/争议话题元素)\n\n此外,我将对你进行严格约束:\n- 优先筛选 **逆天指数最高** 的内容:发情、性压抑话题 > 争议话题 > 元素级 > 颠覆认知级 > 逻辑跳脱级 > 趣味调侃级,剔除单纯玩梗或网络热词堆砌的普通发言\n- 重点标记包含极端类比、反常识论证或无厘头结论的内容,并且包含一定的争议话题元素。\n\n群聊记录:\n{messages_text}\n\n请以JSON格式返回,格式如下:\n[\n {{\n \\\"content\\\": \\\"金句原文\\\",\n \\\"sender\\\": \\\"发言人昵称\\\",\n \\\"reason\\\": \\\"选择这句话的理由(需明确说明逆天特质)\\\"\n }}\n]" + } + } } } diff --git a/src/analysis/analyzers/golden_quote_analyzer.py b/src/analysis/analyzers/golden_quote_analyzer.py index 671ac63..60ef1d8 100644 --- a/src/analysis/analyzers/golden_quote_analyzer.py +++ b/src/analysis/analyzers/golden_quote_analyzer.py @@ -55,33 +55,26 @@ class GoldenQuoteAnalyzer(BaseAnalyzer): ]) max_golden_quotes = self.get_max_count() - prompt = f""" -请从以下群聊记录中挑选出{max_golden_quotes}句最具冲击力、最令人惊叹的"金句"。这些金句需满足: -- 核心标准:**逆天的神人发言**,即具备颠覆常识的脑洞、逻辑跳脱的表达或强烈反差感的原创内容 -- 典型特征:包含某些争议话题元素、夸张类比、反常规结论、一本正经的"胡说八道"或突破语境的清奇思路,并且具备一定的冲击力,让人印象深刻。 - -对于每个金句,请提供: -1. 原文内容(完整保留发言细节) -2. 发言人昵称 -3. 选择理由(具体说明其"逆天"之处,如逻辑颠覆点/脑洞角度/反差感/争议话题元素) - -此外,我将对你进行严格约束: -- 优先筛选 **逆天指数最高** 的内容:发情、性压抑话题 > 争议话题 > 元素级 > 颠覆认知级 > 逻辑跳脱级 > 趣味调侃级,剔除单纯玩梗或网络热词堆砌的普通发言 -- 重点标记包含极端类比、反常识论证或无厘头结论的内容,并且包含一定的争议话题元素。 - -群聊记录: -{messages_text} - -请以JSON格式返回,格式如下: -[ - {{ - "content": "金句原文", - "sender": "发言人昵称", - "reason": "选择这句话的理由(需明确说明逆天特质)" - }} -] -""" - return prompt + + # 从配置读取 prompt 模板(默认使用 "default" 风格) + prompt_template = self.config_manager.get_golden_quote_analysis_prompt() + + if prompt_template: + # 使用配置中的 prompt 并替换变量 + try: + prompt = prompt_template.format( + max_golden_quotes=max_golden_quotes, + messages_text=messages_text + ) + logger.info("使用配置中的金句分析提示词") + return prompt + except KeyError as e: + logger.warning(f"金句分析提示词变量格式错误: {e}") + except Exception as e: + logger.warning(f"应用金句分析提示词失败: {e}") + + logger.warning("未找到有效的金句分析提示词配置,请检查配置文件") + return "" def extract_with_regex(self, result_text: str, max_count: int) -> List[Dict]: """ diff --git a/src/analysis/analyzers/topic_analyzer.py b/src/analysis/analyzers/topic_analyzer.py index d8f580d..a832ccb 100644 --- a/src/analysis/analyzers/topic_analyzer.py +++ b/src/analysis/analyzers/topic_analyzer.py @@ -146,48 +146,25 @@ class TopicAnalyzer(BaseAnalyzer): max_topics = self.get_max_count() - prompt = f""" -你是一个帮我进行群聊信息总结的助手,生成总结内容时,你需要严格遵守下面的几个准则: -请分析接下来提供的群聊记录,提取出最多{max_topics}个主要话题。 - -对于每个话题,请提供: -1. 话题名称(突出主题内容,尽量简明扼要) -2. 主要参与者(最多5人) -3. 话题详细描述(包含关键信息和结论) - -注意: -- 对于比较有价值的点,稍微用一两句话详细讲讲,比如不要生成 "Nolan 和 SOV 讨论了 galgame 中关于性符号的衍生情况" 这种宽泛的内容,而是生成更加具体的讨论内容,让其他人只看这个消息就能知道讨论中有价值的,有营养的信息。 -- 对于其中的部分信息,你需要特意提到主题施加的主体是谁,是哪个群友做了什么事情,而不要直接生成和群友没有关系的语句。 -- 对于每一条总结,尽量讲清楚前因后果,以及话题的结论,是什么,为什么,怎么做,如果用户没有讲到细节,则可以不用这么做。 - -群聊记录: -{messages_text} - -重要:必须返回标准JSON格式,严格遵守以下规则: -1. 只使用英文双引号 " 不要使用中文引号 " " -2. 字符串内容中的引号必须转义为 \" -3. 多个对象之间用逗号分隔 -4. 数组元素之间用逗号分隔 -5. 不要在JSON外添加任何文字说明 -6. 描述内容避免使用特殊符号,用普通文字表达 - -请严格按照以下JSON格式返回,确保可以被标准JSON解析器解析: -[ - {{ - "topic": "话题名称", - "contributors": ["用户1", "用户2"], - "detail": "话题描述内容" - }}, - {{ - "topic": "另一个话题", - "contributors": ["用户3", "用户4"], - "detail": "另一个话题的描述" - }} -] - -注意:返回的内容必须是纯JSON,不要包含markdown代码块标记或其他格式 -""" - return prompt + # 从配置读取 prompt 模板(默认使用 "default" 风格) + prompt_template = self.config_manager.get_topic_analysis_prompt() + + if prompt_template: + # 使用配置中的 prompt 并替换变量 + try: + prompt = prompt_template.format( + max_topics=max_topics, + messages_text=messages_text + ) + logger.info("使用配置中的话题分析提示词") + return prompt + except KeyError as e: + logger.warning(f"话题分析提示词变量格式错误: {e}") + except Exception as e: + logger.warning(f"应用话题分析提示词失败: {e}") + + logger.warning("未找到有效的话题分析提示词配置,请检查配置文件") + return "" def extract_with_regex(self, result_text: str, max_topics: int) -> List[Dict]: """ diff --git a/src/analysis/analyzers/user_title_analyzer.py b/src/analysis/analyzers/user_title_analyzer.py index 1fe44c8..ab04d41 100644 --- a/src/analysis/analyzers/user_title_analyzer.py +++ b/src/analysis/analyzers/user_title_analyzer.py @@ -56,35 +56,24 @@ class UserTitleAnalyzer(BaseAnalyzer): for user in user_summaries ]) - prompt = f""" -请为以下群友分配合适的称号和MBTI类型。每个人只能有一个称号,每个称号只能给一个人。 - -可选称号: -- 龙王: 发言频繁但内容轻松的人 -- 技术专家: 经常讨论技术话题的人 -- 夜猫子: 经常在深夜发言的人 -- 表情包军火库: 经常发表情的人 -- 沉默终结者: 经常开启话题的人 -- 评论家: 平均发言长度很长的人 -- 阳角: 在群里很有影响力的人 -- 互动达人: 经常回复别人的人 -- ... (你可以自行进行拓展添加) - -用户数据: -{users_text} - -请以JSON格式返回,格式如下: -[ - {{ - "name": "用户名", - "qq": 123456789, - "title": "称号", - "mbti": "MBTI类型", - "reason": "获得此称号的原因" - }} -] -""" - return prompt + # 从配置读取 prompt 模板(默认使用 "default" 风格) + prompt_template = self.config_manager.get_user_title_analysis_prompt() + + if prompt_template: + # 使用配置中的 prompt 并替换变量 + try: + prompt = prompt_template.format( + users_text=users_text + ) + logger.info("使用配置中的用户称号分析提示词") + return prompt + except KeyError as e: + logger.warning(f"用户称号分析提示词变量格式错误: {e}") + except Exception as e: + logger.warning(f"应用用户称号分析提示词失败: {e}") + + logger.warning("未找到有效的用户称号分析提示词配置,请检查配置文件") + return "" def extract_with_regex(self, result_text: str, max_count: int) -> List[Dict]: """ diff --git a/src/core/config.py b/src/core/config.py index 37d5d55..7c1c517 100644 --- a/src/core/config.py +++ b/src/core/config.py @@ -110,6 +110,75 @@ class ConfigManager: """获取PDF文件名格式""" return self.config.get("pdf_filename_format", "群聊分析报告_{group_id}_{date}.pdf") + def get_topic_analysis_prompt(self, style: str = "default") -> str: + """ + 获取话题分析提示词模板 + + Args: + style: 提示词风格,默认为 "default" + + Returns: + 提示词模板字符串 + """ + prompts = self.config.get("topic_analysis_prompts", {}) + if isinstance(prompts, dict) and "items" in prompts: + items = prompts.get("items", {}) + if style in items and isinstance(items[style], dict): + return items[style].get("default", "") + # 兼容旧配置 + return self.config.get("topic_analysis_prompt", "") + + def get_user_title_analysis_prompt(self, style: str = "default") -> str: + """ + 获取用户称号分析提示词模板 + + Args: + style: 提示词风格,默认为 "default" + + Returns: + 提示词模板字符串 + """ + prompts = self.config.get("user_title_analysis_prompts", {}) + if isinstance(prompts, dict) and "items" in prompts: + items = prompts.get("items", {}) + if style in items and isinstance(items[style], dict): + return items[style].get("default", "") + # 兼容旧配置 + return self.config.get("user_title_analysis_prompt", "") + + def get_golden_quote_analysis_prompt(self, style: str = "default") -> str: + """ + 获取金句分析提示词模板 + + Args: + style: 提示词风格,默认为 "default" + + Returns: + 提示词模板字符串 + """ + prompts = self.config.get("golden_quote_analysis_prompts", {}) + if isinstance(prompts, dict) and "items" in prompts: + items = prompts.get("items", {}) + if style in items and isinstance(items[style], dict): + return items[style].get("default", "") + # 兼容旧配置 + return self.config.get("golden_quote_analysis_prompt", "") + + def set_topic_analysis_prompt(self, prompt: str): + """设置话题分析提示词模板""" + self.config["topic_analysis_prompt"] = prompt + self.config.save_config() + + def set_user_title_analysis_prompt(self, prompt: str): + """设置用户称号分析提示词模板""" + self.config["user_title_analysis_prompt"] = prompt + self.config.save_config() + + def set_golden_quote_analysis_prompt(self, prompt: str): + """设置金句分析提示词模板""" + self.config["golden_quote_analysis_prompt"] = prompt + self.config.save_config() + def set_output_format(self, format_type: str): """设置输出格式""" self.config["output_format"] = format_type