✨ feat!(llm): 重构并升级大语言模型服务为全新 AI 智能体框架 (#2146)

* ✨ feat!(llm): 重构并升级大语言模型服务为全新 AI 智能体框架

- 【重构】将原 services/llm 重构并迁移至全新的 services/ai 架构,提供向下兼容垫片
- 【新增】引入 Agent、Team、Workflow 三大智能体与工作流编排范式
- 【新增】引入基于 RAG 的长期向量记忆与中期槽位记忆系统
- 【新增】引入基于 Docker 的安全代码执行沙箱环境
- 【新增】支持 MCP 协议,允许动态管理和调用 MCP 服务
- 【新增】引入输入输出安全合规护栏与自愈反思机制
- 【优化】重构并优化多厂商 API 适配器 (Gemini, OpenAI, DeepSeek, GLM 等)
- 【优化】优化日志脱敏与 Token 预估机制
- 【移除】移除旧版 llm default 和 llm reset-key 命令,新增 llm mcp 管理命令

* 🔧 chore(deps): 更新项目依赖与配置

- 添加 mcp、jieba 和 aiodocker 依赖到配置文件及 requirements.txt
- 在 pyright 配置中设置 reportMissingImports 为 none
- 调整 .gitignore 中 resources 目录的忽略规则

* ♻️ refactor(tools): 重构工具终止机制并清理知识库日志输出

- 统一使用 `context.state["__end_run__"]` 替代 `EndRunResult` 控制任务结束
- 移除文件系统和向量知识库检索工具中 `ToolResult` 的 `.with_log` 调用
- 调整指令处理器(Directive)的返回值为 `tool_res.output`
- 修复部分类型检查警告并优化联合类型判断语法

* ♻️ refactor(tools): 重构工具副作用指令与控制流熔断机制

- 引入 `DirectivePayload` 及 `ToolResult` 的子类以结构化表达工具副作用
- 移除通过 `context.state` 传递魔术变量的隐式控制流设计
- 重构 `DirectiveManager` 处理器接口,直接在处理器中修改 `AgentState` 并构建 `AgentRunResult`
- 在 `StandardAgentExecutor` 中统一通过 `directive_manager` 调度工具返回的副作用指令
- 补全 `MessageBuilder` 中部分核心方法的文档注释

* 🐛 fix(sandbox): 修复 Docker 沙箱容器状态检测与会话清理逻辑

-【修复】修正 `is_alive` 中直接读取私有属性的问题,改用 `show()` 返回值
-【修复】解决 `execute_code` 中缓存的执行器与当前会话不一致的问题
-【优化】在清理工作区前增加容器存活检测,避免向已死容器发送请求
-【优化】创建容器时增加运行状态校验,若已停止则自动从缓存中移除并重建
-【优化】优化容器销毁和清理逻辑,静默处理容器不存在 (404) 的异常

* 📝 docs(core): 补充核心模块初始化方法的文档注释

* 🚨 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:
Rumio
2026-07-03 08:53:56 +08:00
committed by GitHub
co-authored by webjoin111 pre-commit-ci[bot]
parent bdc1374848
commit 80fc5b86a7
223 changed files with 41885 additions and 10006 deletions
+19
View File
@@ -0,0 +1,19 @@
from .manager import (
get_ai_config,
get_gemini_safety_threshold,
get_llm_config,
register_llm_configs,
)
from .models import DebugLogOptions, DefaultModelsConfig, LLMConfig, ProviderConfig
register_llm_configs()
__all__ = [
"DebugLogOptions",
"DefaultModelsConfig",
"LLMConfig",
"ProviderConfig",
"get_ai_config",
"get_gemini_safety_threshold",
"get_llm_config",
"register_llm_configs",
]
+274
View File
@@ -0,0 +1,274 @@
from functools import lru_cache
from typing import Any
from zhenxun.configs.config import Config
from zhenxun.configs.utils import parse_as
from zhenxun.utils.pydantic_compat import model_dump
from .models import DebugLogOptions, LLMConfig, ProviderConfig
def get_ai_config():
"""获取 AI 配置组"""
return Config.get("AI")
def get_default_providers() -> list[dict[str, Any]]:
"""获取默认提供商配置列表。"""
return [
{
"name": "DeepSeek",
"api_key": "YOUR_API_KEY",
"api_base": "https://api.deepseek.com",
"api_type": "deepseek",
"models": [
{
"model_name": "deepseek-v4-pro",
},
{
"model_name": "deepseek-v4-flash",
},
],
},
{
"name": "Doubao",
"api_key": "YOUR_ARK_API_KEY",
"api_base": "https://ark.cn-beijing.volces.com/api",
"api_type": "doubao",
"models": [
{"model_name": "doubao-seed-1-6-250615"},
{"model_name": "doubao-seed-1-6-flash-250615"},
],
},
{
"name": "siliconflow",
"api_key": "YOUR_ARK_API_KEY",
"api_base": "https://api.siliconflow.cn",
"api_type": "openai",
"models": [
{"model_name": "deepseek-ai/DeepSeek-V4-Flash"},
{"model_name": "BAAI/bge-m3"},
{"model_name": "BAAI/bge-reranker-v2-m3"},
],
},
{
"name": "GLM",
"api_key": "YOUR_API_KEY",
"api_base": "https://open.bigmodel.cn",
"api_type": "glm",
"models": [
{"model_name": "glm-4.6v-flash"},
{"model_name": "glm-5v-turbo"},
],
},
{
"name": "Gemini",
"api_key": [
"AIzaSy*****************************",
"AIzaSy*****************************",
],
"api_base": "https://generativelanguage.googleapis.com",
"api_type": "gemini",
"models": [
{"model_name": "gemini-3.5-flash"},
{"model_name": "gemini-3.1-flash-lite"},
{"model_name": "gemini-2.5-flash-image"},
{"model_name": "gemini-embedding-2"},
{"model_name": "gemini-3.1-flash-tts-preview"},
],
},
{
"name": "OpenRouter",
"api_key": "YOUR_OPENROUTER_API_KEY",
"api_base": "https://openrouter.ai/api",
"api_type": "openrouter",
"models": [
{"model_name": "google/gemini-3.1-flash-lite"},
{"model_name": "x-ai/grok-4"},
],
},
{
"name": "MiniMax",
"api_key": "YOUR_API_KEY",
"api_base": "https://api.minimaxi.com",
"api_type": "minimax",
"models": [
{"model_name": "MiniMax-M3"},
{"model_name": "MiniMax-M2.7"},
{"model_name": "MiniMax-M2.7-highspeed"},
],
},
{
"name": "MiMo",
"api_key": "YOUR_MIMO_API_KEY",
"api_base": "https://api.xiaomimimo.com",
"api_type": "mimo",
"models": [
{"model_name": "mimo-v2.5-pro"},
{"model_name": "mimo-v2.5"},
{"model_name": "mimo-v2.5-tts"},
],
},
]
def register_llm_configs():
"""注册 LLM 服务的配置项"""
llm_config = LLMConfig()
Config.add_plugin_config(
"AI",
"default_models",
model_dump(llm_config.default_models),
help="不同任务类型的全局默认模型配置字典",
type=dict,
)
Config.add_plugin_config(
"AI",
"client_settings",
model_dump(llm_config.client_settings),
help=(
"LLM客户端高级设置。\n"
"包含: timeout(超时秒数), max_retries(重试次数), "
"retry_delay(重试延迟), structured_retries(结构化生成重试)"
),
type=dict,
)
Config.add_plugin_config(
"AI",
"debug_log",
model_dump(llm_config.debug_log),
help=(
"LLM日志详情开关。示例: {'show_tools': True, 'show_schema': False, "
"'show_safety': False}"
),
type=dict,
)
Config.add_plugin_config(
"AI",
"context_settings",
model_dump(llm_config.context_settings),
help=(
"智能上下文管理与压缩配置。\n"
"包含:\n"
" - llm_summary: 大模型总结策略配置\n"
" - enable: 是否开启大模型对话总结以压缩上下文\n"
" - trigger_threshold: 触发压缩的 Token 阈值。<=1.0为比例,>1.0为绝对 Token 数\n" # noqa: E501
" - max_history_turns: 触发压缩的最大历史对话轮数\n"
" - summarization_model: 指定用于总结的大模型名称\n"
" - summarization_prompt: 指导大模型总结的系统提示词\n"
" - keep_recent_turns: 总结外强制原样保留的最近对话轮数\n"
" - vision_window_size: 多模态滑动窗口大小。0表示无限制,>0表示仅保留最近N轮包含多模态真实数据的消息,超过则自动降级为占位符\n" # noqa: E501
" - tool_pruning: 工具结果过载修剪策略配置\n"
" - enable: 是否开启长工具输出结果的自动修剪\n"
" - trigger_threshold: 触发修剪的工具纯 Token 阈值。<=1.0为比例,>1.0为绝对 Token 数\n" # noqa: E501
" - max_history_turns: 触发修剪的最大工具消息轮数。设为 0 表示不限制轮数\n" # noqa: E501
" - keep_recent_turns: 修剪时强制原样保留的最新的工具消息轮数"
),
type=dict,
)
Config.add_plugin_config(
"AI",
"MODEL_GROUPS",
llm_config.model_groups,
help=(
"虚拟模型路由组配置 (Virtual Router Groups)。\n"
"键为组名,值为模型名称或其它组名的列表。\n"
"使用 chat(model='cheap_models') 时系统将自动按列表顺序轮询和故障转移。"
),
type=dict,
)
Config.add_plugin_config(
"AI",
"agent_settings",
model_dump(llm_config.agent_settings),
help=(
"Agent 执行引擎默认设置。\n"
"包含: max_cycles(最大工具循环数), enable_parallel_calls(允许并行), "
"reflexion_retries(反思重试次数), "
"enable_fallback_summary(达到最大循环时兜底总结), "
"enable_hitl(是否允许智能体主动向用户求助), "
"mcp_cleanup_timeout(MCP 闲置回收时间)"
),
type=dict,
)
Config.add_plugin_config(
"AI",
"sandbox",
model_dump(llm_config.sandbox),
help=(
"沙箱底层环境基础设施配置。\n"
"包含: enable_sandbox(全局开关), sandbox_type(驱动类型), docker_image"
"(使用的镜像), "
"cleanup_timeout(空闲清理超时秒数), enable_vfs_helper(开启VFS防逃逸探针)。"
),
type=dict,
)
Config.add_plugin_config(
"AI",
"provider_settings",
model_dump(llm_config.provider_settings),
help=("厂商专属高级设置。\n包含各厂商全局的特有策略开关"),
type=dict,
)
Config.add_plugin_config(
"AI",
"PROVIDERS",
get_default_providers(),
help=(
"配置多个 AI 服务提供商及其模型信息。\n"
"注意:可以在特定模型配置下添加 'api_type' 以覆盖提供商的全局设置。\n"
"支持的 api_type 包括:\n"
"- 'openai': 标准 OpenAI 格式 (DeepSeek, SiliconFlow等)\n"
"- 'gemini': Google Gemini API\n"
"- 'glm': 智谱 AI (GLM)\n"
"- 'doubao': 字节跳动火山引擎 (Doubao)\n"
"- 'jina': Jina AI (专精于多模态嵌入与重排)\n"
"- 'openrouter': OpenRouter 聚合平台\n"
"- 'openai_responses': 支持新版 responses 格式的 OpenAI 兼容接口\n"
"- 'smart': 智能路由模式 (主要用于第三方中转场景,自动根据模型名"
"分发请求到 openai 或 gemini)"
),
default_value=[],
type=list[ProviderConfig],
)
@lru_cache(maxsize=1)
def get_llm_config() -> LLMConfig:
"""获取 LLM 配置实例"""
ai_config = get_ai_config()
raw_debug = ai_config.get("debug_log", False)
if isinstance(raw_debug, bool):
debug_log_val = DebugLogOptions(
show_tools=raw_debug, show_schema=raw_debug, show_safety=raw_debug
)
else:
debug_log_val = raw_debug
config_data = {
"default_models": ai_config.get("default_models", {}),
"client_settings": ai_config.get("client_settings", {}),
"debug_log": debug_log_val,
"PROVIDERS": ai_config.get("PROVIDERS", []),
"context_settings": ai_config.get("context_settings", {}),
"model_groups": ai_config.get("MODEL_GROUPS", {}),
"agent_settings": ai_config.get("agent_settings", {}),
"sandbox": ai_config.get("sandbox", {}),
"provider_settings": ai_config.get("provider_settings", {}),
}
return parse_as(LLMConfig, config_data)
def get_gemini_safety_threshold() -> str:
"""获取 Gemini 安全过滤阈值配置。"""
return get_llm_config().provider_settings.gemini.safety_threshold
+213
View File
@@ -0,0 +1,213 @@
from pydantic import BaseModel, Field
from zhenxun.services.ai.core.models import ModelDetail
class DebugLogOptions(BaseModel):
"""调试日志细粒度控制选项"""
show_tools: bool = True
"""是否在日志中显示工具定义 (JSON Schema)"""
show_schema: bool = True
"""是否在日志中显示结构化输出 Schema (response_format)"""
show_safety: bool = True
"""是否在日志中显示安全设置 (safetySettings)"""
def __bool__(self) -> bool:
return self.show_tools or self.show_schema or self.show_safety
class ClientSettings(BaseModel):
"""LLM 客户端底层网络与重试设置"""
timeout: int = 300
"""API 请求超时时间 (秒)"""
max_retries: int = 3
"""请求失败时的最大重试次数"""
retry_delay: int = 2
"""请求重试的基础延迟时间 (秒)"""
structured_retries: int = 2
"""结构化生成校验失败时的最大重试次数 (IVR)"""
class LLMSummaryConfig(BaseModel):
"""LLM 自然语言总结压缩策略配置"""
enable: bool = True
"""是否开启大模型对话总结以压缩上下文"""
trigger_threshold: float = 0.8
"""触发压缩的 Token 阈值。<=1.0 为比例,>1.0 为绝对 Token 数"""
max_history_turns: int = 0
"""触发压缩的最大历史对话轮数。设为 0 表示不限制轮数(仅受 Token 阈值控制)。"""
summarization_model: str | None = "DeepSeek/deepseek-v4-flash"
"""指定用于执行总结任务的大模型名称,为空则使用全局默认"""
summarization_prompt: str = (
"请以客观、精炼的语言概括以下对话内容。重点保留:"
"1. 核心讨论话题及重要决定;"
"2. 用户的个性特征、核心偏好、提及的生活背景或特殊设定;"
"3. 双方互动的温度与情感基调。无需保留寒暄等客套话。"
)
"""指导大模型进行总结的系统提示词"""
keep_recent_turns: int = 3
"""在总结之外,强制原样保留的最近对话轮数"""
class ToolPruningConfig(BaseModel):
"""工具结果修剪策略配置"""
enable: bool = False
"""是否开启长工具输出结果的自动修剪"""
trigger_threshold: float = 0.6
"""触发修剪的工具纯 Token 阈值。<=1.0 为比例,>1.0 为绝对 Token 数"""
max_history_turns: int = 15
"""触发修剪的最大工具消息轮数。设为 0 表示不限制轮数。"""
keep_recent_turns: int = 3
"""修剪时强制原样保留的最新的工具消息轮数,确保当下反思不受影响"""
class ContextManagementSettings(BaseModel):
"""智能上下文管理与压缩算法设置"""
llm_summary: LLMSummaryConfig = Field(default_factory=LLMSummaryConfig)
"""大模型自然语言总结策略"""
vision_window_size: int = Field(default=3)
"""多模态滑动窗口大小。0表示无限制,>0表示仅保留最近N轮包含多模态真实数据的消息,超龄则自动降级为占位符"""
tool_pruning: ToolPruningConfig = Field(default_factory=ToolPruningConfig)
"""工具结果过载修剪策略"""
class GeminiProviderSettings(BaseModel):
"""Gemini 厂商专属高级配置"""
safety_threshold: str = Field(default="BLOCK_NONE")
"""Gemini 安全过滤阈值 (BLOCK_LOW_AND_ABOVE, BLOCK_MEDIUM_AND_ABOVE,
BLOCK_ONLY_HIGH, BLOCK_NONE)"""
allow_mixed_tools: bool = Field(default=False)
"""是否允许同时混合使用本地自定义工具和厂商云端内置工具"""
class ProviderSettingsGroup(BaseModel):
"""按厂商划分的高级专属设置组"""
gemini: GeminiProviderSettings = Field(default_factory=GeminiProviderSettings)
"""Gemini 相关专属配置"""
class ProviderConfig(BaseModel):
"""LLM 服务提供商 (接口方) 配置模型"""
name: str
"""提供商唯一标识名称"""
api_key: str | list[str]
"""API 密钥或密钥列表 (支持轮询)"""
api_base: str | None = None
"""API 基础 URL 路径"""
api_type: str = "openai"
"""API 协议类型 (openai/gemini/zhipu/etc.)"""
openai_compat: bool = False
"""是否强制使用 OpenAI 兼容模式"""
temperature: float | None = 0.7
"""该提供商下模型的默认温度"""
generation_max_tokens: int | None = None
"""该提供商下模型的默认最大输出限制"""
models: list[ModelDetail]
"""该提供商提供的具体模型列表"""
timeout: int = 180
"""针对该提供商的特定超时时间"""
class DefaultModelsConfig(BaseModel):
"""按任务分类的默认模型配置"""
chat: str | None = Field(default="Gemini/gemini-3.5-flash")
embedding: str | None = Field(default="Gemini/gemini-embedding-2")
tts: str | None = Field(default="Gemini/gemini-3.1-flash-tts-preview")
image: str | None = Field(default="Gemini/gemini-2.5-flash-image")
rerank: str | None = Field(default="siliconflow/BAAI/bge-reranker-v2-m3")
class AgentEngineSettings(BaseModel):
"""全局默认的 Agent 推理引擎配置"""
max_cycles: int = 10
"""工具调用最大循环次数"""
global_max_cycles: int = 30
"""整个会话生命周期内(跨嵌套智能体)的大模型绝对循环次数上限,用于防死循环"""
enable_parallel_calls: bool = True
"""允许并行工具调用"""
reflexion_retries: int = 1
"""反思重试次数"""
enable_fallback_summary: bool = True
"""达到最大循环次数时,是否触发大模型兜底总结(而不是直接报错)"""
enable_hitl: bool = False
"""是否允许智能体主动挂起任务,向用户求助 (Human-in-the-Loop)"""
mcp_cleanup_timeout: int = 900
"""MCP 服务自动清理的闲置超时时间(秒)。0表示关闭自动清理机制(永久驻留)"""
class SandboxSettings(BaseModel):
"""沙箱底层基础设施环境配置"""
enable_sandbox: bool = Field(default=False)
"""全局沙箱功能硬开关。关闭后将彻底不加载沙箱底层驱动(如 Docker),
极大提升冷启动速度。"""
sandbox_type: str = Field(default="docker")
"""沙箱底层驱动类型: docker 等"""
docker_image: str = Field(default="zhenxun-sandbox:latest")
"""Docker 沙箱使用的镜像名称 (自定义 Jupyter 增强版)"""
cleanup_timeout: int = Field(default=1800)
"""沙箱自动清理的闲置超时时间(秒)。0表示关闭,不自动清理"""
enable_vfs_helper: bool = Field(default=True)
"""是否开启 VFS 路径逃逸防范探针,默认开启。遇到兼容性问题时可关闭"""
class LLMConfig(BaseModel):
"""AI 模块全局持久化配置总模型"""
default_models: DefaultModelsConfig = Field(default_factory=DefaultModelsConfig)
"""全局按任务分类的默认模型路由表"""
client_settings: ClientSettings = Field(default_factory=ClientSettings)
"""客户端通用连接配置"""
providers: list[ProviderConfig] = Field(default_factory=list)
"""已配置的提供商列表"""
debug_log: DebugLogOptions = Field(default_factory=DebugLogOptions)
"""日志调试开关配置"""
context_settings: ContextManagementSettings = Field(
default_factory=ContextManagementSettings
)
"""上下文管理相关配置"""
model_groups: dict[str, list[str]] = Field(
default_factory=lambda: {
"cheap_models": [
"Gemini/gemini-3.5-flash",
"Doubao/doubao-seed-1-6-250615",
],
}
)
"""虚拟模型路由组配置 (Virtual Router Groups)"""
agent_settings: AgentEngineSettings = Field(default_factory=AgentEngineSettings)
"""Agent 执行引擎层核心默认参数配置"""
sandbox: SandboxSettings = Field(default_factory=SandboxSettings)
"""沙箱基础设施环境相关配置"""
provider_settings: ProviderSettingsGroup = Field(
default_factory=ProviderSettingsGroup
)
"""按厂商划分的专属高级全局开关与策略"""
def validate_model_name(self, provider_model_name: str) -> bool:
"""验证模型名称在当前配置中是否存在"""
if "/" not in provider_model_name:
return provider_model_name.strip() in self.model_groups
if not provider_model_name or "/" not in provider_model_name:
return False
parts = provider_model_name.split("/", 1)
p_name, m_name = parts[0], parts[1]
for p in self.providers:
if p.name == p_name:
for m in p.models:
if m.model_name == m_name:
return True
return False