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系列文章导航目录-持续更新中

相关推荐
mobility11 小时前
免费AI视频生成器:我如何用零成本做出带旁白字幕的多场景AI视频
ai·vibe coding
doiito14 小时前
【Agent Harness】Gliding Horse 给 Agent OS 装上双曲空间引擎与默克尔树边云同步
ai·rust·架构设计·系统设计·ai agent
knqiufan17 小时前
从 Python 到 TypeScript,用 GLM-5.2 跑通 PowerMem SDK 的长程任务工程
ai·memory·agentic·powermem
小白跃升坊2 天前
Codex 增强部署:基于 Codex++ 接入 DeepSeek
ai·ai编程·codex·deepseek·ai coding·codex++
AlfredZhao2 天前
GPT 省钱,不是别用最新模型,而是别浪费缓存
gpt·ai
doiito2 天前
【Agent Harness】Gliding Horse 本体论系统设计:给 AI Agent 装上“语义大脑”
ai·rust·架构设计·系统设计·ai agent
小七-七牛开发者2 天前
周一上线 | SpaceX 收购 Cursor、支付宝进入 AI 时代、DeepSeek 完成 500 亿元融资
ai·agent·token·glm·智谱·claudecode·ai coding·周一上线
doiito3 天前
【Agent Harness】为什么我把 JSON‑LD “编译成 DAG” 后,整个 Agent 平台立刻聪明了
ai·rust·架构设计·系统设计·ai agent
xiezhr3 天前
折腾半小时,终于让AI 能直接帮我写飞书文档了
ai·飞书·ai agent·飞书cli·飞书文档
岳小哥AI3 天前
Claude Fable和Claude Mythos 5同时发布:注意力机制下愈加强大的AI大模型
ai·ai基础