自定义工具开发指南

📎 引用文件

本文引用的文件 - agent/src/agent/tools.py - agent/src/tools/__init__.py - agent/src/tools/read_file_tool.py - agent/src/tools/write_file_tool.py - agent/src/tools/path_utils.py - agent/src/tools/redaction.py - agent/src/security/network.py - agent/src/security/workspace_access.py - agent/src/security/workspace_policy.py - agent/tests/test_institutional_holdings_tool.py - agent/tests/test_file_tool_sandbox_security.py

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本指南面向希望在 Vibe-Trading 中开发“自定义工具”的工程师与研究者。你将学习如何基于 BaseTool 类实现可被自动发现、注册和调用的工具,理解参数校验与安全沙箱机制(资源限制、网络访问控制、文件系统权限),掌握单元测试与集成测试策略,并了解工具的部署与分发流程。文末提供从简单到复杂的开发案例与常见陷阱规避建议。

项目结构

Vibe-Trading 的工具系统采用“按功能模块组织”的结构: - 基础框架位于 agent/src/agent/tools.py,定义 BaseTool 与 ToolRegistry。 - 工具自动发现与注册逻辑位于 agent/src/tools/init.py。 - 具体工具实现位于 agent/src/tools/ 下的多个文件(如 read_file_tool.py、write_file_tool.py)。 - 安全能力集中在 agent/src/security/,提供网络与路径访问的安全辅助。 - 测试用例位于 agent/tests/,覆盖工具契约、安全边界与行为验证。

graph TB subgraph "工具基础设施" A["BaseTool<br/>agent/src/agent/tools.py"] B["ToolRegistry<br/>agent/src/agent/tools.py"] end subgraph "工具注册与发现" C["构建注册表<br/>agent/src/tools/__init__.py"] end subgraph "示例工具" D["ReadFileTool<br/>agent/src/tools/read_file_tool.py"] E["WriteFileTool<br/>agent/src/tools/write_file_tool.py"] end subgraph "安全能力" F["网络访问校验<br/>agent/src/security/network.py"] G["工作区路径访问<br/>agent/src/security/workspace_access.py"] H["工作区路径策略<br/>agent/src/security/workspace_policy.py"] end A --> B C --> B D --> A E --> A D --> F E --> F D --> G E --> G D --> H E --> H

图表来源 - agent/src/agent/tools.py:13-95 - agent/src/tools/__init__.py:33-245 - agent/src/tools/read_file_tool.py:18-118 - agent/src/tools/write_file_tool.py:14-107 - agent/src/security/network.py:1-11 - agent/src/security/workspace_access.py:1-15 - agent/src/security/workspace_policy.py:1-12

章节来源 - agent/src/agent/tools.py:13-95 - agent/src/tools/__init__.py:33-245

核心组件

关键要点 - 新增工具只需在 src/tools/ 下创建继承 BaseTool 的类,并确保 name 非空即可被自动发现。 - 可通过重写 check_available() 控制工具是否可用(例如缺少依赖时返回 False)。 - execute() 必须返回 JSON 字符串,错误路径也需以 JSON 形式返回,便于上层统一处理。

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

架构总览

下图展示了从 LLM 调用到工具执行的完整流程,包括参数校验、安全沙箱检查与结果封装。

sequenceDiagram participant LLM as "大模型" participant Reg as "ToolRegistry" participant Tool as "具体工具(BaseTool)" participant Sec as "安全能力(网络/路径)" participant FS as "文件系统" LLM->>Reg : "执行工具(name, params)" Reg->>Reg : "查找工具实例" Reg->>Tool : "execute(**params)" Tool->>Sec : "校验参数/路径/网络目标" Sec-->>Tool : "允许或拒绝" Tool->>FS : "读取/写入文件(受限于白名单)" FS-->>Tool : "数据/错误" Tool-->>Reg : "JSON 结果(ok/error)" Reg-->>LLM : "标准化响应"

图表来源 - agent/src/agent/tools.py:72-84 - agent/src/tools/read_file_tool.py:33-118 - agent/src/tools/write_file_tool.py:30-107 - agent/src/security/network.py:1-11 - agent/src/security/workspace_policy.py:1-12

详细组件分析

BaseTool 与 ToolRegistry

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 ToolRegistry { -_tools : dict +register(tool) void +get(name) BaseTool +get_definitions() list +execute(name, params) string +tool_names : list } ToolRegistry --> BaseTool : "管理/执行"

图表来源 - agent/src/agent/tools.py:13-95

章节来源 - agent/src/agent/tools.py:13-95

工具自动发现与注册

