# Phase 6:工具系统重构(Tool System Refactoring) 日期:2026-04-04 状态:待开始 Demo参考:claw-code-main — tools/, StreamingToolExecutor, toolOrchestration --- ## 1. 阶段目标 建立**分层工具执行架构**,从现有的扁平工具调用进化为具有注册表、编排层、Hook 拦截能力的工具系统。 **与现有系统的区别**: | 现有 | 目标 | |------|------| | Sub-Commander 直接调用 Tools | ToolRegistry → ToolOrchestration → HookExecutor → ToolExecutor → Tools | | 工具集固定 | 工具注册表支持动态注册 | | 无流式工具执行 | StreamingToolExecutor 支持流式 | | 无工具拦截 | PreTool/PostTool Hook 机制 | --- ## 2. 架构设计 ### 2.1 新的工具执行架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ Agent / Sub-Commander │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ ToolOrchestration Layer │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ │ │ ToolRegistry│ │HookExecutor │ │ StreamingToolExecutor │ │ │ │ (注册表) │ │ (拦截层) │ │ (流式执行器) │ │ │ └─────────────┘ └─────────────┘ └─────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ ToolExecutor │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Built-in │ │ External │ │ MCP │ │ Plugin │ │ │ │ Tools │ │ Tools │ │ Tools │ │ Tools │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 2.2 核心组件 #### ToolRegistry(工具注册表) ```python # backend/app/agents/tools/registry.py @dataclass class ToolManifest: """工具元数据""" name: str description: str category: ToolCategory parameters: dict # JSON Schema return_schema: dict permission_class: PermissionClass # READ/WRITE/EXTERNAL side_effect_scope: SideEffectScope # NONE/LOCAL_STATE/DB_WRITE/NETWORK requires_confirmation: bool is_streaming: bool = False tags: list[str] = field(default_factory=list) class ToolRegistry: """工具注册表""" def __init__(self): self._tools: dict[str, ToolManifest] = {} self._executors: dict[str, Callable] = {} self._hooks: dict[str, list[HookConfig]] = defaultdict(list) def register( self, manifest: ToolManifest, executor: Callable, hooks: list[HookConfig] | None = None ): """注册工具""" self._tools[manifest.name] = manifest self._executors[manifest.name] = executor if hooks: for hook in hooks: self._hooks[manifest.name].append(hook) def get(self, name: str) -> ToolManifest | None: """获取工具元数据""" return self._tools.get(name) def get_executor(self, name: str) -> Callable | None: """获取工具执行器""" return self._executors.get(name) def list_by_category(self, category: ToolCategory) -> list[ToolManifest]: """按类别列出工具""" return [t for t in self._tools.values() if t.category == category] def list_all(self) -> list[ToolManifest]: """列出所有工具""" return list(self._tools.values()) ``` #### HookExecutor(拦截执行器) ```python # backend/app/agents/tools/hook_executor.py @dataclass class HookConfig: """Hook 配置""" name: str hook_type: HookType # PRE_TOOL_USE / POST_TOOL_USE / TOOL_ERROR / TOOL_SKIP handler: Callable filter_names: list[str] | None = None # 只对特定工具生效,None 表示全部 class HookExecutor: """工具 Hook 执行器""" async def pre_execute(self, tool_name: str, arguments: dict) -> HookResult: """PreToolUse - 工具执行前拦截""" hooks = self._get_hooks(tool_name, HookType.PRE_TOOL_USE) ctx = HookContext( tool_name=tool_name, arguments=arguments, phase=HookPhase.PRE ) for hook in hooks: result = await hook.handler(ctx) if result.action == HookAction.DENY: return HookResult( action=HookAction.DENY, message=result.message, modified_args=None ) elif result.action == HookAction.MODIFY: ctx.arguments = result.modified_args return HookResult(action=HookAction.ALLOW, modified_args=ctx.arguments) async def post_execute( self, tool_name: str, arguments: dict, result: Any ) -> HookResult: """PostToolUse - 工具执行后拦截""" hooks = self._get_hooks(tool_name, HookType.POST_TOOL_USE) ctx = HookContext( tool_name=tool_name, arguments=arguments, result=result, phase=HookPhase.POST ) for hook in hooks: result = await hook.handler(ctx) if result.action == HookAction.MODIFY_RESULT: ctx.result = result.modified_result return HookResult(action=HookAction.CONTINUE, modified_result=ctx.result) ``` #### StreamingToolExecutor(流式工具执行器) ```python # backend/app/agents/tools/streaming_executor.py class StreamingToolExecutor: """流式工具执行器""" async def execute_streaming( self, tool_name: str, arguments: dict, callback: Callable[[dict], Awaitable[None]] ) -> Any: """执行流式工具""" manifest = self.registry.get(tool_name) if not manifest.is_streaming: raise ValueError(f"Tool {tool_name} does not support streaming") executor = self.registry.get_executor(tool_name) # 使用 aiterator 进行流式执行 async for chunk in executor(**arguments): event = {"type": "chunk", "data": chunk} await callback(event) yield chunk final_event = {"type": "done", "tool": tool_name} await callback(final_event) ``` --- ## 3. 新增工具集 ### 3.1 文件操作工具 | 工具 | 描述 | 权限级别 | |------|------|---------| | GlobTool | 按模式匹配文件 | READ | | GrepTool | 在文件中搜索内容 | READ | | LintTool | 代码检查 | READ | | EditTool | 编辑文件 | WRITE | ### 3.2 开发工具 | 工具 | 描述 | 权限级别 | |------|------|---------| | LSPTool | Language Server Protocol | READ | | BashTool | 执行 Bash 命令 | EXTERNAL | | PowerShellTool | 执行 PowerShell | EXTERNAL | ### 3.3 系统工具 | 工具 | 描述 | 权限级别 | |------|------|---------| | ScheduleCronTool | Cron 定时任务 | WRITE | | ProcessTool | 进程管理 | EXTERNAL | ### 3.4 协作工具 | 工具 | 描述 | 权限级别 | |------|------|---------| | TeamAgentTool | 团队 Agent 协作 | EXTERNAL | | TaskBroadcastTool | 任务广播 | WRITE | ### 3.5 高级工具 | 工具 | 描述 | 权限级别 | |------|------|---------| | RemoteTriggerTool | 远程触发 | EXTERNAL | | MCPClientTool | MCP 客户端 | EXTERNAL | | AskUserQuestionTool | 向用户提问 | READ | --- ## 4. 文件结构变化 ``` backend/app/agents/tools/ ├── __init__.py # 现有 - 需重构 ├── registry.py # 新增 - 工具注册表 ├── manifest.py # 新增 - 工具元数据 ├── hook_executor.py # 新增 - Hook 执行器 ├── hook_config.py # 新增 - Hook 配置 ├── streaming_executor.py # 新增 - 流式执行器 ├── base.py # 新增 - 基础工具类 │ ├── builtins/ # 新增 - 内置工具 │ ├── __init__.py │ ├── file_tools.py # Glob, Grep, Edit, Lint │ ├── system_tools.py # Bash, PowerShell, Cron │ ├── dev_tools.py # LSP, Git │ └── collaboration_tools.py # Team, Broadcast │ ├── task.py # 现有 - 保留 ├── schedule.py # 现有 - 保留 ├── search.py # 现有 - 保留 ├── forum.py # 现有 - 保留 └── time_reasoning.py # 现有 - 保留 ``` --- ## 5. 迁移计划 ### 阶段 6.1:基础设施(1-2周) - 创建 ToolRegistry 类 - 创建 ToolManifest 数据类 - 迁移现有工具到注册表 ### 阶段 6.2:Hook 系统(2-3周) - 创建 HookExecutor - 实现 PreTool/PostTool 机制 - 添加内置 Hook(确认危险操作、日志记录) ### 阶段 6.3:流式执行(1-2周) - 实现 StreamingToolExecutor - 为支持流式的工具添加 streaming 标志 - 更新 AgentService 集成 ### 阶段 6.4:新工具集(2-3周) - 实现新增的工具类 - 添加完整的工具文档 - 单元测试覆盖 --- ## 6. 验收标准 | 检查点 | 标准 | |--------|------| | 工具注册 | 所有现有工具已在 Registry 中注册 | | Hook 执行 | PreTool/PostTool Hook 能正确拦截 | | 流式执行 | 标记为 streaming 的工具可流式返回 | | 新工具 | 新增工具集中每个工具可正常执行 | | 向后兼容 | 现有 Sub-Commander 工具调用不受影响 | --- ## 7. Demo 借鉴 | claw-code 实现 | Jarvis 对应 | |----------------|------------| | `src/tools/` | `backend/app/agents/tools/` | | `StreamingToolExecutor.ts` | `streaming_executor.py` | | `toolExecution.ts` | `hook_executor.py` | | `toolHooks.ts` | `hook_config.py` | | `ToolManifest` | `manifest.py` |