AgentScope扩展开发:自定义工具包管理
【免费下载链接】agentscope 项目地址: https://gitcode.com/GitHub_Trending/ag/agentscope
痛点场景:为什么需要自定义工具包管理?
在构建复杂的多智能体应用时,你是否遇到过这样的困境:
- 工具泛滥:随着项目规模扩大,工具函数越来越多,智能体难以有效管理和选择
- 权限控制缺失:无法按需启用或禁用特定工具组,存在安全隐患
- 上下文污染:所有工具都暴露给智能体,导致提示词过长、决策混乱
- 复用困难:相似功能的工具分散各处,缺乏统一的管理机制
AgentScope的Toolkit类正是为解决这些问题而生,提供了强大的自定义工具包管理能力。
核心概念解析
工具组(Tool Group)架构
基础工具组 vs 自定义工具组
| 特性 | 基础工具组(basic) | 自定义工具组 |
|---|---|---|
| 激活状态 | 始终激活 | 可动态控制 |
| 删除权限 | 不可删除 | 可删除 |
| 默认包含 | 是 | 否 |
| 使用场景 | 核心功能工具 | 按需功能模块 |
实战:构建自定义工具包
1. 基础工具包创建
from agentscope.tool import Toolkit, execute_python_code, execute_shell_command
# 初始化工具包
toolkit = Toolkit()
# 注册基础工具
toolkit.register_tool_function(execute_python_code)
toolkit.register_tool_function(execute_shell_command)
print("可用工具:", list(toolkit.tools.keys()))
# 输出: ['execute_python_code', 'execute_shell_command']
2. 创建功能分组
# 创建数据分析工具组
toolkit.create_tool_group(
group_name="data_analysis",
description="数据分析相关工具,包括数据清洗、统计分析和可视化功能",
active=False, # 默认不激活
notes="使用数据分析工具时请确保数据格式正确,避免内存溢出"
)
# 创建网络工具组
toolkit.create_tool_group(
group_name="network_tools",
description="网络请求和API调用工具",
active=False,
notes="注意API调用频率限制,妥善处理敏感信息"
)
print("工具组列表:", list(toolkit.groups.keys()))
# 输出: ['data_analysis', 'network_tools']
3. 分组注册工具函数
import requests
import pandas as pd
from agentscope.tool import ToolResponse, TextBlock
# 自定义数据分析工具
async def data_clean_csv(file_path: str, output_path: str) -> ToolResponse:
"""清洗CSV数据文件"""
try:
df = pd.read_csv(file_path)
# 数据清洗逻辑
df = df.dropna()
df.to_csv(output_path, index=False)
return ToolResponse(
content=[TextBlock(type="text", text=f"数据清洗完成,保存至{output_path}")]
)
except Exception as e:
return ToolResponse(
content=[TextBlock(type="text", text=f"数据清洗失败: {str(e)}")]
)
# 自定义网络工具
async def http_get_request(url: str, headers: dict = None) -> ToolResponse:
"""发送HTTP GET请求"""
try:
response = requests.get(url, headers=headers, timeout=30)
return ToolResponse(
content=[TextBlock(type="text", text=response.text)]
)
except Exception as e:
return ToolResponse(
content=[TextBlock(type="text", text=f"请求失败: {str(e)}")]
)
# 按分组注册工具
toolkit.register_tool_function(data_clean_csv, group_name="data_analysis")
toolkit.register_tool_function(http_get_request, group_name="network_tools")
4. 动态工具管理
# 激活特定工具组
toolkit.update_tool_groups(["data_analysis"], active=True)
# 获取当前激活的工具JSON schema
active_schemas = toolkit.get_json_schemas()
print("激活的工具数量:", len(active_schemas))
# 动态切换工具组
async def dynamic_tool_management():
# 任务1: 需要数据分析工具
toolkit.update_tool_groups(["data_analysis"], active=True)
toolkit.update_tool_groups(["network_tools"], active=False)
# 执行数据分析任务...
# 任务2: 需要网络工具
toolkit.update_tool_groups(["data_analysis"], active=False)
toolkit.update_tool_groups(["network_tools"], active=True)
# 执行网络请求任务...
高级特性详解
预设参数(Preset Arguments)
# 注册带预设参数的工具
toolkit.register_tool_function(
http_get_request,
group_name="network_tools",
preset_kwargs={
"headers": {"User-Agent": "AgentScope-Bot/1.0"}
},
func_description="发送HTTP GET请求(已预设User-Agent)"
)
# 预设参数不会暴露给智能体,但会在调用时自动传入
后处理函数(Post-processing)
from agentscope.message import ToolUseBlock
def log_tool_usage(tool_call: ToolUseBlock, response: ToolResponse) -> ToolResponse:
"""工具使用日志记录"""
print(f"工具调用: {tool_call['name']}, 参数: {tool_call.get('input', {})}")
return response # 返回原始响应,不做修改
def error_handler(tool_call: ToolUseBlock, response: ToolResponse) -> ToolResponse:
"""错误处理后处理"""
if "Error" in str(response.content):
return ToolResponse(
content=[TextBlock(type="text", text="工具执行失败,请检查参数或重试")]
)
return response
# 注册带后处理的工具
toolkit.register_tool_function(
data_clean_csv,
group_name="data_analysis",
postprocess_func=error_handler
)
MCP客户端集成
from agentscope.mcp import HttpStatelessClient
async def integrate_mcp_tools():
# 初始化MCP客户端
mcp_client = HttpStatelessClient(
name="weather_mcp",
transport="streamable_http",
url="https://weather-api.com/mcp"
)
# 注册MCP工具到特定分组
await toolkit.register_mcp_client(
mcp_client=mcp_client,
group_name="weather_tools",
enable_funcs=["get_current_weather", "get_forecast"],
disable_funcs=["admin_functions"] # 禁用敏感功能
)
最佳实践模式
模式1:按场景分组的工具包
class ScenarioToolkit:
"""按业务场景组织的工具包管理器"""
def __init__(self):
self.toolkit = Toolkit()
self.setup_scenarios()
def setup_scenarios(self):
# 研究分析场景
self.toolkit.create_tool_group(
"research_analysis",
"学术研究和数据分析工具",
notes="适用于文献检索、数据分析和报告生成"
)
# 内容创作场景
self.toolkit.create_tool_group(
"content_creation",
"内容创作和编辑工具",
notes="适用于文本生成、编辑和格式化"
)
# 系统管理场景
self.toolkit.create_tool_group(
"system_admin",
"系统管理和运维工具",
notes="谨慎使用,涉及系统底层操作"
)
async def activate_scenario(self, scenario_name: str):
"""激活特定场景的工具包"""
all_groups = list(self.toolkit.groups.keys())
deactivate_groups = [g for g in all_groups if g != scenario_name]
self.toolkit.update_tool_groups([scenario_name], active=True)
self.toolkit.update_tool_groups(deactivate_groups, active=False)
return self.toolkit.get_activated_notes()
模式2:权限分级工具管理
class RoleBasedToolkit:
"""基于角色权限的工具包管理"""
def __init__(self):
self.toolkit = Toolkit()
self.role_permissions = {
"guest": ["basic"],
"user": ["basic", "data_analysis"],
"admin": ["basic", "data_analysis", "system_tools"],
"super_admin": ["basic", "data_analysis", "system_tools", "mcp_tools"]
}
async def set_role_tools(self, role: str):
"""根据角色设置可用的工具组"""
if role not in self.role_permissions:
raise ValueError(f"未知角色: {role}")
permitted_groups = self.role_permissions[role]
all_groups = list(self.toolkit.groups.keys())
# 激活权限内的工具组
self.toolkit.update_tool_groups(permitted_groups, active=True)
# 禁用权限外的工具组
forbidden_groups = [g for g in all_groups if g not in permitted_groups]
self.toolkit.update_tool_groups(forbidden_groups, active=False)
return f"已为角色 {role} 设置工具权限"
性能优化与调试技巧
工具包状态序列化
# 保存工具包状态
def save_toolkit_state(toolkit: Toolkit) -> dict:
"""序列化工具包状态"""
return {
"active_groups": [
name for name, group in toolkit.groups.items()
if group.active
],
"tools_count": len(toolkit.tools),
"groups_count": len(toolkit.groups)
}
# 恢复工具包状态
def restore_toolkit_state(toolkit: Toolkit, state: dict):
"""从状态恢复工具包配置"""
toolkit.load_state_dict(state)
内存使用监控
import sys
def monitor_toolkit_memory(toolkit: Toolkit):
"""监控工具包内存使用"""
tool_memory = sum(
sys.getsizeof(tool) for tool in toolkit.tools.values()
)
group_memory = sum(
sys.getsizeof(group) for group in toolkit.groups.values()
)
return {
"total_tools": len(toolkit.tools),
"total_groups": len(toolkit.groups),
"tool_memory_bytes": tool_memory,
"group_memory_bytes": group_memory,
"total_memory_bytes": tool_memory + group_memory
}
常见问题解决方案
Q1: 工具函数冲突如何处理?
问题:多个工具函数同名冲突 解决方案:使用工具别名或分组隔离
# 方案1: 使用不同的工具组
toolkit.register_tool_function(search_web, group_name="web_search_v1")
toolkit.register_tool_function(search_web_v2, group_name="web_search_v2")
# 方案2: 动态重命名
def register_with_suffix(base_name: str, func: callable, suffix: str):
"""为工具函数添加后缀避免冲突"""
func.__name__ = f"{base_name}_{suffix}"
toolkit.register_tool_function(func)
Q2: 如何优化大型工具包的加载性能?
问题:工具数量过多导致初始化缓慢 解决方案:延迟加载和按需注册
class LazyToolkit(Toolkit):
"""支持延迟加载的工具包"""
def __init__(self):
super().__init__()
self.lazy_registries = {}
def register_lazy_tool(self, group_name: str, tool_loader: callable):
"""注册延迟加载的工具"""
self.lazy_registries[group_name] = tool_loader
async def activate_group(self, group_name: str):
"""激活组时加载工具"""
if group_name in self.lazy_registries:
tool_loader = self.lazy_registries[group_name]
tools = await tool_loader()
for tool in tools:
self.register_tool_function(tool, group_name)
del self.lazy_registries[group_name]
self.update_tool_groups([group_name], active=True)
Q3: 工具权限如何与用户系统集成?
问题:需要将工具权限与现有用户系统结合 解决方案:基于策略的权限控制
from abc import ABC, abstractmethod
class ToolAccessPolicy(ABC):
"""工具访问策略抽象类"""
@abstractmethod
async def can_access_tool(self, user_id: str, tool_name: str) -> bool:
pass
class DatabaseToolPolicy(ToolAccessPolicy):
"""基于数据库的工具访问策略"""
def __init__(self, db_connection):
self.db = db_connection
async def can_access_tool(self, user_id: str, tool_name: str) -> bool:
# 查询数据库获取用户权限
query = "SELECT allowed FROM tool_permissions WHERE user_id = ? AND tool_name = ?"
result = await self.db.execute(query, (user_id, tool_name))
return result[0]["allowed"] if result else False
# 集成到工具包管理
class SecureToolkit(Toolkit):
"""带权限检查的安全工具包"""
def __init__(self, access_policy: ToolAccessPolicy):
super().__init__()
self.access_policy = access_policy
async def call_tool_function(self, tool_call: ToolUseBlock, user_id: str):
"""带权限检查的工具调用"""
if not await self.access_policy.can_access_tool(user_id, tool_call["name"]):
return ToolResponse(
content=[TextBlock(type="text", text="权限不足,无法使用该工具")]
)
return await super().call_tool_function(tool_call)
总结与展望
【免费下载链接】agentscope 项目地址: https://gitcode.com/GitHub_Trending/ag/agentscope
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



