# Tool Agent 设计文档 ## 1. 概述 - 项目名称:tool_agent - 目标:可自动封装、接入、部署、编写工具的 Agent + 工具库系统 - 目标用户:其他 Agent 系统(作为工具供应商) ## 2. 系统架构 tool_agent 由三个核心角色协作: ``` ┌─────────────────────────────────────────────────────────┐ │ RouterAgent(常驻) │ │ main 启动时即运行,负责: │ │ - 对外接口(FastAPI: /health, /tools, /run_tool, /chat)│ │ - CodingAgent 调度(接收任务书 → 创建工具) │ │ - 工具注册表 + 状态管理 │ │ - 全局状态监控(工具/CodingAgent/ServiceAgent 窗口) │ ├─────────────────────────────────────────────────────────┤ │ ServiceAgent(按需创建) │ │ 每个 chat_id 对应一个独立对话 session: │ │ - 只读查询工具表、工具组、后端运行时、状态 │ │ - 与外部 Agent 交流,解答工具使用问题 │ │ - 撰写任务书 → 提交给 RouterAgent │ │ - 一个实例,多个 chat_id 窗口并发 │ ├─────────────────────────────────────────────────────────┤ │ CodingAgent(按需唤醒) │ │ 接收 RouterAgent 的任务书: │ │ - 自主编码、测试、部署工具 │ │ - 注册工具到 Registry │ └─────────────────────────────────────────────────────────┘ ``` ### 2.1 调用层与后端执行环境 所有工具对外统一为 **本地 Python/FastAPI 调用层**(uv 管理), 内部后端执行环境(backend_runtime)分三类: ``` 外部调用者(其他 Agent / HTTP 客户端) │ ▼ 统一调用层(本地 Python + FastAPI HTTP 接口) │ ├─ backend_runtime: local → 本地 Python 运行时(纯 uv 子进程) ├─ backend_runtime: docker → Docker 容器运行时 └─ backend_runtime: remote → 远程 API / 云端服务 ``` ### 2.2 消息流 ``` 外部 Agent │ ├─ IM 消息 ──→ IMClient ──→ ChatWindow(chat_id) ──→ SessionManager ──→ ServiceAgent │ │ ├─ HTTP /chat ─────────────────────────────────────→ SessionManager ──→ ServiceAgent │ │ │ 需要创建工具时: │ │ submit_task() ────→ RouterAgent │ │ │ CodingAgent │ │ └─ HTTP /run_tool ──→ Dispatcher ──→ 工具进程 ←── 注册完成 ←──────────────┘ ``` ### 2.3 工具组(Tool Group) 需要固定配合使用的工具组成工具组,定义在 `data/groups.json`。 例如 RunComfy 生命周期管理组:launch → run → stop。 ## 3. 三层架构 ``` 外部 Agent 请求 │ ▼ ┌─────────────────────────────────────┐ │ 注册层 (Registry) │ │ - 工具元数据 CRUD (registry.json) │ │ - 工具组管理 (groups.json) │ │ - 按类别/关键字/后端运行时搜索 │ └──────────────┬──────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ 路由层 (Router) — 兼任对外网关 │ │ - FastAPI 对外接口 │ │ - 来源管理 (SourceStore) │ │ - 工具启停 (ToolStatusManager) │ │ - 请求分发 (Dispatcher) │ │ - CodingAgent 调度 │ │ - 全局状态监控 │ └──────────────┬──────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ 运行层 (Runtime) │ │ - LocalRunner (uv 本地进程) │ │ - DockerRunner (Docker 容器) │ │ - 远程 API 直接转发 │ └─────────────────────────────────────┘ ``` ## 4. 对外接口 仅暴露 4 个 HTTP 接口: | 接口 | 方法 | 说明 | |------|------|------| | `/health` | GET | 健康检查 | | `/tools` | GET | 完整工具表(含后端分类、工具组、运行状态) | | `/run_tool` | POST | 调用工具 `{tool_id, params}` | | `/chat` | POST | 与 ServiceAgent 对话 `{message, chat_id}` | ### 4.1 /tools 响应示例 ```json { "backend_runtimes": [ {"backend_runtime": "local", "name": "本地 Python 运行时", "tool_count": 5}, {"backend_runtime": "docker", "name": "Docker 容器运行时", "tool_count": 0}, {"backend_runtime": "remote", "name": "远程 API / 云端服务", "tool_count": 0} ], "groups": [ { "group_id": "runcomfy_lifecycle", "name": "RunComfy 生命周期管理", "tool_ids": ["launch_comfy_env", "runcomfy_workflow_executor", "runcomfy_stop_env"], "usage_order": ["launch_comfy_env", "runcomfy_workflow_executor", "runcomfy_stop_env"] } ], "tools": [ { "tool_id": "image_stitcher", "name": "图片拼接工具", "category": "cv", "backend_runtime": "local", "group_ids": [], "state": "stopped" } ] } ``` ### 4.2 /chat 请求/响应 ```json // 请求 {"message": "有哪些图片处理工具?", "chat_id": "user_A_window_1"} // 响应 {"response": "当前有 image_stitcher...", "chat_id": "user_A_window_1"} ``` ## 5. 内部通信 ### 5.1 来源类型(SourceType) | SourceType | 说明 | 通信方式 | | ---------- | ----------------------- | ----------------------------------- | | `local` | 本地 uv 项目 | `uv run` 启动 HTTP 服务,httpx 调用 | | `docker` | Docker 容器 | 端口映射 HTTP | | `remote` | 远程 API / 云端服务 | 直接转发 HTTP | ### 5.2 请求分发流程 ``` POST /run_tool {tool_id, params} │ ▼ ToolStatusManager.get_status(tool_id) │ 未运行? ▼ ToolStatusManager.start_tool(tool_id) ├─ local: uv run python main.py --port {free_port} ├─ docker: 检查容器端口映射 └─ remote: 直接标记 running │ ▼ Dispatcher.dispatch(tool_id, params) → httpx.post("http://127.0.0.1:{port}{endpoint_path}", json=params) │ ▼ 返回结果 ``` ### 5.3 端口分配 ``` 对外(固定): 8001 - FastAPI 对内(动态): uv 本地工具 - 随机空闲端口(socket bind 0) Docker 工具 - 容器内部端口映射 远程工具 - 无需端口,直接转发 ``` ## 6. Agent 角色详解 ### 6.1 RouterAgent 常驻进程,main 启动时即运行。 **职责**: - 管理工具注册表(Registry)和状态表(ToolStatusManager) - 调度 CodingAgent 执行工具创建任务 - 监控全局状态(工具、CodingAgent 任务、ServiceAgent 窗口) - 对外暴露 FastAPI 接口 **全局状态查询** (`router.get_system_status()`): ```json { "tools": {"total": 5, "active": 5}, "coding_agent": { "running_count": 1, "running_task_ids": ["create_a1b2c3d4"], "queued_count": 0, "recent_tasks": [ {"task_id": "create_a1b2c3d4", "status": "pending", "task_spec": "..."} ] }, "service_agent": { "total_windows": 3, "im_connected": true, "windows": [ {"chat_id": "user_A_w1", "sdk_session_id": "...", "has_im_window": true} ] } } ``` ### 6.2 ServiceAgent 按需创建,一个实例管理多个 chat_id 窗口。 **职责**: - 只读查询工具表、工具组、后端运行时、工具状态 - 与外部 Agent 对话,解答工具使用问题 - 撰写任务书提交给 RouterAgent **工具列表**(6 个): | 工具 | 权限 | 说明 | |------|------|------| | `list_tools` | 读 | 列出所有工具 | | `get_tool_details` | 读 | 查看工具详情(参数、Schema) | | `list_groups` | 读 | 列出工具组及使用顺序 | | `list_backend_runtimes` | 读 | 列出后端执行环境类型 | | `check_task_status` | 读 | 查询任务进度 | | `submit_task` | 写 | 撰写任务书提交给 RouterAgent | **会话管理**: - SessionManager 按 chat_id 管理 Claude SDK session - 每个 chat_id 独立的对话记忆(通过 SDK resume 机制) - 同一个 ServiceAgent 实例并发处理多个窗口 ### 6.3 CodingAgent 按需唤醒,接收 RouterAgent 的任务书。 **工具列表**(10 个): | 分类 | 工具 | 说明 | | ------ | ---------------------- | --------------------------------- | | Docker | `create_docker_env` | 创建容器(端口映射/挂载/GPU) | | Docker | `run_in_docker` | 容器内执行命令(前台/后台) | | Docker | `rebuild_docker_ports` | 重建容器加端口映射 | | Docker | `destroy_docker_env` | 销毁容器 | | uv | `create_uv_project` | 创建 uv 项目 | | uv | `run_in_uv` | 在 uv 环境中运行命令 | | uv | `uv_add_dependency` | 添加依赖 | | 文件 | `write_file` | 写文件(overwrite/append) | | 文件 | `read_file` | 读文件 | | 注册 | `register_tool` | 注册工具到 Registry | ## 7. IM Client 接入 ### 7.1 架构 ``` IM Server (WebSocket, port 8000) ↕ IMClient (单 WebSocket 连接,contact_id="tool_agent") ├─ ChatWindow(chat_id_1) ──→ SessionManager ──→ ServiceAgent session_1 ├─ ChatWindow(chat_id_2) ──→ SessionManager ──→ ServiceAgent session_2 └─ ChatWindow(chat_id_3) ──→ SessionManager ──→ ServiceAgent session_3 ``` ### 7.2 消息路由 - 外部 Agent 发送消息时指定 `receiver_chat_id`,定向到对应窗口 - 未指定 `receiver_chat_id` 时广播到所有窗口 - 回复时带上 `receiver_chat_id = sender_chat_id`,消息回到对方窗口 ### 7.3 并发模型 - 一个 IMClient 实例管理多个 ChatWindow - 每个 ChatWindow 有独立的 `pending.json` / `chatbox.jsonl` - SessionManager 收到通知后,按 chat_id 路由到对应 ServiceAgent session - 同一个 ServiceAgent 实例并发处理,Claude SDK session 隔离对话记忆 ## 8. 数据模型 ### 8.1 ToolMeta(工具元数据) ```json { "tool_id": "image_stitcher", "name": "图片拼接工具", "description": "将多张图片拼接成一张", "category": "cv", "backend_runtime": "local", "group_ids": [], "input_schema": {}, "output_schema": {}, "stream_support": false, "status": "active" } ``` ### 8.2 ToolSource(工具来源) ```json { "type": "local", "host_dir": "tools/local/image_stitcher", "endpoint_path": "/", "http_method": "POST", "internal_port": 0 } ``` ### 8.3 ToolRoute(运行状态) ```json { "tool_id": "image_stitcher", "sources": [{"type": "local", "host_dir": "..."}], "active_source": 0, "state": "running", "pid": 12345, "port": 52341 } ``` ### 8.4 BackendRuntime(后端执行环境枚举) | 值 | 说明 | |----|------| | `local` | 本地 Python 运行时(纯 uv 子进程) | | `docker` | Docker 容器运行时 | | `remote` | 远程 API / 云端服务 | ### 8.5 ToolGroup(工具组) ```json { "group_id": "runcomfy_lifecycle", "name": "RunComfy 生命周期管理", "description": "云端 ComfyUI 环境的完整生命周期", "category": "remote", "tool_ids": ["launch_comfy_env", "runcomfy_workflow_executor", "runcomfy_stop_env"], "usage_order": ["launch_comfy_env", "runcomfy_workflow_executor", "runcomfy_stop_env"], "usage_example": "先 launch 获取 server_id,再 run 执行 workflow,最后 stop 释放资源" } ``` ## 9. 目录结构 ``` src/ ├── tool_agent/ │ ├── __main__.py # 入口:启动 Router + SessionManager + IM │ ├── config.py # 全局配置 │ ├── models.py # 数据模型(ToolMeta, BackendRuntime 等) │ ├── router/ │ │ ├── agent.py # RouterAgent(常驻,调度 CodingAgent) │ │ ├── server.py # FastAPI 接口定义 │ │ ├── dispatcher.py # 请求分发 │ │ └── status.py # 工具状态管理 + 来源存储 │ ├── service/ │ │ ├── agent.py # ServiceAgent(只读客服 + 任务书提交) │ │ └── session.py # SessionManager(chat_id 会话管理 + IM 接入) │ ├── registry/ │ │ ├── registry.py # 工具注册表 │ │ └── groups.py # 工具组管理 │ ├── tool/ │ │ └── agent.py # CodingAgent(自主编码部署) │ └── runtime/ │ └── local_runner.py # 本地 uv 运行器 ├── im-client/ # IM 通信客户端(独立模块) │ ├── client.py # IMClient + ChatWindow │ ├── protocol.py # 消息协议 │ ├── notifier.py # 通知接口 │ └── tools.py # Agent 工具函数封装 data/ ├── registry.json # 工具注册表 ├── sources.json # 工具来源 └── groups.json # 工具组配置 ``` ## 10. 启动流程 ```python async def main(): router = Router() # RouterAgent 初始化 session_mgr = SessionManager(router) # 会话管理 router.set_session_manager(session_mgr) # 双向引用 router.create_app(session_manager=session_mgr) await session_mgr.start_im("tool_agent", "ws://localhost:8000") # IM 连接(可选) await router.start(port=8001) # FastAPI 启动 ``` 启动命令:`uv run python -m tool_agent` ## 11. KnowHub 工具表集成 ### 11.1 双向索引架构 Tool Agent 与 KnowHub 工具表通过双向索引互相关联: ``` Tool Agent Registry KnowHub 工具表 ┌─────────────────────┐ ┌──────────────────────────┐ │ tool_id: launch_env │◄────────│ id: tools/image_gen/ │ │ tool_slug_ids: │ │ comfyui │ │ ["comfyui"] │────────►│ toolhub_items: │ │ │ │ [{launch_env: "..."}, │ │ group_ids: │ │ {runcomfy_group: ...}]│ │ ["runcomfy_group"]│ └──────────────────────────┘ └─────────────────────┘ ``` **字段说明**: - `tool_slug_ids: list[str]` - Tool Agent 工具关联的 KnowHub tool_slug 列表 - `toolhub_items: list[dict]` - KnowHub 工具关联的 Tool Agent 工具/组列表 ### 11.2 智能匹配机制 Router Agent 在 CodingAgent 注册完工具后,自动执行智能匹配: **匹配规则**: 1. 工具名称/ID 包含 KnowHub 的 slug 或 title 2. 工具描述包含 KnowHub 描述的关键词 3. 分类匹配 **自动更新流程**: ```python # router/agent.py:_sync_knowhub_after_register() 1. 遍历所有 registry 工具 2. 调用 _match_knowhub_tools() 智能匹配 3. 更新 registry.tool_slug_ids 4. 收集工具和组,更新 KnowHub.toolhub_items 5. 点亮 KnowHub 工具 status="已接入" ``` **相关文件**: - `src/tool_agent/models.py:58` - ToolMeta.tool_slug_ids 字段定义 - `src/tool_agent/router/agent.py:115-217` - 智能匹配和同步逻辑 - `src/tool_agent/tool_table.py` - KnowHub API 客户端 - `docs/tool_table/tool-table-integration.md` - 详细集成文档 ## 12. 里程碑 | 阶段 | 内容 | 状态 | | ------- | ---------------------------------------------- | --------- | | Phase 1 | Router + Registry + FastAPI + CodingAgent | ✅ 已完成 | | Phase 2 | LocalRunner + DockerRunner + 请求分发 | ✅ 已完成 | | Phase 3 | 工具分类 + 工具组 + BackendRuntime 语义统一 | ✅ 已完成 | | Phase 4 | ServiceAgent + SessionManager + IM Client 接入 | ✅ 已完成 | | Phase 5 | KnowHub 工具表集成 + 智能匹配 | ✅ 已完成 | | Phase 6 | 冷热调度集成 + 健康检查集成 | 🔲 待集成 | | Phase 7 | 中间件集成(鉴权/缓存/计量) | 🔲 待集成 | | Phase 8 | 自修复 + Browser-Use + 财务管理 | 🔲 待实现 |