Skip to main content

概述

Tool 是 agent 与外部世界交互的方式 —— 执行业务操作、调用 API、读写数据等。每个 tool 通过 JSON Schema 暴露给 LLM,agent 通过统一接口完成调用。 AgentScope 把 tool 相关的构件组织成三个概念:
  • Tool —— 任意实现 AgentTool 接口(通常通过继承 ToolBase)或在普通类的方法上标注 @Tool 注解的对象。Java 端把后者称为 reflective function tool,由 Toolkit#registerTool(Object) 自动反射注册。
  • Toolkit —— 容器,负责注册 tool、MCP 客户端与 skill,向模型暴露它们的 JSON schema,并把每次工具调用分发到对应的 tool 对象。
  • Tool Group —— 一组带名称的 tool / MCP / skill 集合,可以作为整体激活或停用。Agent 在运行时通过内置 meta tool 切换 group,让上下文保持聚焦。
只调用 registerTool(Object) 时,被注册对象上所有 @Tool 方法都进入特殊的 "basic" 组 —— 该组始终激活。追加 MCP 客户端、tool group 或 skill 即可拓展 agent 的能力 —— 见下文各节。

Java Tool

Java tool 是任意满足 AgentTool 契约的对象。AgentScope 同时提供了一个 ToolBase 抽象基类用于显式建模带参数 schema 的 tool,以及一个反射适配器用于把普通方法包装成 tool。

AgentTool / ToolBase 接口

ToolBaseAgentTool 的抽象实现,下表列出其属性与方法。 向 agent 与运行时描述 tool 的属性: 接入执行流程与权限系统的方法:

使用内置 Tool

AgentScope 当前提供以下内置 tool: 使用方式:
Toolkit 在出现额外 tool group 或 skill 时会自动注册 reset_tools meta tool 与 skill 查看器工具 load_skill_through_path,开发者无需手动实例化。详见 自我管理 ToolSkill

自定义 Tool(注解式)

最轻量的写法:在普通类的方法上标注 @Tool@ToolParam,然后通过 Toolkit#registerTool(Object) 反射注册。框架自动从 Java 类型推导 JSON schema,从 description 取面向 agent 的说明。
@Tool 常用属性:

