Agent Skills:把团队里“只会做一遍“的经验,变成 Agent 能反复调用的能力包
刷 GitHub 热榜前十五名里有一串名字让我停了一下openclaw 排第 3ECC 第 8hermes-agent 第 9mattpocock/skills 第 12opencode 第 13。它们干的事各不相同描述里却反复出现同一个词skills。ECC 自己的简介写得最直白说它是 Skills, instincts, memory, security... for Claude Code, Codex, Opencode, Cursor。这不是巧合。2026 年的 Agent 圈正从造一堆专用机器人转向给一个通用机器人外挂能力包。这个能力包就是 Anthropic 在 2025 年底推出来的 Agent Skills。我打算把它讲透它解决什么真问题底层怎么省上下文和 Prompt、MCP 到底差在哪以及一个写 Java 后端的人该怎么把它接进自己的系统。一、Agent Skills 到底是什么Agent Skills 是 Anthropic 提出的一套开放标准。据阿里技术 2026 年 4 月的复盘Claude Skills 最早在 2025 年 10 月 16 日随 Claude 3.7 作为产品内能力推出到 2025 年 12 月 18 日Anthropic 把它开源成跨平台标准规范叫 Agent Skills Specification V1.0托管在 agentskills.io同时放出官方 SDK支持 Python、TypeScript 和 Java。TechCrunch 当时给了一句评价说它是AI 领域的 Dockerfile。到 2026 年 2 月公开可用的 Skills 已经超过 8.5 万个支持该标准的主流平台到了 27 家Cursor 是第一个全面采用它的 AI IDE微软 Azure AI Studio 宣布原生支持GitHub Copilot Workspace 做了实验性支持。理解它最关键的一句话MCP 解决能调什么工具Skills 解决怎么把一件事做对。前者是连接层后者是知识层两者互补。一个 Skill 其实就是由文件组成的最小形态只需要一个 SKILL.md里面分两块开头的 YAML frontmatter必须含 name 和 description和下面的 Markdown 指令。复杂一点的会带上 scripts/可执行的 Python、Bash、JS、references/按需查阅的文档、assets/模板、图标等静态资源。name 最多 64 个字符只能是小写字母、数字和连字符description 最多 1024 字符要写清楚这东西干嘛用、什么时候用。为什么需要它Anthropic 打过一个比方报税这种事你愿意交给一个从第一性原理现推的 300 IQ 数学天才还是一个填过几千份税表的老手大多数人选老手不是因为他更聪明而是他有 accumulated expertise。通用模型今天就像那个数学天才推理能力强但缺你公司那套没人写下来的流程。Skills 干的事就是把老手的经验打包让通用模型变成某个领域的专家。二、渐进式披露为什么塞再多资料也不爆上下文为什么一个文件夹能装很多东西却不把上下文撑爆靠的是渐进式披露progressive disclosure分三级加载。第一级是元数据。Agent 一启动就把所有已安装 Skill 的 name 和 description 预载进系统提示。这部分很轻每个 Skill 只占几十到一百来个 token所以你装几百个 Skill 也不会有感知。第二级是 SKILL.md 正文。只有当模型判断当前任务跟某个 Skill 的 description 匹配时才通过 bash 把整个 SKILL.md 读进上下文。官方建议正文控制在几千 token 以内文档给的上限是不超过 5k token。第三级是 references/ 和 scripts/ 里的东西。这些文件平时躺在文件系统上一个 token 都不占模型觉得需要了才去读某一个或者去跑某一个脚本。脚本这一点很妙当模型执行 scripts/ 里的 Python 时脚本代码本身永远不会进上下文只有运行输出比如校验通过或具体的报错回来。这比让模型现场现编等效代码省 token而且结果是确定性的。三级加载画出来就是下面这条链三、Skills 和 Prompt、MCP 不是一回事很多人第一次见 Skill 会以为不就是高级提示词吗不是。三者分工不同我用一张表摆清楚维度PromptMCPSkills定位模型的一次性指令工具调用的通信协议任务执行的标准能力包作用告诉模型做什么、怎么做的文本定义模型如何安全发现并调用外部工具封装一个完整、可复用、可版本化的任务方案粒度单次对话上下文内的指令工具接口的标准化描述类似给 AI 的 OpenAPI跨会话、跨应用的独立功能单元类似 Docker 镜像可复用性低靠人工复制粘贴中工具可被多个 Prompt 调用高任意支持该标准的 Agent 直接加载更准确地说Skills 不是 Prompt 的替代品而是 Prompt 的容器一个 Skill 里必然包含精心设计的 Prompt外加脚本、依赖声明和测试用例Skills 也不是 MCP 的替代品而是 MCP 的消费者Skill 里的执行脚本会通过 MCP 去碰真实世界的工具。三者协同时是这样一条链Prompt 告诉模型这次要干嘛模型匹配到合适的 SkillSkill 加载后通过内部指令调 MCP 拿工具闭环完成。Anthropic 自己的厨房比喻很贴切MCP 是专业厨房食材、灶具、设备Skills 是菜谱一步步怎么做。没有菜谱用户连上 MCP 也不知道下一步该干什么。四、一个能跑的例子把周报生成固化成 Skill光讲结构太空给一个能落地的例子。假设团队每周要从 git 提交记录生成双周报这个流程完全可以固化成一个 Skill目录长这样weekly_git_report/ ├── SKILL.md ├── scripts/ │ └── fetch_git_commits.py └── references/ └── weekly_report_template.mdSKILL.md 的写法注意 description 要带什么时候用的关键词这是模型自动匹配的依据--- name: weekly_git_report description: 基于近 14 天 git commit 记录生成结构化双周工作周报。当用户要写周报、总结近期工作、或提到 commit/提交记录时使用。 version: 0.1.0 --- # 概述 读取用户所有本地仓库近两周的 commit message按模块归类套用模板生成周报。 # 数据获取 运行 scripts/fetch_git_commits.py 拿到提交列表周报模板见 references/weekly_report_template.md。 # 异常处理 如果一条提交都拿不到直接写明本期无实质提交。scripts/fetch_git_commits.py 是一段确定性代码它负责把脏活干了模型只消费它的输出#!/usr/bin/env python3 import os import subprocess from datetime import datetime, timedelta ROOT os.path.expanduser(~/code) # 所有仓库的父目录 def collect(): since (datetime.now() - timedelta(days14)).strftime(%Y-%m-%d) rows [] for name in os.listdir(ROOT): repo os.path.join(ROOT, name) if not os.path.isdir(os.path.join(repo, .git)): continue try: out subprocess.check_output( [git, -C, repo, log, f--since{since}, --prettyformat:%s], stderrsubprocess.DEVNULL, textTrue, ) rows.extend(out.splitlines()) except subprocess.CalledProcessError: continue return rows if __name__ __main__: commits collect() print(f近 14 天共 {len(commits)} 条提交) for c in commits[:50]: print(f- {c})这个例子的价值不在代码多高明而在它把怎么写周报这件事从某个人脑子里的习惯变成了团队任何人、任何 agent 都能调起的标准能力。新人来了不用口口相传加载这个 Skill 就会了。五、生态版图谁在吃这套标准今天热榜上的 ECC 明说支持 Claude Code、Codex、OpenCode、Cursor 四种后端而它自己就是用 SKILL.md 组织能力的。这意味着你写一份技能描述可以在这几个 agent 之间复用。底下接的模型从 Claude大家口头说的 cc5 那条线、OpenAI 的 Codex 5.6到自托管的 Kimi K3、智谱 GLM-5.2 都能挂前提是那个 harness 支持按 description 自动加载 SKILL.md。前面几篇写过用 vLLM 自托管 Kimi K3 和 GLM-5.2那种部署形态接进开源 harness 跑同一套技能目录2026 年已经能做。顺带一提OpenClaw 自己的 SKILL.md 技能系统其实比 Anthropic 正式标准化还早几个月是这套模式在实践里先被验证过才有后来的开放标准。第三方市场SkillsMP、AgentPowers.ai、Lobehub也已经能下载别人写好的 Skill。六、安全Skill 不是提示词是会被执行的代码Skill 看起来像文档但它会被执行。Anthropic 自己在文档里写得很重把 Skill 当作软件来装只从可信来源取。要审查的不只是 SKILL.md还有 scripts/ 和 assets/ 里所有的文件重点找异常的网络调用、文件访问模式、和声明目的对不上的操作。从外部 URL 拉数据的 Skill 风险尤其高因为拉回来的内容可能夹带恶意指令即便是可信的 Skill如果它的外部依赖后来被改也可能被攻破。工具滥用和数据外泄是两个最实在的后果一个能碰敏感目录的 Skill可能被设计成把数据往外发。这跟我之前写过的提示注入是一体两面一个是骗模型说错话一个是借技能干坏事根子都在模型不区分指令和数据。生产里接 Skill至少要做到只装团队自己写或从官方市场下的上线前人工过一遍 scripts/给脚本执行单独划沙箱目录和命令白名单。七、Java 后端怎么落地自己写一个 Skill 调度器作为后端我更关心怎么把这套机制接进来。Spring AI 2.02026-06 GA配 Spring Boot 4.xJava 21的 ChatClient 已经能把系统指令 用户任务这套玩法封装得很干净。下面这个例子不依赖任何未公开 API思路是扫描技能目录、解析 frontmatter、按任务关键词匹配、把 SKILL.md 正文当 system 提示注入再调模型。模型可以走 OpenAI 兼容端点接 Kimi K3 / GLM-5.2也可以走 Anthropic 绑定接 Claudecc5 线具体 baseUrl 和模型名以官方文档为准。先是实体和加载器public record Skill(String name, String description, String body) {} public final class SkillLoader { public static ListSkill loadAll(Path root) { ListSkill out new ArrayList(); if (!Files.isDirectory(root)) return out; try (var dirs Files.list(root)) { for (Path dir : dirs.filter(Files::isDirectory).toList()) { Path md dir.resolve(SKILL.md); if (Files.exists(md)) out.add(parse(md)); } } catch (IOException e) { throw new IllegalStateException(load skills failed, e); } return out; } // 简化版 frontmatter 解析取 --- 之间的 name / description 与正文 private static Skill parse(Path md) throws IOException { String text Files.readString(md); int start text.indexOf(---) 3; int end text.indexOf(---, start); String fm text.substring(start, end); String name grab(fm, name); String desc grab(fm, description); String body text.substring(end 3).trim(); return new Skill(name, desc, body); } private static String grab(String fm, String key) { for (String line : fm.split(\n)) { if (line.trim().startsWith(key :)) { return line.substring(line.indexOf(:) 1).trim(); } } return ; } }再是调度器用 Spring AI 2.0 的 ChatClient 调模型public class SkillDispatcher { private final ChatClient chatClient; private final ListSkill skills; public SkillDispatcher(ChatClient chatClient, Path skillsRoot) { this.chatClient chatClient; this.skills SkillLoader.loadAll(skillsRoot); } public String run(String task) { Skill skill match(task); // 先按 description 关键词命中 String system (skill null) ? 你是一个严谨的助手。 : skill.body(); return chatClient.prompt() .system(system) .user(task) .call() .content(); } private Skill match(String task) { return skills.stream() .filter(s - s.description().toLowerCase().contains(task.toLowerCase()) || task.toLowerCase().contains(s.name().toLowerCase())) .findFirst() .orElse(null); } }要点就两个技能目录用 git 管版本和代码一起走评审匹配逻辑别搞太复杂先按 description 做关键词命中命中多了再上向量检索。真要上线把脚本执行单独扔进 sandbox 目录命令白名单之外的一律不让跑。八、我踩过的坑以及对 Skills 的判断我们团队踩过的坑列几个给后来人。第一个是 Skill 爆炸。一开始什么都想写成 Skill结果元数据列表本身就变成噪声模型反而匹配不准。我的做法是先问一句这件事是不是会被反复做、且步骤固定不是就别上 Skill写进 CLAUDE.md 当事实就好。第二个是 SKILL.md 写成文档而不是操作步骤。模型需要的是第一步干啥、第二步干啥不是背景科普。你给一篇洋洋洒洒的原理它读完照样不会执行。第三个是脚本白名单。Skill 里的脚本有 bash 权限如果不限死能跑什么agent 就可能越权。我们给脚本执行单独划了沙箱目录和命令白名单。第四个也是最容易被忽略的别在 Skill 里塞外部依赖又不锁版本。一个靠某个 SaaS API 的 Skill对方接口一变你就跟着挂。能本地确定性解决的尽量用 scripts/ 里的代码解决少引外部不确定性。我的判断Skills 把AI 工作流从一道精心设计的填空题变成了可版本、可分享、可组合的能力资产。小团队别急着造市场先把两三个高频流程跑测试套件、发版、生成周报固化成 Skill收益就很明显。新人 onboarding 和 CI 一致性都会好一截。Anthropic 的工程博客也建议从先评估做起拿真实任务跑一遍 agent看它在哪一步掉链子再把掉链子的环节写成 Skill比凭空设计一个 Skill 靠谱得多。九、版本、组合与可移植三个工程属性让 Skill 比把提示词存进备忘录强出一个量级。可移植。Anthropic 的文档明确说同一份 Skill 在 Claude.ai、Claude Code 和 API 上行为一致只要运行环境支持它的依赖。这意味着你为 Claude Code 写的 Skill理论上不用改就能在别的兼容 harness 上跑。可组合。Agent 能同时加载多个 Skill它们应该相互配合而不是假设自己是场上的唯一能力。比如发版Skill 可以顺手引用跑测试Skill 产出的结果而不是各写各的。写 Skill 时要留好这个心眼别把前提假设写死。可版本。Skill 就是个文件夹天然能用 git 管理改了能回滚、能 review、能团队共享。我们把它和源码放在同一个仓库的子目录里PR 里一起审谁改了怎么发版一目了然。这点是把经验真正变成资产的关键否则它又会退回成某个人脑子里的习惯。给团队一个提醒Skill 不是越多越好。元数据列表本身会变成上下文噪声定期清理没人用的 Skill和清理没人维护的代码一样重要。十、收个尾Agent Skills 不性感没有新模型、没有新算法就是用文件夹把领域经验打包。但 2026 年 agent 生态集体往这上面靠说明行业想通了一件事通用模型不缺智商缺的是你公司那点没人写下来的 know-how。明天我打算把团队内部的代码评审 checklist 也拆成一个 Skill顺手接进 opencode 跑。