From ce578f0417fc79d59bb0f9b6f38a17c70465e3e2 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Wed, 5 Feb 2025 15:40:52 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E4=BD=BF=E7=94=A8=20?= =?UTF-8?q?LLM=20=E8=BE=85=E5=8A=A9=E5=88=86=E6=AE=B5=E5=9B=9E=E5=A4=8D=20?= =?UTF-8?q?#338?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astrbot/core/config/default.py | 6 ++++++ .../process_stage/method/llm_request.py | 2 +- .../core/pipeline/result_decorate/stage.py | 19 +++++++++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/astrbot/core/config/default.py b/astrbot/core/config/default.py index 0f18ba243..ba880ef45 100644 --- a/astrbot/core/config/default.py +++ b/astrbot/core/config/default.py @@ -29,6 +29,7 @@ DEFAULT_CONFIG = { "enable": False, "only_llm_result": True, "interval": "1.5,3.5", + "seg_prompt": "", "regex": ".*?[。?!~…]+|.+$" }, "no_permission_reply": True, @@ -217,6 +218,11 @@ CONFIG_METADATA_2 = { "type": "string", "hint": "每一段回复的间隔时间,格式为 `最小时间,最大时间`。如 `0.75,2.5`", }, + "seg_prompt": { + "description": "分段提示词辅助", + "type": "string", + "hint": "此项为空时表达不启用这个方法。此方法会调用一次LLM请求。让 LLM 在某一句话中插入一个可以用正则表达式分隔的标记,来实现LLM基于情感分段。如: `请基于情感对以下文本进行分段, 并在两段之间添加``以便我用正则匹配。` 然后将下面的正则表达式更换为`.+?`。", + }, "regex": { "description": "正则表达式", "type": "string", diff --git a/astrbot/core/pipeline/process_stage/method/llm_request.py b/astrbot/core/pipeline/process_stage/method/llm_request.py index dee23211a..b2ee8d508 100644 --- a/astrbot/core/pipeline/process_stage/method/llm_request.py +++ b/astrbot/core/pipeline/process_stage/method/llm_request.py @@ -77,7 +77,7 @@ class LLMRequestSubStage(Stage): req.contexts = json.loads(req.contexts) try: - logger.debug(f"提供商请求 Payload: {req.__dict__}") + logger.debug(f"提供商请求 Payload: {req}") if _nested: req.func_tool = None # 暂时不支持递归工具调用 llm_response = await provider.text_chat(**req.__dict__) # 请求 LLM diff --git a/astrbot/core/pipeline/result_decorate/stage.py b/astrbot/core/pipeline/result_decorate/stage.py index 60720ceb7..332e1cef4 100644 --- a/astrbot/core/pipeline/result_decorate/stage.py +++ b/astrbot/core/pipeline/result_decorate/stage.py @@ -23,6 +23,7 @@ class ResultDecorateStage: # 分段回复 self.enable_segmented_reply = ctx.astrbot_config['platform_settings']['segmented_reply']['enable'] self.only_llm_result = ctx.astrbot_config['platform_settings']['segmented_reply']['only_llm_result'] + self.seg_prompt = ctx.astrbot_config['platform_settings']['segmented_reply']['seg_prompt'] self.regex = ctx.astrbot_config['platform_settings']['segmented_reply']['regex'] async def process(self, event: AstrMessageEvent) -> Union[None, AsyncGenerator[None, None]]: @@ -49,12 +50,26 @@ class ResultDecorateStage: new_chain = [] for comp in result.chain: if isinstance(comp, Plain): - split_response = re.findall(r".*?[。?!~…]+|.+$", comp.text) + + if self.seg_prompt: + try: + llm_resp = await self.ctx.plugin_manager.context.get_using_provider().text_chat( + prompt=f"{self.seg_prompt}\n{comp.text}", + ) + comp.text = llm_resp.completion_text + except BaseException as e: + traceback.print_exc() + logger.error("使用 LLM 分段回复失败: " + str(e)) + new_chain.append(comp) + continue + + split_response = re.findall(self.regex, comp.text) if not split_response: new_chain.append(comp) continue for seg in split_response: - new_chain.append(Plain(seg)) + if seg: + new_chain.append(Plain(seg)) else: # 非 Plain 类型的消息段不分段 new_chain.append(comp)