From 4a8ba9c80b88fbeedc3d03048b85b32afe85230b Mon Sep 17 00:00:00 2001 From: hrz <1710360675@qq.com> Date: Sat, 24 Oct 2026 07:57:49 +0000 Subject: [PATCH] =?UTF-8?q?=E5=A4=A9=E6=B0=94=E6=B2=A1=E9=85=8D=E5=A5=BD?= =?UTF-8?q?=E6=97=B6=E6=8F=90=E7=A4=BA=E8=AF=8D=E7=BB=99=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=B8=80=E5=8F=A5=E8=AF=B4=E6=98=8E=EF=BC=8C=E4=B8=8D=E7=95=99?= =?UTF-8?q?=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 没配凭据时插件给不出天气报告,提示词里的天气内容以前是空的,模型会自己编一个。现在改成给用户一句「尚未配置」的说明,空结果也不再写进缓存,开发者配好凭据后下一次就能出天气。 --- .../core/utils/prompt_manager.py | 55 +++++++++++++++---- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/main/xiaozhi-server/core/utils/prompt_manager.py b/main/xiaozhi-server/core/utils/prompt_manager.py index edae6e9a1..2b3b9d35c 100644 --- a/main/xiaozhi-server/core/utils/prompt_manager.py +++ b/main/xiaozhi-server/core/utils/prompt_manager.py @@ -50,6 +50,12 @@ EMOJI_List = [ ] +# 天气取不到时给终端用户的一句话。给开发者的申请指引留在服务端日志里, +# 仓库路径不能进提示词,模型会把它当内容念给用户 +WEATHER_NOT_CONFIGURED_NOTICE = "天气功能尚未配置,暂时查不到天气。" +WEATHER_UNAVAILABLE_NOTICE = "暂时查不到天气信息。" + + class PromptManager: """系统提示词管理器,负责管理和更新系统提示词""" @@ -58,6 +64,8 @@ class PromptManager: self.logger = logger or setup_logging() self.base_prompt_template = None self.last_update_time = 0 + # 天气取不到时给用户的一句话,提示词要用它占位 + self._weather_notice = "" # 导入全局缓存管理器 from core.utils.cache.manager import cache_manager, CacheType @@ -168,15 +176,18 @@ class PromptManager: try: # 先从缓存获取 cached_weather = self.cache_manager.get(self.CacheType.WEATHER, location) - if cached_weather is not None: + if cached_weather: return cached_weather + # 缓存里留着空条目说明上次没取到,留着会挡住下一次取, + # 删掉重来,开发者把凭据配好之后下一次就该出天气 + self.cache_manager.delete(self.CacheType.WEATHER, location) # 缓存未命中,调用 async get_weather 函数 # Windows ProactorEventLoop 不支持 run_coroutine_threadsafe().result() # 因此用 call_soon_threadsafe 提交任务 + threading.Event 等待结果 # 注意:Event.wait() 只阻塞当前线程池线程,不阻塞主事件循环 from plugins_func.functions.get_weather import get_weather - from plugins_func.register import ActionResponse + from plugins_func.register import Action, ActionResponse result_holder = [] exception_holder = [] @@ -200,13 +211,26 @@ class PromptManager: result = result_holder[0] if isinstance(result, ActionResponse): weather_report = result.result - self.cache_manager.set(self.CacheType.WEATHER, location, weather_report) - return weather_report - return "天气信息获取失败" + if weather_report: + self.cache_manager.set( + self.CacheType.WEATHER, location, weather_report + ) + self._weather_notice = "" + return weather_report + # 凭据没配好时插件给不出报告。这种结果不写进缓存: + # 空条目留着的话,开发者配好凭据后还得等缓存过期才出天气 + if result.action == Action.RESPONSE: + self._weather_notice = WEATHER_NOT_CONFIGURED_NOTICE + else: + self._weather_notice = WEATHER_UNAVAILABLE_NOTICE + return self._weather_notice + self._weather_notice = WEATHER_UNAVAILABLE_NOTICE + return self._weather_notice except Exception as e: self.logger.bind(tag=TAG).error(f"获取天气信息失败: {e}") - return "天气信息获取失败" + self._weather_notice = WEATHER_UNAVAILABLE_NOTICE + return self._weather_notice def update_context_info(self, conn, client_ip: str): """同步更新上下文信息""" @@ -246,6 +270,18 @@ class PromptManager: except Exception as e: self.logger.bind(tag=TAG).error(f"更新上下文信息失败: {e}") + def _get_weather_context(self, location: str) -> str: + """给提示词用的天气内容 + +

+ 缓存里没有有效报告时给一句说明,不留空。占位符空着的话,模型会自己 + 编一个天气出来。 + """ + cached_weather = self.cache_manager.get(self.CacheType.WEATHER, location) + if cached_weather: + return cached_weather + return self._weather_notice or WEATHER_UNAVAILABLE_NOTICE + def build_enhanced_prompt( self, user_prompt: str, device_id: str, client_ip: str = None, *args, **kwargs ) -> str: @@ -259,7 +295,7 @@ class PromptManager: # 获取缓存的上下文信息 local_address = "" - weather_info = "" + weather_info = WEATHER_UNAVAILABLE_NOTICE if client_ip: # 获取位置信息(从全局缓存) @@ -269,10 +305,7 @@ class PromptManager: # 获取天气信息(从全局缓存) if local_address: - weather_info = ( - self.cache_manager.get(self.CacheType.WEATHER, local_address) - or "" - ) + weather_info = self._get_weather_context(local_address) # 获取TTS选择的语言,默认值为中文 language = (