From cd6c3e4f79c9abf5c7aaecc72310189b14350081 Mon Sep 17 00:00:00 2001 From: 3030332422 <3030332422@qq.com> Date: Thu, 4 Dec 2025 11:04:16 +0800 Subject: [PATCH] =?UTF-8?q?update:=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E6=96=87=E5=A1=AB=E5=85=85=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E5=8D=95=E6=A8=A1=E5=9D=97=E5=AE=9E=E7=8E=B0=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E4=B8=8A=E4=B8=8B=E6=96=87=E5=A1=AB=E5=85=85=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/agent-base-prompt.txt | 1 + main/xiaozhi-server/config.yaml | 8 +++ .../core/utils/context_provider.py | 62 +++++++++++++++++++ .../core/utils/prompt_manager.py | 13 +++- 4 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 main/xiaozhi-server/core/utils/context_provider.py diff --git a/main/xiaozhi-server/agent-base-prompt.txt b/main/xiaozhi-server/agent-base-prompt.txt index 490b23d3..7fd90d21 100644 --- a/main/xiaozhi-server/agent-base-prompt.txt +++ b/main/xiaozhi-server/agent-base-prompt.txt @@ -74,6 +74,7 @@ - **今天农历:** {{lunar_date}} - **用户所在城市:** {{local_address}} - **当地未来7天天气:** {{weather_info}} +{{ dynamic_context }} diff --git a/main/xiaozhi-server/config.yaml b/main/xiaozhi-server/config.yaml index a4087395..13d9fcb3 100644 --- a/main/xiaozhi-server/config.yaml +++ b/main/xiaozhi-server/config.yaml @@ -113,6 +113,14 @@ wakeup_words: # MCP接入点地址,地址格式为:ws://你的mcp接入点ip或者域名:端口号/mcp/?token=你的token # 详细教程 https://github.com/xinnan-tech/xiaozhi-esp32-server/blob/main/docs/mcp-endpoint-integration.md mcp_endpoint: 你的接入点 websocket地址 + +# 数据上下文填充配置 +# 用于在系统提示词中注入动态数据,如健康数据、股票信息等 +context_providers: + - url: "" + headers: + Authorization: "" + # 插件的基础配置 plugins: # 获取天气插件的配置,这里填写你的api_key diff --git a/main/xiaozhi-server/core/utils/context_provider.py b/main/xiaozhi-server/core/utils/context_provider.py new file mode 100644 index 00000000..617250d7 --- /dev/null +++ b/main/xiaozhi-server/core/utils/context_provider.py @@ -0,0 +1,62 @@ +import httpx +from typing import Dict, Any, List +from config.logger import setup_logging + +TAG = __name__ + +class ContextDataProvider: + """数据上下文填充,负责从配置的API获取数据""" + + def __init__(self, config: Dict[str, Any], logger=None): + self.config = config + self.logger = logger or setup_logging() + self.context_data = "" + + def fetch_all(self, device_id: str) -> str: + """获取所有配置的上下文数据""" + context_providers = self.config.get("context_providers", []) + if not context_providers: + return "" + + formatted_lines = [] + for provider in context_providers: + url = provider.get("url") + headers = provider.get("headers", {}) + + if not url: + continue + + try: + headers = headers.copy() if isinstance(headers, dict) else {} + # 将 device_id 添加到请求头 + headers["device_id"] = device_id + + # 发送请求 + response = httpx.get(url, headers=headers, timeout=3) + + if response.status_code == 200: + result = response.json() + if isinstance(result, dict): + if result.get("code") == 0: + data = result.get("data") + # 格式化数据 + if isinstance(data, dict): + for k, v in data.items(): + formatted_lines.append(f"- **{k}:** {v}") + elif isinstance(data, list): + for item in data: + formatted_lines.append(f"- {item}") + else: + formatted_lines.append(f"- {data}") + else: + self.logger.bind(tag=TAG).warning(f"API {url} 返回错误码: {result.get('msg')}") + else: + self.logger.bind(tag=TAG).warning(f"API {url} 返回的不是JSON字典") + else: + self.logger.bind(tag=TAG).warning(f"API {url} 请求失败: {response.status_code}") + except Exception as e: + self.logger.bind(tag=TAG).error(f"获取上下文数据 {url} 失败: {e}") + + # 将所有格式化后的行拼接成一个字符串 + self.context_data = "\n".join(formatted_lines) + return self.context_data diff --git a/main/xiaozhi-server/core/utils/prompt_manager.py b/main/xiaozhi-server/core/utils/prompt_manager.py index 444b16ee..4ec952ae 100644 --- a/main/xiaozhi-server/core/utils/prompt_manager.py +++ b/main/xiaozhi-server/core/utils/prompt_manager.py @@ -4,7 +4,6 @@ """ import os -import cnlunar from typing import Dict, Any from config.logger import setup_logging from jinja2 import Template @@ -60,6 +59,11 @@ class PromptManager: self.cache_manager = cache_manager self.CacheType = CacheType + + # 初始化数据上下文填充 + from core.utils.context_provider import ContextDataProvider + self.context_provider = ContextDataProvider(config, self.logger) + self.context_data = {} self._load_base_template() @@ -184,6 +188,11 @@ class PromptManager: local_address = self._get_location_info(client_ip) # 获取天气信息(使用全局缓存) self._get_weather_info(conn, local_address) + + # 获取配置的上下文数据 + if hasattr(conn, "device_id") and conn.device_id: + self.context_data = self.context_provider.fetch_all(conn.device_id) + self.logger.bind(tag=TAG).debug(f"上下文信息更新完成") except Exception as e: @@ -230,6 +239,7 @@ class PromptManager: emojiList=EMOJI_List, device_id=device_id, client_ip=client_ip, + dynamic_context=self.context_data, *args, **kwargs, ) @@ -240,6 +250,7 @@ class PromptManager: self.logger.bind(tag=TAG).info( f"构建增强提示词成功,长度: {len(enhanced_prompt)}" ) + print("enhanced_prompt:", enhanced_prompt) return enhanced_prompt except Exception as e: