
如果你写的Skill没有被执行,从来不是因为没有指令,而是因为描述不当。这就是大多数人在经历一个小时的沮丧后才会想通的事情。你写了一个 Skill.md,把它放在正确的文件夹里,让Agent使用它,但什么也没发生。你重新写了文档,仍然什么也没发生。问题从来就不在于你在 Skill 内部写了什么,而是Agent用来决定是否要激活它的最上面两行。
在这里,老码农想详细介绍 Agent Skill 是如何工作的,为什么大多数人在写错了关键部分,如何从简单到复杂地构建Skill?
Skill 不是插件,也不是你连接到 API 的脚本,可以把它想象成为新团队成员编写入门指南。与其在每次对话中重新解释你的工作流程和偏好,不如将它们打包一次,每当你的请求匹配时,Agent就会自动提取它们。
Skill 的核心只是一个文件夹:
your-Skill-name/
├── SKILL.md (必须: 指令+ 元数据)
├── scripts/ (可选: Agent 润型的代码)
├── references/(可选: 按需加载的文档)
└── assets/ (可选:其他资源如模版、图片、字体)
唯一需要的文件是 SKILL.md。其他所有内容都是可选的,但随着 Skill 变得越来越复杂,这些内容就变得越来越重要。
目前,SKILL.md 格式之所以特别有用,是因为它是一个开放标准,由 Anthropic 于 2025 年 12 月在 agentSkills.io 上发布。它适用于主流大模型以及爆火的OpenClaw。虽然格式是标准化的,但每个平台实现发现和工具的方式略有不同。思考共享语言,而不是相同的行为。适用于 Claude Code 的 Skill.md 很可能适用于 Codex,但运行时行为 (如会话快照、工具权限和调用模式) 在不同平台之间存在差异。
在写任何Skill之前,你需要知道该把它放在哪里。每个平台都从特定位置加载技能,而这个位置定义了技能的范围。
Claude Code: 位于~/.claude/Skills/{Personal},可在所有项目中使用.claude/Skills/{Project_level},通过 git 与团队共享
OpenAI Codex: 位于~/.codex/Skills/{User-level},适用于在.codex/Skills/Repo 级中工作的任何代码仓库
OpenClaw:位于 ~/.openclaw/Skills/Global,适用于所有配置Agent的每个工作空间仅适用于特定Agent
Cursor:位于~/.cursor/Skills/{Personal}, 可在所有项目中使用.claude/Skills/{Project_level}
当两个Skill共享同一名称时,优先级更高的位置会胜出。项目级的Skill可以覆盖具有相同名称的个人技能。这使得团队可以定义默认设置,个人可以对自己的设置进行覆盖。
这是大多数人都会跳过的部分,它解释了几乎所有不触发或消耗太多背景信息的问题。
Skill使用渐进式披露,这是一个三级加载系统,其中内容只有在需要时才会被提取到上下文中。
等级 1: 元数据 (始终加载,每个Skill约 100 token)
在启动时,Agent只会从每个已安装技能的 YAML 前缀中读取名称和描述,仅此而已。这个简洁的列表会进入系统提示,以便Agent知道存在哪些技能以及何时使用它们。也就是说,我们可以安装许多技能而不会产生上下文惩罚。
等级 2: 指令 (触发时加载,一般低于 5000 token)
当Agent判断某个 Skill.md 是否相关时,它会使用 bash 调用将整个 Skill.md 的内容读取到上下文中。只有在这个时候,你的实际指令才会被加载。
等级 3: 参考文件和脚本 (按需加载,实际上无限制)
如果Skill主体引用了其他文件,Agent只会在需要时读取这些文件。脚本可以在完全不被读取到上下文的情况下执行。这就是技能可扩展性的原因:无论你捆绑了多少内容,空闲时的token成本都是零。
以下是实际请求的顺序:
1. Session 启动
--> Agent 加载: 名称 + 每一个Skill的描述 (Level 1)
2. 用户Query: "Can you write a README for this project?"
--> Agent 加载: readme-writer/Skill.md full body (Level 2)
3. Skill.md 引用style文件
--> Agent 加载: readme-writer/references/style.md (Level 3)
4. Skill.md包含了用户脚步
--> Agent executes: scripts/validate.sh (可以无上下文执行)
Skills 一般都支持两种调用模式。当请求与描述相匹配时,Agent 可以自动激活一个技能 (隐式调用),或者可以直接调用它 (显式调用)。
在CC中,Skill默认出现在斜杠命令菜单中。我们可以直接使用/Skill-name 调用其中一个技能,或者只需描述您想要的内容,CC就会自动激活相关技能,例如;
显式调用
/readme-writer
隐式调用
Can you write a README for this project?
尽管如此,一个写得好的描述仍然非常重要。它驱动着自动激活,使技能感觉像是你工作方式的自然延伸,而不是一个必须记住输入的命令。
YAML 前缀中的描述字段不是针对人类的,它是Agent在决定是否激活目标Skill时使用的触发条件。以下是工作结构:
[这个Skill 做什么] + [什么时间使用它?使用怎样的触发语句]
如果你曾经在DuerOS Bot Platform 上开发过语音技能的话, 你就会有一种似曾相识的感觉。
agentSkills.io 规范定义了以下约束:
一些平台在这些之上添加了约定,我们可以在 agentSkills.io/specification 中查看平台特定的文档以及基本规范。
Skill并不能保证执行,大模型仍然决定是否遵循指令。将Skill视为结构化指导,可以显著提高一致性,而不是确定性的自动化。如果模型偏离了脚本,解决方案几乎总是改进指令或描述,而不是调试运行时的行为。
另外,Skill.md 建议保持在 40 行以下,详细的指令细则存储在 references/xxx.md 中,并且只有在运行时才会加载。这使得第 2 级加载保持精简,同时Agent仍然可以访问第3 级所需的一切。
我们可以通过Skill 来增强MCP服务。MCP 服务器为Agent提供了对指定功能API 的访问权限。Skill 让Agent 知道如何可靠且一致地使用这种访问权限。如果没有这个Skill,用户虽然可以连接 MCP,但仍然需要解决每一个步骤。有了Skill,整个工作流程就可以从一句话开始。
一个使用MCP的Skill.md 模版如下:
---
name: { 使用某MCP服务的Skill 名称}
Description: { Skill 的具体描述}
metadata:
mcp-server: { MCP 服务的名称}
version: { MCP 服务的版本}
---
{ Skill 的执行步骤}
在执行步骤中, 我们还可以引入异常处理的机制,例如references/error-handling.md, 处理诸如连接错误, 数据丢失等问题。
需要注意的是,allowed-tools 在 Agent Skills 规范中被标记为实验性的,并且支持情况因 Agent 实现而异。目前,它在 CC中得到了很好的支持。
Skill可以捆绑可执行代码和指令来控制Agent行为,同样的能力也使恶意技能变得危险。我们需要仅安装来自可信来源的技能。在安装任何社区技能之前,请阅读文件夹中的每个文件,特别是脚本/中的任何内容。请注意告诉Agent进行出站网络呼叫或向外部服务发送数据的说明。
Cisco 的研究人员已经提出了警告,Skill 可能被用于通过提示注入进行静默的数据泄露。安全审计扫描了数千种社区技能,发现了一小部分Skill存在关键漏洞,包括凭证盗窃和恶意软件。Snyk 专门发布了这方面的研究结果。ClawHub 有一个 VirusTotal 集成,我们可以用它在安装前检查技能,但对于任何具有广泛权限的技能,手动审核仍然是值得的。
一些实用的方法如下:
三级加载系统是Skill 的核心概念,第 1 级是触发器,第 2 级是运行手册,第 3 级是参考库。正确理解这些,我们就可以构建从单个 Markdown 文件到协调外部 API 和执行代码的多步骤工作流程,甚至尝试构建方便我们工作和生活的任何内容。