# 工具参考文档 / Tools Reference Flyto Agent Engine 内置 19 个工具的完整参考(项目共 129 个源文件,911 个测试函数). ## 目录 - [工具接口](#工具接口) - [内置工具](#内置工具) - [Bash](#bash) - [Read](#read) - [Edit](#edit) - [Write](#write) - [Glob](#glob) - [Grep](#grep) - [WebFetch](#webfetch) - [WebSearch](#websearch) - [Agent](#agent) - [TaskCreate / TaskList / TaskUpdate](#task-工具) - [ToolSearch](#toolsearch) - [Gitignore](#gitignore) - [自定义工具](#自定义工具) - [工具编排](#工具编排) - [工具延迟加载](#工具延迟加载) ## 工具接口 所有工具实现 `tools.Tool` 接口: ```go type Tool interface { Name() string Description(ctx context.Context) string InputSchema() json.RawMessage Execute(ctx context.Context, input json.RawMessage, progress ProgressFunc) (*Result, error) } ``` 可选的元数据接口: ```go type MetadataProvider interface { Metadata() Metadata } type Metadata struct { ConcurrencySafe bool // 是否可与其他工具并行执行 ReadOnly bool // 是否只读 Destructive bool // 是否可能造成不可逆破坏 Aliases []string // 别名 SearchHint string // 延迟加载搜索提示词 } ``` 执行结果: ```go type Result struct { Output string // 文本输出 IsError bool // 是否为错误 Data interface{} // 结构化数据(可选) UndoInfo *UndoInfo // 撤销信息(由 Reversible 工具填充) } ``` ### 安全能力接口(可选) ```go // 能力声明 type CapabilityProvider interface { Capability() ToolCapability } // 模拟执行(不产生副作用) type DryRunnable interface { DryRun(ctx context.Context, input json.RawMessage) (*DryRunResult, error) } // 可撤销(生成补偿操作) type Reversible interface { GenerateUndo(ctx context.Context, input json.RawMessage, result *Result) (*UndoInfo, error) } ``` 安全等级:Level 0(无能力)→ Level 1(Reversible)→ Level 2(DryRun + Reversible). --- ## 内置工具 ### Bash 在 shell 中执行命令.支持 AST 解析,命令分类,后台执行,进程组管理. | 属性 | 值 | |------|-----| | Name | `Bash` | | ConcurrencySafe | `false` | | ReadOnly | `false` | | Destructive | `true` | | SearchHint | `shell command execute terminal` | **输入参数 / Input Schema:** ```json { "type": "object", "properties": { "command": { "type": "string", "description": "The bash command to execute" }, "timeout": { "type": "integer", "description": "Timeout in milliseconds (default 120000, max 600000)" }, "run_in_background": { "type": "boolean", "description": "Run the command in the background and return a task_id immediately" }, "description": { "type": "string", "description": "A description of what this command does" } }, "required": ["command"] } ``` **AST 解析能力:** 命令在权限检查前经过 `internal/bash/` 包的完整 AST 解析,支持: | 语法特性 | 示例 | |----------|------| | Heredoc(3 种变体) | `<(cmd)` | | 算术展开 | `$((expr))` -- 正确区分 `<<` 是位移还是 heredoc | | 管道和列表 | `cmd1 \| cmd2`, `cmd1 && cmd2 \|\| cmd3` | | 环境变量前缀 | `VAR=value command` -- 识别真正的命令名 | | 控制结构 | `if/for/while/case/function` | | 重定向 | `>`, `>>`, `<`, `2>&1` + 静态性检测 | AST 解析后,`ExtractCommands()` 递归遍历所有节点提取 `CommandInfo`,包括命令名(跳过 env/sudo/nohup 等前缀),参数,重定向列表,管道位置等. **命令分类(6 类):** | 分类 | 典型命令 | 说明 | |------|---------|------| | `search` | grep, rg, find, ag, fd, locate | 搜索类 | | `read` | cat, head, tail, less, wc, jq, sort | 读取类 | | `list` | ls, tree, du, df, ps, stat | 列表类 | | `write` | (无预定义集合) | 写入类 | | `silent` | mv, cp, rm, mkdir, touch, chmod | 静默操作 | | `general` | 其他所有命令 | 通用 | 管道分类规则:管道中任一命令为 write/general 时,整条管道降级.语义中性命令(echo, printf, test)不影响管道分类. 分类用于:输出截断策略选择,权限提示,UI 展示. **后台执行模式(run_in_background):** 设置 `run_in_background: true` 时: 1. 命令在独立 goroutine 中启动 2. 立即返回 `task_id`(如 `bg_task_1`) 3. 输出实时累积到线程安全的 `BashOutput` 4. 可通过 Task 工具查询状态 5. 支持取消(`CancelBackgroundTask(taskID)`) 6. 超时后自动终止 后台任务集成到 `BackgroundTaskStore`,支持 List/Get/Cancel 操作. **进程组管理:** - 子进程在独立进程组中运行(`Setpgid: true, Pgid: 0`) - 不继承多余文件描述符(`ExtraFiles: nil`) - 过滤敏感环境变量(`ANTHROPIC_API_KEY`,`OPENAI_API_KEY` 等 8 种) - 优雅终止:SIGTERM → 进程组 → 5 秒等待 → SIGKILL → 进程组 → 2 秒等待 **输出截断策略(stdout/stderr 分离):** | 限制 | 值 | |------|-----| | stdout 上限 | 200KB | | stderr 上限 | 56KB | | 总计上限 | 256KB | | 截断头部比例 | 80% | | 截断尾部比例 | 20% | stdout 和 stderr 独立截断,保留头 80% 和尾 20%(保留开头结构和结尾总结).stderr 行带 `[stderr]` 前缀. **二进制检测(magic bytes):** 检测前 512 字节,识别 13 种二进制格式: ELF, PNG, JPEG, PDF, GIF, GZIP, ZIP, TAR, WASM, Mach-O (32/64), BMP, WEBP/RIFF 同时检查 null bytes 和无效 UTF-8.检测到二进制输出时替换为提示信息. **其他特性:** - 超过 5 秒的命令在结果末尾报告耗时 - CJK 字符显示宽度计算(全角字符占 2 列) - 通过 progress 回调实时报告输出行 --- ### Read 读取本地文件内容. | 属性 | 值 | |------|-----| | Name | `Read` | | Aliases | `FileRead` | | ConcurrencySafe | `true` | | ReadOnly | `true` | | Destructive | `false` | **输入参数 / Input Schema:** ```json { "type": "object", "properties": { "file_path": { "type": "string", "description": "The absolute path to the file to read" }, "offset": { "type": "integer", "description": "The line number to start reading from (0-based)", "minimum": 0 }, "limit": { "type": "integer", "description": "The number of lines to read (default 2000)", "minimum": 1 } }, "required": ["file_path"] } ``` **行为特性:** - 文件路径必须是绝对路径 - 默认读取 2000 行 - 输出使用 `cat -n` 格式(行号 + tab + 内容) - 自动检测二进制文件(前 512 字节检查 null bytes) - PDF 文件返回类型和大小提示 - 图片文件(JPEG/PNG/GIF/WebP/TIFF/HEIC/AVIF)自动 EXIF 方向校正后以 base64 返回, 不支持的格式(如 HEIC/TIFF)先转 JPEG 再返回;CGO + libheif 处理 HEIC/AVIF - 空文件返回 "File exists but is empty" - 目录返回错误提示使用 `ls` - 读取结果记录到 FileStateCache(用于检测外部修改) --- ### Edit 精确字符串替换编辑文件. | 属性 | 值 | |------|-----| | Name | `Edit` | | Aliases | `FileEdit` | | ConcurrencySafe | `false` | | ReadOnly | `false` | | Destructive | `false` | **输入参数 / Input Schema:** ```json { "type": "object", "properties": { "file_path": { "type": "string", "description": "The absolute path to the file to modify" }, "old_string": { "type": "string", "description": "The text to replace" }, "new_string": { "type": "string", "description": "The text to replace it with (must be different from old_string)" }, "replace_all": { "type": "boolean", "description": "Replace all occurrences of old_string (default false)", "default": false } }, "required": ["file_path", "old_string", "new_string"] } ``` **行为特性:** - `old_string` 必须在文件中唯一(除非 `replace_all=true`) - `old_string` 和 `new_string` 必须不同 - 多处匹配时列出所有匹配位置的行号 - 找不到时提供智能提示(空白差异检测,相似内容推荐) - 自动处理 CRLF/LF 换行符规范化 - 保留原文件权限 --- ### Write 写入文件内容(创建或覆盖). | 属性 | 值 | |------|-----| | Name | `Write` | | Aliases | `FileWrite` | | ConcurrencySafe | `false` | | ReadOnly | `false` | | Destructive | `false` | **输入参数 / Input Schema:** ```json { "type": "object", "properties": { "file_path": { "type": "string", "description": "The absolute path to the file to write" }, "content": { "type": "string", "description": "The content to write to the file" } }, "required": ["file_path", "content"] } ``` **行为特性:** - 文件不存在则创建 - 文件已存在则覆盖 - 自动创建父目录(类似 `mkdir -p`) --- ### Glob 文件模式匹配搜索. | 属性 | 值 | |------|-----| | Name | `Glob` | | ConcurrencySafe | `true` | | ReadOnly | `true` | | Destructive | `false` | **输入参数 / Input Schema:** ```json { "type": "object", "properties": { "pattern": { "type": "string", "description": "The glob pattern to match files against (e.g. **/*.go, src/**/*.ts)" }, "path": { "type": "string", "description": "The directory to search in. Defaults to the current working directory." }, "include_ignored": { "type": "boolean", "description": "Force include files that are normally ignored by .gitignore (default false)", "default": false } }, "required": ["pattern"] } ``` **行为特性:** - 支持 `**` 递归通配符 - 尊重 `.gitignore` 规则 - 默认排除:`.git/`, `node_modules/`, `__pycache__/`, `.DS_Store`, `*.pyc`, `vendor/`, `dist/`, `build/` - 结果按修改时间排序(最新在前),包含文件大小 - 超过 10,000 个匹配时截断 --- ### Grep 正则表达式搜索文件内容. | 属性 | 值 | |------|-----| | Name | `Grep` | | ConcurrencySafe | `true` | | ReadOnly | `true` | | Destructive | `false` | **输入参数 / Input Schema:** ```json { "type": "object", "properties": { "pattern": { "type": "string", "description": "The regular expression pattern to search for" }, "path": { "type": "string", "description": "File or directory to search in (default: cwd)" }, "glob": { "type": "string", "description": "File filter pattern (e.g. *.go, *.{ts,tsx})" }, "output_mode": { "type": "string", "description": "Output mode: content / files_with_matches / count", "enum": ["content", "files_with_matches", "count"] }, "context": { "type": "integer", "description": "Number of surrounding lines to show" }, "case_insensitive": { "type": "boolean", "description": "Case insensitive search" }, "head_limit": { "type": "integer", "description": "Maximum output lines (default 250)" } }, "required": ["pattern"] } ``` **行为特性:** - 支持完整正则表达式语法 - 自动跳过二进制文件 - 尊重 `.gitignore` 规则 - 匹配文本用 `>> <<` 标记 - 长行截断(超过 500 字符) - 默认输出上限 250 行 - 支持 `files_with_matches` 模式(只返回文件路径)和 `count` 模式(返回匹配计数) --- ### WebFetch HTTP GET 请求获取网页内容. | 属性 | 值 | |------|-----| | Name | `WebFetch` | | ConcurrencySafe | `true` | | ReadOnly | `true` | | Destructive | `false` | **输入参数 / Input Schema:** ```json { "type": "object", "properties": { "url": { "type": "string", "description": "The URL to fetch content from" }, "timeout": { "type": "integer", "description": "Timeout in seconds (default 30, max 120)" } }, "required": ["url"] } ``` **行为特性:** - HTML 智能转为纯文本(保留段落,列表,标题结构) - 提取 `` 作为输出第一行 - 移除 `<script>` 和 `<style>` 内容 - 完整处理 HTML entities - JSON 响应直接格式化返回 - 非 2xx 状态码返回错误 - 响应大小限制 1MB - 默认超时 30 秒,最大 120 秒 --- ### WebSearch 网页搜索(占位实现). | 属性 | 值 | |------|-----| | Name | `WebSearch` | | ConcurrencySafe | `true` | | ReadOnly | `true` | | Destructive | `false` | **输入参数 / Input Schema:** ```json { "type": "object", "properties": { "query": { "type": "string", "description": "The search query" }, "max_results": { "type": "integer", "description": "Maximum number of results to return (default 10)", "default": 10 } }, "required": ["query"] } ``` **注意:** 当前为占位实现,需要配置搜索 API 才能使用.可对接 Google Custom Search,Bing Search 或 SearXNG. --- ### Agent 生成子 Agent 处理子任务. | 属性 | 值 | |------|-----| | Name | `Agent` | | ConcurrencySafe | `false` | | ReadOnly | `false` | | Destructive | `false` | **输入参数 / Input Schema:** ```json { "type": "object", "properties": { "prompt": { "type": "string", "description": "The task prompt for the sub-agent" }, "description": { "type": "string", "description": "Task description for tracking" }, "model": { "type": "string", "description": "Model to use (inherits parent if empty)" }, "mode": { "type": "string", "description": "Run mode: sync (default) / background / worktree", "enum": ["sync", "background", "worktree"] }, "branch_name": { "type": "string", "description": "Branch name for worktree mode (auto-generated if empty)" } }, "required": ["prompt"] } ``` **行为特性(Fork 模式):** - 三种运行模式: - `sync` -- 等待子 Agent 完成后返回结果 - `background` -- 立即返回任务 ID,后台运行 - `worktree` -- 在独立的 git worktree 中运行. **真隔离**: 子 agent 的 Bash / Edit / Write / Gitignore 工具经 ctx-embedded cwd 覆盖在 worktree 目录执行 (BashTool 的 `pwd` 输出就是 worktree 路径, FileEdit 的 symlink 沙箱检查也绑定 worktree 根), 不会意外污染父仓库. 实现走 pkg/tools `WithWorkdir` / `WorkdirFromContext` helper, 详见引擎源码注释 - **可观测性**: 子 agent 的开工 / 每个业务事件 / 收工都经 ctx-embedded EventEmitter 转发到父 Run channel, 消费端 (TUI 树形视图 / SSE / observer / 审计 sink) 通过 `subagent_start` / `subagent_event` / `subagent_end` 事件看到子 agent 活动并按 `subagent_id` 归属. 详见 [docs/api-reference.md](./api-reference.md#sse-事件格式) SSE 章节的 子 agent 生命周期事件. - **Fork 模式**:子 Agent 共享父 Engine 的 prompt cache(API 层传完整工具列表保持 cache key 一致,运行时 `canUseTool` 拦截) - **经济账**:每个子 agent 调用净省 ~$0.018(Sonnet 定价),10 个子 agent = 省 $0.18 - 通过 `AgentExecutor` 接口解耦,避免循环依赖 - 子 Agent 注册到 `SubAgentRegistry`,支持查找和监控 - 进度追踪:工具调用计数,token 计数,最近活动 --- ### Task 工具 任务管理工具组(TaskCreate, TaskList, TaskUpdate),共享同一个 TaskStore. #### TaskCreate | 属性 | 值 | |------|-----| | Name | `TaskCreate` | | ConcurrencySafe | `true` | ```json { "type": "object", "properties": { "title": {"type": "string", "description": "Task title"}, "description": {"type": "string", "description": "Task description"} }, "required": ["title"] } ``` #### TaskList | 属性 | 值 | |------|-----| | Name | `TaskList` | | ConcurrencySafe | `true` | | ReadOnly | `true` | 无输入参数(空 JSON 对象).返回所有任务的列表. #### TaskUpdate | 属性 | 值 | |------|-----| | Name | `TaskUpdate` | | ConcurrencySafe | `true` | ```json { "type": "object", "properties": { "id": {"type": "string", "description": "Task ID"}, "status": {"type": "string", "description": "New status: pending/in_progress/done/failed/cancelled"} }, "required": ["id", "status"] } ``` **任务状态:** `pending` -> `in_progress` -> `done` / `failed` / `cancelled` 任务存储在内存中(线程安全),不跨会话持久化. --- ### Gitignore 管理 `.gitignore` 文件,支持添加 pattern 和检查路径是否被忽略. | 属性 | 值 | |------|-----| | Name | `Gitignore` | | ConcurrencySafe | `false` | | ReadOnly | `false` | | Destructive | `false` | **action=add**:向指定目录的 `.gitignore` 追加 pattern(幂等,文件不存在则创建): ```json {"action": "add", "dir": "/project", "patterns": ["*.log", "dist/"]} ``` **action=check**:检查路径是否被忽略: ```json {"action": "check", "dir": "/project", "path": "build/output.bin"} ``` --- ### ToolSearch 搜索并发现延迟加载的工具. | 属性 | 值 | |------|-----| | Name | `ToolSearch` | | ConcurrencySafe | `true` | | ReadOnly | `true` | | Destructive | `false` | | SearchHint | `tool search find discover deferred` | **输入参数 / Input Schema:** ```json { "type": "object", "properties": { "query": { "type": "string", "description": "Search query to find tools (e.g., 'fetch web page', 'search files')" } }, "required": ["query"] } ``` **行为特性:** - 当工具数量超过阈值(默认 15)时,非核心工具被延迟加载 - ToolSearch 搜索范围包括工具名称,描述和 SearchHint 元数据 - 搜索匹配逻辑:名称包含匹配 + SearchHint 词匹配 + 别名匹配 - 搜索到的工具自动激活(`DeferredRegistry.ActivateTool`),后续调用中可直接使用 - 如果没有配置延迟注册表(工具总数不超过阈值),返回提示所有工具已激活 - 返回匹配工具的名称和描述列表 **输出示例:** ``` Found 2 tool(s) matching 'web': - WebFetch: Fetches content from a URL... - WebSearch: Searches the web... These tools have been activated and are now available for use. ``` --- --- ## 自定义工具 ### 通过 Go SDK 注册 ```go type MyTool struct{} func (t *MyTool) Name() string { return "MyTool" } func (t *MyTool) Description(ctx context.Context) string { return "Does something" } func (t *MyTool) InputSchema() json.RawMessage { return json.RawMessage(`{"type":"object","properties":{"input":{"type":"string"}},"required":["input"]}`) } func (t *MyTool) Execute(ctx context.Context, input json.RawMessage, progress tools.ProgressFunc) (*tools.Result, error) { var params struct{ Input string `json:"input"` } json.Unmarshal(input, ¶ms) return &tools.Result{Output: "result: " + params.Input}, nil } func (t *MyTool) Metadata() tools.Metadata { return tools.Metadata{ ConcurrencySafe: true, ReadOnly: true, SearchHint: "my custom tool keyword", } } // 注册 agent.Tools().Register(&MyTool{}) ``` ### 通过自进化系统创建 Agent 可以在运行时创建工具,详见 [evolution.md](evolution.md). --- ## 工具编排 Orchestrator 负责工具调用的并发调度: 1. 从 API 响应中提取工具调用列表 2. 按并发安全性分批: - 连续的 `ConcurrencySafe=true` 工具 -> 同一批(并行执行) - `ConcurrencySafe=false` 工具 -> 单独一批(串行执行) 3. 逐批执行,每批内最大并发数为 10 ``` 示例输入: [Glob, Grep, Edit, Glob, Grep, Bash] 分批结果: Batch 1: [Glob, Grep] -> 并行执行 Batch 2: [Edit] -> 串行执行 Batch 3: [Glob, Grep] -> 并行执行 Batch 4: [Bash] -> 串行执行 ``` --- ## 工具延迟加载 当注册的工具数量超过阈值(默认 15)时,`DeferredRegistry` 自动启用延迟加载. ### 始终加载的核心工具 以下工具始终处于活跃状态,不会被延迟加载: - `Bash`, `Read`, `Edit`, `Write`, `Glob`, `Grep`, `Agent`, `ToolSearch` ### 延迟加载流程 ``` 1. Engine 启动,注册所有工具(内置 + MCP + 插件 + 自进化创建的) 2. 工具总数 > 15 → DeferredRegistry 启用延迟加载 3. 只有核心工具提供给模型(ActiveTools) 4. 模型需要非核心工具 → 调用 ToolSearch 5. ToolSearch 搜索匹配的延迟工具 → 自动激活 6. 激活后的工具在后续 ActiveTools 调用中包含 7. 新会话开始时 ResetActivations(重置激活状态) ``` ### DeferredRegistry API ```go // 获取当前活跃工具 activeTools := deferred.ActiveTools() // 搜索延迟工具 matches := deferred.SearchTools("web fetch") // 手动激活 deferred.ActivateTool("WebFetch") // 检查是否延迟中 isDeferred := deferred.IsDeferred("WebFetch") // 重置激活状态 deferred.ResetActivations() ```