欢迎光临
我们一直在努力

16-大模型智能体开发工程师:全面学习Agent Skill系统

系列文章导航:AI系列文章导航目录-持续更新中

第16课:全面学习Agent Skill系统

📝 本文摘要:本文从零讲解Agent Skill系统——Agent能力的"插件化"组织方式。内容包括:①Skill是什么(定义、与Tool/MCP的本质区别);②为什么需要Skill(单纯工具列表的四大问题、Skill如何解决);③Skill在Agent技术栈中的定位(三层架构图解);④Skill的核心结构(五大组成要素详解与案例);⑤Skill的生命周期(自动发现→注册→发现→加载→执行→卸载完整流程);⑥Skill的动态加载与编排(按需加载、冲突处理、组合模式);⑦Skill生态与标准化(OpenSpec、skills.sh、ClawHub等);⑧Skill设计的工程原则(六大原则与反模式)。适合AI小白从零理解Skill系统的本质、定位和实践。

Skill是Agent从"能调工具"到"真正有能力"的关键跃升。理解Skill,你就理解了Agent如何像人一样"学会"做一件事,而不只是"能用"一个工具。


一、Skill是什么

1.1 一句话定义

Skill = Agent可动态加载的"能力包"
类比: Skill之于Agent ≈ App之于手机 ≈ 插件之于浏览器

展开理解:

你的手机出厂时只有基础功能(打电话、发短信),但装了微信就能聊天,装了高德就能导航,装了美团就能点外卖。每个App不只是一个"按钮",而是一整套能力(界面+逻辑+数据+规则)。

Agent也一样。一个裸的Agent只有LLM的基础推理能力,但加载了"代码审查"Skill就能审查代码,加载了"故障排障"Skill就能排查故障,加载了"数据分析"Skill就能分析数据。

关键点:Skill ≠ 工具(Tool)。工具是"一把锤子",Skill是"会用锤子的木匠"——它不仅有工具,还有知识、经验、规则和方法论。

1.2 Skill vs Tool vs MCP:到底什么关系?

这是最容易混淆的概念,必须彻底讲清楚。

┌─────────────────────────────────────────────────────────────────────────┐
│ 三者的层级关系 │
└─────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────┐
│ Skill(能力层) │
│ │
│ "我知道怎么做代码审查" │
│ = 工具 + 知识 + 提示词 + 规则 + 示例 │
│ = 一个完整的能力包 │
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ MCP(连接层) │ │
│ │ │ │
│ │ "我标准化地暴露工具给所有Client用" │ │
│ │ = 工具的标准化连接协议 │ │
│ │ = 解决工具的发现、调用、复用问题 │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ Tool(执行层) │ │ │
│ │ │ │ │ │
│ │ │ "我能读文件 / 我能查数据库 / 我能发邮件" │ │ │
│ │ │ = 最小粒度的单一功能 │ │ │
│ │ │ = 一个函数 │ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘

用一个具体例子说明三者的区别:

场景: Agent需要"审查代码安全性"

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

【只有Tool时】

Agent拿到的:
– read_file(path) → 读文件
– search_code(query) → 搜代码

Agent的困境:
"我有工具了,但是…
– 代码安全审查应该看哪些方面?我不知道
– SQL注入长什么样?我只有通用知识
– 审查报告应该什么格式?没人告诉我
– 我能不能直接修改代码?不确定边界"

结果: Agent可能漏掉关键安全问题,输出格式不统一,行为不可预测

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

【有MCP时】

改进: 工具的连接方式标准化了
– 不用自己写read_file的实现
– 从MCP Server动态获取工具
– 工具可以跨应用复用

但Agent的困境依然存在:
"工具连接方式标准化了,但我还是不知道怎么做安全审查…"

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

【有Skill时】

Agent拿到的是一个完整的"代码安全审查"能力包:
✅ 工具: read_file, search_code(知道用什么工具)
✅ 知识: SQL注入、XSS、CSRF的具体模式和检测方法
✅ 提示词: "请按以下5个维度审查…"(知道怎么做)
✅ 示例: 输入一段有漏洞的代码 → 期望的审查输出
✅ 约束: "只能审查,不能修改代码"(知道边界)

结果: Agent像一个经过培训的安全工程师,输出专业、一致、可控

一句话总结三者关系:

Tool = 锤子(一个工具)
MCP = 五金店的标准货架(工具的标准化管理方式)
Skill = 木匠师傅(知道用什么工具 + 怎么用 + 什么时候用 + 不能做什么)

你不会只给一个人一把锤子就说"去把房子建好"。
你需要给他完整的能力: 工具 + 图纸 + 规范 + 经验 + 安全守则。
这就是Skill做的事。

1.3 为什么需要Skill?(催生Skill的四大问题)

核心问题:只给Agent一堆工具,它真的能做好事情吗?

答案是:不能。就像只给一个实习生一堆工具但不给任何培训,他大概率会搞砸。

问题1: 工具太多,Agent不知道该用哪个
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

场景: 你的Agent连接了50个MCP Server,暴露了200个工具

问题:
– 每次请求都把200个工具定义传给LLM?→ Token爆炸,成本飙升
– LLM面对200个工具选择?→ 选择困难,容易选错
– 很多工具之间有依赖关系?→ LLM不知道先调A再调B

Skill的解决方案:
→ 按任务类型组织工具,每次只加载相关的Skill(5-10个工具)
→ Agent不需要面对200个工具,只需要面对当前任务相关的能力包

问题2: Agent缺乏领域知识,工具用不好
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

场景: Agent有query_database工具,用户说"帮我查一下最近的异常订单"

问题:
– "异常订单"的定义是什么?→ LLM只能猜
– 应该查哪张表?字段叫什么?→ LLM不知道你的数据库结构
– 查询结果怎么解读?→ LLM缺乏业务上下文

Skill的解决方案:
→ "订单分析"Skill内置了:
– 知识: 异常订单的定义(金额>10000 或 状态=refunded 且 创建<1小时)
– 知识: 数据库表结构(orders表、order_items表、字段说明)
– 提示: "查询异常订单时,请按以下SQL模板…"

问题3: Agent行为不可控,没有边界
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

场景: Agent有execute_sql工具,用户说"帮我清理一下过期数据"

问题:
– Agent可能执行 DELETE FROM orders WHERE … → 删除了生产数据!
– Agent可能执行 DROP TABLE … → 灾难性后果!
– 没有明确的"能做什么/不能做什么"的边界

Skill的解决方案:
→ "数据清理"Skill内置了安全约束:
– "只能执行SELECT和软删除(UPDATE status='deleted')"
– "禁止执行DROP、TRUNCATE、硬DELETE"
– "单次操作影响行数不能超过1000"
– "必须先执行COUNT确认影响范围,再执行实际操作"

问题4: Agent输出不一致,质量参差不齐
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

场景: 团队有5个Agent都需要做代码审查

