
本文基于 Agent Skills 开放规范(agentskills.io) 、spring-ai-agent-utils 0.11.0 与 Spring AI Alibaba 1.1.2.0编写,事实核对自 agentskills.io 规范页、anthropics/skills 仓库与两个框架的官方文档。该领域迭代极快,请以官方文档为准。

开篇:Agent 也该有个应用商店
2008 年 App Store 上线之前,手机出厂什么样就是什么样------电话、短信、浏览器,能力边界焊死在固件里。之后的故事我们都知道了:能力变成可以随时安装的东西。
2026 年的 AI Agent 正站在同一个节点上。你精心装配了一个 Java Agent:它能读写文件、执行 Shell、调用 MCP 工具,骨架很完整。然后你让它干一件具体的事------比如"把这个库发到 Maven Central"------它开始胡言乱语:编造 Sonatype 的流程、忘记 GPG 签名、把 SNAPSHOT 版本直接 deploy 上去。
问题不是模型笨,是它缺经验。而你司那位每次发版都一次过的高级工程师,经验全在他的脑子里和一篇内部 Wiki 里。
Agent Skills 干的就是这件事:把领域经验打包成一个文件夹,Agent 需要时自动加载 。它由 Anthropic 在 2025 年底发布为开放标准,官方仓库 anthropics/skills 目前已有 171.9k stars,Claude Code、Cursor、Codex CLI、OpenCode 等约 30 款 Agent 产品都能读这个格式。
而它最反直觉的地方在于:给 Agent"装应用",不用编译、不用 API、不用重启进程------写一个 Markdown 文件就行。
这篇文章把规范讲透,再给出 Java 侧的两条落地路径,最后手写一个能在你项目里直接用的技能。
一、先分清:MCP 管"接工具",Skills 管"装技能"
写过 MCP Server 的读者(上一篇【一个 @McpTool 注解,让 Claude 和 Cursor 直接调用你的 Spring 服务】我们刚写过)容易把 Skills 理解成又一个工具协议。它们解决的是两个维度的问题:
| 维度 | MCP | Agent Skills |
|---|---|---|
| 扩展什么 | Agent 的手:能操作哪些外部系统 | Agent 的脑:具备哪些领域经验 |
| 形态 | 运行中的服务(JSON-RPC over Streamable HTTP / STDIO) | 一个静态文件夹(SKILL.md + 资源) |
| 类比 | USB-C 外设:接上就有新硬件 | App:装上就有新软件 |
| 谁执行 | Server 进程干活 | Agent 用已有的工具照着说明干活 |
| 上下文成本 | 工具 schema 常驻上下文 | 元数据常驻,正文激活时才加载 |
还是拿"发布 Maven Central"举例,两者是互补而非竞争关系:
- MCP 提供通道 :一个
mvn执行工具让 Agent 能跑命令------但它不知道该跑什么命令、什么顺序; - Skill 提供剧本:先查 POM 必填字段、再确认非 SNAPSHOT、GPG 签名、deploy、close、release,以及每一步的经典翻车点。
Agent 拿着剧本(Skill),通过通道(MCP/Shell 工具)把活干了。这就是 2026 年 Agent 扩展的完整拼图。
二、技能包长什么样:一个带说明书的文件夹
规范定义的技能包结构,全部约定就这么多:
bash
maven-central-release/
├── SKILL.md # 必需:元数据 + 指令正文
├── scripts/ # 可选:可执行代码(Python/Bash/JS 均可)
│ └── verify-signature.sh
├── references/ # 可选:按需阅读的文档
│ └── GPG-TROUBLESHOOTING.md
└── assets/ # 可选:模板、数据文件
核心是 SKILL.md,格式为 YAML frontmatter + Markdown 正文:
markdown
---
name: maven-central-release
description: Guides through publishing Java artifacts to Maven Central via the Central Portal, including POM checks, GPG signing and staging release. Use when the user wants to release, publish or deploy a library to Maven Central.
license: Apache-2.0
metadata:
author: lambert
version: "1.0"
---
# Maven Central 发布流程
(正文:具体指令,见第七节完整示例)
frontmatter 字段全表:
| 字段 | 必需 | 约束 | 说明 |
|---|---|---|---|
name |
✅ | 1--64 字符,小写字母/数字/连字符,须与目录名一致 | 不能大写、不能 - 开头结尾、不能连续 -- |
description |
✅ | 1--1024 字符 | 整个技能的灵魂,Agent 靠它判断何时激活 |
license |
❌ | --- | 许可证名或指向捆绑许可文件 |
compatibility |
❌ | ≤500 字符 | 环境要求,如 Requires git, jq and network access |
metadata |
❌ | string→string 映射 | 任意扩展:author、version 等都放这里(没有顶层 version 字段) |
allowed-tools |
❌ | 空格分隔 | 预批准工具列表,实验性,各实现支持不一 |
两个容易被忽视的细节:
description 是给模型看的,不是给人看的。 规范的好例子/坏例子对比很直白------Helps with PDFs. 是坏例子;Extracts text and tables from PDF files... Use when working with PDF documents or when the user mentions PDFs, forms, or document extraction. 是好例子。后者把做什么 和何时用都写全了,还埋了触发关键词。写技能时在这上面花的时间,回报率最高。
没有编译,没有注册中心。 一个文件夹扔进约定目录(Claude Code 是 .claude/skills/),Agent 下次启动就能发现它。"技能即文件"和 T01 里"子 Agent 即 Markdown" 是同一套扩展哲学:声明式配置 + 运行时发现------Spring 开发者应该感到眼熟,这不就是 component scanning 吗。
三、最妙的设计:渐进式加载(Progressive Disclosure)
如果一百个技能的正文全部常驻上下文,Agent 还没干活 token 就烧完了。规范的解法是三层按需加载:
| 层级 | 加载内容 | 加载时机 | Token 预算 |
|---|---|---|---|
| 第 1 层:元数据 | name + description |
启动时全部技能都加载 | 每技能约 100 |
| 第 2 层:指令 | SKILL.md 完整正文 | 技能被激活时才加载 | 建议 < 5000 |
| 第 3 层:资源 | scripts/ references/ assets/ |
执行中按需读取 | 视需要而定 |
对应到 Agent 的运行时:
- 启动时,100 个技能只占用约 1 万 token 的"目录页";
- 用户说"帮我发个版",模型比对 description 判断
maven-central-release相关,调用技能工具,正文(八步发布流程)这时才进入上下文; - 执行到 GPG 签名报错,Agent 才去读
references/GPG-TROUBLESHOOTING.md,定位问题后继续。
配套的工程约束也清晰:SKILL.md 保持在 500 行以内 ,细节拆到 references/;文件引用一层深度、走相对路径,避免 A 引 B、B 引 C 的加载链。
这套设计值得每个做 Agent 应用的人细品------它本质上是一份上下文预算的分配方案:常驻的只留目录,重的内容全部惰性加载。同样的思路可以(也应该)用在你自己的系统提示词、工具描述、知识库注入上。此前业内把这叫 Context Engineering,Skills 规范给出了它的第一个大规模标准化实践。
四、生态现状:商店已经开业
一个"App Store"要成立,需要三样东西:标准、货架、装机的手机。Agent Skills 三样都有了。
标准 :规范独立维护在 agentskills.io,不绑定任何厂商。配套 skills-ref 参考实现(含 skills-ref validate 命令)可以校验技能包合规性。
货架 :官方仓库 anthropics/skills 按"创意与设计 / 开发与技术 / 企业与沟通 / 文档技能"分类陈列,其中 docx/pdf/pptx/xlsx 四个文档技能是 Claude 文档能力的底层实现(source-available),另有 Notion 等合作伙伴的官方技能。社区侧,GitHub 上的 Claude Code Skills 已超过 1400 个,官方 plugin marketplace 收录 650+。安装体验是真·App Store 式的:
bash
/plugin marketplace add anthropics/skills
/plugin install document-skills@anthropic-agent-skills
装机的手机 :Claude Code(插件方式)、Claude.ai(付费计划内置全部示例技能)、Claude API(Skills API 上传自定义技能);规范侧则是约 30 款第三方 Agent 产品(Cursor、Codex CLI、OpenCode 等,见官方 Client Showcase 收录)都能直接读 SKILL.md------一次编写,处处运行,这就是开放标准该有的样子。
对 Java 开发者,真正的问题只剩一个:我的 Spring Agent 怎么"装机"? 两条路径。
五、路径一:spring-ai-agent-utils 的 SkillsTool
T01 介绍过这个"Java 版 Claude Code"工具库,其中 SkillsTool 就是 Agent Skills 规范的 Spring AI 原生实现。当前版本 0.11.0(SkillsTool 的装配 API 与 0.10.0 保持一致)。
最小装配:
java
@Bean
CommandLineRunner runner(ChatClient.Builder chatClientBuilder,
@Value("${agent.skills.paths}") List<Resource> skillPaths) {
return args -> {
ChatClient chatClient = chatClientBuilder
.defaultTools(
// 技能系统:运行时扫描 SKILL.md
SkillsTool.builder()
.addSkillsResources(skillPaths)
.build(),
// 技能的"手脚":没有这些,技能只是纸上谈兵
FileSystemTools.builder().build(),
ShellTools.builder().build())
.build();
// ...
};
}
properties
# 支持通配符扫描,classpath 与文件系统均可
agent.skills.paths=classpath:/skills/*/SKILL.md,file:.claude/skills/*/SKILL.md
机制拆解------SkillsTool 与第 2、5 节的规范是如何对应的:
SkillsTool实现的是ToolCallbackProvider接口:启动时扫描所有 SKILL.md 的 frontmatter,把每个技能动态注册成一个工具 ------工具名取name,工具描述取description。这就是第 1 层加载:约 100 token 的元数据常驻;- 模型判断某个技能与当前任务相关、发起工具调用,此时才读取 SKILL.md 正文------第 2 层;
- 正文中引用的
references/、scripts/,Agent 用FileSystemTools、ShellTools按需读取执行------第 3 层。
也就是说,规范的"渐进式加载"在 Spring AI 里被映射成了"动态工具生成":技能的发现靠工具描述,技能的激活就是一次工具调用。很优雅------没有引入任何新抽象,全部建立在既有的 Tool 体系上。
两个进阶用法(0.x 版本 API 迭代较快,以 examples/skills-demo 与官方文档为准):
java
// 1. 子 Agent 也能带技能:TaskTool 委派时共享技能目录
var taskTools = TaskToolCallbackProvider.builder()
.chatClientBuilder(chatClientBuilder.clone())
.skillsDirectories(".claude/skills") // 方法名以官方示例为准
.build()
.getToolCallbacks();
// 2. ClaudeSubagentType 上按子 Agent 粒度注入
ClaudeSubagentType.builder()
.chatClientBuilder("release-engineer", chatClientBuilder.clone())
.skillsResources(skillPaths)
.build();
设想一个组合:主 Agent 把"发版"任务委派给一个只挂了 maven-central-release 技能和 Shell 工具的子 Agent------技能限定 + 工具最小权限,发版这种高危操作就有了执行边界。
官方在 examples/skills-demo 提供了完整示例(含 ai-tuto 演示技能),cd examples/skills-demo && mvn spring-boot:run 即可体验。
六、路径二:Spring AI Alibaba 的 Skills 体系
如果你的技术栈是阿里系(DashScope / Qwen / Graph 编排),SAA 从 1.1.2.0(2026-02 发布)开始原生支持 Agent Skills,且集成面更广(从 ReAct 智能体到 Graph 工作流都有接入口):
- ReactAgent 集成 :通过
SkillsAgentHook把技能挂进 ReAct 循环,实现"技能发现 → 按需加载 → 工具执行"全流程自动化; - Graph / ChatClient 链路:不使用 ReactAgent 的 Graph 工作流或纯 ChatClient 应用同样可以接入技能(通过对应的 Hook / Advisor 机制);
- 可扩展的注册中心 :内置
FileSystemSkillRegistry/ClasspathSkillRegistry两种技能注册中心,并开放SkillRegistry扩展接口------实现该接口即可接入自建存储体系,社区已有 OSS 远端存储 + 多租户的实践案例(按团队、按组织集中管理技能库)。中心化能力是"可扩展"出来的,不是开箱即用的,选型时要算上这层自研成本。
具体 API 以 官方 Skills 教程 为准。一个务实的选型判断:Spring 原生技术栈 + 本地/仓库内技能管理 → agent-utils;阿里云生态 + 愿意基于 SkillRegistry 自建中心化技能库 → SAA。两者读的是同一份 SKILL.md,技能资产本身可迁移。
七、实战:写一个"Maven Central 发布"技能
现在把三层加载机制走成一遍真实流程。选"发布 Maven Central"这个场景是有讲究的:流程繁琐(POM 规范、GPG 签名、staging、同步等待)、经验密集(每一步都有经典翻车点)、且是 Java 开发者的高频痛点------这正是技能的甜区:知识在文档里躺着,但组合运用需要老手经验。
第 1 步:创建技能包
sql
.claude/skills/maven-central-release/
├── SKILL.md
└── references/
└── GPG-TROUBLESHOOTING.md
第 2 步:写 SKILL.md
markdown
---
name: maven-central-release
description: Guides through publishing Java artifacts to Maven Central, covering POM verification, GPG signing, staging deployment and release. Use when the user wants to release, publish, or deploy a library to Maven Central, or mentions Sonatype, OSSRH or the Central Portal.
license: Apache-2.0
metadata:
author: lambert
version: "1.0"
---
# Maven Central 发布流程
按以下步骤操作。任何一步失败,先读 references/GPG-TROUBLESHOOTING.md(仅签名问题)再重试。
## 发布前检查(不可跳过)
1. 确认版本号非 SNAPSHOT:`mvn help:evaluate -Dexpression=project.version`
2. 确认 POM 含全部必填字段:name、description、url、licenses、developers、scm
3. 确认 javadoc 与 sources jar 已配置(maven-javadoc-plugin / maven-source-plugin)
4. 确认 GPG 密钥未过期,且公钥已上传至 keyserver.ubuntu.com
## 发布
5. 先本地演练:`mvn clean package -P release`,并验证签名(逐一指定文件,勿用 `*.asc` 通配------glob 展开后第二个 .asc 会被当作被签数据):
`gpg --verify target/mylib-2.1.0.jar.asc target/mylib-2.1.0.jar`
6. 确认无误后执行 `mvn clean deploy -P release`(release profile 含 GPG 签名配置)
7. 登录 Central Portal(central.sonatype.com),找到 staging 仓库,逐项检查:
- POM 渲染正常、坐标正确
- 三个 jar(main/sources/javadoc)与 .asc 签名文件齐全
8. 点击 Publish,记录发布坐标
## 发布后
9. 同步需要 30 分钟到 2 小时,用以下命令验证可拉取:
`curl -sI https://repo1.maven.org/maven2/<group-as-path>/<artifact>/<version>/`
## 已知翻车点
- deploy 报 401:检查用户 token(不是账号密码),server id 必须与 POM 中 distributionManagement 的 id 一致
- 签名验证失败:见 references/GPG-TROUBLESHOOTING.md
- 404 但 Portal 显示已发布:同步延迟,等满 2 小时再排查
注意这个文件的写法处处体现第 2、3 节的规范:正文只放流程主干与高频翻车点(约 60 行,远低于 500 行红线);GPG 深度排查这种低频内容拆到 references;description 里埋足了触发关键词(release、publish、Sonatype、Central Portal)。
第 3 步:写按需加载的 references
markdown
# GPG 签名问题排查
(GPG-TROUBLESHOOTING.md,仅在签名失败时被 Agent 读取)
## gpg: signing failed: No secret key
密钥不在当前 keyring。检查:`gpg --list-secret-keys`。
若为空,导入备份或重新生成:`gpg --full-generate-key`(选择 RSA 4096)。
## gpg: signing failed: Inappropriate ioctl for device
PIN 输入程序在无终端环境不可用。pom.xml 的 gpg 插件配置加:
<configuration><gpgArguments><arg>--pinentry-mode</arg><arg>loopback</arg></gpgArguments></configuration>
## keyserver 上传后仍提示找不到公钥
keyserver 同步有延迟(可达数小时)。可换用 keys.openpgp.org 的上传 API(注意是 POST,不是 `curl -T` 的 PUT):
`gpg --export -a <key-id> | curl -X POST -F 'key=@-' https://keys.openpgp.org/v1.0/upload`
上传后需按提示完成邮箱验证,公钥才可被检索。
第 4 步:校验并注册
bash
# 规范校验(skills-ref 参考实现)
skills-ref validate .claude/skills/maven-central-release
然后按第五节的装配代码把 .claude/skills/*/SKILL.md 挂到 SkillsTool。
第 5 步:验证
对 Agent 说:
"我要把项目发到 Maven Central,2.1.0 版本"
观察它的行为:模型比对 description 判断 maven-central-release 技能命中 → 调用技能工具加载正文 → 从第 1 步开始执行,检查版本号时发现你忘了去 SNAPSHOT 后缀,主动叫停并提示你 ------这就是"技能生效"的样子:它不只是会执行,还知道什么时候不该继续。
八、Skill、MCP、子 Agent:什么时候用哪个
三者经常被混为一谈,用一张表收束:
| 扩展需求 | 用什么 | 例子 |
|---|---|---|
| 注入领域知识 / 操作流程 | Skill | 发布流程、公司规范、代码审查清单 |
| 接入外部系统 / 数据源 | MCP | 数据库查询、内部 API、SaaS |
| 隔离执行环境 / 并行分工 | 子 Agent | 大范围代码检索、独立评审任务 |
| 复杂能力 | 组合使用 | Skill 提供剧本,MCP 提供通道,子 Agent 提供隔离舞台 |
判断口诀:知识用 Skill、通道用 MCP、隔离用子 Agent。
小结
回到开篇的对照:手机的能力边界曾焊死在固件里,App Store 把它变成了可安装的。Agent Skills 对 AI Agent 做了同一件事------而且比 App Store 更彻底:装一个"应用"的成本低到了写一个 Markdown 文件。
对 Java 开发者,这件事有三层价值:
- 直接可用:agent-utils 与 SAA 两条路径都已支持规范,你的 Spring Agent 今天就能"装机";
- 技能资产可沉淀:团队的老手经验(发版流程、联调排障、线上预案)第一次有了标准化的封装格式,写一次、所有 Agent 通用;
- 架构可借鉴:渐进式加载是一份生产级的上下文预算方案,即使不用 Skills,这套"目录常驻、正文惰性"的思路也适用于任何 Agent 的提示词工程。
下一步,我会继续沿着"Agent 的经验从哪来"这条线写下去------技能解决了经验的外置,记忆解决状态的持久,两者合起来就是长时程 Agent 的基础。系列后续见下方导航。