工具注册与发现

📎 引用文件

本文引用的文件 - agent/src/tools/__init__.py - agent/src/agent/tools.py - agent/src/tools/mcp.py - agent/src/tools/market_data_tool.py - agent/src/tools/web_search_tool.py

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录:自定义工具注册示例

简介

本文件系统性说明 Vibe-Trading 中“工具注册与发现”机制的实现原理,覆盖以下关键点: - 工具类的自动发现、元数据提取与依赖解析 - 工具描述生成、参数 JSON Schema 验证与类型检查 - 工具生命周期管理(初始化、配置加载、资源清理) - 自定义工具注册的完整示例(接口实现、参数与返回值约定) - 工具冲突解决、版本管理与热重载支持

该机制以 BaseTool 抽象基类为核心,通过包扫描自动发现本地工具,并通过 MCP 适配器将远程工具包装为本地工具,统一纳入 ToolRegistry 进行调度。

项目结构

graph TB A["工具注册入口<br/>build_registry"] --> B["自动发现本地工具<br/>_discover_subclasses"] A --> C["MCP 远程工具适配<br/>build_mcp_tool_wrappers"] B --> D["ToolRegistry 注册<br/>register/get/execute"] C --> D D --> E["工具执行<br/>BaseTool.execute"]

图表来源 - agent/src/tools/__init__.py:66-245 - agent/src/agent/tools.py:54-95 - agent/src/tools/mcp.py:143-206

章节来源 - agent/src/tools/__init__.py:1-365 - agent/src/agent/tools.py:1-95 - agent/src/tools/mcp.py:1-800

核心组件

章节来源 - agent/src/agent/tools.py:13-95 - agent/src/tools/__init__.py:33-63 - agent/src/tools/mcp.py:123-206

架构总览

系统由三层组成: - 本地工具层:继承 BaseTool 的具体工具,通过包扫描自动注册 - 远程工具层:通过 MCP 协议发现并包装为本地工具 - 注册与调度层:ToolRegistry 统一管理工具生命周期与执行

sequenceDiagram participant Caller as "调用方" participant Reg as "ToolRegistry" participant Local as "本地工具(BaseTool)" participant MCP as "MCP适配器(MCPRemoteTool)" participant Remote as "远程MCP服务" Caller->>Reg : execute(name, params) alt 本地工具 Reg->>Local : execute(**params) Local-->>Reg : JSON字符串 else 远程工具 Reg->>MCP : execute(**params) MCP->>Remote : call_tool(remote_name, arguments) Remote-->>MCP : CallToolResult MCP-->>Reg : 标准化JSON end Reg-->>Caller : JSON字符串

图表来源 - agent/src/agent/tools.py:72-84 - agent/src/tools/mcp.py:629-665 - agent/src/tools/mcp.py:439-473

详细组件分析

自动发现与注册流程

flowchart TD Start(["开始"]) --> Scan["扫描src/tools模块"] Scan --> Collect["收集BaseTool子类"] Collect --> FilterShell{"是否shell工具且未启用?"} FilterShell --> |是| SkipShell["跳过该工具"] FilterShell --> |否| CheckAvail{"check_available()"} CheckAvail --> |False| SkipAvail["跳过该工具"] CheckAvail --> |True| InjectCtx{"是否需要注入上下文?"} InjectCtx --> |是| RegisterCtx["构造时注入session/event/memory"] InjectCtx --> |否| RegisterPlain["直接注册"] RegisterCtx --> Next["继续下一个工具"] RegisterPlain --> Next SkipShell --> Next SkipAvail --> Next Next --> End(["完成"])

图表来源 - agent/src/tools/__init__.py:33-63 - agent/src/tools/__init__.py:136-154

章节来源 - agent/src/tools/__init__.py:33-63 - agent/src/tools/__init__.py:66-245

元数据提取与参数Schema

classDiagram class BaseTool { +string name +string description +dict parameters +bool repeatable +bool is_readonly +check_available() bool +execute(**kwargs) string +to_openai_schema() dict } class MCPRemoteTool { +name string +description string +parameters dict +execute(**kwargs) string -_filter_arguments(arguments) dict } BaseTool <|-- MCPRemoteTool : "继承"