问题:
– Agent A审查时关注安全性,Agent B关注性能,Agent C随机关注
– 输出格式不统一:有的用表格,有的用列表,有的写散文
– 审查标准不一致:同样的代码,不同Agent给出矛盾的结论

Skill的解决方案:
→ 统一的"代码审查"Skill:
– 统一的审查维度(安全/性能/可读性/最佳实践)
– 统一的输出格式模板
– 统一的评分标准
– 所有Agent加载同一个Skill → 行为一致

总结:Skill解决的核心问题

Tool/MCP解决的是: "Agent能不能调工具"(能力的有无)
Skill解决的是: "Agent能不能把事做好"(能力的质量)

类比:
Tool/MCP = 给你一把手术刀(你有了工具)
Skill = 给你完整的外科培训(你有了能力)

有手术刀不代表你能做手术。
有了完整的培训(知识+技能+规范+经验),你才真正有能力做手术。


二、Skill在Agent技术栈中的定位

2.1 Agent的完整技术栈

理解Skill的定位,需要看清Agent系统的完整分层:

┌─────────────────────────────────────────────────────────────────────────┐
│ Agent完整技术栈(从上到下) │
└─────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────┐
│ 第1层: 用户交互层 │
│ 用户输入 → "帮我审查这段代码的安全性" │
└──────────────────────────────────┬──────────────────────────────────────┘

┌──────────────────────────────────▼──────────────────────────────────────┐
│ 第2层: Agent编排层(核心控制循环) │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────────┐ │
│ │ Skill发现 │───▶│ Skill加载 │───▶│ 构建LLM请求 │ │
│ │ "这个任务需 │ │ 加载相关Skill │ │ system_prompt(Skill) │ │
│ │ 要什么能力" │ │ 的工具+知识 │ │ + tools(Skill) │ │
│ └─────────────┘ └──────────────┘ │ + messages(用户) │ │
│ └──────────┬──────────┘ │
│ │ │
│ ┌─────────────┐ ┌──────────────┐ │ │
│ │ 结果处理 │◀───│ 工具执行 │◀─────────────┘ │
│ │ 格式化输出 │ │ 调用实际工具 │ LLM返回tool_call │
│ └─────────────┘ └──────────────┘ │
└──────────────────────────────────────────────────────────────────────────┘
│ │
│ │ 实际执行工具
│ ┌───────────┴───────────────────────┐
│ │ │
┌────────▼──────────▼───┐ ┌────────────▼─────────────────┐
│ 第3层: Skill层 │ │ 第4层: 工具连接层 │
│ (能力的组织与管理) │ │ (MCP / 本地函数) │
│ │ │ │
│ ┌────────────────────┐ │ │ ┌──────────┐ ┌────────────┐ │
│ │ 代码审查 Skill │ │ │ │MCP Server│ │ 本地函数 │ │
│ │ – tools: […] │ │ 调用工具 │ │(标准化) │ │(直接调用) │ │
│ │ – knowledge: … │─┼─────────────────▶│ │ │ │ │ │
│ │ – prompt: … │ │ │ └──────────┘ └────────────┘ │
│ │ – guardrails: … │ │ │ │
│ └────────────────────┘ │ │ ↓ │
│ ┌────────────────────┐ │ │ ┌──────────────────────────┐ │
│ │ 故障排障 Skill │ │ │ │ 第5层: 实际外部服务 │ │
│ │ – tools: […] │ │ │ │ (数据库/API/文件系统) │ │
│ │ – knowledge: … │ │ │ └──────────────────────────┘ │
│ └────────────────────┘ │ └──────────────────────────────┘
└────────────────────────┘

2.2 Skill层的核心职责

Skill层做的事情(向上对Agent编排层负责):

1. 能力注册: 告诉Agent"我有哪些能力可用"
2. 能力发现: 根据用户任务,推荐最相关的能力
3. 能力加载: 把选中的Skill的工具+知识+提示注入Agent上下文
4. 能力约束: 限制Agent在当前Skill范围内的行为边界
5. 能力卸载: 任务完成后释放资源,避免上下文膨胀

Skill层不做的事情:
✗ 不负责工具的实际执行(那是MCP/本地函数的事)
✗ 不负责LLM的推理决策(那是LLM的事)
✗ 不负责用户交互(那是应用层的事)

2.3 Skill与MCP的协作关系

很多人会问:有了MCP,为什么还需要Skill?它们不是重复了吗?

答案:完全不重复。MCP管"连接",Skill管"组织"。它们是互补关系。

类比理解:

MCP = 图书馆的借阅系统
– 标准化地管理书籍(工具)的借出和归还
– 任何人(Client)都能用同一套流程借书
– 解决的是"怎么拿到书"的问题

Skill = 大学的课程体系
– 把相关的书籍组织成一门课(能力包)
– 告诉学生"学这门课需要读哪些书、按什么顺序、重点是什么"
– 解决的是"怎么用好这些书"的问题

实际协作流程:
1. Skill定义了"代码审查需要read_file和search_code工具"
2. Agent加载这个Skill时,通过MCP协议从对应的MCP Server获取这些工具
3. Skill提供的知识和提示词注入到LLM的上下文中
4. LLM决定调用工具时,通过MCP协议实际执行
5. Skill的约束规则在执行前/后进行校验

Skill负责"编排和约束",MCP负责"连接和执行"


三、Skill的核心结构

3.1 Skill的五大组成要素

一个完整的Skill包含以下五个部分:

┌─────────────────────────────────────────────────────────────────────────┐
│ Skill的五大组成要素 │
└─────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────┐
│ ① 元数据 (Metadata) │
│ – name: Skill的唯一标识 │
│ – description: 能力描述(用于Skill发现时的匹配) │
│ – version: 版本号 │
│ – tags: 标签(用于分类和搜索) │
│ – author: 作者 │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ ② 工具集 (Tools) │
│ – 这个Skill需要用到的工具列表 │
│ – 可以是本地函数,也可以是MCP Server提供的工具 │
│ – 定义了Agent在这个Skill下"能做什么操作" │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ ③ 知识库 (Knowledge) │
│ – 使用这个Skill需要的领域知识 │
│ – 可以是文本、规则列表、数据库Schema等 │
│ – 注入到LLM上下文中,让Agent"懂行" │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ ④ 提示模板 (System Prompt) │
│ – 引导Agent正确使用这个能力的指令 │
│ – 包括: 工作流程、输出格式、注意事项 │
│ – 这是Skill的"灵魂"——决定了Agent的行为模式 │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ ⑤ 安全约束 (Guardrails) │
│ – 明确声明Agent在这个Skill下"不能做什么" │
│ – 防止Agent越界操作 │
│ – 可以是软约束(提示词中声明)或硬约束(代码层面拦截) │
└─────────────────────────────────────────────────────────────────────────┘

3.2 Skill的表现形式

上面讲了Skill的五大组成要素(元数据、工具集、知识库、提示模板、安全约束),那么在实际工程中,一个Skill到底长什么样?它是以什么形式存在的?

