前言

在构建 AI Agent 时,「让大模型用上工具」几乎是最关键的环节。AgentScope 2.0 把这一环节拆成了三个互补的能力:

  • Tool(自定义工具):开发者用 Java 写的本地方法,最贴近业务
  • MCP(Model Context Protocol):跨进程、跨语言的标准工具协议,复用生态
  • Skill(技能):基于 Markdown 的指令包,不动代码就能扩展 Agent 能力

这三类能力既独立又统一——最终都汇入 Toolkit,并以 JSON Schema 的形式暴露给 LLM。本文以 [agentscope2.0demo](file:///c:/me/kaiyuan/agenttrace/agentscope2.0demo) 项目为示例,结合源码讲清楚它们各自的加载流程与协作方式。


一、项目概览

在深入加载机制之前,先认识一下示例项目本身。这个 demo 是一个基于 Spring Boot 的 Chat Service,用 AgentScope 2.0 把一个 ReActAgent 包装成 HTTP 接口,演示了 Tool/MCP/Skill 三种能力的完整集成。
在这里插入图片描述

1.1 技术栈与版本

项目依赖在 [pom.xml](file:///c:/me/kaiyuan/agenttrace/agentscope2.0demo/pom.xml) 中声明,核心版本如下:

框架 / 库版本用途
JDK17运行时基线
Spring Boot3.5.0Web 框架与 IoC 容器
AgentScope2.0.0Agent 核心框架(agentscope-core + agentscope-extensions-model-openai
MCP SDK0.17.0Model Context Protocol 客户端实现(版本由 AgentScope 2.0.0 决定)
OpenTelemetry1.61.0可观测性 API/SDK + OTLP Exporter
OpenTelemetry SemConv1.27.0-alphaGenAI 语义约定
Lombok随 Spring Boot 父 POM减少样板代码

其中 OpenTelemetry 相关依赖主要为可观测性预留,本文不展开,后续会单独成文。

1.2 代码结构

项目采用典型的 Spring Boot 分层结构:

agentscope2.0demo/
├── pom.xml                          # Maven 依赖与构建配置
├── src/main/
│   ├── java/com/conca/chat/
│   │   ├── ChatApplication.java         # Spring Boot 启动入口
│   │   ├── config/                       # 配置层(装配核心 Bean)
│   │   │   ├── AgentConfig.java          #   ★ ReActAgent + Toolkit 装配
│   │   │   ├── McpToolkitConfig.java     #   ★ MCP 客户端装配
│   │   │   ├── ModelConfig.java          #   OpenAIChatModel 装配
│   │   │   ├── WorkspaceLoader.java      #   工作区扫描(subagents 等)
│   │   │   ├── TracingConfig.java        #   可观测性配置
│   │   │   └── LangfuseEnrichmentMiddleware.java
│   │   ├── controller/                   # HTTP 接口层
│   │   │   ├── ChatController.java       #   /chat 对话接口
│   │   │   └── DebugController.java      #   调试接口
│   │   ├── dto/                          # 数据传输对象
│   │   │   ├── ChatRequest.java
│   │   │   ├── ChatResponse.java
│   │   │   └── StreamEvent.java
│   │   ├── session/
│   │   │   └── SessionManager.java       # 会话管理
│   │   └── tool/
│   │       └── CustomTools.java          #   ★ @Tool 自定义工具
│   └── resources/
│       └── application.yaml              # ★ 配置入口(workspace、mcp.clients)
├── workspace/                            # 运行时工作区
│   ├── AGENTS.md                         # 系统提示词补充
│   ├── skills/                           # ★ Skill 仓库
│   │   └── demo-skill/SKILL.md
│   ├── subagents/                        # 子智能体定义
│   │   └── helper.md
│   └── sessions/                         # 会话状态持久化目录
│       └── __anon__/<sessionId>/agent_state.json
└── io/agentscope/core/                   # AgentScope 核心源码(参考阅读用)
    ├── ReActAgent.java
    ├── skill/                            # Skill 子系统
    │   ├── AgentSkill.java
    │   └── repository/FileSystemSkillRepository.java
    └── tool/
        ├── Toolkit.java                  # ★ 工具容器核心
        └── mcp/                          # MCP 客户端

1.3 关键约定

从结构上能看出几个项目约定:

  • 配置集中在 config/ :所有 Spring @Configuration / @Bean 都在这里,业务代码不感知装配细节;
  • 工具与 Agent 解耦CustomTools 是纯业务工具,AgentConfig 负责把它和 MCP、Skill 装到一起;
  • workspace 是运行时数据根:Skill、subagent、session 状态都在这个目录下,便于热更新与备份;
  • io/agentscope/core/ 是 AgentScope 框架源码:放在项目里只是为了方便阅读源码,不是业务代码。

1.4 装配链路一览

后面几章会展开细节,这里先给一张装配链路速查:

ChatApplication (启动)
     │
     ▼
Spring 自动扫描 @Configuration
     │
     ├─ ModelConfig        →  OpenAIChatModel
     ├─ McpToolkitConfig   →  List<McpClientWrapper>     ← application.yaml:mcp.clients
     ├─ AgentConfig        →  Toolkit (含 CustomTools + MCP)
     │                     →  FileSystemSkillRepository  ← workspace/skills/
     │                     →  ReActAgent
     ├─ WorkspaceLoader    →  扫描 workspace/subagents/
     └─ TracingConfig     →  可观测性
              │
              ▼
        ChatController 注入 ReActAgent,对外暴露 /chat

带着这张地图,下面进入正式的加载机制讲解。


二、整体架构

AgentScope 把 tool 相关的构件组织成三个概念:

概念角色注册入口
Tool任意实现 AgentTool 接口或标注 @Tool 注解的对象Toolkit.registerTool()
MCP Client通过 MCP 协议连接的外部工具服务器Toolkit.registerMcpClient()
SkillMarkdown 写成的指令包,附带可选资源文件ReActAgent.builder().skillRepository()

注意:Skill 是「指令 + 资源」,不会直接出现在 Toolkit 的工具表里;Agent 在推理过程中通过 load_skill_through_path 这个内置工具按需读取 Skill 内容。这是 Skill 与 Tool/MCP 在加载方式上最大的区别。

加载流程可以浓缩成下面这张图:

        ┌─────────────────────┐
        │  application.yaml   │  ← 配置入口(workspace、mcp.clients)
        └──────────┬──────────┘
                   │
   ┌───────────────┼────────────────┐
   ▼               ▼                ▼
CustomTools    McpToolkitConfig   skillRepository()
(@Tool 注解)   (McpClientWrapper) (FileSystemSkillRepository)
   │               │                │
   └──────►Toolkit◄─┘                │
                │                     │
                ▼                     ▼
        ReActAgent.builder().toolkit(...).skillRepository(...)
                │
                ▼
           ReActAgent(推理循环中把 schema 暴露给 LLM)

下面分别展开。


三、自定义工具(Tool)的加载

3.1 用 @Tool 注解定义工具

最简单的扩展方式:在一个 Spring @Component 上标注 @Tool 方法。项目中的 [CustomTools.java](file:///c:/me/kaiyuan/agenttrace/agentscope2.0demo/src/main/java/com/conca/chat/tool/CustomTools.java) 就是范例:

@Component
public class CustomTools {

    @Tool(
        name = "get_current_datetime",
        description = "获取当前日期和时间",
        readOnly = true,
        concurrencySafe = true
    )
    public String getCurrentDateTime() {
        LocalDateTime now = LocalDateTime.now();
        return now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
}

@Tool 注解的常用属性:

属性说明
name工具名(默认取方法名)
description面向 LLM 的工具说明,决定模型何时调用
readOnly是否只读(影响权限判定)
concurrencySafe是否可并发调用
stateInjected是否注入 AgentState
dangerousFiles / dangerousDirectories自定义危险路径

3.2 通过 Toolkit.registerTool 注册

在 [AgentConfig.java](file:///c:/me/kaiyuan/agenttrace/agentscope2.0demo/src/main/java/com/conca/chat/config/AgentConfig.java#L34-L51) 中,Toolkit 由 Spring 装配:

@Bean
public Toolkit toolkit(CustomTools customTools,
                       List<McpClientWrapper> mcpClientWrappers) {
    Toolkit toolkit = new Toolkit();

    // 1. 注册自定义工具(扫描 @Tool 注解)
    toolkit.registerTool(customTools);

    // 2. 注册所有 MCP 客户端
    for (McpClientWrapper wrapper : mcpClientWrappers) {
        toolkit.registerMcpClient(wrapper).block();
    }
    return toolkit;
}

Toolkit.registerTool(Object) 内部的扫描逻辑(见 [Toolkit.java](file:///c:/me/kaiyuan/agenttrace/agentscope2.0demo/io/agentscope/core/tool/Toolkit.java#L154-L197)):

  1. 遍历对象的所有声明方法;
  2. 对带 @Tool 注解的方法,解析 name/description/converter 等元数据;
  3. ToolSchemaGenerator 生成参数的 JSON Schema;
  4. 包装成 ReflectiveFunctionToolToolBase 的子类),统一进入权限、并发、流式输出的处理链。

注册完成后,工具名会被记入 ToolRegistry,并在每次推理时通过 ToolSchemaProvider 把可见工具的 schema 一并提交给 LLM。


四、MCP 客户端的加载

4.1 配置驱动:application.yaml

MCP 客户端完全由配置驱动,无需写代码:

mcp:
  clients:
    - name: file-list-server
      url: http://localhost:8765/mcp
      transport: auto
  • transport: auto 表示根据 URL 后缀自动判断:以 /sse 结尾走 SSE,否则走 Streamable HTTP。
  • name 是 MCP 客户端的唯一标识,用于日志与工具归属。

4.2 构造 McpClientWrapper 列表

[McpToolkitConfig.java](file:///c:/me/kaiyuan/agenttrace/agentscope2.0demo/src/main/java/com/conca/chat/config/McpToolkitConfig.java) 把 yaml 中的每条配置转成一个 McpClientWrapper

@Bean
public List<McpClientWrapper> mcpClientWrappers(McpClientsProperties props) {
    List<McpClientWrapper> wrappers = new ArrayList<>();
    for (McpClientConfig cfg : props.getClients()) {
        wrappers.add(buildClient(cfg));   // 单个 client 失败不影响其他
    }
    return wrappers;
}

private McpClientWrapper buildClient(McpClientConfig config) {
    McpClientBuilder builder = McpClientBuilder.create(config.getName());
    if ("sse".equalsIgnoreCase(transport)
            || ("auto".equalsIgnoreCase(transport) && url.endsWith("/sse"))) {
        builder.sseTransport(url);
    } else {
        builder.streamableHttpTransport(url);   // 默认走 Streamable HTTP
    }
    return builder.buildSync();
}

AgentScope 的 MCP 客户端支持三种传输:

传输方式适用场景Builder
Streamable HTTP默认推荐,性能更好McpClientBuilder.streamableHttp()
SSE兼容老版本 MCP 服务器McpClientBuilder.sse()
STDIO启动本地子进程型 MCP 服务器McpClientBuilder.stdio()

4.3 注册到 Toolkit

回到上面 Toolkit toolkit(...) 这个 Bean——它会把 List<McpClientWrapper> 全部注入:

for (McpClientWrapper wrapper : mcpClientWrappers) {
    try {
        toolkit.registerMcpClient(wrapper).block();
        log.info("Registered MCP client: {}", wrapper.getName());
    } catch (Exception e) {
        log.warn("Failed to register MCP client '{}': {}", wrapper.getName(), e.getMessage());
    }
}

Toolkit.registerMcpClient 把工作委托给 McpClientManager

  1. 调用 MCP 协议的 listTools 拿到远端工具列表;
  2. 把每个远端工具包装成 AgentTool,注册到 ToolRegistry
  3. 同时记录这些工具属于哪个 MCP 客户端,便于后续按 client 维度卸载。

注册完成后,MCP 工具和本地 @Tool 方法在 Toolkit地位完全一致——LLM 看到的都是 JSON Schema,调用流程也走统一的 ToolExecutor

4.4 高级用法:Builder API

如果想对 MCP 工具做更细粒度的控制(白名单、分组、预设参数),可以用流式 API:

toolkit.registration()
    .mcpClient(mcpClientWrapper)
    .enableTools(List.of("read_file", "list_files"))   // 只启用这两个工具
    .group("file-ops")                                  // 归入 file-ops 分组
    .presetParameters(Map.of(                           // 自动注入参数
        "read_file", Map.of("encoding", "UTF-8")))
    .apply();

五、Skill 的加载

Skill 是 AgentScope 里最「轻量」的扩展方式——不写一行 Java 代码,只要放一个 Markdown 目录就够了。

5.1 Skill 目录结构

项目中的 demo skill 位于 [workspace/skills/demo-skill/SKILL.md](file:///c:/me/kaiyuan/agenttrace/agentscope2.0demo/workspace/skills/demo-skill/SKILL.md):

workspace/skills/
└── demo-skill/
    └── SKILL.md

SKILL.md 由两部分组成:YAML frontmatter + Markdown 正文。

---
name: demo-skill
description: 示例技能,展示如何为 Agent 添加自定义能力
version: 1.0.0
---

# Demo Skill

## 使用场景
当用户询问时间时,Agent 可以使用此技能中的工具。

## 可用工具
- `getCurrentDateTime` - 获取当前日期时间

如果还需要附带参考资料或脚本,可以扩展成:

demo-skill/
├── SKILL.md              # 必需
├── references/           # 可选:参考文档
│   └── style-guide.md
└── scripts/              # 可选:可被 shell 调用的脚本
    └── run.sh

5.2 FileSystemSkillRepository:从磁盘加载

[AgentConfig.java](file:///c:/me/kaiyuan/agenttrace/agentscope2.0demo/src/main/java/com/conca/chat/config/AgentConfig.java#L53-L57) 中只用了两行就完成了 Skill 仓库的装配:

@Bean
public FileSystemSkillRepository skillRepository() {
    Path skillsPath = Paths.get(workspacePath, "skills");
    return new FileSystemSkillRepository(skillsPath, false);
}

构造参数:

  • baseDir:技能根目录(这里是 ./workspace/skills
  • writeable:是否允许运行时写入/删除 skill

FileSystemSkillRepository 的加载细节(见 [FileSystemSkillRepository.java](file:///c:/me/kaiyuan/agenttrace/agentscope2.0demo/io/agentscope/core/skill/repository/FileSystemSkillRepository.java#L179-L220))有几个值得注意的点:

  1. 目录扫描getAllSkills() 遍历 baseDir 下的一级子目录,每个子目录必须包含 SKILL.md
  2. 按需缓存:用 Map<Path, Snapshot> 缓存已解析的 AgentSkill,并以 SKILL.md 的 mtime + size 作为失效依据——重复调用 getAllSkills() 不会重复读盘;
  3. 资源加载策略:构造时通过 lazy 参数控制是否预读所有支持文件。demo 项目里 lazy=false,会把 SKILL.md 和支持文件都读进内存;
  4. 目录消失时自动清理缓存,避免已删除的 skill 仍被引用。

5.3 把 SkillRepository 注入 Agent

ReActAgent 在构造时接收 skillRepository

@Bean
public ReActAgent chatAgent(OpenAIChatModel model, Toolkit toolkit,
                            WorkspaceLoader workspaceLoader,
                            FileSystemSkillRepository skillRepository) {
    return ReActAgent.builder()
            .name("chat-agent")
            .sysPrompt(sysPrompt)
            .model(model)
            .toolkit(toolkit)                  // 工具 + MCP 都在这里
            .skillRepository(skillRepository)  // skill 仓库
            .enableMetaTool(true)
            .maxIters(10)
            .build();
}

5.4 Agent 如何“使用” Skill

这是 Skill 和 Tool/MCP 在机制上最大的不同:

  • 推理前:Agent 把所有 Skill 的 name + description 列在 system prompt 的 <available_skills> 块里(仅元信息,不占大量 token);
  • 推理中:当 LLM 觉得需要某个 Skill 时,会调用内置工具 load_skill_through_path
    • load_skill_through_path(skillId, path="SKILL.md") —— 读取 Markdown 正文
    • load_skill_through_path(skillId, path="references/style-guide.md") —— 读取任意资源文件
  • 加载后:Agent 把 Skill 内容拼入上下文,再按 Skill 中的指令执行后续动作(可能调用其他工具)。

这种「按需加载」的设计让 Skill 适合承载体积较大、低频使用的能力——既不挤占每次推理的上下文,又能在需要时被精准唤起。

5.5 多源 Skill 仓库

FileSystemSkillRepository 只是其中一种实现。AgentScope 还提供:

实现适用场景
GitSkillRepository团队共享、版本化管理的 skill 库
NacosSkillRepository配置中心动态分发
MysqlSkillRepository数据库存储、带审计
ClasspathSkillRepository随 jar 打包的内置 skill

可以多次调用 .skillRepository(repo) 接入多个源,后注册的同名 skill 会覆盖先注册的。


六、三种能力如何在 ReActAgent 中协作

6.1 装配关系

回到 [AgentConfig.java](file:///c:/me/kaiyuan/agenttrace/agentscope2.0demo/src/main/java/com/conca/chat/config/AgentConfig.java#L59-L85),可以清晰看到三者的汇合点:

ReActAgent.builder()
    .name("chat-agent")
    .model(model)                   // LLM
    .toolkit(toolkit)               // ← Tool + MCP 在这里
    .skillRepository(skillRepository)  // ← Skill 在这里
    .enableMetaTool(true)           // 让 Agent 能自我管理工具分组
    .maxIters(10)
    .build();

在这里插入图片描述

6.2 推理循环里的统一视图

每次用户发消息,ReActAgent 的 ReAct 循环大致这样运转:

  1. 构造 system prompt:包含原始 sysPrompt、可用 skill 列表、当前激活工具分组的说明;
  2. 收集 tool schemasToolkit.getToolSchemas() 返回所有可见工具(含 @Tool、MCP、内置 meta tool),交给 LLM;
  3. LLM 决策:模型返回文本或 tool_call;
  4. 工具执行:调用 Toolkit.callTools(),由 ToolExecutor 并发执行(受 concurrencySafe 标记约束);
  5. 结果回填:工具结果作为 ToolResultBlock 加入消息,进入下一轮推理;
  6. 循环直到:模型不再调用工具,或达到 maxIters

Skill 在这套循环中扮演的是「上下文增强」的角色——它本身不参与工具 schema 列表,而是通过 load_skill_through_path 把指令注入对话,再由 LLM 在后续轮次里调度 Tool/MCP 去落地。

6.3 工具分组(Tool Group):动态开关

Toolkit 还支持把工具划分到不同的 group 里,运行时按需激活。enableMetaTool(true) 会注入一个名为 reset_equipped_tools 的内置工具,让 LLM 自己决定哪些分组可见。这在工具数量多、需要按场景裁剪时非常有用。

ToolGroup database = new ToolGroup(
    "database",
    "数据库相关工具",
    ToolGroupScope.SESSION,
    false);                // 初始未激活
database.addTool("db_query");
toolkit.registerToolGroup(database);

七、配置一览

把整个加载链路用 [application.yaml](file:///c:/me/kaiyuan/agenttrace/agentscope2.0demo/src/main/resources/application.yaml) 串起来:

agentscope:
  workspace: ./workspace          # Skill 和 subagent 的根目录
  sessions-dir: ./workspace/sessions

mcp:
  clients:                        # MCP 客户端列表
    - name: file-list-server
      url: http://localhost:8765/mcp
      transport: auto
  • workspace 路径,Skill 和 subagent 的加载位置会同步变化;
  • 增减 mcp.clients 条目,就能挂载/卸载外部 MCP 服务器;
  • 自定义工具通过 Spring @Component 自动扫描注入,不在这里配置。

八、快速验证:一次端到端测试

配置就绪后,启动 Spring Boot 应用(mvn spring-boot:run),用一条 PowerShell 命令即可验证整条加载链路是否打通。下面这个用例会让 Agent 调用 MCP 工具 file-list-server 来列出当前目录下的文件:

PS C:\Users\conca> Invoke-RestMethod -Uri http://localhost:8080/api/chat `
>>     -Method Post `
>>     -Headers @{"Content-Type"="application/json; charset=utf-8"} `
>>     -Body ([System.Text.Encoding]::UTF8.GetBytes('{"message":"请列出当前目录下的文件"}'))

sessionId                              reply
---------                              -----
62186f9a-d1f3-4277-8476-fabebf684d23   起来你的系统根目录是 **C:\** ,以下是该目录下的...

8.1 这条命令做了什么

要素说明
接口POST /api/chat,由 [ChatController](file:///c:/me/kaiyuan/agenttrace/agentscope2.0demo/src/main/java/com/conca/chat/controller/ChatController.java) 暴露
请求体{"message":"请列出当前目录下的文件"},用 UTF-8 字节传输,避免中文乱码
触发的工具Agent 收到"列出文件"的请求后,会调度 MCP 客户端 file-list-server(即 application.yaml 里配置的那个)
返回的 sessionId62186f9a-d1f3-4277-8476-fabebf684d23,对应 workspace/sessions/__anon__/ 下的状态文件,可用于多轮对话

8.2 背后发生了什么

这一次看似简单的调用,实际上完整跑通了本文介绍的三条加载链路:

  1. Tool 链路get_current_datetime 已注册到 Toolkit(虽然本次对话没用上,但 schema 已暴露给 LLM);
  2. MCP 链路:Agent 通过 file-list-server 这个 MCP 客户端调用了远端的文件列表工具——这正是 reply 里能看到目录内容的原因;
  3. Skill 链路demo-skillname + description 已出现在 system prompt 的 <available_skills> 块里,Agent 可以按需加载。

用一张时序图概括:

PowerShell 客户端
      │
      │  POST /api/chat  {"message":"请列出当前目录下的文件"}
      ▼
ChatController ──► ReActAgent.chat(msgs)
                        │
                        │  1. 构造 system prompt(含 <available_skills>)
                        │  2. 收集 tool schemas(@Tool + MCP 工具)
                        │  3. 调用 LLM
                        ▼
                    OpenAIChatModel (via OpenRouter)
                        │
                        │  返回 tool_call: file-list-server 的某工具
                        ▼
                    Toolkit.callTools()
                        │
                        │  通过 MCP 协议调用 http://localhost:8765/mcp
                        ▼
                    MCP Server (file-list-server)
                        │
                        │  返回目录列表
                        ▼
                    ReActAgent 拼装最终回复
                        │
                        ▼
ChatController 返回 {sessionId, reply}

8.3 关于中文乱码

上面示例中,如果直接用 Invoke-RestMethod 而不指定 UTF-8 编码,回复可能出现类似 çèµ·æ¨çç³»ç» 的乱码——这是 PowerShell 5.x 默认按系统编码(GBK)解析响应体导致的。解决方案有两种:

方案一:强制 UTF-8 编码请求体(推荐)

$body = [System.Text.Encoding]::UTF8.GetBytes('{"message":"请列出当前目录下的文件"}')
Invoke-RestMethod -Uri http://localhost:8080/api/chat `
    -Method Post `
    -Headers @{"Content-Type"="application/json; charset=utf-8"} `
    -Body $body

方案二:切换到 PowerShell 7+

PowerShell 7 默认使用 UTF-8,无需额外处理:

pwsh -c 'irm http://localhost:8080/api/chat -Method Post -ContentType "application/json; charset=utf-8" -Body ''{"message":"请列出当前目录下的文件"}'''

8.4 更多测试场景

通过调整 message 字段,可以分别验证三类能力的加载是否正常:

测试 message期望触发验证目标
现在几点了?get_current_datetime(@Tool)自定义工具注册成功
请列出当前目录下的文件file-list-server(MCP)MCP 客户端连接与工具注册
加载 demo-skill 技能load_skill_through_path(内置工具)Skill 仓库扫描与按需加载
加载 demo-skill 后,告诉我它能做什么Skill 加载 + 后续推理Skill 与推理循环的协作

每次对话返回的 sessionId 都可以用于后续追问,实现多轮上下文。例如:{"message":"还有别的吗?","sessionId":"62186f9a-d1f3-4277-8476-fabebf684d23"}


九、设计要点小结

回到 AgentScope 2.0 的工具加载机制,有几个设计决策值得品味:

  1. 统一入口 Toolkit:本地工具、MCP 工具、子 Agent 工具在注册后共用同一套执行、权限、流式输出机制,LLM 侧无需感知差异;
  2. 配置驱动 MCP:通过 yaml + Spring 自动装配,新增一个 MCP 服务器只需改配置;
  3. Skill 的按需加载:用 <available_skills> 列元信息 + load_skill_through_path 按需取内容,平衡能力扩展与上下文成本;
  4. 缓存与失效FileSystemSkillRepository 用 mtime+size 做缓存键,热加载友好;
  5. 失败隔离:单个 MCP client 注册失败只 warn 不抛,避免一处坏掉影响整体启动;
  6. 分组与 meta tool:当工具数量增长后,Tool Group + reset_equipped_tools 提供了运行时动态裁剪工具表面的能力。

十、结语

AgentScope 2.0 把「Agent 用工具」这件事拆成了三层:

  • 想写业务逻辑 → Tool@Tool 注解,最快上手)
  • 想复用生态 → MCP(标准协议,跨语言)
  • 想不动代码就扩展 → Skill(Markdown 指令包,按需加载)

三者通过 Toolkit + skillRepositoryReActAgent 中汇合,给 LLM 呈现出一张统一的「工具表 + 技能目录」。理解了这条加载链路,后续无论是扩展现有 Agent,还是把项目迁移到生产环境,都能有的放矢。

下一篇我们会单独聊一聊这套架构在可观测性(Langfuse/OTel)上的实践——本文先聚焦「能跑起来」。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