图表来源 - agent/src/agent/tools.py:13-51 - agent/src/tools/mcp.py:629-693

章节来源 - agent/src/agent/tools.py:13-51 - agent/src/tools/mcp.py:289-324 - agent/src/tools/mcp.py:667-693

依赖解析与可用性检查

章节来源 - agent/src/agent/tools.py:29-36 - agent/src/tools/web_search_tool.py:139-149 - agent/src/tools/qveris_tool.py:382-391

工具描述生成与类型检查

章节来源 - agent/src/agent/tools.py:42-51 - agent/src/tools/mcp.py:667-693 - agent/src/agent/tools.py:72-84

生命周期管理

sequenceDiagram participant Boot as "启动" participant Reg as "ToolRegistry" participant MCP as "MCPServerAdapter" participant Store as "TokenStore" Boot->>Reg : build_registry(...) Reg->>MCP : build_mcp_tool_wrappers(...) MCP->>Store : _build_token_store(cache_dir) Store-->>MCP : FileTreeStore(权限0700) Note over MCP,Store : 首次连接建立OAuth/HTTP会话 Boot-->>Reg : 返回已注册工具集合

图表来源 - agent/src/tools/__init__.py:66-245 - agent/src/tools/mcp.py:340-367 - agent/src/tools/mcp.py:475-535

章节来源 - agent/src/tools/__init__.py:66-245 - agent/src/tools/mcp.py:340-367 - agent/src/tools/mcp.py:475-535

工具冲突解决与版本管理

章节来源 - agent/src/tools/mcp.py:240-286 - agent/src/tools/mcp.py:766-793 - agent/src/tools/mcp.py:77-84

依赖关系分析

graph LR ToolsInit["tools/__init__.py"] --> BaseTool["agent/tools.py::BaseTool"] ToolsInit --> Registry["agent/tools.py::ToolRegistry"] ToolsInit --> MCP["tools/mcp.py"] MCP --> FastMCP["fastmcp 客户端"] MCP --> OAuth["OAuth 认证"] MCP --> Transports["SSE/Stdio/Streamable HTTP"]

图表来源 - agent/src/tools/__init__.py:66-245 - agent/src/agent/tools.py:13-95 - agent/src/tools/mcp.py:17-41

章节来源 - agent/src/tools/__init__.py:66-245 - agent/src/tools/mcp.py:17-41

性能考量

章节来源 - agent/src/tools/__init__.py:29-63 - agent/src/tools/mcp.py:62-84 - agent/src/tools/mcp.py:521-535 - agent/src/tools/web_search_tool.py:249-285

故障排查指南

章节来源 - agent/src/tools/__init__.py:136-154 - agent/src/tools/__init__.py:155-245 - agent/src/agent/tools.py:72-84 - agent/src/tools/mcp.py:439-473

结论

Vibe-Trading 的工具注册与发现机制以 BaseTool 为核心,结合包扫描与 MCP 适配器,实现了本地与远程工具的统一接入与管理。通过 JSON Schema 描述参数、严格的参数过滤与统一的执行封装,确保了工具调用的安全性与一致性。同时,提供了依赖检测、冲突去重、缓存与重试等工程化能力,支撑复杂场景下的稳定运行。

附录:自定义工具注册示例

以下为自定义工具注册的步骤与要点(不展示代码内容,仅提供路径参考): - 创建工具类:继承 BaseTool,定义 name、description、parameters、repeatable、is_readonly - 实现 check_available:检测依赖(如第三方库、环境变量),返回布尔值 - 实现 execute:接收 **kwargs,返回 JSON 字符串;内部进行参数校验与业务逻辑 - 注册与发现:将工具类放入 src/tools 目录下,无需额外注册,build_registry 会自动发现 - 参数与返回值: - 参数:使用 JSON Schema 描述,required 列出必填字段 - 返回值:统一 JSON 字符串,错误时包含 status 与 error 字段

参考路径 - agent/src/agent/tools.py:13-51 - agent/src/tools/market_data_tool.py:11-104 - agent/src/tools/web_search_tool.py:134-170 - agent/src/tools/__init__.py:33-63