答案是:Skill本质上是一个文件夹,包含一个必需的 SKILL.md 文件和可选的捆绑资源目录。

3.2.1 Skill的标准目录结构

skill-name/
├── SKILL.md ← 必需:Skill的核心文件(元数据 + 指令正文)
└── 可选的捆绑资源/
├── scripts/ ← 可执行脚本(Python/Bash等)
├── references/ ← 参考文档(按需加载到上下文)
└── assets/ ← 输出资源(模板、图片、字体等)

关键理解:Skill不是一段代码,不是一个API,而是一个自包含的文件包。Agent通过读取这个文件包中的内容来"获得"某项能力。

3.2.2 SKILL.md:Skill的核心文件

每个Skill必须有且只有一个 SKILL.md 文件,它由两部分组成:

① YAML Frontmatter(元数据)—— 始终在Agent上下文中,用于Skill的发现和触发:


name: codesecurityreview
description: >
审查代码中的安全漏洞,包括SQL注入、XSS、CSRF、敏感信息泄露等。
当用户要求进行代码安全审查、安全扫描、漏洞检测时触发此Skill。

② Markdown正文(指令)—— 只在Skill被触发后才加载到上下文:

# Code Security Review

## Workflow

1. Use list_files to understand project structure
2. Read entry files (routes, API endpoints) first
3. Check each file against known vulnerability patterns
4. Use search_code to find suspicious patterns across codebase
5. Output report in standard format

## Vulnerability Patterns

### SQL Injection
– Dangerous: f-string or % formatting in SQL queries
– Safe: parameterized queries, ORM usage

### XSS
– Dangerous: innerHTML with user input, render_template_string
– Safe: textContent, HTML escaping, CSP headers

## Output Format

| # | Severity | Type | Location | Description | Fix |
|—|———-|——|———-|————-|—–|

## Constraints
– Read-only operations only
– Never expose full secrets in output (mask with ***)
– Only audit files within user-specified scope

注意:description 字段是Skill的触发机制——Agent通过匹配description来决定是否加载这个Skill。因此description必须清晰描述"这个Skill做什么"和"什么时候该用它"。

3.2.3 捆绑资源:三种可选目录
scripts/ —— 可执行脚本

存放需要确定性执行的代码,避免Agent每次重写相同逻辑。

code-security-review/
├── SKILL.md
└── scripts/
├── scan_sql_injection.py ← 自动扫描SQL注入模式
└── generate_report.py ← 生成标准格式的审查报告

什么时候用scripts/:

  • 同样的代码需要反复执行(如格式转换、数据处理)
  • 需要确定性结果(不能让LLM每次自由发挥)
  • 复杂的多步骤操作(如PDF处理、图片编辑)

特点:脚本可以直接执行,不需要加载到上下文窗口中,因此不占用token。

references/ —— 参考文档

存放Agent在工作过程中可能需要查阅的知识文档,按需加载。

big-query-analyst/
├── SKILL.md
└── references/
├── finance.md ← 财务相关的表结构和指标定义
├── sales.md ← 销售相关的表结构和指标定义
└── product.md ← 产品相关的表结构和指标定义

什么时候用references/:

  • 领域知识量大,不适合全部塞进SKILL.md(如数据库Schema、API文档)
  • 不同场景需要不同的知识子集(如用户问销售数据时只加载sales.md)
  • 公司内部的规范、政策、模板等

特点:按需加载——Agent根据用户的具体问题决定读取哪个reference文件,避免一次性加载所有知识撑爆上下文。

assets/ —— 输出资源

存放不需要被Agent"阅读理解",而是直接用于输出的文件。

frontend-webapp-builder/
├── SKILL.md
└── assets/
├── template/ ← React/HTML项目模板
│ ├── index.html
│ ├── styles.css
│ └── app.js
└── logo.png ← 品牌Logo

什么时候用assets/:

  • 项目模板/脚手架(Agent基于模板创建新项目)
  • 品牌资源(Logo、字体、图标)
  • 文档模板(PPT模板、合同模板)

特点:Agent不需要把这些文件读入上下文来"理解"它们,而是直接复制、修改或引用。

3.2.4 渐进式披露:三级加载机制

Skill的设计遵循"渐进式披露"原则,按需逐级加载,节省上下文空间:

┌─────────────────────────────────────────────────────────────────────────┐
│ Skill的三级加载机制 │
└─────────────────────────────────────────────────────────────────────────┘

第1级: 元数据(name + description)
→ 始终在上下文中(约100词)
→ 用于Skill发现和触发判断

第2级: SKILL.md正文
→ Skill被触发后加载(建议<500行)
→ 包含核心工作流和指令

第3级: 捆绑资源(scripts/ references/ assets/)
→ Agent按需加载(无上限)
→ scripts可直接执行不占上下文
→ references按需读取特定文件

为什么这样设计? 上下文窗口是稀缺资源。如果Agent同时注册了50个Skill,不可能把所有Skill的全部内容都塞进上下文。三级加载机制确保:

  • 50个Skill的元数据(~5000词)始终可见,用于匹配
  • 只有被触发的1-2个Skill的正文(~2000词)被加载
  • 只有真正需要的reference文件才被读取
3.2.5 完整案例:一个真实的Skill长什么样

以"代码安全审查"Skill为例,展示完整的文件结构:

code-security-review/
├── SKILL.md
├── scripts/
│ └── scan_patterns.py
└── references/
├── owasp-top10.md
└── company-security-policy.md

SKILL.md 完整内容:


name: code-security-review
description: >
Comprehensive code security audit covering OWASP Top 10 vulnerabilities
including SQL injection, XSS, CSRF, sensitive data exposure, and
authentication flaws. Use when the user asks to: review code security,
audit for vulnerabilities, check for security issues, scan for injection
flaws, or perform any security-related code analysis.

# Code Security Review

## Workflow

1. Run `scripts/scan_patterns.py` on target directory for automated detection
2. Review flagged files manually for false positives
3. Check entry points (routes, API handlers) for auth/authz issues
4. For OWASP details, see `references/owasp-top10.md`
5. For company-specific rules, see `references/company-security-policy.md`
6. Generate final report in standard format

## Quick Reference: Common Patterns

### Dangerous (flag immediately)
– String interpolation in SQL: `f"SELECT … {user_input}"`
– innerHTML with user data
– Hardcoded secrets: `API_KEY = "sk-…"`
– Missing auth decorators on admin routes

### Safe (no flag)
– Parameterized queries
– ORM usage (SQLAlchemy, Django ORM)
– Environment variables for secrets
– Role-based access decorators

## Output Format

### Security Audit Report

**Scope**: [files reviewed]
**Risk Level**: 🔴 Critical / 🟡 Medium / 🟢 Low / ✅ Clean

| # | Severity | Type | File:Line | Description | Suggested Fix |
|—|———-|——|———–|————-|—————|

## Constraints

