Skip to content

Commit 339cd0f

Browse files
committed
refactor: 重构工具获取逻辑,移除过时的工具接口,优化上下文工具管理
1 parent 9d1e2b9 commit 339cd0f

File tree

12 files changed

+225
-202
lines changed

12 files changed

+225
-202
lines changed

docs/latest/advanced/agents-config.md

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,67 @@
3636

3737
<<< @/../src/agents/reporter/graph.py
3838

39+
### 工具系统
3940

41+
系统提供统一的工具获取函数 `get_tools_from_context(context)`,自动从上下文配置中组装工具列表:
42+
43+
```python
44+
from src.agents.common.tools import get_tools_from_context
45+
46+
async def get_graph(self, **kwargs):
47+
context = self.get_context()
48+
tools = await get_tools_from_context(context)
49+
# tools 已包含:基础工具、知识库工具、MCP 工具
50+
```
51+
52+
该函数会自动处理三类工具的组装:
53+
1. **基础工具**: 从 `context.tools` 筛选的内置工具
54+
2. **知识库工具**: 根据 `context.knowledges` 自动生成检索工具
55+
3. **MCP 工具**: 根据 `context.mcps` 加载并过滤的 MCP 服务器工具
56+
57+
### BaseContext 配置字段
58+
59+
`BaseContext` 已内置以下常用配置字段,所有智能体可直接复用:
60+
61+
| 字段 | 类型 | 说明 |
62+
|------|------|------|
63+
| `model` | str | 使用的 LLM 模型 |
64+
| `system_prompt` | str | 系统提示词 |
65+
| `tools` | list[str] | 启用的内置工具列表 |
66+
| `knowledges` | list[str] | 关联的知识库列表 |
67+
| `mcps` | list[str] | 启用的 MCP 服务器名称 |
68+
69+
```python
70+
from src.agents.common import BaseContext
71+
72+
@dataclass(kw_only=True)
73+
class MyAgentContext(BaseContext):
74+
# 继承所有 BaseContext 字段
75+
# 可在此添加智能体特有的额外配置
76+
custom_field: str = "默认值"
77+
```
78+
79+
如需自定义工具选项(如 ReporterAgent 的 MySQL 工具),可覆盖 `tools` 字段的 `options` 元数据:
80+
81+
```python
82+
from src.agents.common import BaseContext, gen_tool_info
83+
from src.agents.common.tools import get_buildin_tools
84+
from src.agents.common.toolkits.mysql import get_mysql_tools
85+
86+
@dataclass(kw_only=True)
87+
class ReporterContext(BaseContext):
88+
tools: Annotated[list[dict], {"__template_metadata__": {"kind": "tools"}}] = field(
89+
default_factory=lambda: [t.name for t in get_mysql_tools()],
90+
metadata={
91+
"name": "工具",
92+
"options": lambda: gen_tool_info(get_buildin_tools() + get_mysql_tools()),
93+
"description": "包含内置工具和 MySQL 工具包。",
94+
},
95+
)
96+
97+
def __post_init__(self):
98+
self.mcps = ["mcp-server-chart"] # 默认启用图表 MCP
99+
```
40100

41101
智能体实例的生命周期交给管理器处理,会在自动发现时完成初始化并缓存单例,以便快速响应请求。在容器内热重载时,只要保存文件即可触发重新导入;需要强制刷新可调用 `agent_manager.get_agent(<id>, reload=True)`
42102

