---
title: "工具与工具集 · Finch Agent"
description: "了解小程序接入的工具与权限机制"
source: https://finchwork.app/zh/docs/tools
---

# 工具与工具集

在 Finch 里，Agent 能调用的一切——读文件、发搜索、改主题、装 Mini Tool、连 MCP server——都叫「工具」（Tool）。这些工具不是单一来源：了解它们分别从哪来、怎么命名、怎么被授权，能帮你判断「这个能力该不该自己写一个 Mini Tool」，以及 Mini Tool 里的工具要怎么和内置工具配合。

## 工具的四层来源

| 层级 | 来源 | 特点 |
| --- | --- | --- |
| **Agent 运行时内置** | Finch 依赖的 Agent 核心（`pi` 二进制） | 文件读写、搜索、终端等基础原语，随 Agent 核心分发，不经过 Finch 的工具注册表 |
| **工具集** | Finch 源码 | Finch 自己实现的「一个工具多个 action」的复合工具，覆盖记忆、Skill、会话、App 控制、自动化等产品能力 |
| **Mini Tool 贡献的工具** | 已安装并启用的 Mini Tool，通过 `ctx.tools.register()` 注册 | 见 [Mini Tools 开发指南](/zh/docs/minitools) |
| **MCP 贡献的工具** | 官方 MCP 桥接 Mini Tool 动态接入的外部 MCP server | 工具名固定格式 `mcp__<server>__<tool>` |

四层工具在模型看来没有本质区别——都是一次函数调用；区别主要体现在**命名规则**和**权限网关**上，见下文。

## Agent 运行时内置工具

这些工具由 Finch 依赖的 Agent 核心提供，Finch 只持有它们的权限策略（是否需要用户确认、超时时间），不重新实现执行逻辑。

| 工具 | 用途 |
| --- | --- |
| `Read` | 读文件（支持按行 offset/limit 读取，也能读图片、PDF） |
| `Write` | 创建/覆盖文本文件 |
| `Edit` | 对已读取过的文件做精确文本替换 |
| `Grep` | 正则内容搜索（支持 glob 过滤、上下文行、多种输出模式） |
| `Glob` | 按文件名模式匹配 |
| `Bash` | 执行 shell 命令；危险命令（`rm`、`git reset --hard` 等）与只读命令有专门的判定逻辑 |
| `WebSearch` | 网页搜索 |
| `WebFetch` | 抓取单个网页并转换为文本/Markdown |
| `AskUserQuestion` | 结构化多选问答卡片，Finch 用它替代纯文本提问 |
| `TodoWrite` | 维护当前任务的待办清单，供长任务过程中展示进度 |
| `Skill` | Composer 里插入 `/skill` 引用时，由此工具承载 Skill 的调用 |

这一层是「基础设施」层，Mini Tool 不需要也不应该重新实现文件读写、搜索这类能力——直接假设它们已经存在。

## 工具集

Finch 自己的产品能力没有拆成几十个零散工具，而是收敛成 7 个「调度器工具」，每个工具用 `action` 参数复用同一个工具定义，模型省略 `action` 时会拿到该工具的完整用法说明（等价于工具自带的 `--help`）。

| 工具 | 用途 | 常见 action |
| --- | --- | --- |
| `Memory` | 中长期记忆管理，落盘到 `MEMORY.md` / 每日日志 / Space 记忆 | `remember` / `replace` / `forget` / `search` |
| `Skills` | 发现并调用 `SKILL.md` 技能包 | `list` / `invoke` |
| `Session` | 当前会话内的操作 | `search`（历史会话）/ `extendDir`（信任新目录）/ `attach`（把文件推进输入框）/ `rename` |
| `AppCall` | App 级控制 + 用户画像写入 | `info` / `setAppearance` / `listSpaces` / `listModels` / `createSpace` / `checkUpdate` / `saveProfile` 等 |
| `ToolSearch` | 发现并激活当前会话尚未加载的动态工具（详见下文） | 传 `query`/`source`/`limit` |
| `MiniTool` | 管理已安装的 Mini Tool（通过 `@finchtoys/minitools` CLI） | `list` / `add` / `update` / `remove` / `enable` / `disable` / `reload` |
| `Schedule` | 管理定时自动化任务 | `list` / `create` / `update` / `enable` / `disable` / `delete` / `run` / `history` |

这套「调度器」设计是 Finch 自己的架构选择，不是 Mini Tool API 的强制要求——Mini Tool 既可以照这个思路把一组相关能力收进一个带 `action` 的工具，也可以按需注册多个独立工具，取决于你希望模型怎么发现和调用它们。

## 动态工具与 ToolSearch

