文章目录
- [1. 基础概述](#1. 基础概述)
-
- [1.1 Tool 定位](#1.1 Tool 定位)
- [1.2 三大核心构件](#1.2 三大核心构件)
- [1.3 基础注册示例](#1.3 基础注册示例)
- [2. 底层契约:AgentTool & ToolBase](#2. 底层契约:AgentTool & ToolBase)
-
- [2.1 工具元信息属性(对外描述能力)](#2.1 工具元信息属性(对外描述能力))
- [2.2 权限与执行生命周期方法](#2.2 权限与执行生命周期方法)
- [3. 框架内置工具](#3. 框架内置工具)
-
- [3.1 内置工具清单](#3.1 内置工具清单)
- [3.2 注册代码](#3.2 注册代码)
- [3.3 补充说明](#3.3 补充说明)
- [4. 三种自定义 Tool 实现方式](#4. 三种自定义 Tool 实现方式)
-
- [4.1 注解式 @Tool(轻量首选)](#4.1 注解式 @Tool(轻量首选))
- [4.2 继承 ToolBase(高度定制场景)](#4.2 继承 ToolBase(高度定制场景))
- [4.3 外部执行Tool(HITL人在回路)](#4.3 外部执行Tool(HITL人在回路))
- [5. RuntimeContext 上下文透传](#5. RuntimeContext 上下文透传)
-
- [5.1 @Tool 注解方法:自动注入](#5.1 @Tool 注解方法:自动注入)
- [5.2 ToolBase 实现类:手动获取](#5.2 ToolBase 实现类:手动获取)
- [6. 自我管理工具(Meta Tool reset_tools)](#6. 自我管理工具(Meta Tool reset_tools))
-
- [6.1 ToolGroup 分组注册示例](#6.1 ToolGroup 分组注册示例)
- [6.2 reset_tools 自动注册条件](#6.2 reset_tools 自动注册条件)
- [6.3 运行时行为规则](#6.3 运行时行为规则)
1. 基础概述
1.1 Tool 定位
Tool 是 Agent 对接外部环境的交互媒介,可完成业务逻辑执行、第三方 API 调用、数据读写等操作。所有工具统一通过 JSON Schema 向大模型暴露能力,Agent 依靠标准化统一接口完成调用执行。
1.2 三大核心构件
AgentScope 将工具体系拆分为 Tool、Toolkit、Tool Group 三层结构。
Tool 是满足 AgentTool 契约的执行单元,两种实现形态:
- 普通类方法标注
@Tool注解(反射式工具,由Toolkit#registerTool(Object)自动反射注册) - 继承
ToolBase抽象基类,显式实现工具完整契约
Toolkit 是全局工具容器管理器,负责:
- 注册
Tool、MCP客户端、Skill - 聚合生成工具
JSON Schema下发模型 - 分发调度每一次工具调用请求
Tool Group 是命名式集合:
- 可收纳
Tool/MCP/Skill,支持整体启用/停用 Agent运行时可通过内置元工具切换分组状态,精简LLM上下文。
1.3 基础注册示例
java
import io.agentscope.core.tool.Toolkit;
import io.agentscope.core.tool.builtin.TodoTools;
Toolkit toolkit = new Toolkit();
toolkit.registerTool(new TodoTools());
toolkit.registerTool(new MyCustomTools());
规则:仅使用
registerTool(Object)注册时,所有@Tool方法自动归入basic分组,该分组永久激活。可额外注册MCP、自定义ToolGroup、Skill扩展能力。
2. 底层契约:AgentTool & ToolBase
ToolBase 是 AgentTool 接口标准抽象实现,封装工具元信息、权限、执行全生命周期。
2.1 工具元信息属性(对外描述能力)
| 方法 | 返回类型 | 说明 |
|---|---|---|
getName() |
String | 暴露给Agent的工具唯一名称 |
getDescription() |
String | 面向LLM的工具功能描述 |
getParameters() |
Map<String, Object> | 自定义入参JSON Schema结构 |
isConcurrencySafe() |
boolean | 是否支持并发调用 |
isReadOnly() |
boolean | 是否只读、无数据变更副作用 |
isExternalTool() |
boolean | true=执行逻辑外置(人工HITL场景) |
isStateInjected() |
boolean | true=自动注入会话状态AgentState |
isMcp() |
boolean | 是否来源于MCP远程服务 |
getMcpName() |
String | MCP服务标识,仅isMcp()=true生效 |
2.2 权限与执行生命周期方法
| 方法 | 是否必需 | 功能说明 |
|---|---|---|
checkPermissions(toolInput, context) |
必选 | 调用前置权限校验,返回Mono<PermissionDecision> |
matchRule(ruleContent, toolInput) |
可选 | 权限体系自定义规则匹配,返回布尔值 |
generateSuggestions(toolInput) |
可选 | 根据本次调用生成权限规则建议列表 |
callAsync(param) |
可选 | 工具异步执行主逻辑,返回Mono<ToolResultBlock>;外部执行工具无需实现 |
3. 框架内置工具
3.1 内置工具清单
| 工具 | 功能说明 | 只读 |
|---|---|---|
| TodoTools.todoWrite | 维护会话结构化任务列表,全列表替换语义 | 否 |
3.2 注册代码
java
Toolkit toolkit = new Toolkit();
toolkit.registerTool(new io.agentscope.core.tool.builtin.TodoTools());
3.3 补充说明
当 Toolkit 中存在自定义 ToolGroup 或 Skill 资源时,框架自动注册两类元工具,无需手动实例化:
reset_tools:分组启停管理元工具load_skill_through_path:Skill加载查看工具
4. 三种自定义 Tool 实现方式
4.1 注解式 @Tool(轻量首选)
最简开发模式,框架自动解析 Java 类型生成 Schema,注解填充功能描述。
@Tool 核心属性
| 属性 | 类型 | 说明 |
|---|---|---|
| name | String | 工具名称,默认取方法名 |
| description | String | LLM可见功能描述 |
| readOnly | boolean | 是否只读,默认false |
| concurrencySafe | boolean | 是否并发安全,默认false |
| stateInjected | boolean | 自动注入AgentState参数,默认false |
| dangerousFiles / dangerousDirectories | String\[\] | 自定义高危文件/目录黑名单 |
| converter | ToolResultConverter子类 | 自定义返回值序列化转换器 |
简单示例:
java
import io.agentscope.core.tool.Tool;
import io.agentscope.core.tool.ToolParam;
import io.agentscope.core.tool.Toolkit;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class SimpleTools {
@Tool(
name = "get_current_time",
description = "Returns the current time in a given IANA timezone.",
readOnly = true,
concurrencySafe = true)
public String getCurrentTime(
@ToolParam(name = "timezone", description = "IANA timezone, e.g. Asia/Shanghai")
String timezone) {
return LocalDateTime.now(ZoneId.of(timezone))
.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
}
// 注册
Toolkit toolkit = new Toolkit();
toolkit.registerTool(new SimpleTools());
4.2 继承 ToolBase(高度定制场景)
适用于自定义权限、复杂 Schema、特殊返回结构场景。
简单示例:
java
import io.agentscope.core.message.TextBlock;
import io.agentscope.core.message.ToolResultBlock;
import io.agentscope.core.permission.PermissionDecision;
import io.agentscope.core.tool.ToolBase;
import io.agentscope.core.tool.ToolCallParam;
import io.agentscope.core.tool.ToolExecutionContext;
import java.util.List;
import java.util.Map;
import reactor.core.publisher.Mono;
public class WebSearchTool extends ToolBase {
public WebSearchTool() {
super(
ToolBase.builder()
.name("WebSearch")
.description("Search the web for information on a given query.")
.inputSchema(Map.of(
"type", "object",
"properties", Map.of(
"query", Map.of(
"type", "string",
"description", "The search query.")),
"required", List.of("query")))
.readOnly(true)
.concurrencySafe(true));
}
// 权限校验
@Override
public Mono<PermissionDecision> checkPermissions(
Map<String, Object> toolInput, ToolExecutionContext context) {
return Mono.just(PermissionDecision.allow("Web search is read-only."));
}
// 异步执行逻辑
@Override
public Mono<ToolResultBlock> callAsync(ToolCallParam param) {
String query = (String) param.getInput().get("query");
return doSearchAsync(query)
.map(text ->
ToolResultBlock.builder()
.id(param.getId())
.name(getName())
.output(List.of(TextBlock.builder().text(text).build()))
.build());
}
}
4.3 外部执行Tool(HITL人在回路)
执行逻辑剥离到 Agent 运行时外部(人工审批、第三方系统);Agent 调用后暂停,等待外部事件回调结果。
核心标识:externalTool(true),无需实现callAsync
执行流程:
Agent发起调用 → 推送RequireExternalExecutionEvent并暂停运行- 人工/外部系统处理业务
- 通过
ExternalExecutionResultEvent回传结果,Agent恢复推理
简单示例:
java
import io.agentscope.core.permission.PermissionDecision;
import io.agentscope.core.tool.ToolBase;
import io.agentscope.core.tool.ToolExecutionContext;
import java.util.List;
import java.util.Map;
import reactor.core.publisher.Mono;
public class HumanApprovalTool extends ToolBase {
public HumanApprovalTool() {
super(
ToolBase.builder()
.name("HumanApproval")
.description("Request human approval for a sensitive operation.")
.inputSchema(Map.of(
"type", "object",
"properties", Map.of(
"action", Map.of("type", "string"),
"reason", Map.of("type", "string")),
"required", List.of("action", "reason")))
.readOnly(false)
.concurrencySafe(true)
.externalTool(true)); // 标记外部执行
}
@Override
public Mono<PermissionDecision> checkPermissions(
Map<String, Object> toolInput, ToolExecutionContext context) {
return Mono.just(PermissionDecision.allow("External tool dispatch is always allowed."));
}
}
5. RuntimeContext 上下文透传
agent.call(msgs, runtimeContext) 传入的运行上下文,会自动透传给本次会话内所有工具调用,分两种取值方式。
5.1 @Tool 注解方法:自动注入
未标注@ToolParam的参数,框架自动匹配注入源:
| 参数类型 | 注入来源 |
|---|---|
| ToolEmitter | 流式输出发射器 |
| Agent | 当前运行Agent实例 |
| AgentState | 会话独立状态(取自RuntimeContext) |
| RuntimeContext | 单次调用全局上下文 |
| ToolExecutionContext | 兼容层,已废弃 |
| 自定义POJO | runtimeContext.get(POJO.class) |
POJO 判定规则 :无@ToolParam、非基础类型、非消息块/Msg、不属于java.* / javax.*包。该类参数不会出现在 LLM 入参 Schema。
示例:
java
public record UserContext(String username, String locale) {}
public class PersonalizedTools {
@Tool(name = "greet", description = "Greet the user with a custom greeting")
public String greet(
@ToolParam(name = "greeting", description = "Greeting word, e.g. 'Hello'")
String greeting,
UserContext userCtx) { // 框架自动注入
return greeting + ", " + (userCtx == null ? "unknown" : userCtx.username()) + "!";
}
}
// 调用方组装上下文
RuntimeContext ctx =
RuntimeContext.builder()
.put(UserContext.class, new UserContext("alice", "en"))
.userId("alice")
.build();
agent.call(List.of(new UserMessage("Greet me.")), ctx).block();
5.2 ToolBase 实现类:手动获取
在callAsync中通过ToolCallParam读取上下文:
java
import io.agentscope.core.agent.RuntimeContext;
import io.agentscope.core.tool.ToolBase;
import io.agentscope.core.tool.ToolCallParam;
import reactor.core.publisher.Mono;
public class TenantAwareTool extends ToolBase {
@Override
public Mono<io.agentscope.core.message.ToolResultBlock> callAsync(ToolCallParam param) {
RuntimeContext rc = param.getRuntimeContext();
String tenantId = rc != null ? rc.getUserId() : null;
TenantConfig cfg = rc != null ? rc.get(TenantConfig.class) : null;
// 租户隔离业务逻辑
}
}
ToolCallParam额外支持获取:Agent 实例、原始入参、Emitter、ToolUseBlock 元数据。
6. 自我管理工具(Meta Tool reset_tools)
内置元工具允许 Agent 运行时自主启停分组,只暴露当前任务所需工具,降低上下文 Token消耗与模型混淆概率。
6.1 ToolGroup 分组注册示例
java
import io.agentscope.core.ReActAgent;
import io.agentscope.core.tool.Toolkit;
import io.agentscope.core.tool.ToolGroup;
import io.agentscope.core.tool.ToolGroupScope;
Toolkit toolkit = new Toolkit();
toolkit.registerTool(new BasicTools()); // 归入basic永久分组
// 数据库分组:会话域、默认关闭
ToolGroup database =
new ToolGroup(
"database",
"Tools for database operations.",
ToolGroupScope.SESSION,
false);
database.addTool("db_query");
database.addTool("db_migrate");
toolkit.registerTool(new DatabaseTools());
toolkit.registerToolGroup(database);
// 部署运维分组:会话域、默认关闭
ToolGroup deployment =
new ToolGroup(
"deployment",
"Tools for deploying services.",
ToolGroupScope.SESSION,
false);
deployment.addTool("deploy");
deployment.addTool("rollback");
toolkit.registerTool(new DeploymentTools());
toolkit.registerToolGroup(deployment);
// 构建Agent并开启元工具
ReActAgent agent =
ReActAgent.builder()
.name("router")
.toolkit(toolkit)
.enableMetaTool(true)
.build();
6.2 reset_tools 自动注册条件
同时满足两点自动注册并透出 Schema:
- 存在至少一个非
basic自定义ToolGroup; Agent构建开启开关:enableMetaTool(true)。
每个非 basic 分组在 reset_tools 入参 Schema 映射为独立布尔字段,Agent 传布尔值声明全部分组最终启用状态。
6.3 运行时行为规则
basic分组永久激活,不受元工具任何操作影响;- 全量覆盖模式:每次调用
reset_tools整体刷新激活集合,非basic分组未显式设为true则强制停用,无视历史状态; - 新激活分组自动拼接分组描述、自定义使用提示,随元工具返回值下发给
Agent; - 停用分组内所有工具从
LLM工具Schema中移除,压缩上下文。
reset_tools入参代表全局最终状态,并非增量开关。仅填写要开启的分组会导致其余所有自定义分组全部关闭,历史激活状态不会保留。