@@ -81,7 +141,7 @@ from src.agents.common.middlewares import inject_attachment_context
81141
async def get_graph(self):
82142
graph = create_agent(
83143
model=load_chat_model("..."),
84-
tools=get_tools(),
144+
tools=tools,
85145
middleware=[
86146
inject_attachment_context, # 添加附件中间件
87147
context_aware_prompt, # 其他中间件...

server/routers/chat_router.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from src import executor
2020
from src import config as conf
2121
from src.agents import agent_manager
22-
from src.agents.common.tools import gen_tool_info, get_buildin_tools
2322
from src.models import select_model
2423
from src.plugins.guard import content_guard
2524
from src.services.doc_converter import (
@@ -728,26 +727,6 @@ async def update_chat_models(model_provider: str, model_names: list[str], curren
728727
return {"models": conf.model_names[model_provider].models}
729728

730729

731-
@chat.get("/tools")
732-
async def get_tools(agent_id: str, current_user: User = Depends(get_required_user)):
733-
"""获取所有可用工具(需要登录)"""
734-
logger.error("[DEPRECATED] 该接口已被弃用,将在未来版本中移除")
735-
# 获取Agent实例和配置类
736-
if not (agent := agent_manager.get_agent(agent_id)):
737-
raise HTTPException(status_code=404, detail=f"智能体 {agent_id} 不存在")
738-
739-
if hasattr(agent, "get_tools") and callable(agent.get_tools):
740-
if asyncio.iscoroutinefunction(agent.get_tools):
741-
tools = await agent.get_tools()
742-
else:
743-
tools = agent.get_tools()
744-
else:
745-
tools = get_buildin_tools()
746-
747-
tools_info = gen_tool_info(tools)
748-
return {"tools": {tool["id"]: tool for tool in tools_info}}
749-
750-
751730
@chat.post("/agent/{agent_id}/resume")
752731
async def resume_agent_chat(
753732
agent_id: str,

src/agents/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def auto_discover_agents(self):
5454

5555
# 遍历所有子目录
5656
for item in agents_dir.iterdir():
57-
logger.info(f"尝试导入模块:{item}")
57+
# logger.info(f"尝试导入模块:{item}")
5858
# 跳过非目录、common 目录、__pycache__ 等
5959
if not item.is_dir() or item.name.startswith("_") or item.name == "common":
6060
continue

src/agents/chatbot/context.py

Lines changed: 0 additions & 42 deletions
This file was deleted.

src/agents/chatbot/graph.py

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,16 @@
55
from src.agents.common.middlewares import (
66
inject_attachment_context,
77
)
8-
from src.agents.common.tools import get_kb_based_tools
9-
from src.services.mcp_service import get_enabled_mcp_tools
10-
11-
from .context import Context
12-
from .tools import get_tools
8+
from src.agents.common.tools import get_tools_from_context
139

1410

1511
class ChatbotAgent(BaseAgent):
1612
name = "智能体助手"
17-
description = "基础的对话机器人,可以回答问题,默认不使用任何工具,可在配置中启用需要的工具。"
13+
description = "基础的对话机器人,可以回答问题,可在配置中启用需要的工具。"
1814
capabilities = ["file_upload"] # 支持文件上传功能
1915

2016
def __init__(self, **kwargs):
2117
super().__init__(**kwargs)
22-
self.context_schema = Context
23-
24-
async def get_tools(self, tools: list[str] = None, mcps=None, knowledges=None):
25-
# 1. 基础工具 (从 context.tools 中筛选)
26-
all_basic_tools = get_tools()
27-
selected_tools = []
28-
29-
if tools:
30-
# 创建工具映射表
31-
tools_map = {t.name: t for t in all_basic_tools}
32-
for tool_name in tools:
33-
if tool_name in tools_map:
34-
selected_tools.append(tools_map[tool_name])
35-
36-
# 2. 知识库工具
37-
if knowledges:
38-
kb_tools = get_kb_based_tools(db_names=knowledges)
39-
selected_tools.extend(kb_tools)
40-
41-
# 3. MCP 工具(使用统一入口,自动过滤 disabled_tools)
42-
if mcps:
43-
for server_name in mcps:
44-
mcp_tools = await get_enabled_mcp_tools(server_name)
45-
selected_tools.extend(mcp_tools)
46-
47-
return selected_tools
4818

4919
async def get_graph(self, **kwargs):
5020
"""构建图"""
@@ -57,7 +27,7 @@ async def get_graph(self, **kwargs):
5727
# 使用 create_agent 创建智能体
5828
graph = create_agent(
5929
model=load_chat_model(context.model), # 使用 context 中的模型配置
60-
tools=await self.get_tools(context.tools, context.mcps, context.knowledges),
30+
tools=await get_tools_from_context(context),
6131
system_prompt=context.system_prompt,
6232
middleware=[
6333
inject_attachment_context, # 附件上下文注入

src/agents/chatbot/tools.py

Lines changed: 0 additions & 56 deletions
This file was deleted.

src/agents/common/context.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@
99
import yaml
1010

1111
from src import config as sys_config
12+
from src.knowledge import knowledge_base
13+
from src.services.mcp_service import get_mcp_server_names
1214
from src.utils import logger
1315

16+
from .tools import gen_tool_info, get_buildin_tools
17+
1418

1519
@dataclass(kw_only=True)
1620
class BaseContext:
@@ -53,6 +57,37 @@ def update(self, data: dict):
5357
},
5458
)
5559

60+
tools: Annotated[list[dict], {"__template_metadata__": {"kind": "tools"}}] = field(
61+
default_factory=list,
62+
metadata={
63+
"name": "工具",
64+
"options": lambda: gen_tool_info(get_buildin_tools()),
65+
"description": "内置的工具。",
66+
},
67+
)
68+
69+
knowledges: list[str] = field(
70+
default_factory=list,
71+
metadata={
72+
"name": "知识库",
73+
"options": lambda: [k["name"] for k in knowledge_base.get_retrievers().values()],
74+
"description": "知识库列表,可以在左侧知识库页面中创建知识库。",
75+
"type": "list", # Explicitly mark as list type for frontend if needed
76+
},
77+
)
78+
79+
mcps: list[str] = field(
80+
default_factory=list,
81+
metadata={
82+
"name": "MCP服务器",
83+
"options": lambda: get_mcp_server_names(),
84+
"description": (
85+
"MCP服务器列表,建议使用支持 SSE 的 MCP 服务器,"
86+
"如果需要使用 uvx 或 npx 运行的服务器,也请在项目外部启动 MCP 服务器,并在项目中配置 MCP 服务器。"
87+
),
88+
},
89+
)
90+
5691
@classmethod
5792
def from_file(cls, module_name: str, input_context: dict = None) -> "BaseContext":
5893
"""Load configuration from a YAML file. 用于持久化配置"""

src/agents/common/subagents/calc_agent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
calc_agent = create_agent(
99
model=load_chat_model(config.default_model),
1010
tools=[calculator],
11-
system_prompt="你可以使用计算器工具,处理各种数学计算任务。",
11+
system_prompt="你可以使用计算器工具,处理各种数学计算任务。最终仅返回计算结果,不需要任何额外的解释。",
1212
)
1313

1414

0 commit comments

Comments
 (0)