自定义 Tool(继承 ToolBase

需要自定义权限策略、外部执行或更复杂的 schema 时,继承 ToolBase

定义外部执行 Tool

外部执行 tool 把实际执行委派给 agent 运行时之外 —— 通常是人工操作员或外部系统。Agent 调用此类 tool 时会发出 RequireExternalExecutionEvent 并暂停。下一次调用回传匹配的 ToolResultBlock 后,agent 会发出带有相同 replyIdExternalExecutionResultEvent,然后继续执行。 这种模式是 human-in-the-loop 工作流的基础 —— 某些动作需要人工确认或人工执行。 创建外部执行 tool 只需把 externalTool 设为 true,不必实现 callAsync
完整可运行示例:agentscope-examples/documentation/.../tool/ToolBaseExample.javatool/ToolExecutionContextExample.java

接收 Context

每次 agent.call(msgs, runtimeContext) 传入的 RuntimeContext 会自动透传到所在 reply 内每一次工具调用。Tool 可以用两种方式拿到它:注解式 tool 走自动注入,ToolBase.callAsyncToolCallParam

自动注入(@Tool 方法)

@Tool 方法签名里,没有标注 @ToolParam 的参数会被框架视为「需要从框架注入」,并按下表的优先级解析: 「用户自定义 POJO」的判定:参数没有 @ToolParam、不是基本类型、不是 ContentBlock / Msg、不在 java.* / javax.* 包下。其余参数(带 @ToolParam 或属于上述兜底类型)从 LLM 提供的 JSON 输入按名称取值。
调用方按类型注册同款 POJO 后,每次 call 就会自动把对应实例分发到所有需要它的 tool:
模型不需要把 userCtx 写进 JSON 参数——schema 里也不会出现它。完整示例:agentscope-examples/documentation/.../tool/ToolExecutionContextExample.java

ToolBase.callAsync 中访问

继承 ToolBase 的 tool 通过 ToolCallParam 取 context:
ToolCallParam 同时暴露 getAgent()getInput()getEmitter()getToolUseBlock() 以及(已 deprecated 的)getContext()。新代码使用 getRuntimeContext()

协调 hook 与 tool

RuntimeContext 的 string 层(put(String, Object) / get(String))是同一次 call 内 middleware 与 tool 之间的临时通信通道——middleware 在 onActing/onReasoning 等位置写入,tool 通过注入 RuntimeContext 参数读取;调用结束后该实例与 hook 一并解绑。

MCP

AgentScope 集成 Model Context Protocol (MCP),让 agent 可以接入任意 MCP 兼容的工具提供方。框架自动处理协议协商、工具发现与结果转换。 支持三种连接方式:
  • STDIO —— 本地进程 stdin/stdout 通信
  • SSE / Streamable HTTP —— 远程 HTTP 长连接
MCP tool 在 toolkit 中以 mcp__{server_name}__{tool_name} 命名,避免冲突;标注了 readOnlyHint 的 tool 会被权限系统自动放行。

注册 MCP Tool

通过 McpClientBuilder 构建 McpClientWrapper,再注册到 Toolkit
完整运行示例:agentscope-examples/documentation/.../mcp/McpStdioExample.javamcp/McpSseExample.javamcp/McpStreamableHttpExample.java

Skill

Skill 是基于 markdown 的指令集,无需写新工具代码即可拓展 agent 能力。每个 skill 是一个目录,包含一个带 frontmatter 元数据与详细指令的 SKILL.md 文件。 与 tool 不同,skill 不能被直接调用。Agent 通过自动注册的查看器工具 load_skill_through_path 读取 skill 指令,再用现有的 tool 按指令执行。

注册 Skill

通过 ReActAgent.builder().skillRepository(...) 直接挂载一个或多个 AgentSkillRepository。Builder 在 build() 时自动装配 DynamicSkillMiddleware,每次 call() 都会按 skill 来源刷新 skill prompt 与 tool group:
多次调用 skillRepository(...) 按调用顺序追加(低 → 高优先级),同名 skill 后者覆盖前者;如需替换整批,调用 skillRepositories(List<AgentSkillRepository>) 参考实现:agentscope-examples/documentation/.../skill/AgentSkillExample.javaskill/SkillWithToolGroupExample.java

Skill 的工作方式

Toolkit 在含 skill 时,注册与查看分两阶段进行。 初始化阶段:
  • Toolkit 扫描所有注册的 skill 来源,收集每个 skill 的名称、描述与目录。
  • 自动把内置查看器工具 load_skill_through_path(实现位于 io.agentscope.core.skill.SkillToolFactory)注册到 skill-build-in-tools 这个 tool group。
  • 组装一段 system prompt 片段,列出可用 skill(仅名称与描述),并指示 agent 通过 load_skill_through_path 读取完整内容。
运行时阶段,agent 用两个必填参数调用查看器: 调用示例:
每次成功调用产生两件事:
  1. 返回请求的内容(SKILL.md markdown,或指定的资源文件)。
  2. 激活该 skill —— Toolkit 中与之绑定的 tool group 被启用,本轮对话余下时段都可调用 skill 自带的工具。如果 path 不存在,查看器会返回错误并列出可用资源路径(SKILL.md 始终排在第一位),便于 agent 重试。
Skill 不是 tool —— agent 不能直接调用 skill。它必须先用 load_skill_through_path 读取指令,再用其他 tool 按描述的步骤执行。

Skill 执行脚本:配置 Shell 工具

Skill 只提供指令,真正的执行依赖 agent 已有的 tool。如果 skill 指令涉及脚本执行(例如 scripts/run.py),agent 需要拥有 shell 执行能力:
  • ReActAgent —— 注册 ShellCommandTool 到 toolkit:
  • HarnessAgent —— harness 模块自带 workspace 感知的 shell 与文件工具(executeread_filewrite_file 等),无需额外注册。

Skill + ToolGroup:按需披露工具

SkillToolGroup 把一组 tool 绑定到某个 skill name —— agent 加载该 skill 时 tool group 自动激活,未加载时 tool 不出现在模型 schema 中,减少上下文噪音。
当 agent 通过 load_skill_through_path 加载名为 data-analysis 的 skill 时,analysis-tools group 自动激活,其中的 tool 立即可用。配合 enableMetaTool(true),模型还可以通过 reset_tools 主动管理 tool group 的激活状态。 参考实现:agentscope-examples/documentation/.../skill/SkillWithToolGroupExample.java

自我管理 Tool

内置 meta toolreset_tools)让 agent 在运行时自我管理哪些 tool group 处于激活状态,从而保持上下文聚焦 —— 只有与当前任务相关的 tool 暴露给模型。

定义 Tool Group

ToolGroup 是带名称的 tool / MCP / skill 集合。把 group 注册到 Toolkit 后再用 builder 启用 meta tool:
ToolGroup 接收名称、描述、作用域(ToolGroupScope)以及初始激活态。保留名 "basic"Toolkit#registerTool(Object) 自动构成,且始终激活。

使用 Meta Tool

只要存在至少一个非 basic 的 tool group,并通过 enableMetaTool(true) 打开开关,Toolkit 就会自动注册 reset_tools 并把其 schema 暴露给 agent。每个非 basic group 在 schema 中表示为一个布尔字段,agent 调用 meta tool 时声明期望的最终状态。 运行时行为:
  • "basic" 组中的 tool 始终暴露,meta tool 不会影响它们。
  • 每次调用 reset_tools 都会整体覆盖激活集合 —— 任何未显式置为 true 的非 basic group 都会被停用,无论之前的状态。
  • 对每个本次切换为激活的 group,其 description 与(若提供的)使用说明会被拼接进 meta tool 的返回值,告诉 agent 如何正确使用该组。
  • 未激活 group 中的 tool 不会出现在 agent 的工具 schema 中,从而把上下文留给当前激活的工具集。
Meta tool 的输入表示所有 group 的最终状态而非增量。任何未显式置为 true 的 group 都会被停用,无论之前的状态如何。

延伸阅读

Agent

Agent 如何在 ReAct 循环中编排 tool 调用

Permission System

精细控制哪个 tool 可以执行、何时执行

Middleware

用洋葱式 middleware 拦截并改写 tool 调用

Human-in-the-Loop

外部执行 tool 与人工审批工作流