deerflow2/frontend/src/content/zh/harness/tools.mdx
Ryker_Feng 0bbbbc06f4
feat(community): add Serper Google Images provider for image_search (#3575)
* feat(community): add Serper Google Images provider for image_search

Add a Serper-backed `image_search` tool alongside the existing Serper
`web_search` provider, so users with a SERPER_API_KEY can pull Google
Images results as reference images for downstream image generation.

- Share request/response handling between web_search and image_search
  via `_serper_post` / `_response_items`, with bounded `max_results`
  (capped at 10) and query normalization.
- Add a best-effort SSRF guard (`_safe_public_url`) that rejects
  non-http(s), localhost and private/non-global IP image URLs; filtered
  entries are dropped and never consume the result limit.
- doctor: flag literal `api_key` values in config as a warning and steer
  users toward `.env` + `$SERPER_API_KEY`.
- Docs/config: document the Serper image_search provider and SERPER_API_KEY,
  and discourage committing literal keys to config.yaml.
- Tests: cover the provider end-to-end (100% line coverage on tools.py)
  and the doctor literal-key warning path.

* fix(community): block obfuscated IPv4 literals in Serper image SSRF guard

The image_search SSRF guard only rejected dotted-decimal IP literals; encoded
forms such as decimal (http://2130706433/), hex (0x7f000001) and octal
(0177.0.0.1) raised ValueError in ip_address() and were allowed through, even
though many HTTP clients resolve them to private addresses like 127.0.0.1.

Add _decode_ipv4() to permissively decode these inet_aton-style encodings and
apply the same is_global check; hostnames that do not decode to an IP (e.g.
cafe.com) are still treated as hosts and left to fetch-time re-validation.

Addresses PR review feedback. Tests cover decimal/hex/octal loopback and
private encodings plus non-IP edge cases; tools.py stays at 100% line coverage.

* test(community): cover IPv4-mapped IPv6 URL filtering

* fix(community): address Serper image search review feedback

- Block trailing-dot hostname SSRF bypass (localhost./127.0.0.1.) in
  _safe_public_url by stripping the FQDN root label before checks.
- Keep a filtered image/thumbnail URL empty instead of collapsing onto
  its counterpart, preserving the high-res/preview contract.
- Evaluate the SSRF guard once per field rather than twice.
- Treat a null-typed organic/images field as "no results" rather than a
  malformed payload.
- doctor.py: when a config $VAR is unset, fall through to the default env
  var before reporting it as not set.
2026-06-18 07:36:35 +08:00

260 lines
8.2 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 工具
description: Lead Agent 是一个工具调用 Agent。工具是它与世界交互的方式搜索网络、读写文件、运行命令、委派任务以及向用户呈现输出。
---
import { Callout, Cards, Tabs } from "nextra/components";
# 工具
<Callout type="info" emoji="🔧">
工具是 Lead Agent 可以采取的行动。DeerFlow 提供内置工具、社区集成、MCP
工具和技能工具——全部通过 <code>config.yaml</code> 控制。
</Callout>
Lead Agent 是一个工具调用 Agent。工具是它与世界交互的方式搜索网络、读写文件、运行命令、委派任务以及向用户呈现输出。
DeerFlow 将工具分为四类:
1. **内置工具** — 核心运行时能力,始终对 Agent 可用
2. **社区工具** — 与外部搜索、抓取和图像服务的集成
3. **MCP 工具** — 由外部 Model Context Protocol 服务器提供的工具
4. **技能工具** — 与特定技能包捆绑的工具
## 内置工具
内置工具是 Harness 的一部分,无需配置即可使用。
### task
将子任务委派给子 Agent。当任务对单个推理线程来说太宽泛或并行工作有利时Lead Agent 使用此工具。
```
task(agent="general-purpose", task="...", context="...")
```
参见[子 Agent](/docs/harness/subagents)页面了解子 Agent 的配置方式。
---
### present_files
将输出文件作为产出物呈现给用户。Agent 在生成文件(报告、图表、代码等)后调用此工具,将其显示在对话中。
---
### view_image
读取图像文件并将其内容注入到模型的上下文中进行视觉分析。仅当活跃模型具有 `supports_vision: true` 时可用。
---
### clarification
在继续之前向用户提问。当模型认为没有足够信息来行动时,由 `ClarificationMiddleware` 触发。
---
### setup_agent
动态配置当前 Agent 会话。在设置新自定义 Agent 的引导流程中使用。
---
### update_agent
将更新持久化到当前自定义 Agent 的 `SOUL.md` 和 `config.yaml`。仅当激活了自定义 Agent运行时上下文中存在 `agent_name`)时,才会绑定到 lead agent。当用户在 Agent 内开启 chat 并要求该 Agent 调整自身的描述、人格、技能白名单、工具组白名单或默认模型时使用——它会直接写入按用户隔离的 `{base_dir}/users/{user_id}/agents/{agent_name}/` 下的真实配置文件,下一轮对话即可生效。仅显式传入的字段会被更新;省略某个字段以保留其现有值。传入 `skills=[]` 可禁用全部技能,省略 `skills` 则保留现有白名单。
---
### invoke_acp_agent
使用 [Agent Connect Protocol (ACP)](https://agentconnectprotocol.org/) 调用外部 Agent。需要在 `config.yaml` 中配置 `acp_agents:`。参见[子 Agent](/docs/harness/subagents)页面了解 ACP 配置。
---
### tool_search
按名称或描述搜索工具,并按需将其加载到 Agent 上下文中。仅当 `config.yaml` 中 `tool_search.enabled: true` 时激活。当 MCP 或其他工具集暴露大量工具且你希望减少上下文使用时很有用。
## 沙箱文件工具
以下工具与沙箱文件系统交互,需要配置并激活沙箱。
| 工具 | 描述 |
| ------------- | ---------------------------------------------------------- |
| `ls` | 列出目录中的文件 |
| `read_file` | 读取文件内容 |
| `glob` | 查找匹配模式的文件 |
| `grep` | 搜索文件内容 |
| `write_file` | 向文件写入内容 |
| `str_replace` | 替换文件中的字符串 |
| `bash` | 执行 Shell 命令(需要 `allow_host_bash: true` 或容器沙箱) |
在 `config.yaml` 的 `tools:` 下配置:
```yaml
tools:
- use: deerflow.sandbox.tools:ls_tool
- use: deerflow.sandbox.tools:read_file_tool
- use: deerflow.sandbox.tools:glob_tool
- use: deerflow.sandbox.tools:grep_tool
- use: deerflow.sandbox.tools:write_file_tool
- use: deerflow.sandbox.tools:str_replace_tool
- use: deerflow.sandbox.tools:bash_tool
```
## 社区工具
社区工具将 Agent 连接到外部服务。在 `config.yaml` 的 `tools:` 下使用 `use:` 字段指定实现来配置。
### 网络搜索
<Tabs items={["DuckDuckGo默认", "Tavily", "Brave", "Exa", "InfoQuest", "Firecrawl"]}>
<Tabs.Tab>
```yaml
tools:
- use: deerflow.community.ddg_search.tools:web_search_tool
```
无需 API Key。默认配置适合开发和通用用途。
</Tabs.Tab>
<Tabs.Tab>
```yaml
tools:
- use: deerflow.community.tavily.tools:web_search_tool
api_key: $TAVILY_API_KEY
```
高质量搜索,带结构化结果。需要 [Tavily](https://tavily.com) API Key。
安装:`cd backend && uv add 'deerflow-harness[tavily]'`
</Tabs.Tab>
<Tabs.Tab>
```yaml
tools:
- use: deerflow.community.brave.tools:web_search_tool
api_key: $BRAVE_SEARCH_API_KEY
```
通过官方 [Brave Search API](https://brave.com/search/api/) 返回 Brave 独立索引的结果。需要 API Key`max_results` 上限为 20。
无需额外依赖。
</Tabs.Tab>
<Tabs.Tab>
```yaml
tools:
- use: deerflow.community.exa.tools:web_search_tool
api_key: $EXA_API_KEY
```
带神经检索的语义搜索。需要 [Exa](https://exa.ai) API Key。
安装:`cd backend && uv add 'deerflow-harness[exa]'`
</Tabs.Tab>
<Tabs.Tab>
```yaml
tools:
- use: deerflow.community.infoquest.tools:web_search_tool
api_key: $INFOQUEST_API_KEY
```
InfoQuest 搜索集成。
</Tabs.Tab>
<Tabs.Tab>
```yaml
tools:
- use: deerflow.community.firecrawl.tools:web_search_tool
api_key: $FIRECRAWL_API_KEY
```
Firecrawl 驱动的搜索和爬取。需要 [Firecrawl](https://firecrawl.dev) API Key。
</Tabs.Tab>
</Tabs>
### 网页内容抓取
<Tabs items={["Jina AI默认", "Exa"]}>
<Tabs.Tab>
```yaml
tools:
- use: deerflow.community.jina_ai.tools:web_fetch_tool
api_key: $JINA_API_KEY # 可选;匿名使用有速率限制
```
将网页转换为干净的 Markdown。无 API Key 也可使用,但有更严格的速率限制。
</Tabs.Tab>
<Tabs.Tab>
```yaml
tools:
- use: deerflow.community.exa.tools:web_fetch_tool
api_key: $EXA_API_KEY
```
</Tabs.Tab>
</Tabs>
### 图像搜索
<Tabs items={["DuckDuckGo默认", "InfoQuest", "Serper"]}>
<Tabs.Tab>
```yaml
tools:
- use: deerflow.community.image_search.tools:image_search_tool
```
无需 API Key。默认配置适合开发和通用用途。
</Tabs.Tab>
<Tabs.Tab>
```yaml
tools:
- use: deerflow.community.infoquest.tools:image_search_tool
api_key: $INFOQUEST_API_KEY
```
需要 InfoQuest API Key。
</Tabs.Tab>
<Tabs.Tab>
```yaml
tools:
- use: deerflow.community.serper.tools:image_search_tool
api_key: $SERPER_API_KEY
```
通过 Serper 获取 Google 图片结果。需要 [Serper](https://serper.dev) API Key与 Serper `web_search` 工具复用同一个 `SERPER_API_KEY`。
</Tabs.Tab>
</Tabs>
## 工具组
工具组允许你将工具组织为命名集合,并限制自定义 Agent 可以访问哪些组:
```yaml
tool_groups:
- name: research
tools:
- web_search
- web_fetch
- image_search
- name: coding
tools:
- bash
- read_file
- write_file
- str_replace
- glob
- grep
```
自定义 Agent 然后可以在其配置中按名称引用组,将其工具访问限制为仅相关集合。
## 工具搜索(延迟加载)
当有许多工具时(特别是来自多个 MCP 服务器),预先加载所有工具会增加上下文使用量并可能混淆模型。工具搜索功能解决了这个问题:
```yaml
tool_search:
enabled: true
```
启用后,工具不会直接列在模型上下文中。相反,它们在运行时通过 `tool_search` 内置工具按需发现Agent 按名称或描述搜索,匹配的工具按需加载到上下文中。
当 MCP 服务器暴露数十个工具时特别有用。
<Cards num={2}>
<Cards.Card title="MCP 集成" href="/docs/harness/mcp" />
<Cards.Card title="技能" href="/docs/harness/skills" />
</Cards>