Skip to content

工具系统

一个工具就是 Agent 能伸出去的一只手。

把语言模型单独放在那里,它只是一个包在文本里的模式匹配器。它不知道现在几点。它不知道你的文件里写了什么。它不能搜索网页、执行命令、看一份 PDF、把任务交给另一个 Agent、打开一个浏览器。它只能谈论做这些事。

工具是 MateClaw 解决这件事的方式。每一个工具是一个 Agent 被允许调用的具体操作——读文件、搜网页、执行 shell 命令、从 PDF 抽文字、把任务委托给另一个 Agent。Agent 判断需要某个工具时,发出一次工具调用,运行时执行它,结果作为观察回到 Agent 下一步推理里。

二十个内置工具开箱即用。无限多个可以通过 MCP 服务、自定义技能脚本、或者你自己写的 @Tool Spring bean 加进来。


一次工具调用实际发生了什么

Agent 判断需要一个工具


  发出工具调用:{"name": "WebSearchTool", "args": {"query": "..."}}


  ┌─────────────────────┐
  │    工具注册表       │  ← 按名字查工具
  └─────────────────────┘


  ┌─────────────────────┐
  │   Tool Guard        │  ← 基于规则的检查:allow / deny / 审批
  └─────────────────────┘

   ┌────┴────┐
   │         │
   ▼         ▼
 允许     审批挂起 → 用户决定 → 允许 / 拒绝


  ┌─────────────────────┐
  │  执行(带超时)     │  ← 异步,按工具单独设超时
  └─────────────────────┘


  结果 → 观察 → Agent 下一步推理

Tool Guard 是守门员。超时是每个工具独立的(这样一个慢工具冻不了整个回合)。在一次 Action 阶段里,Agent 同时调多个独立工具时它们可以并发执行

这整套对 Agent 的 prompt 是不可见的。


工具注册的三条路

1. 内置工具。 MateClaw 出厂带的二十个工具,启动时自动注册到工具表里。

2. MCP 服务。 说 Model Context Protocol 的外部进程动态暴露工具。MateClaw 通过 tools/list 发现它们。见 MCP 协议