flowchart TD Start(["开始"]) --> Scan["扫描 src/tools 模块"] Scan --> Import["导入模块(跳过_)"] Import --> Collect["收集 BaseTool 子类"] Collect --> Build["构建 ToolRegistry"] Build --> ShellPolicy{"包含shell工具?"} ShellPolicy --> |否| SkipShell["跳过bash/background_run/cancel_background"] ShellPolicy --> |是| Continue["继续注册"] SkipShell --> Continue Continue --> MCPServers{"配置了MCP服务器?"} MCPServers --> |否| Done(["完成"]) MCPServers --> |是| AddMCP["添加MCP工具包装器"] AddMCP --> Done

图表来源 - agent/src/tools/__init__.py:33-63 - agent/src/tools/__init__.py:66-245

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

文件系统工具:读与写

flowchart TD RStart(["read_file 入口"]) --> Parse["解析 path/limit/run_dir"] Parse --> Roots["计算允许根目录(run_dir/skills/extra)"] Roots --> TryPaths["尝试候选路径(含去前缀)"] TryPaths --> Found{"找到文件?"} Found --> |否| ErrNotFound["返回错误: 未找到或越权"] Found --> |是| Read["读取文本内容"] Read --> Limit{"有行限制?"} Limit --> |是| Trunc["截取至 limit 行"] Limit --> |否| Keep["保持全文"] Trunc --> OutputLimit{"超过输出上限?"} Keep --> OutputLimit OutputLimit --> |是| Cut["截断并追加提示"] OutputLimit --> |否| NoCut["不截断"] Cut --> ReturnOK["返回 ok + content"] NoCut --> ReturnOK ErrNotFound --> End(["结束"]) ReturnOK --> End

图表来源 - agent/src/tools/read_file_tool.py:33-118 - agent/src/tools/path_utils.py - agent/src/tools/redaction.py

章节来源 - agent/src/tools/read_file_tool.py:18-118 - agent/src/tools/write_file_tool.py:14-107 - agent/src/tools/path_utils.py - agent/src/tools/redaction.py

安全沙箱机制

graph LR A["工具代码"] --> B["网络校验(validate_url_target/validate_resolved_url)"] A --> C["路径校验(is_path_within/allowed roots)"] B --> D["允许/拒绝网络请求"] C --> E["允许/拒绝文件操作"]

图表来源 - agent/src/security/network.py:1-11 - agent/src/security/workspace_access.py:1-15 - agent/src/security/workspace_policy.py:1-12 - agent/src/tools/read_file_tool.py:33-118 - agent/src/tools/write_file_tool.py:30-107

章节来源 - agent/src/security/network.py:1-11 - agent/src/security/workspace_access.py:1-15 - agent/src/security/workspace_policy.py:1-12

参数验证与错误处理

章节来源 - agent/src/agent/tools.py:72-84 - agent/src/tools/read_file_tool.py:33-118 - agent/src/tools/write_file_tool.py:30-107

依赖关系分析

graph TB Tools["工具实现(read/write)"] --> Infra["BaseTool/ToolRegistry"] Tools --> SecNet["security.network"] Tools --> SecPath["security.workspace_*"] Tests["测试用例"] --> Tools Tests --> Infra

图表来源 - agent/src/agent/tools.py:13-95 - agent/src/tools/read_file_tool.py:18-118 - agent/src/tools/write_file_tool.py:14-107 - agent/src/security/network.py:1-11 - agent/src/security/workspace_access.py:1-15 - agent/src/security/workspace_policy.py:1-12

章节来源 - agent/src/tools/__init__.py:33-245 - agent/src/agent/tools.py:13-95

性能考虑

[本节为通用指导,无需特定文件引用]

故障排查指南

章节来源 - agent/src/agent/tools.py:72-84 - agent/src/tools/read_file_tool.py:33-118 - agent/src/tools/write_file_tool.py:30-107

结论

通过 BaseTool 与 ToolRegistry,Vibe-Trading 提供了可扩展、可发现、安全的工具生态。开发者只需遵循统一契约,即可快速实现从简单到复杂的工具,并通过安全沙箱保障运行环境。配合完善的测试与部署流程,可实现高质量的工具交付与维护。

[本节为总结性内容,无需特定文件引用]

附录

从零到一:自定义工具开发步骤

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

单元测试编写与集成测试策略

章节来源 - agent/tests/test_institutional_holdings_tool.py:1634-1664 - agent/tests/test_file_tool_sandbox_security.py

工具部署与分发

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

常见陷阱与调试技巧

章节来源 - agent/src/agent/tools.py:72-84 - agent/src/tools/read_file_tool.py:33-118 - agent/src/tools/write_file_tool.py:30-107

从简单到复杂:开发案例

[本节为概念性说明,无需特定文件引用]