15-12 AgentScope Java进阶:Skill
✅AgentScope Java进阶:Skill
Skill之前我们有专门的讲过,包括Spring Ai Alibaba也介绍过他的支持Skill的原理。
ASJ当然也是支持Skill的,并且支持的要比SAA好。
数据模型
前面我们介绍过skill的结构,在ASJ中对应的就是AgentSkill这个类,它包含以下这几个字段:
| Column 1 | Column 2 | Column 3 |
|---|---|---|
| 字段 | 说明 | 必填 |
| name | Skill 名称 | 是 |
| description | Skill 描述,决定 LLM 何时触发该 Skill | 是 |
| skillContent | Skill 的实际内容/指令 | 是 |
| metadata | 元数据 Map(含 name、description 及扩展字段) | 是 |
| resources | 资源文件 Map(path -> content) | 否 |
| source | 来源标识,默认 “custom” | 否 |
Skill创建方式
我们有三种方式创建 AgentSkill:
方式一:直接构造
1 | AgentSkill skill = new AgentSkill( "my-skill", "Does something useful", "Detailed instructions here...", Map.of("scripts/run.py", "print('hello')")); |
方式二:通过 Builder
1 | AgentSkill skill = AgentSkill.builder() .name("my-skill") .description("Does something useful") .skillContent("Instructions here...") .addResource("scripts/run.py", "print('hello')") .build(); |
方式三:从 Markdown 解析(推荐)
1 | String skillMd = "---\nname: my_skill\ndescription: Does something\n---\nContent here"; |
方式四:从 ZIP 包加载
1 | AgentSkill skill = SkillUtil.createFromZip(Path.of("my-skill.skill")); |
SkillUtil中还提供了几个create方法,也都可以用来创建Skill。
方式六:从持久化存储中加载
AgentScope 提供了 Repository 模式来从不同来源加载 Skill,接口为 AgentSkillRepository。
1 | public interface AgentSkillRepository extends AutoCloseable { |
默认支持以下几种实现:

分别从文件系统、classpath、git、mysql以及nacos上获取skill。
如文件系统:
1 | Path baseDir = Paths.get("/path/to/skills");FileSystemSkillRepository repo = new FileSystemSkillRepository(baseDir);AgentSkill skill = repo.getSkill("my-skill"); |
即从/path/to/skills中找到my-skill这个skill。
SkillBox
SkillBox 是 Skill 的运行时管理中心,它负责 Skill 的注册、激活、工具绑定和代码执行环境管理。他提供了以下方法:
| Field | Value |
|---|---|
| 方法 | 作用 |
| registerSkill(skill) | 注册一个技能 |
| getSkillPrompt() | 生成全部技能的 XML 目录 prompt |
| registerSkillLoadTool() | 向 Toolkit 注load_skill_through_path工具 |
| setSkillActive(skillId, active) | 激活/停用技能(同步 ToolGroup 状态) |
| deactivateAllSkills() | 每次 call 开始时重置为全部未激活 |
| syncToolGroupStates() | 批量同步 ToolGroup 的enable/disable |
| uploadSkillFiles() | 把 resources 写入磁盘供脚本执行 |
使用方式:
1 | Toolkit toolkit = new Toolkit();SkillBox skillBox = new SkillBox(toolkit); |
Skill 的系统提示注入
有了Skill之后,需要把他们注入到系统提示词中,这样LLM才能知道有哪些Skill没用。这里的实现主要是基于SkillHook的。在SkillHook中,在PreReasoningEvent阶段会讲将skill提示词注入到系统提示词中。
1 | public <T extends HookEvent> Mono<T> onEvent(T event) { |
注册之后的提示词在AgentSkillPromptProvider 中能看到,大致长这样:
1 |
|
load_skill_through_path
上面的提示词中,提到了一个工具——load_skill_through_path,他是一个动态生成的 AgentTool,由 SkillToolFactory.createSkillAccessToolAgentTool() 创建。它的职责可以概括为三点:
加载 Skill 内容——返回 SKILL.md 或资源文件的内容
激活 Skill——将 Skill 从”休眠”状态切换为”激活”状态
暴露关联工具——激活后,该 Skill 绑定的工具组才对 LLM 可见
在 ReActAgent.Builder.build() 中会针对这个工具做注册,不需要我们自己注册:
1 | private void configureSkillBox(Toolkit agentToolkit) { |
完整流程:
1 | 1. Agent 初始化 └── configureSkillBox() 注册 load_skill_through_path 到 Toolkit 2. 每次用户调用 agent.call() └── SkillHook.onEvent(PreReasoningEvent) └── 将可用 Skill 列表注入 System Message └── LLM 看到 <available_skills> XML 提示 3. LLM 决定使用某个 Skill └── 调用 load_skill_through_path(skillId="...", path="SKILL.md") └── Skill 被激活 └── 关联工具组被启用 └── 返回 SKILL.md 内容给 LLM 4. LLM 阅读 Skill 内容后 └── 调用该 Skill 暴露的工具(或执行脚本) |
Skill 的代码执行环境
SkillBox 提供了强大的代码执行配置能力,允许 Skill 中的脚本在受控环境中运行。
1 | skillBox.codeExecution() .workDir("/path/to/workdir") // 工作目录(不设置则创建临时目录) .withShell() // 启用默认 Shell(python, python3, node, nodejs) .withRead() // 启用文件读取 .withWrite() // 启用文件写入 .enable(); |
自定义 Shell 安全策略
1 | ShellCommandTool customShell = new ShellCommandTool( "/path/to/workdir", Set.of("python3", "node"), // 允许的命令白名单 command -> askUserApproval(command) // 审批回调); |