不是所有工具都会在新会话一开始就塞进模型的工具表——工具定义本身要消耗上下文，工具越多，模型选择的准确率越低。Finch 用 `exposure` 区分两种暴露策略：

-   **`startup`**（默认）：新会话启动时就注入，例如上面列出的内置工具和调度器工具。
-   **`dynamic`**：不进初始工具表，需要先被激活才能调用。典型场景是 MCP server 暴露的工具、按需发现的大量 Mini Tool 工具。

模型需要用不常用的工具时，先调用 `ToolSearch` 按自然语言描述检索，Finch 把匹配到的工具「激活」进当前会话，模型才能在下一步真正调用它们。MCP 贡献的工具遵循固定命名 `mcp__<server>__<tool>`（例如 `mcp__tavily__tavily_search`），且**永远不会预加载**——必须先经过 `ToolSearch source="mcp"` 激活。

## Mini Tool 贡献工具的命名

Mini Tool 通过 `ctx.tools.register({ name, ... })` 注册的工具，模型看到的最终名字是 `<mini-tool-id>_<name>`（例如 id 为 `myextension` 的 Mini Tool 注册了 `search_docs`，模型看到的是 `myextension_search_docs`）。

如果一个 Mini Tool 代表另一个 Mini Tool 的贡献注册工具（比如官方 MCP 桥接为其它 Mini Tool 贡献的 MCP server 注册工具），可以在工具定义里设置 `owner` 字段，把工具的来源、权限归属、UI 计数都记到贡献方而不是实际注册方名下——这是官方 MCP 桥接自己用的机制，普通 Mini Tool 一般不需要。

## 权限与执行策略

每次工具调用在执行前都要过一层策略判断，一共三种结果：

| 策略 | 行为 | 适用对象 |
| --- | --- | --- |
| **完全免审批**（`autoAllow`） | 直接执行，不弹权限卡 | `AskUserQuestion`/`TodoWrite`/`Skill`，以及 Finch 调度器工具里除 `MiniTool` 外的全部（`Memory`/`Skills`/`Session`/`AppCall`/`ToolSearch`/`Schedule`） |
| **快速通道**（`acceptCallsAutoAllow`） | 仅在用户把权限模式切到「Accept Calls」时自动放行，默认模式仍需确认 | `Read`/`Write`/`Edit`/`Grep`/`Glob`/`WebSearch`/`WebFetch`，以及只读的 `Bash` 命令 |
| **逐次确认**（权限卡） | 每次调用都展示权限卡，用户手动批准 | 危险 `Bash` 命令、**所有** Mini Tool 贡献的工具、`MiniTool` 调度器工具本身 |

关键结论：**Mini Tool 贡献的工具永远不会自动放行**，无论用户处于哪种权限模式——每次调用都要经过权限卡。这是有意的设计：内置工具和 Finch 自身的调度器工具经过审计，Mini Tool 代码来自第三方，不能获得同等信任级别。写 Mini Tool 工具时，把这一点考虑进交互设计：如果某个操作会被频繁调用，尽量把它拆成一次性配置（存进 `ctx.storage`/`ctx.settings`）而不是每轮都触发一次新的工具调用。

`Bash` 单独判定「只读 / 危险」：只读命令（如 `ls`、`git status`）走快速通道，`rm`、`git reset --hard` 一类命令始终要求确认，与权限模式无关。

## 给 Mini Tool 开发者的启示

-   **先看这张清单，再决定要不要写新工具**：文件读写、搜索、网页抓取、待办清单这些能力已经存在，不要在 Mini Tool 里重新造轮子。
-   **工具名不会和内置工具冲突**：模型侧名字自动加了 `<mini-tool-id>_` 前缀，但工具描述仍然要写清楚「和 Read/Grep 这类通用工具比，我的工具专门解决什么」，否则模型可能优先选熟悉的内置工具。
-   **`description` 决定被调用的概率**：内置工具和调度器工具的 `description` 都在系统提示词里长期可见、经过反复打磨；你的 Mini Tool 工具只有安装且启用后才会出现，描述要足够具体地说明触发场景，才能在候选工具里被模型选中。
-   **不要假设自己会被无审批调用**：设计交互时默认「每次调用都会先给用户看一张权限卡」，把关键信息（会做什么、影响范围）放进 `title`/`description`，而不是指望用户去看代码。

## 参考资料

-   工具注册与执行接口：见 [Mini Tools 开发指南](/zh/docs/minitools) 中的 `ctx.tools`
-   完整类型定义：npm 包 [`@finchtoys/minitool-api`](https://www.npmjs.com/package/@finchtoys/minitool-api)
