mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-21 22:53:56 +08:00
update:添加数据上下文填充功能,单模块实现数据上下文填充功能
This commit is contained in:
@@ -74,6 +74,7 @@
|
|||||||
- **今天农历:** {{lunar_date}}
|
- **今天农历:** {{lunar_date}}
|
||||||
- **用户所在城市:** {{local_address}}
|
- **用户所在城市:** {{local_address}}
|
||||||
- **当地未来7天天气:** {{weather_info}}
|
- **当地未来7天天气:** {{weather_info}}
|
||||||
|
{{ dynamic_context }}
|
||||||
</context>
|
</context>
|
||||||
|
|
||||||
<memory>
|
<memory>
|
||||||
|
|||||||
@@ -113,6 +113,14 @@ wakeup_words:
|
|||||||
# MCP接入点地址,地址格式为:ws://你的mcp接入点ip或者域名:端口号/mcp/?token=你的token
|
# MCP接入点地址,地址格式为:ws://你的mcp接入点ip或者域名:端口号/mcp/?token=你的token
|
||||||
# 详细教程 https://github.com/xinnan-tech/xiaozhi-esp32-server/blob/main/docs/mcp-endpoint-integration.md
|
# 详细教程 https://github.com/xinnan-tech/xiaozhi-esp32-server/blob/main/docs/mcp-endpoint-integration.md
|
||||||
mcp_endpoint: 你的接入点 websocket地址
|
mcp_endpoint: 你的接入点 websocket地址
|
||||||
|
|
||||||
|
# 数据上下文填充配置
|
||||||
|
# 用于在系统提示词中注入动态数据,如健康数据、股票信息等
|
||||||
|
context_providers:
|
||||||
|
- url: ""
|
||||||
|
headers:
|
||||||
|
Authorization: ""
|
||||||
|
|
||||||
# 插件的基础配置
|
# 插件的基础配置
|
||||||
plugins:
|
plugins:
|
||||||
# 获取天气插件的配置,这里填写你的api_key
|
# 获取天气插件的配置,这里填写你的api_key
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import cnlunar
|
|
||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
from config.logger import setup_logging
|
from config.logger import setup_logging
|
||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
@@ -60,6 +59,11 @@ class PromptManager:
|
|||||||
|
|
||||||
self.cache_manager = cache_manager
|
self.cache_manager = cache_manager
|
||||||
self.CacheType = CacheType
|
self.CacheType = CacheType
|
||||||
|
|
||||||
|
# 初始化数据上下文填充
|
||||||
|
from core.utils.context_provider import ContextDataProvider
|
||||||
|
self.context_provider = ContextDataProvider(config, self.logger)
|
||||||
|
self.context_data = {}
|
||||||
|
|
||||||
self._load_base_template()
|
self._load_base_template()
|
||||||
|
|
||||||
@@ -184,6 +188,11 @@ class PromptManager:
|
|||||||
local_address = self._get_location_info(client_ip)
|
local_address = self._get_location_info(client_ip)
|
||||||
# 获取天气信息(使用全局缓存)
|
# 获取天气信息(使用全局缓存)
|
||||||
self._get_weather_info(conn, local_address)
|
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"上下文信息更新完成")
|
self.logger.bind(tag=TAG).debug(f"上下文信息更新完成")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -230,6 +239,7 @@ class PromptManager:
|
|||||||
emojiList=EMOJI_List,
|
emojiList=EMOJI_List,
|
||||||
device_id=device_id,
|
device_id=device_id,
|
||||||
client_ip=client_ip,
|
client_ip=client_ip,
|
||||||
|
dynamic_context=self.context_data,
|
||||||
*args,
|
*args,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
@@ -240,6 +250,7 @@ class PromptManager:
|
|||||||
self.logger.bind(tag=TAG).info(
|
self.logger.bind(tag=TAG).info(
|
||||||
f"构建增强提示词成功,长度: {len(enhanced_prompt)}"
|
f"构建增强提示词成功,长度: {len(enhanced_prompt)}"
|
||||||
)
|
)
|
||||||
|
print("enhanced_prompt:", enhanced_prompt)
|
||||||
return enhanced_prompt
|
return enhanced_prompt
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user