每 Agent 的 MCP 工具范围(1.4.0+,#117):当一个 Agent 没有勾选任何具体的 MCP 工具行时,已启用的 MCP 工具会自动并入它的工具集;一旦它勾选了某些具体 MCP 工具,就只限定在这个集合内。只绑技能 / 内置工具的 Agent 仍保留对全部 MCP 工具的访问。

3. 技能脚本。 技能包可以带可执行脚本,运行时被包装成工具。见 技能系统

工具发现是黑名单式的——默认所有可发现的工具都会被注册,需要排除哪个就显式排除。这样新加进来的工具不会因为白名单遗漏被默默忽略。


渐进式工具披露(1.4.0+)

工具一多,系统 prompt 就会被几十个完整的工具 schema 撑大——哪怕这次任务只用得上一两个。渐进式披露把工具分成两层,让 prompt 跟着任务走,而不是跟着工具总数走。

层级系统 prompt 里怎么呈现能不能直接调
核心层(CORE)始终完整广播,带完整 schema开箱即用
扩展层(EXTENSION)只列一份压缩目录——名字 + 来源 + 一行说明,完整 schema 隐藏先用 enable_tool 激活才能调

默认分层:生成类工具(image_generatemusic_generatevideo_generatemodel3d_generate)和 browser_use 默认放进扩展层;其余全部是核心层

  • 页面控制——Tools 页面分「核心 / 扩展」两栏,内置工具和渠道工具每行有一个层级开关;MCP / ACP 工具的层级是锁定的。
  • 持久化——层级存在 mate_tool.disclosure_tiermate_mcp_server.disclosure_tier
  • 配置——mateclaw.tools.disclosure.mode,默认 progressive;设成 legacy 则恢复"全部广播"的老行为。

为什么这么做:不让上下文被白白撑爆——系统 prompt 的体积应该跟当前任务的需要成正比,而不是跟你装了多少工具成正比。


二十个内置工具

工具作用危险
DateTimeTool获取任意时区的当前日期时间
WebSearchTool通过搜索引擎链搜索(Serper / Tavily / DuckDuckGo / SearXNG)
ReadFileTool读文件
WriteFileTool写内容到文件⚠️
EditFileTool查找替换编辑⚠️
ShellExecuteTool执行 shell 命令⚠️
FileTypeDetectorTool检测 MIME 类型和编码
DocumentExtractTool从 PDF / DOCX / XLSX 抽文字
WorkspaceMemoryTool读写 Agent 的工作空间记忆
SkillFileTool读取和管理 SKILL.md 文件
SkillScriptTool执行技能脚本⚠️
SkillManageTool创建 / 编辑 / 删除技能包⚠️
BrowserUseTool驱动无头浏览器⚠️
DelegateAgentTool把任务委托给另一个 Agent(支持并行)
MateClawDocTool读取内置项目文档
ImageGenerateTool文生图 / 图生图(1.3.0+)
VideoGenerateTool文生视频 / 图生视频
DocxRenderTool1.3.0+ Markdown → .docx(Word 文档)
XlsxRenderTool1.3.0+ Markdown 表格 → .xlsx(Excel)
PptxRenderTool1.3.0+ Markdown(Marp 风格 --- 分页) → .pptx
PdfRenderTool1.3.0+ Markdown → 出版级 PDF(中文字体内嵌)
CronJobTool创建和管理定时任务⚠️
DatasourceTool管理外部数据源连接⚠️
SqlQueryTool对已连接数据源执行 SQL 查询⚠️
send_file1.4.0+ 把服务器上已有文件作为原生 IM 附件投递(#199)
enable_tool1.4.0+ 在本次会话里激活一个扩展层工具
load_skill1.4.0+ 按需加载某个技能的 SKILL.md

此外还有 多模态创作 的音乐生成工具 MusicGenerateTool。以及 LLM Wiki 的 14 个 Wiki 工具:wiki_read_pagewiki_read_manywiki_list_pageswiki_search_pageswiki_semantic_searchwiki_compile_pagewiki_trace_sourcewiki_create_pagewiki_delete_pagewiki_archive_pagewiki_unarchive_pagewiki_related_pageswiki_explain_relationwiki_enrich_page

DateTimeTool

返回给定时区的当前日期时间。没有意外。

输入:{"timezone": "America/New_York"}
输出:"2026-04-11T14:30:22"

WebSearchTool

通过供应商链搜索——DuckDuckGo 和 SearXNG 作为无 Key 的 fallback,Serper 和 Tavily 在你有 Key 时启用。在 设置 → 系统设置 → 搜索服务 里配置,改完即生效,不需要重启

输入:{"query": "Spring AI Alibaba 最新版本", "freshness": "month", "count": 5}
输出:"Spring AI Alibaba 1.1 发布..."

特性:

  • 供应商链——主 provider 失败时链式 fallback 到下一个
  • 高级参数——freshnesslanguagecount
  • 结果缓存——近期查询被缓存
  • 安全包装——结果返回前先净化
  • 原生搜索 + 工具搜索共存——自带搜索的模型用原生搜索,工具搜索作为 fallback

ShellExecuteTool

跨平台 shell 执行。Linux/macOS 用 /bin/sh -c,Windows 用 cmd.exe /D /S /C每一次调用都过 Tool Guard。

安全设计:

  • 超时——默认 60 秒,硬上限 300 秒
  • 输出上限——stdout 和 stderr 各自上限 10,000 字节
  • 文件支撑输出——写到临时文件,不是管道
  • 结构化结果——{exitCode, stdout, stderr, timedOut}
  • 危险模式检测——find -deleterm -rf /、管道 bash 下载触发更高级别审批

ReadFileTool / WriteFileTool / EditFileTool

读是安全的。写和编辑都过 Tool Guard。

DocumentExtractTool

PDF、DOCX、XLSX 之类变成纯文本。扫描件在可用的地方降级到 OCR。

Office 文档生成(1.3.0+)

四个新工具,把 Markdown 直接渲染为可下载的 Office 文件——不 fork 子进程,不依赖 npm。生成的字节缓存在内存里,返回一个一次性下载链接:

工具适用关键能力
DocxRenderTool.renderDocx报告 / 备忘录 / 合同 / 简历标题(# ## ###) / 加粗(text) / 列表 / 表格 / 图片(PNG/JPG/GIF/BMP/SVG → PNG)
DocxRenderTool.renderDocxFromFile同上,但 markdown 在工作区文件里用于 LLM 不想把已经写好的大段 markdown 当 tool 参数再发一次
XlsxRenderTool.renderXlsx财务表 / 数据导出 / 模板Markdown 表格语法 → 多 sheet(用 ## SheetName 切分)
PptxRenderTool.renderPptx演讲稿 / 项目方案 / 简报Marp 风格 --- 分页;16:9(默认)/ 4:3 比例
PptxRenderTool.renderPptxFromFile同上,markdown 在文件里内容大于 5KB 时优选
PdfRenderTool.renderPdf出版级文档 / 周报 / 制式文件1in 边距 / 智能分页 / 页码 / 封面页 / 中英混排(CJK 字体内嵌)

跟原有 skills/docx 的关系

现成的 skills/docx skill 保留——它擅长的是编辑已有 .docx(tracked changes / 复杂 XML 操作)和首次安装时跑 npm install docx。新四个工具专门处理"从零创建"路径,没有 npm 启动延迟。Agent 首选这四个 RenderTool;要修已有 .docx 才转回 skill。

ImageGenerateTool —— 1.3.0 起支持图像编辑

v1.2.0 时这个工具只能"文生图"。v1.3.0 起新增 image / images 两个参数,支持多图输入的图像编辑。详见 多模态创作

WorkspaceMemoryTool

让 Agent 读、写、编辑自己的工作空间记忆文件——workspace/{agentId}/ 下面的任何 .md。见 记忆系统

BrowserUseTool

驱动一个无头浏览器。每次调用都过 Tool Guard。

DelegateAgentTool —— Agent 之间委托

一个 Agent 可以把子任务交给另一个 Agent:

  • delegateToAgent(agentName, task)——按名字调用指定 Agent,在隔离会话里执行任务
  • listAvailableAgents()——列出所有可用 Agent
用户:搜一下 Spring AI 的新闻,让 Writer 总结一下
Agent A:[调 WebSearchTool]
        [调 delegateToAgent(agentName="Writer", task="总结:...")]
        [收到 Writer 的回复]
        合并后回复用户

安全:

  • 递归上限——委托最多嵌套 3 层
  • 隔离会话——被委托的 Agent 跑在自己的会话里
  • 结果截断——委托结果上限 4000 字符

MateClawDocTool

读取内置的 MateClaw 项目文档。让 Agent 回答"MateClaw 里 X 是怎么工作的"这种问题时,去查真文档而不是猜。

enable_tool —— 激活扩展层工具(1.4.0+)

enable_tool(toolName) 把一个扩展层工具激活,使它在本次会话剩余的回合里完整可调。

  • 会校验——只有在 Agent 的有效工具集里的工具才能激活。
  • 下一回合生效——激活在同一个 ReAct 循环的下一次推理时生效(Agent 先看到完整 schema,再发真正的调用)。
  • 会话级,不持久化——激活只对当前会话有效,不写库;新会话回到默认分层。

load_skill —— 按需加载技能(1.4.0+)

load_skill(skillName, filePath?) 在需要时才把某个技能的 SKILL.md 加载进来——不传 filePath 读主文件,传了就读技能包内的子文件。

  • 走消息历史注入——加载的内容是注入到消息历史里,而不是系统 prompt,这样 prompt 缓存保持稳定(系统 prompt 不变,缓存不失效)。
  • 后续回合保持——已加载的技能在之后的回合里钉住,不用反复加载。
  • 配置——mateclaw.skill.disclosure.load-skill-tool.enabled,默认开启。

详见 技能系统

send_file —— 把已有文件作为原生附件投递(1.4.0+,#199)

send_file(filePath, fileName?) 读取服务器上一个已经存在的文件,把它作为原生 IM 附件投递——不是一条文本下载链接。

  • 进生成文件缓存——文件被放进生成文件缓存,渠道适配器(飞书 / 钉钉 / Telegram)自动识别并投递
  • 任意常见文件类型,上限 20 MB
  • ReadFileTool 的区别——ReadFileTool 把文件抽成文本喂给 Agent 推理;send_file 把文件原样发给用户

ReadFileTool —— 超长行分页(1.4.0+,#190)

针对单行特别长的文件,ReadFileTool 新增可选的 startColumn(在 startLine 内的 1-based 字符偏移),用来从一行的中间续读它的尾部。

  • 截断时始终返回 nextStartLine
  • 当这一行还有剩余没读完时,额外返回 nextStartColumn

把两者回填到下一次调用,就能把一个巨大的单行文件分段读完。


Tool Guard —— 权限层

Tool Guard 是 MateClaw 不让强工具干蠢事的机制。它是基于规则的,不是一个扁平的"危险 / 不危险"清单。每条规则说:对这个工具,带这些参数,在这个上下文里,做 X——X 是 allowdeny、或 require_approval

核心几张表:

  • mate_tool_guard_rule——单条规则
  • mate_tool_guard_config——全局配置
  • mate_tool_guard_audit_log——每一次受守护的调用一条记录

示例规则:ShellExecuteTool,命令以 lscatgrepfind 开头时允许。其他情况要求审批。

yaml
mateclaw:
  tool:
    guard:
      enabled: true
      default-policy: require_approval
      rules:
        - tool: ShellExecuteTool
          arg-pattern: "^(ls|cat|grep|find)\\s"
          action: allow
        - tool: WriteFileTool
          action: require_approval

或者在 设置 → 安全与审批 里可视化管理。规则判定为需要审批时,运行时会在 mate_tool_approval 持久化一条记录并把 Agent 回合挂起。完整机制在 安全与审批

声明式 Hook 系统

Tool Guard 规则是一种更通用机制的特例——声明式 Hook 系统。5 个生命周期钩子覆盖工具调用和 LLM 调用的全部关键时刻:

Hook触发时机典型用途
before_tool工具执行前参数脱敏、注入上下文、额外校验
after_tool工具执行后结果过滤、审计记录
before_llmLLM 调用前prompt 增强、缓存命中检查
after_llmLLM 返回后输出过滤、token 统计
on_error错误发生时告警、降级策略

Hook 在进程内执行,可以改参数、改结果、脱敏、加审计日志。你可以用 Hook 做 Tool Guard 之外的事——比如在每次 LLM 调用前注入安全策略,或者在工具返回后自动脱敏敏感字段。


执行:并发、隔离、有界

  • 并发执行——一个回合里独立的工具调用并发跑。Guard 检查是顺序的,执行在安全的地方并发。
  • 每工具超时——每个工具有自己的超时。默认:快工具 30s,shell/browser 60s,生成类 300s。
  • 段隔离——回合中间需要审批时,段在审批边界处分裂。
  • 观察截断——结果超长会被自动截断。
  • 错误隔离——单个工具失败不会中止整个回合。

API 管理

bash
# 列出所有工具
curl http://localhost:18088/api/v1/tools \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

# 启用 / 禁用
curl -X PUT http://localhost:18088/api/v1/tools/1 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{"enabled": false}'

# 设置内置或渠道工具的披露分级
curl -X PUT http://localhost:18088/api/v1/tools/1/disclosure-tier \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{"tier": "core"}'

当前 REST API 管理工具行、启用状态和披露分级。内置工具的直接执行走 Agent runtime,不存在 /tools/{name}/test 端点。


自定义工具

路线 1:@Tool Spring bean

java
@Component
public class FactorialTool {

    @Tool(description = "Calculate the factorial of a number")
    public String factorial(
            @ToolParam(description = "The number to compute factorial for") int n) {
        long result = 1;
        for (int i = 2; i <= n; i++) {
            result *= i;
        }
        return String.valueOf(result);
    }
}
  • Spring @Component
  • 每个 @Tool 方法变成一个可调用的工具
  • 每个参数上用 @ToolParam——这是 LLM 读的描述
  • 返回值就是 Agent 看到的观察
  • 工具做任何危险的事情时,为它加一条 Tool Guard 规则

重启后工具就活了。

路线 2:技能脚本

不想写 Java?把行为打包成一个技能包,带 SKILL.md 和脚本。见 技能系统

路线 3:MCP 服务

能力已经以 MCP 服务形式存在?加个服务配置就行。见 MCP 协议


下一步