系统工具

📎 引用文件

本文引用的文件 - agent/src/tools/__init__.py - agent/src/tools/bash_tool.py - agent/src/tools/background_tools.py - agent/src/tools/read_file_tool.py - agent/src/tools/write_file_tool.py - agent/src/tools/edit_file_tool.py - agent/src/tools/path_utils.py - agent/src/tools/_shell_safety.py - agent/src/security/workspace_policy.py - agent/src/security/workspace_access.py

目录

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

简介

本章节面向 Vibe-Trading 的“系统工具”能力,聚焦以下目标: - 命令行执行、文件编辑与读写、后台任务管理等核心功能的使用与安全机制。 - 系统命令的安全沙箱与权限控制策略,确保 LLM 驱动的工具调用在受控范围内运行。 - 后台任务的调度机制、资源限制(超时、输出截断)与取消流程。 - 错误处理与日志记录模式,便于定位问题与审计。 - 通过系统工具扩展 Vibe-Trading 的能力边界(例如结合 MCP 工具、工作区路径白名单等)。

项目结构

系统工具以“工具注册表 + 具体工具实现 + 安全/路径校验”的分层组织: - 工具注册与发现:自动扫描 src/tools 下的 BaseTool 子类并注册,支持按名称过滤、MCP 工具合并、Shell 工具开关。 - 具体工具:bash、read_file、write_file、edit_file、background_run/check_background/cancel_background。 - 安全与路径:统一的路径白名单、UNC 拒绝、run_dir 隔离、写操作根目录限制;Shell 命令的广杀 Python 进程拦截。 - 安全策略兼容:为通道适配器提供 workspace 范围检查的兼容接口。

graph TB A["工具注册中心<br/>src/tools/__init__.py"] --> B["文件系统工具<br/>read/write/edit"] A --> C["命令执行工具<br/>bash"] A --> D["后台任务工具<br/>background_run / check / cancel"] B --> E["路径安全与白名单<br/>path_utils.py"] C --> F["Shell 安全拦截<br/>_shell_safety.py"] D --> F E --> G["工作区策略兼容<br/>security/*"]

图表来源 - agent/src/tools/__init__.py:66-245 - agent/src/tools/read_file_tool.py:1-118 - agent/src/tools/write_file_tool.py:1-107 - agent/src/tools/edit_file_tool.py:1-98 - agent/src/tools/bash_tool.py:1-84 - agent/src/tools/background_tools.py:1-377 - agent/src/tools/path_utils.py:1-404 - agent/src/tools/_shell_safety.py:1-60 - agent/src/security/workspace_policy.py:1-12

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

核心组件

章节来源 - agent/src/tools/__init__.py:66-245 - agent/src/tools/read_file_tool.py:1-118 - agent/src/tools/write_file_tool.py:1-107 - agent/src/tools/edit_file_tool.py:1-98 - agent/src/tools/bash_tool.py:1-84 - agent/src/tools/background_tools.py:1-377

架构总览

系统工具围绕“工具注册表”组织,所有工具继承自 BaseTool,具备统一的参数描述、可重复性标记与只读标记。注册阶段根据配置决定是否启用 Shell 工具、是否注入会话 ID、是否附加 MCP 工具。文件与命令执行均通过安全层进行约束,后台任务通过进程组管理实现可控的生命周期。

sequenceDiagram participant Caller as "调用方" participant Registry as "工具注册表" participant Tool as "具体工具" participant Safety as "安全/路径层" participant OS as "操作系统" Caller->>Registry : 请求执行某工具 Registry->>Tool : 构造并调用 execute() alt 文件类工具 Tool->>Safety : 解析/校验路径(白名单/隔离) Safety-->>Tool : 安全路径或抛出异常 Tool->>OS : 读取/写入/编辑文件 OS-->>Tool : 结果 else 命令执行 Tool->>Safety : 检查命令安全性(防广杀) Safety-->>Tool : 允许或拒绝 Tool->>OS : 子进程执行(shell) OS-->>Tool : stdout/stderr/退出码 end Tool-->>Caller : JSON 结果(含状态/错误信息)

