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的发现和触发:

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

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

markdown 复制代码
# 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/

特点:按需加载------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 完整内容

markdown 复制代码
---
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后,实际发生了什么?

python 复制代码
# 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?

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

类比理解

复制代码
Skill管理 之于 Agent ≈ 应用商店 之于 手机

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

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

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

python 复制代码
# 伪代码: 你的应用编排层
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
目录扫描的实现逻辑

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

python 复制代码
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)

python 复制代码
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。

python 复制代码
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注入")

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

python 复制代码
# 生产环境中,通常用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)

python 复制代码
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)

python 复制代码
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 按需加载模式

python 复制代码
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冲突处理

python 复制代码
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的输入 → 最终输出
python 复制代码
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为例):

yaml 复制代码
# skill.yaml - 一个标准的Skill描述文件

# 元数据
name: code-security-review
version: 2.1.0
description: "审查代码中的安全漏洞,包括SQL注入、XSS、CSRF、敏感信息泄露"
author: security-team
license: MIT
tags:
  - security
  - code-review
  - 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

要求:

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

作业2:实现Skill的语义发现

要求:

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

作业3:实现Skill管道(Pipeline)

要求:

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

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

相关推荐
Dragon Wu1 小时前
AI视频创作笔记(二)分镜、运镜、角度
ai
多年小白2 小时前
AI 日报 - 2026年6月3日
科技·ai
nebula-AI2 小时前
Understand Anything 简要使用文档
人工智能·ai·github·项目管理·知识图谱·dashboard
MicrosoftReactor2 小时前
技术速递|使用 GitHub Copilot CLI 构建 Emoji 列表生成器
ai·github·copilot·cli
摸鱼同学2 小时前
从0到1打造AI学习体系,从LLM到Multi-Agent
ai·agent·vibe coding·claudecode·skills
梁萌2 小时前
LightRAG知识库
ai·知识库·rag·检索·问答
摸鱼同学3 小时前
LLM 是什么?从 API 调用到 Token 机制
ai·大模型·llm·token·claudecode
一锅炖出任易仙3 小时前
创梦汤锅学习日记day23
学习·ai·ue5
Elastic 中国社区官方博客3 小时前
Elasticsearch Reindex 现已支持跨节点自动迁移:无需人工干预,不会丢失进度
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索