– Read-only: never modify source files
– Mask secrets in output with ***
– Stay within user-specified directory scope
– Report only confirmed issues, not speculation

对比3.1的五大要素映射:

五大要素在Skill文件中的体现
① 元数据 YAML frontmatter(name + description)
② 工具集 Agent已有的工具(read_file, search_code等),Skill中通过指令引导使用
③ 知识库 references/ 目录 + SKILL.md正文中的Quick Reference
④ 提示模板 SKILL.md正文(Workflow、Output Format等)
⑤ 安全约束 SKILL.md正文中的Constraints部分

3.3 各要素的作用机制

当Agent加载这个Skill后,实际发生了什么?

# Agent加载Skill后,构建给LLM的请求:

messages = [
{
"role": "system",
"content": f"""
{skill.system_prompt}

## 领域知识
{skill.knowledge}

## 安全约束(你必须遵守)
{chr(10).join(f'- {g}' for g in skill.guardrails)}

## 参考示例
输入: {skill.examples[0]['input']}
期望输出:
{skill.examples[0]['output']}
"""

},
{
"role": "user",
"content": "请审查 /src/api/ 目录下的代码安全性"
}
]

tools = skill.tools # 只传这个Skill定义的工具,不是全部200个工具

response = openai.chat.completions.create(
model="gpt-4",
messages=messages,
tools=tools # LLM只看到3个工具,而不是200个
)

关键理解:Skill本质上是在"精心构造LLM的输入"——通过注入专业的system_prompt、领域knowledge、限定的tools和guardrails,让一个通用的LLM在特定任务上表现得像一个专家。


四、Skill的生命周期

4.0 谁来管理Skill的生命周期?

在进入具体流程之前,必须先搞清楚一个关键问题:Skill的生命周期由谁来管理?

答案是:由你(研发)编写的应用编排层代码来管理,而不是LLM自己。

┌─────────────────────────────────────────────────────────────────────────┐
│ Skill管理的职责分工 │
└─────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────┐
│ 你的代码(应用编排层)负责: │
│ │
│ ✅ 注册: 把哪些Skill加入系统 │
│ ✅ 发现: 根据用户输入匹配到合适的Skill │
│ ✅ 加载: 把Skill的内容注入到LLM的上下文中 │
│ ✅ 卸载: 任务完成后释放上下文空间 │
│ ✅ 冲突处理: 多个Skill同时激活时的优先级管理 │
│ │
│ 简单说: 你的代码决定"什么时候给LLM什么能力" │
└─────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────┐
│ LLM负责: │
│ │
│ ✅ 执行: 在被注入Skill内容后,按照Skill的指令完成任务 │
│ ✅ 工具调用: 使用Skill中声明的工具 │
│ ✅ 遵守约束: 按照Skill的guardrails行事 │
│ │
│ 简单说: LLM只负责"用好被给予的能力" │
└─────────────────────────────────────────────────────────────────────────┘