图表来源 - agent/src/tools/__init__.py:66-245 - agent/src/tools/read_file_tool.py:33-118 - agent/src/tools/write_file_tool.py:30-107 - agent/src/tools/edit_file_tool.py:31-98 - agent/src/tools/bash_tool.py:36-84 - agent/src/tools/path_utils.py:185-240 - agent/src/tools/_shell_safety.py:38-60

详细组件分析

Bash 工具(命令行执行)

flowchart TD Start(["进入 execute"]) --> CheckCmd["检查命令安全性"] CheckCmd --> |拒绝| ReturnErr["返回错误(JSON)"] CheckCmd --> |允许| RunProc["subprocess.run(command, cwd=run_dir)"] RunProc --> Timeout{"是否超时?"} Timeout --> |是| ReturnTO["返回超时错误(JSON)"] Timeout --> |否| Truncate["截断 stdout/stderr"] Truncate --> BuildRes["组装 JSON 结果"] BuildRes --> End(["返回结果"])

图表来源 - agent/src/tools/bash_tool.py:36-84 - agent/src/tools/_shell_safety.py:38-60

章节来源 - agent/src/tools/bash_tool.py:1-84 - agent/src/tools/_shell_safety.py:1-60

文件读取工具(read_file)

flowchart TD S(["进入 execute"]) --> Roots["计算 allowed_roots<br/>run_dir/skills/环境变量"] Roots --> TryPaths["尝试 path 与去前缀 skills/ 的候选"] TryPaths --> Found{"找到合法路径?"} Found --> |否| ErrNotFound["返回未找到/越界错误"] Found --> |是| Read["读取内容"] Read --> Limit{"是否设置 limit?"} Limit --> |是| Slice["截取前 N 行"] Limit --> |否| KeepAll["保留全部"] Slice --> Trunc["按最大字符数截断"] KeepAll --> Trunc Trunc --> Ret["返回 JSON(状态/路径/内容)"]

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

章节来源 - agent/src/tools/read_file_tool.py:1-118 - agent/src/tools/path_utils.py:1-404

文件写入工具(write_file)

flowchart TD S(["进入 execute"]) --> Normalize["归一化 path/content 键"] Normalize --> Resolve["resolve_safe_path(run_dir, allowed_write_roots)"] Resolve --> |失败| ErrPath["返回路径错误(JSON)"] Resolve --> |成功| Mkdir["mkdir(parents=True)"] Mkdir --> Write["write_text(content)"] Write --> Ret["返回 JSON(状态/路径/bytes_written)"]

图表来源 - agent/src/tools/write_file_tool.py:30-107 - agent/src/tools/path_utils.py:150-182 - agent/src/tools/path_utils.py:185-240

章节来源 - agent/src/tools/write_file_tool.py:1-107 - agent/src/tools/path_utils.py:1-404

文件编辑工具(edit_file)

flowchart TD S(["进入 execute"]) --> Resolve["resolve_safe_path(write)"] Resolve --> Exists{"文件存在?"} Exists --> |否| ErrFile["返回文件不存在错误"] Exists --> |是| Read["读取内容"] Read --> Find{"old_text 存在?"} Find --> |否| ErrText["返回 old_text 未找到错误"] Find --> |是| Replace["replace(old_text, new_text, count=1)"] Replace --> Write["写回文件"] Write --> Ret["返回 JSON(状态/路径/消息)"]

图表来源 - agent/src/tools/edit_file_tool.py:31-98 - agent/src/tools/path_utils.py:150-182

章节来源 - agent/src/tools/edit_file_tool.py:1-98 - agent/src/tools/path_utils.py:1-404

后台任务管理(background_run / check_background / cancel_background)

