mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-11 06:39:59 +08:00
✨ feat(llm): 全面重构LLM服务模块,增强多模态与工具支持 (#1953)
* ✨ feat(llm): 全面重构LLM服务模块,增强多模态与工具支持 🚀 核心功能增强 - 多模型链式调用:新增 `pipeline_chat` 支持复杂任务流处理 - 扩展提供商支持:新增 ARK(火山方舟)、SiliconFlow(硅基流动) 适配器 - 多模态处理增强:支持URL媒体文件下载转换,提升输入灵活性 - 历史对话支持:AI.analyze 方法支持历史消息上下文和可选 UniMessage 参数 - 文本嵌入功能:新增 `embed`、`analyze_multimodal`、`search_multimodal` 等API - 模型能力系统:新增 `ModelCapabilities` 统一管理模型特性(多模态、工具调用等) 🔧 架构重构与优化 - MCP工具系统重构:配置独立化至 `data/llm/mcp_tools.json`,预置常用工具 - API调用逻辑统一:提取通用 `_perform_api_call` 方法,消除代码重复 - 跨平台兼容:Windows平台MCP工具npx命令自动包装处理 - HTTP客户端增强:兼容不同版本httpx代理配置(0.28+版本适配) 🛠️ API与配置完善 - 统一返回类型:`AI.analyze` 统一返回 `LLMResponse` 类型 - 消息转换工具:新增 `message_to_unimessage` 转换函数 - Gemini适配器增强:URL图片下载编码、动态安全阈值配置 - 缓存管理:新增模型实例缓存和管理功能 - 配置预设:扩展 CommonOverrides 预设配置选项 - 历史管理优化:支持多模态内容占位符替换,提升效率 📚 文档与开发体验 - README全面重写:新增完整使用指南、API参考和架构概览 - 文档内容扩充:补充嵌入模型、缓存管理、工具注册等功能说明 - 日志记录增强:支持详细调试信息输出 - API简化:移除冗余函数,优化接口设计 * 🎨 feat(llm): 统一LLM服务函数文档格式 * ✨ feat(llm): 添加新模型并简化提供者配置加载 * 🚨 auto fix by pre-commit hooks --------- Co-authored-by: webjoin111 <455457521@qq.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
webjoin111
pre-commit-ci[bot]
parent
1e7ae38684
commit
48cbb2bf1d
@@ -49,12 +49,36 @@ class LLMHttpClient:
|
||||
max_keepalive_connections=self.config.max_keepalive_connections,
|
||||
)
|
||||
timeout = httpx.Timeout(self.config.timeout)
|
||||
|
||||
client_kwargs = {}
|
||||
if self.config.proxy:
|
||||
try:
|
||||
version_parts = httpx.__version__.split(".")
|
||||
major = int(
|
||||
"".join(c for c in version_parts[0] if c.isdigit())
|
||||
)
|
||||
minor = (
|
||||
int("".join(c for c in version_parts[1] if c.isdigit()))
|
||||
if len(version_parts) > 1
|
||||
else 0
|
||||
)
|
||||
if (major, minor) >= (0, 28):
|
||||
client_kwargs["proxy"] = self.config.proxy
|
||||
else:
|
||||
client_kwargs["proxies"] = self.config.proxy
|
||||
except (ValueError, IndexError):
|
||||
client_kwargs["proxies"] = self.config.proxy
|
||||
logger.warning(
|
||||
f"无法解析 httpx 版本 '{httpx.__version__}',"
|
||||
"LLM模块将默认使用旧版 'proxies' 参数语法。"
|
||||
)
|
||||
|
||||
self._client = httpx.AsyncClient(
|
||||
headers=headers,
|
||||
limits=limits,
|
||||
timeout=timeout,
|
||||
proxies=self.config.proxy,
|
||||
follow_redirects=True,
|
||||
**client_kwargs,
|
||||
)
|
||||
if self._client is None:
|
||||
raise LLMException(
|
||||
@@ -156,7 +180,16 @@ async def create_llm_http_client(
|
||||
timeout: int = 180,
|
||||
proxy: str | None = None,
|
||||
) -> LLMHttpClient:
|
||||
"""创建LLM HTTP客户端"""
|
||||
"""
|
||||
创建LLM HTTP客户端
|
||||
|
||||
参数:
|
||||
timeout: 超时时间(秒)。
|
||||
proxy: 代理服务器地址。
|
||||
|
||||
返回:
|
||||
LLMHttpClient: HTTP客户端实例。
|
||||
"""
|
||||
config = HttpClientConfig(timeout=timeout, proxy=proxy)
|
||||
return LLMHttpClient(config)
|
||||
|
||||
@@ -185,7 +218,20 @@ async def with_smart_retry(
|
||||
provider_name: str | None = None,
|
||||
**kwargs: Any,
|
||||
) -> Any:
|
||||
"""智能重试装饰器 - 支持Key轮询和错误分类"""
|
||||
"""
|
||||
智能重试装饰器 - 支持Key轮询和错误分类
|
||||
|
||||
参数:
|
||||
func: 要重试的异步函数。
|
||||
*args: 传递给函数的位置参数。
|
||||
retry_config: 重试配置。
|
||||
key_store: API密钥状态存储。
|
||||
provider_name: 提供商名称。
|
||||
**kwargs: 传递给函数的关键字参数。
|
||||
|
||||
返回:
|
||||
Any: 函数执行结果。
|
||||
"""
|
||||
config = retry_config or RetryConfig()
|
||||
last_exception: Exception | None = None
|
||||
failed_keys: set[str] = set()
|
||||
@@ -294,7 +340,17 @@ class KeyStatusStore:
|
||||
api_keys: list[str],
|
||||
exclude_keys: set[str] | None = None,
|
||||
) -> str | None:
|
||||
"""获取下一个可用的API密钥(轮询策略)"""
|
||||
"""
|
||||
获取下一个可用的API密钥(轮询策略)
|
||||
|
||||
参数:
|
||||
provider_name: 提供商名称。
|
||||
api_keys: API密钥列表。
|
||||
exclude_keys: 要排除的密钥集合。
|
||||
|
||||
返回:
|
||||
str | None: 可用的API密钥,如果没有可用密钥则返回None。
|
||||
"""
|
||||
if not api_keys:
|
||||
return None
|
||||
|
||||
@@ -338,7 +394,13 @@ class KeyStatusStore:
|
||||
logger.debug(f"记录API密钥成功使用: {self._get_key_id(api_key)}")
|
||||
|
||||
async def record_failure(self, api_key: str, status_code: int | None):
|
||||
"""记录失败使用"""
|
||||
"""
|
||||
记录失败使用
|
||||
|
||||
参数:
|
||||
api_key: API密钥。
|
||||
status_code: HTTP状态码。
|
||||
"""
|
||||
key_id = self._get_key_id(api_key)
|
||||
async with self._lock:
|
||||
if status_code in [401, 403]:
|
||||
@@ -356,7 +418,15 @@ class KeyStatusStore:
|
||||
logger.info(f"重置API密钥状态: {self._get_key_id(api_key)}")
|
||||
|
||||
async def get_key_stats(self, api_keys: list[str]) -> dict[str, dict]:
|
||||
"""获取密钥使用统计"""
|
||||
"""
|
||||
获取密钥使用统计
|
||||
|
||||
参数:
|
||||
api_keys: API密钥列表。
|
||||
|
||||
返回:
|
||||
dict[str, dict]: 密钥统计信息字典。
|
||||
"""
|
||||
stats = {}
|
||||
async with self._lock:
|
||||
for key in api_keys:
|
||||
|
||||
Reference in New Issue
Block a user