为什么LLM不能自己管理Skill?

  • LLM没有持久状态:每次请求都是独立的,它不知道系统里有哪些Skill可用
  • LLM不能修改自己的输入:它不能自己决定"我要加载某个Skill"然后改变自己的system prompt
  • 需要工程化保障:Skill的注册、版本管理、权限控制、冲突检测等都需要确定性的代码逻辑
  • 类比理解:

    Skill管理 之于 Agent ≈ 应用商店 之于 手机

    – 应用商店(你的编排代码): 管理App的安装、更新、卸载、权限
    – 手机操作系统(LLM): 运行被安装好的App
    – 用户不会期望手机自己决定装什么App,而是通过应用商店来管理

    在你的智能体项目中,这意味着:

    你需要在LLM调用之外,编写一层"Skill编排代码",它的职责是:

    # 伪代码: 你的应用编排层
    def handle_user_request(user_message: str):
    # 1. 你的代码负责发现合适的Skill(不是LLM决定的)
    matched_skills = skill_registry.discover(user_message)

    # 2. 你的代码负责把Skill内容注入到LLM的输入中
    system_prompt = build_prompt_with_skills(matched_skills)
    tools = collect_tools_from_skills(matched_skills)

    # 3. LLM只负责在这个"被精心构造的环境"中执行任务
    response = llm.chat(
    system=system_prompt, # ← 已经包含了Skill的知识和指令
    tools=tools, # ← 已经限定了Skill的工具集
    message=user_message
    )

    # 4. 你的代码负责任务完成后的清理
    unload_skills_if_done(matched_skills)

    return response

    理解了这个前提后,下面我们逐步看每个阶段的具体实现。

    4.1 完整生命周期

    ┌──────────────────────────────────────────────────────────────────────────┐
    │ Skill的完整生命周期 │
    └──────────────────────────────────────────────────────────────────────────┘

    ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
    │自动发现 │────▶│ 注册 │────▶│ 匹配 │────▶│ 加载 │────▶│ 执行 │────▶│ 卸载 │
    │ Scan │ │Register │ │ Match │ │ Load │ │Execute │ │ Unload │
    └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
    │ │ │ │ │ │
    ▼ ▼ ▼ ▼ ▼ ▼
    扫描本地目录 解析SKILL.md 根据用户任务 Skill的知识/ Agent使用 任务完成后
    发现所有Skill 注册到Registry 找到最匹配的 提示注入Agent Skill的能力 释放上下文
    文件夹 Skill 上下文 完成任务 空间

    4.2 Skill的自动发现

    在4.0中我们说了"你的代码负责注册Skill",但一个自然的问题是:Skill从哪里来?你的代码怎么知道有哪些Skill可用?

    这就是"自动发现"要解决的问题——Agent启动时(或运行时),自动扫描并识别所有可用的Skill,然后注册到Registry中。

    常见的Skill发现方式

    ┌─────────────────────────────────────────────────────────────────────────┐
    │ Skill的发现方式 │
    └─────────────────────────────────────────────────────────────────────────┘

    方式1: 本地目录扫描(最常见)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    约定一个目录存放所有Skill,Agent启动时扫描该目录:

    ~/.agent/skills/ ← 全局Skill目录
    ├── code-security-review/
    │ └── SKILL.md
    ├── big-query-analyst/
    │ ├── SKILL.md
    │ └── references/
    └── frontend-builder/
    ├── SKILL.md
    └── assets/

    典型实现: Cursor、Claude Code、Windsurf等IDE Agent

    方式2: 项目级目录扫描
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    每个项目可以有自己的Skill目录,只在该项目中生效:

    my-project/
    ├── .skills/ ← 项目级Skill目录
    │ ├── db-migration/
    │ │ └── SKILL.md
    │ └── api-design/
    │ └── SKILL.md
    ├── src/
    └── package.json

    适用场景: 团队共享的项目特定Skill(如特定业务的审查规则)

    方式3: 配置文件声明
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    在配置文件中显式列出要加载的Skill:

    # agent.yaml
    skills:
    – path: ./skills/code-review
    – path: ~/.global-skills/security-audit
    – remote: https://skills.sh/packages/data-analysis@2.1.0

    适用场景: 需要精确控制加载哪些Skill、不希望自动扫描的场景

    方式4: 远程市场同步
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    从Skill市场(如skills.sh、SkillHub)拉取并缓存到本地:

    agent skill install code-security-review
    # → 下载到 ~/.agent/skills/code-security-review/
    # → 下次启动时自动被目录扫描发现

    适用场景: 使用社区共享的Skill、团队统一分发Skill

    方式5: 运行时热加载(文件监听)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Agent运行期间监听Skill目录的文件变化,新增/修改时自动重新加载:

    # 开发者往目录里放了一个新Skill
    cp -r my-new-skill/ ~/.agent/skills/
    # → Agent检测到变化,自动解析并注册新Skill(无需重启)

    适用场景: Skill开发调试阶段、需要动态扩展能力的长运行Agent

    目录扫描的实现逻辑

    以最常见的"本地目录扫描"为例,核心逻辑如下:

    import os
    import yaml

    class SkillScanner:
    """Skill目录扫描器: 自动发现并解析Skill"""

    def __init__(self, skill_dirs: list):
    """
    Args:
    skill_dirs: 要扫描的目录列表,如:
    ['~/.agent/skills', './project/.skills']
    """

    self.skill_dirs = [os.path.expanduser(d) for d in skill_dirs]

    def scan_all(self) > list:
    """扫描所有目录,返回发现的Skill元数据列表"""
    discovered = []

    for base_dir in self.skill_dirs:
    if not os.path.isdir(base_dir):
    continue

    # 遍历目录下的每个子文件夹
    for entry in os.listdir(base_dir):
    skill_path = os.path.join(base_dir, entry)
    skill_md = os.path.join(skill_path, "SKILL.md")

    # 判断是否是一个合法的Skill(必须有SKILL.md)
    if os.path.isdir(skill_path) and os.path.isfile(skill_md):
    metadata = self._parse_skill_md(skill_md)
    if metadata:
    metadata['path'] = skill_path
    discovered.append(metadata)
    print(f" 🔍 发现Skill: {metadata['name']} ({skill_path})")

    return discovered

    def _parse_skill_md(self, filepath: str) > dict:
    """解析SKILL.md的YAML frontmatter,提取元数据"""
    with open(filepath, 'r') as f:
    content = f.read()

    # 解析YAML frontmatter(— 包裹的部分)
    if content.startswith('—'):
    end = content.find('—', 3)
    if end != 1:
    frontmatter = content[3:end].strip()
    return yaml.safe_load(frontmatter)

    return None

    # 使用示例
    scanner = SkillScanner([
    '~/.agent/skills', # 全局Skill
    './.skills', # 项目级Skill
    ])

    # Agent启动时自动扫描
    skills = scanner.scan_all()
    # 输出:
    # 🔍 发现Skill: code-security-review (~/.agent/skills/code-security-review)
    # 🔍 发现Skill: big-query-analyst (~/.agent/skills/big-query-analyst)
    # 🔍 发现Skill: db-migration (./.skills/db-migration)

    # 然后逐个注册到Registry
    for skill_meta in skills:
    registry.register(skill_meta)

    多级目录的优先级

    当全局目录和项目目录存在同名Skill时,需要定义优先级:

    优先级(从高到低):
    1. 项目级 ./.skills/ ← 最高优先级(项目特定覆盖)
    2. 用户级 ~/.agent/skills/ ← 用户个人安装的Skill
    3. 系统级 /etc/agent/skills/ ← 系统预装(如企业统一分发)
    4. 远程市场缓存 ← 最低优先级

    规则: 同名Skill,高优先级覆盖低优先级

    这个优先级机制允许:

    • 团队在项目中放置定制化Skill,覆盖通用版本
    • 个人可以安装自己偏好的Skill
    • 企业可以统一分发合规性相关的Skill

    4.3 注册(Register)

    class SkillRegistry:
    """Skill注册中心: 管理所有可用的Skill"""

    def __init__(self):
    self._skills: Dict[str, Skill] = {}
    self._tag_index: Dict[str, List[str]] = {} # tag → skill names

    def register(self, skill: Skill):
    """注册一个Skill到注册中心"""
    self._skills[skill.name] = skill
    # 建立标签索引,加速发现
    for tag in skill.tags:
    if tag not in self._tag_index:
    self._tag_index[tag] = []
    self._tag_index[tag].append(skill.name)
    print(f"✅ Skill已注册: {skill.name} v{skill.version} (tags: {skill.tags})")

    def unregister(self, name: str):
    """从注册中心移除一个Skill"""
    if name in self._skills:
    skill = self._skills.pop(name)
    for tag in skill.tags:
    if tag in self._tag_index:
    self._tag_index[tag].remove(name)
    print(f"❌ Skill已移除: {name}")

    def list_all(self) > List[str]:
    """列出所有已注册的Skill"""
    return list(self._skills.keys())

    def get(self, name: str) > Optional[Skill]:
    """按名称获取Skill"""
    return self._skills.get(name)

    # 使用示例
    registry = SkillRegistry()
    registry.register(code_security_review_skill)
    # 输出: ✅ Skill已注册: code_security_review v2.1.0 (tags: ['security', 'code-review', 'audit'])

    4.4 发现(Discover)

    Skill发现是整个系统中最关键的环节——Agent需要根据用户的任务,自动找到最相关的Skill。

    class SkillRegistry:
    # … 前面的代码 …

    def discover(self, task_description: str, top_k: int = 3) > List[Skill]:
    """根据任务描述,发现最相关的Skill

    发现策略(从简单到复杂):
    1. 关键词匹配(最简单,适合demo)
    2. 标签匹配(中等复杂度)
    3. 语义相似度(生产级,用embedding向量)
    """
    scored_skills = []
    task_lower = task_description.lower()

    for name, skill in self._skills.items():
    score = 0

    # 策略1: 名称匹配(权重最高)
    if any(word in task_lower for word in skill.name.split("_")):
    score += 10

    # 策略2: 描述关键词匹配
    desc_words = skill.description.lower().split()
    for word in desc_words:
    if len(word) > 2 and word in task_lower:
    score += 2

    # 策略3: 标签匹配
    for tag in skill.tags:
    if tag.lower() in task_lower:
    score += 5

    if score > 0:
    scored_skills.append((score, skill))

    # 按分数降序排列
    scored_skills.sort(key=lambda x: x[0], reverse=True)
    return [skill for _, skill in scored_skills[:top_k]]

    # 使用示例
    results = registry.discover("帮我检查这段代码有没有SQL注入漏洞")
    # → 返回 code_security_review_skill(因为匹配了"security"标签和描述中的"SQL注入")

    生产级发现方案:语义搜索

    # 生产环境中,通常用embedding向量做语义匹配
    # 这样即使用户说"看看代码有没有安全隐患"(没有直接提到SQL注入),也能匹配到

    from openai import OpenAI

    class SemanticSkillDiscovery:
    """基于语义相似度的Skill发现"""

    def __init__(self, registry: SkillRegistry):
    self.client = OpenAI()
    self.registry = registry
    self._embeddings: Dict[str, List[float]] = {}
    self._build_index()

    def _build_index(self):
    """为所有Skill的描述生成embedding向量"""
    for name, skill in self.registry._skills.items():
    # 把Skill的名称+描述+标签组合成一段文本
    text = f"{skill.name}: {skill.description}. Tags: {', '.join(skill.tags)}"
    response = self.client.embeddings.create(
    model="text-embedding-3-small",
    input=text
    )
    self._embeddings[name] = response.data[0].embedding

    def discover(self, task: str, top_k: int = 3) > List[Skill]:
    """语义搜索最相关的Skill"""
    # 生成任务描述的embedding
    task_embedding = self.client.embeddings.create(
    model="text-embedding-3-small",
    input=task
    ).data[0].embedding

    # 计算余弦相似度
    scores = []
    for name, emb in self._embeddings.items():
    similarity = self._cosine_similarity(task_embedding, emb)
    scores.append((similarity, name))

    scores.sort(reverse=True)
    return [self.registry.get(name) for _, name in scores[:top_k]]

    @staticmethod
    def _cosine_similarity(a, b):
    import numpy as np
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

    4.5 加载(Load)

    class SkillAwareAgent:
    """能动态加载Skill的Agent"""

    def __init__(self, registry: SkillRegistry):
    self.registry = registry
    self.active_skills: List[Skill] = [] # 当前激活的Skill
    self.base_system_prompt = "你是一个智能助手。"

    def load_skill(self, skill: Skill):
    """加载一个Skill到Agent的活跃上下文中"""
    if skill not in self.active_skills:
    self.active_skills.append(skill)
    print(f" 📦 加载Skill: {skill.name} (工具数: {len(skill.tools)})")

    def get_combined_system_prompt(self) > str:
    """组合基础提示 + 所有活跃Skill的提示/知识/约束"""
    parts = [self.base_system_prompt]

    for skill in self.active_skills:
    parts.append(f"\\n{'='*60}")
    parts.append(f"## 当前能力: {skill.name}")
    parts.append(f"{'='*60}")
    parts.append(skill.system_prompt)

    if skill.knowledge:
    parts.append(f"\\n### 领域知识\\n{skill.knowledge}")

    if skill.guardrails:
    parts.append(f"\\n### ⚠️ 安全约束(必须遵守)")
    for g in skill.guardrails:
    parts.append(f"- {g}")

    if skill.examples:
    parts.append(f"\\n### 参考示例")
    for ex in skill.examples:
    parts.append(f"输入: {ex['input'][:100]}…")
    parts.append(f"输出: {ex['output'][:200]}…")

    return "\\n".join(parts)

    def get_active_tools(self) > List[dict]:
    """获取所有活跃Skill的工具(去重)"""
    tools = []
    seen_names = set()
    for skill in self.active_skills:
    for tool in skill.tools:
    name = tool["function"]["name"]
    if name not in seen_names:
    tools.append(tool)
    seen_names.add(name)
    return tools

    4.6 执行(Execute)

    class SkillAwareAgent:
    # … 前面的代码 …

    def chat(self, user_message: str) > str:
    """完整的对话流程: 发现→加载→执行"""

    # Step 1: 自动发现相关Skill
    relevant_skills = self.registry.discover(user_message, top_k=2)

    # Step 2: 加载发现的Skill
    for skill in relevant_skills:
    self.load_skill(skill)

    # Step 3: 构建LLM请求
    messages = [
    {"role": "system", "content": self.get_combined_system_prompt()},
    {"role": "user", "content": user_message}
    ]
    tools = self.get_active_tools()

    print(f"\\n 🤖 发送给LLM:")
    print(f" System Prompt长度: {len(self.get_combined_system_prompt())}字")
    print(f" 可用工具数: {len(tools)}")

    # Step 4: 调用LLM(这里是伪代码,实际需要处理tool_call循环)
    # response = openai.chat.completions.create(
    # model="gpt-4",
    # messages=messages,
    # tools=tools
    # )
    # … 处理tool_call,执行工具,循环直到LLM给出最终回复 …

    return "…"

    def unload_all(self):
    """卸载所有Skill(任务完成后调用)"""
    self.active_skills.clear()
    print(" 🧹 所有Skill已卸载")

    4.7 卸载(Unload)

    为什么需要卸载?

    1. 上下文窗口有限:
    每个Skill的知识+提示可能占用2000-5000 token
    如果不卸载,累积10个Skill就占了20000-50000 token
    LLM的上下文窗口会被撑爆

    2. 避免能力冲突:
    "代码审查"Skill说"不能修改代码"
    "代码修复"Skill说"请修改代码"
    两个同时激活会让Agent精神分裂

    3. 保持专注:
    当前任务是"审查代码",不需要"故障排障"的知识
    无关信息会干扰LLM的判断

    卸载时机:
    – 用户明确切换了任务
    – 当前任务完成
    – 上下文接近窗口上限时,卸载最不相关的Skill


    五、Skill的动态加载与编排

    5.1 按需加载模式

    class SmartSkillLoader:
    """智能Skill加载器: 根据对话动态加载/卸载Skill"""

    def __init__(self, registry: SkillRegistry, max_active: int = 3):
    self.registry = registry
    self.max_active = max_active # 最多同时激活的Skill数
    self.active_skills: List[Skill] = []
    self.usage_history: Dict[str, int] = {} # 使用频率统计

    def on_new_message(self, message: str) > List[Skill]:
    """每次收到新消息时,重新评估需要哪些Skill"""

    # 发现与当前消息相关的Skill
    needed = self.registry.discover(message, top_k=self.max_active)

    # 计算需要加载和卸载的Skill
    needed_names = {s.name for s in needed}
    active_names = {s.name for s in self.active_skills}

    to_load = needed_names active_names
    to_unload = active_names needed_names

    # 执行卸载
    for name in to_unload:
    self.active_skills = [s for s in self.active_skills if s.name != name]
    print(f" 📤 卸载Skill: {name}")

    # 执行加载
    for skill in needed:
    if skill.name in to_load:
    self.active_skills.append(skill)
    self.usage_history[skill.name] = self.usage_history.get(skill.name, 0) + 1
    print(f" 📥 加载Skill: {skill.name}")

    return self.active_skills

    5.2 Skill冲突处理

    class SkillConflictResolver:
    """处理Skill之间的冲突"""

    # 预定义的冲突规则
    CONFLICTS = {
    ("code_review", "code_fix"): "code_review说不能改代码,code_fix说要改代码",
    ("read_only_audit", "data_cleanup"): "审计要求只读,清理要求写入",
    }

    @classmethod
    def check_conflicts(cls, skills: List[Skill]) > List[str]:
    """检查一组Skill之间是否有冲突"""
    warnings = []
    names = [s.name for s in skills]

    for (a, b), reason in cls.CONFLICTS.items():
    if a in names and b in names:
    warnings.append(f"⚠️ 冲突: {a}{b} 不能同时激活 ({reason})")

    return warnings

    @classmethod
    def resolve(cls, skills: List[Skill], task: str) > List[Skill]:
    """解决冲突: 保留与当前任务更相关的Skill"""
    conflicts = cls.check_conflicts(skills)
    if not conflicts:
    return skills

    # 简单策略: 保留排名靠前的(即与任务更相关的)
    # 生产环境可以用更复杂的策略
    print(f" ⚠️ 检测到Skill冲突,自动解决:")
    for c in conflicts:
    print(f" {c}")

    # 去掉冲突中排名靠后的
    return skills[:len(skills)len(conflicts)]

    5.3 Skill组合模式

    有些复杂任务需要多个Skill协作完成:

    场景: "帮我审查代码,修复发现的安全问题,然后写一份报告"

    这个任务需要3个Skill按顺序协作:

    Step 1: code_security_review Skill(审查代码)
    → 输出: 安全审查报告(发现了哪些问题)

    Step 2: code_fix Skill(修复代码)
    → 输入: 上一步发现的问题
    → 输出: 修复后的代码

    Step 3: report_generation Skill(生成报告)
    → 输入: 审查结果 + 修复内容
    → 输出: 完整的安全审查修复报告

    这就是Skill的"管道组合"模式:
    Skill_A的输出 → Skill_B的输入 → Skill_C的输入 → 最终输出

    class SkillPipeline:
    """Skill管道: 多个Skill按顺序协作"""

    def __init__(self, skills: List[Skill]):
    self.skills = skills

    def describe(self) > str:
    """描述这个管道的执行流程"""
    steps = []
    for i, skill in enumerate(self.skills, 1):
    steps.append(f" Step {i}: {skill.name}{skill.description}")
    return "\\n".join(steps)

    # 定义一个"安全审查修复"管道
    security_fix_pipeline = SkillPipeline([
    code_security_review_skill, # 先审查
    # code_fix_skill, # 再修复(假设已定义)
    # report_generation_skill, # 最后生成报告
    ])

    print(security_fix_pipeline.describe())
    # Step 1: code_security_review – 审查代码中的安全漏洞…
    # Step 2: code_fix – 根据审查结果修复代码…
    # Step 3: report_generation – 生成完整的审查修复报告…


    六、Skill生态与标准化

    6.1 为什么Skill需要标准化

    当前的问题(2024-2025):

    每个Agent框架都有自己的Skill格式:
    – Cursor: 用 .cursorrules 文件定义能力
    – Claude: 用 system prompt + tools 组合
    – AutoGPT: 用 Python类 定义能力
    – LangChain: 用 Agent + Tools + Memory 组合

    结果:
    – 你为Cursor写的Skill,不能在Claude里用
    – 你为LangChain写的Agent能力,不能在AutoGPT里用
    – 大量重复开发

    这和MCP出现前的情况一模一样!
    MCP之前: 每个AI应用自己写工具连接代码 → MCP统一了
    现在: 每个Agent框架自己定义Skill格式 → 需要一个"Skill的MCP"

    正在发展的标准化方向:
    1. skills.sh: 90,000+ 技能库,统一的Skill描述和分发格式
    2. ClawHub: 40,000+ 技能市场,支持Skill的搜索和安装
    3. OpenSpec: 开放的Agent能力描述规范
    4. A2A (Google): Agent-to-Agent协议,让Agent之间共享能力

    6.2 Skill的标准描述格式

    目前社区正在收敛的Skill描述格式(以YAML为例):

    # skill.yaml – 一个标准的Skill描述文件

    # 元数据
    name: codesecurityreview
    version: 2.1.0
    description: "审查代码中的安全漏洞,包括SQL注入、XSS、CSRF、敏感信息泄露"
    author: securityteam
    license: MIT
    tags:
    security
    codereview
    audit

    # 能力声明
    capabilities:
    sql_injection_detection
    xss_detection
    sensitive_data_detection
    permission_check

    # 输入输出
    inputs:
    code_path:
    type: string
    required: true
    description: "需要审查的代码目录路径"
    language:
    type: string
    required: false
    description: "编程语言(自动检测如果不指定)"

    outputs:
    report:
    type: object
    description: "安全审查报告"
    properties:
    risk_level: { type: string, enum: [high, medium, low, none] }
    issues: { type: array }
    summary: { type: string }

    # 依赖的工具
    tools_required:
    read_file
    search_code
    list_files

    # 约束
    constraints:
    read_only: true
    network_access: false
    max_files: 100

    # 兼容性
    compatible_with:
    cursor: ">=0.40"
    claude-desktop: ">=1.0"
    langchain: ">=0.2"

    6.3 Skill市场与共享

    当前主流的Skill/Prompt市场一览(截至2026年6月3日,数据来自各平台实时查询):

    平台地址规模特点
    skills.sh https://skills.sh 9,605 Skills,总安装量 651,691+ The Agent Skills Directory,支持一键安装到Cursor/Claude Code/Windsurf等IDE,有官方认证标识
    Glama https://glama.ai/mcp/servers 30,517 MCP Servers 最大的开源MCP Server注册表,提供质量评分(A/B/C级)、分类浏览、兼容性标注
    mcp.so https://mcp.so 自称最大MCP集合 MCP Server聚合搜索平台,包含Awesome MCP Servers和Claude MCP集成
    Smithery https://smithery.ai 2,621 MCP Servers MCP Server市场,支持一键部署和远程托管,提供详情页和安装指引
    SkillHub https://www.skillhub.club 7,000+ Skills 通用Agent Skills市场,支持Claude Code/Codex CLI/Gemini CLI/OpenCode,提供Playground即时试用、5维度AI质量评估
    ClawHub https://clawhub.ai 快速Skill注册表 面向Agent的Skill注册中心,支持向量语义搜索,快速发现和安装
    Cursor Directory https://cursor.directory 社区驱动 专注Cursor Rules/Skills的社区分享平台,按语言/框架分类
    OpenTools https://opentools.ai 2,500+ AI Tools AI工具+MCP Server综合目录,含对比和评测
    GitHub Topics https://github.com/topics/agent-skills 5,982 repos(agent-skills)17,067 repos(mcp-server) 通过GitHub Topics发现开源Skill和MCP Server

    💡 实际使用建议:

    • 找Agent Skill:优先去 skills.sh(专注Skill,有安装量排行和官方认证)
    • 找MCP Server:优先去 Glama(30,000+,最全且有质量评分),其次 Smithery(支持远程托管)
    • 语义搜索:ClawHub 支持向量搜索,适合用自然语言描述需求来发现Skill
    • 开源探索:GitHub Topics 是最原始的开源社区,适合深度研究和贡献

    Skill的分发方式(类比App Store):

    ┌─────────────────────────────────────────────────────────────────────────┐
    │ Skill生态系统 │
    └─────────────────────────────────────────────────────────────────────────┘

    ┌──────────────────┐ ┌──────────────────┐
    │ Skill开发者 │ │ Skill市场 │
    │ │ 发布 │ │
    │ 写Skill │────────▶│ skills.sh │
    │ 测试Skill │ │ ClawHub │
    │ 版本管理 │ │ GitHub │
    └──────────────────┘ └────────┬─────────┘
    │ 搜索/安装

    ┌──────────────────┐
    │ Agent应用 │
    │ │
    │ 安装Skill │
    │ 加载Skill │
    │ 使用Skill │
    └──────────────────┘

    实际的Skill安装流程(以Cursor为例):
    1. 搜索: 在skills.sh搜索"code review"
    2. 选择: 找到评分最高的code-security-review skill
    3. 安装: 一键安装到你的Cursor工作区
    4. 使用: Agent自动发现并使用这个Skill

    类比:
    写App → 发布到App Store → 用户搜索安装 → 手机获得新能力
    写Skill → 发布到Skill市场 → Agent搜索安装 → Agent获得新能力


    七、Skill设计的工程原则

    7.1 六大设计原则

    原则1: 单一能力(Single Responsibility)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    ✅ 好的Skill: "代码安全审查" — 只做安全审查这一件事
    ❌ 坏的Skill: "开发助手" — 又能审查、又能写代码、又能部署

    为什么?
    – 单一能力的Skill更容易被精确发现(用户说"审查安全"就能匹配)
    – 单一能力的Skill更容易维护和测试
    – 单一能力的Skill可以灵活组合(管道模式)

    粒度参考:
    太粗: "全栈开发" → 拆成 "前端开发" + "后端开发" + "数据库设计"
    太细: "检测SQL注入" → 合并到 "代码安全审查"
    刚好: "代码安全审查" / "性能优化建议" / "API设计审查"

    原则2: 自包含(Self-Contained)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    ✅ 好的Skill: 加载后就能独立工作,不依赖其他Skill
    ❌ 坏的Skill: 必须先加载Skill A才能用Skill B

    为什么?
    – 减少加载复杂度
    – 避免循环依赖
    – 方便独立测试

    如果确实有依赖,要显式声明:
    dependencies:
    – name: "file_reader"
    reason: "需要读取文件的能力"

    原则3: 明确边界(Clear Boundaries)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    ✅ 好的Skill:
    输入: 代码文件路径
    输出: 结构化的审查报告(JSON格式)
    约束: 只读,不修改代码

    ❌ 坏的Skill:
    输入: "什么都可以"
    输出: "看情况"
    约束: 没有

    为什么?
    – 明确的输入输出让Agent知道"什么时候该用这个Skill"
    – 明确的约束让Agent知道"用这个Skill时不能做什么"
    – 方便自动化测试(给定输入,验证输出)

    原则4: 可测试(Testable)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    每个Skill都应该有验收标准:
    – 给定输入X,期望输出包含Y
    – 给定危险操作,期望被约束拦截
    – 给定边界情况,期望优雅处理

    测试示例:
    test_cases:
    – input: "有SQL注入的代码"
    expect: "报告中包含SQL注入警告"
    – input: "安全的代码"
    expect: "报告显示无风险"
    – input: "请帮我删除数据库"
    expect: "被guardrails拒绝"

    原则5: 安全约束优先(Security First)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    每个Skill必须声明"不能做什么":
    – 不能做什么操作(只读?可写?可删除?)
    – 不能访问什么范围(只限指定目录?不能联网?)
    – 不能输出什么内容(不能泄露密钥?不能输出个人信息?)

    为什么?
    – Agent的行为本质上不可完全预测(LLM是概率模型)
    – 约束是最后一道防线
    – 没有约束的Skill = 没有安全带的汽车

    原则6: 版本管理(Versioned)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    Skill需要版本化管理:
    v1.0.0: 初始版本,支持SQL注入检测
    v1.1.0: 新增XSS检测(向后兼容)
    v2.0.0: 重构输出格式(Breaking Change,不向后兼容)

    为什么?
    – Agent可能依赖特定版本的Skill
    – 升级Skill时需要知道是否有Breaking Change
    – 方便回滚到之前的版本

    7.2 常见反模式(Anti-Patterns)

    反模式1: "上帝Skill"
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    问题: 一个Skill包含50个工具、10000字的知识、3000字的提示
    后果: 占满上下文窗口,LLM无法有效处理
    解决: 拆分成多个小Skill

    反模式2: "空壳Skill"
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    问题: Skill只有工具列表,没有知识、提示和约束
    后果: 和直接给Agent工具没区别,失去了Skill的价值
    解决: 补充领域知识、工作流程提示和安全约束

    反模式3: "硬编码Skill"
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    问题: Skill中硬编码了具体的文件路径、数据库地址等
    后果: 换个环境就不能用
    解决: 使用参数化配置,环境相关的信息通过参数传入

    反模式4: "无约束Skill"
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    问题: Skill没有任何guardrails
    后果: Agent可能执行危险操作(删除数据、泄露信息)
    解决: 每个Skill必须有至少3条安全约束


    八、完整实战:从零构建一个Skill系统

    本章将真正动手创建一个完整的Skill,并构建一个能自动发现、注册、匹配、加载、执行、卸载的Skill管理系统。不是模拟代码,而是可以直接运行的真实项目。

    详见:16.1-大模型智能体开发工程师:从零构建一个Skill系统


    📝 作业

    作业1:设计一个"数据分析"Skill

    要求:

  • 包含完整的五大要素(元数据、工具集、知识库、提示模板、安全约束)
  • 工具至少包含:query_database、generate_chart、export_csv
  • 知识库包含常见的数据分析方法论(描述性统计、趋势分析等)
  • 提示模板要有明确的工作流程和输出格式
  • 安全约束要防止Agent执行DELETE/DROP等危险SQL
  • 作业2:实现Skill的语义发现

    要求:

  • 使用OpenAI的embedding API为Skill描述生成向量
  • 实现基于余弦相似度的Skill匹配
  • 测试:输入"我的服务挂了"能匹配到troubleshoot Skill
  • 测试:输入"看看代码有没有问题"能匹配到code_review Skill
  • 作业3:实现Skill管道(Pipeline)

    要求:

  • 定义3个Skill:code_review → code_fix → test_generation
  • 实现SkillPipeline类,支持按顺序执行多个Skill
  • 前一个Skill的输出作为后一个Skill的输入
  • 如果中间某个Skill失败,整个管道停止并报告错误

  • 下一篇文章见:AI系列文章导航目录-持续更新中

    赞(0)
    未经允许不得转载:171主机测评 » 16-大模型智能体开发工程师:全面学习Agent Skill系统
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址