sequenceDiagram participant Client as "调用方" participant BG as "BackgroundManager" participant Proc as "子进程" Client->>BG : background_run(command) BG->>BG : 生成task_id/记录任务 BG->>Proc : Popen(shell, 新会话/进程组) Proc-->>BG : communicate(timeout) alt 正常完成 BG->>BG : 记录completed/exit_code else 超时 BG->>Proc : 终止进程树(SIGTERM/SIGKILL或taskkill) BG->>BG : 记录timeout end Client->>BG : check_background(task_id?) BG-->>Client : 状态/耗时/剩余时间/结果摘要 Client->>BG : cancel_background(task_id) BG->>Proc : 安全终止(进程组) BG-->>Client : 取消结果

图表来源 - agent/src/tools/background_tools.py:24-96 - agent/src/tools/background_tools.py:102-319 - agent/src/tools/background_tools.py:322-377

章节来源 - agent/src/tools/background_tools.py:1-377

安全沙箱与权限控制

classDiagram class PathUtils { +safe_path(p, workdir) Path +safe_user_path(p) Path +safe_document_path(p) Path +safe_run_dir(p) Path +resolve_safe_path(file_path, run_dir, allowed_roots, purpose) Path +allowed_file_roots() Path[] +allowed_write_roots() Path[] } class ShellSafety { +broad_python_kill_error(command) str? } class WorkspacePolicy { +is_path_within(path) bool } PathUtils <.. WorkspacePolicy : "被复用" ShellSafety <.. BashTool : "被调用" PathUtils <.. ReadFileTool : "被调用" PathUtils <.. WriteFileTool : "被调用" PathUtils <.. EditFileTool : "被调用"

图表来源 - agent/src/tools/path_utils.py:46-74 - agent/src/tools/path_utils.py:137-182 - agent/src/tools/path_utils.py:185-240 - agent/src/tools/path_utils.py:243-369 - agent/src/tools/_shell_safety.py:38-60 - agent/src/security/workspace_policy.py:1-12

章节来源 - agent/src/tools/path_utils.py:1-404 - agent/src/tools/_shell_safety.py:1-60 - agent/src/security/workspace_policy.py:1-12 - agent/src/security/workspace_access.py:1-15

依赖关系分析

graph LR Reg["工具注册表"] --> RFT["read_file"] Reg --> WFT["write_file"] Reg --> EFT["edit_file"] Reg --> BT["bash"] Reg --> BRT["background_run"] Reg --> CB["check_background"] Reg --> CBT["cancel_background"] RFT --> PU["path_utils"] WFT --> PU EFT --> PU BT --> SS["_shell_safety"] BRT --> SS BRT --> PG["进程组/超时/通知"]

图表来源 - agent/src/tools/__init__.py:66-245 - agent/src/tools/read_file_tool.py:1-118 - agent/src/tools/write_file_tool.py:1-107 - agent/src/tools/edit_file_tool.py:1-98 - agent/src/tools/bash_tool.py:1-84 - agent/src/tools/background_tools.py:1-377 - agent/src/tools/path_utils.py:1-404 - agent/src/tools/_shell_safety.py:1-60

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

性能考量

[本节为通用性能建议,不直接分析具体文件]

故障排查指南

章节来源 - agent/src/tools/__init__.py:136-153 - agent/src/tools/background_tools.py:141-204 - agent/src/tools/background_tools.py:258-311

结论

Vibe-Trading 的系统工具通过严格的沙箱与权限控制,为 LLM 驱动的自动化提供了安全的执行环境: - 文件操作限定在工作区与白名单根目录,避免任意路径写入风险。 - 命令执行具备超时与输出限制,并拦截危险的广杀 Python 进程命令。 - 后台任务提供进程组级别的生命周期管理与安全终止,保障资源回收。 - 工具注册表支持按需启用 Shell 工具与合并 MCP 工具,灵活扩展能力边界。 建议在生产环境中: - 明确配置 allowed_*_roots,最小化暴露面。 - 谨慎启用 include_shell_tools,仅在可信 CLI 场景开启。 - 使用 cancel_background 而非外部命令终止任务,确保进程组完整回收。

[本节为总结性内容,不直接分析具体文件]

附录

[本节为补充说明,不直接分析具体文件]