用好 AI
Skills(技能)是封装好的 AI 能力模块 — 把特定任务的流程、知识和工具打包在一起,让 AI 按专业标准稳定执行。
Prompt 是「临时任务」,Rules 是「行为规范」,Skills 是「标准操作流程(SOP)」。
用 Prompt 做简单任务没问题。但遇到复杂任务,你会发现自己每次都在写同一大段指令:
「帮我做 Code Review,检查线程安全、循环引用、内存泄漏、架构规范、命名规范、错误处理,按严重程度分级输出,给出修复建议和代码示例……」
写一次可以,每周都写就很痛苦。而且 Prompt 用完就消失了,下次还得重新写,质量也不稳定 — 这次记得检查线程安全,下次可能就忘了。
Skills 就是把这类「反复执行的复杂任务」固化成一个可复用模块。 封装之后,说一句「帮我做 Code Review」,AI 就按完整流程执行,每次都按同一套标准,不会遗漏。
从 iOS 开发者的视角来类比:Skills 很像 Framework。SDWebImage、Alamofire、SnapKit 都是封装好的能力模块,调用者不需要关心内部实现;Skills 也一样 — 封装一次,反复调用,稳定输出。
| 概念 | 回答的问题 | 生命周期 | 类比 |
|---|---|---|---|
| Prompt | 这次做什么? | 一次性 | 口头吩咐 |
| Rules | 始终遵守什么? | 长期生效 | 公司制度 |
| Skills | 这类事按什么流程做? | 按需触发,可复用 | Framework / SOP |
三者协作:Prompt 触发任务 → Skills 提供执行流程 → Rules 约束过程中的行为规范。
你可能在社区里看到「Agent Skill」这个词。它和 Skill 是同一个东西,只是强调了使用者的不同:
| 叫法 | 含义 |
|---|---|
| Skill | 通用说法,封装好的能力模块 |
| Agent Skill | 强调这个 Skill 是被 Agent 自动发现和调用的,而不是人手动触发的 |
就像你写一个 iOS Framework,有人叫它「Framework」,有人叫它「App Extension 用的 Framework」— 东西是同一个,只是强调了谁在用。
Skill 还有一个维度值得区分:它定义的是「标准」还是「流程」。
文档形 Skill 像 .swiftlint.yml — 不告诉你先写什么后写什么,而是告诉你「命名用驼峰、闭包用 [weak self]、VC 不超过 400 行」。AI 执行相关任务时,这些约束自动生效。写作规范、代码规范、设计规范都是文档形。
动作形 Skill 像 Fastlane Lane — 触发后按步骤跑完,给你一个结果。Git 提交(分析 diff → 生成 message → 提交)、UI 走查(对比设计稿 → 输出差异报告)都是动作形。
| 文档形 | 动作形 | |
|---|---|---|
| 定义的是 | 标准 / 约束 | 流程 / 工作流 |
| 触发方式 | 被动(执行相关任务时自动生效) | 主动(用户指令或关键词匹配) |
| 有没有步骤 | 没有,是一组原则 | 有,是可执行的流程 |
| iOS 类比 | .swiftlint.yml |
Fastlane Lane |
放哪里:文档形通常是项目特有的(每个项目的写作风格、代码规范不同),放项目级。动作形看通用性 — 换一个项目还能直接用的(如 Git 提交),放全局;需要改的(如专属部署流程),放项目级。
很多人以为 Skill 就是一个 Markdown 文件,写几行说明就完了。实际上 Skill 是一个完整的文件夹——除了核心的 SKILL.md,还可以包含参考文档、脚本工具、模板资源,甚至动态钩子。
ios-code-review/
├── SKILL.md # 核心文件(必须)
├── references/ # 参考文档:检查清单、规范等(可选)
│ ├── security-checklist.md
│ └── naming-conventions.md
├── scripts/ # 可执行脚本(可选)
│ └── lint-check.sh
├── templates/ # 模板文件(可选)
│ └── review-report.md
└── logs/ # 运行记录(可选)
└── history.jsonl
SKILL.md 是入口,但不是全部。好的 Skill 会利用整个文件夹——把详细资料放在子目录里,让 AI 需要时主动去读,不需要时不占上下文。
由 元数据 和 正文 两部分构成:
---
name: ios-code-review # 唯一标识
description: | # 触发描述(AI 据此决定何时激活)
当用户要求审查 iOS/Swift 代码时使用。
覆盖架构、内存安全、线程安全、性能检查。
---元数据下面是 Markdown 正文,包含四个部分:
| 部分 | 作用 |
|---|---|
| 执行流程 | 一步步怎么做,是 Skill 的核心 |
| 约束规则 | 禁止行为、必须遵守的原则 |
| 输出规范 | 结果用什么格式呈现 |
| 参考引用 | 指向 references/ 中的详细文档 |
上下文窗口是有限的。如果把几千字的检查清单全塞进 SKILL.md,会浪费大量 Token。
更好的做法是利用文件系统做渐进式披露:
- 详细 API 说明 → 放到
references/api.md - 模板文件 → 放到
templates/目录 - 主文件只告诉 AI 这些文件在哪里
AI 会在需要时主动去读对应文件,既保持主文件简洁,又不损失任何信息。
这就是 Skills 的三级加载机制:
| 级别 | 内容 | 何时加载 | 开销 |
|---|---|---|---|
| L1 | name + description | 始终在上下文中 | ~100 词 |
| L2 | SKILL.md 正文 | Skill 被触发后 | < 5000 词 |
| L3 | references / scripts / templates | AI 判断需要时 | 不限 |
AI 随时知道有哪些 Skills(L1),触发后才读流程(L2),遇到具体检查项才加载清单(L3)。
---
name: ios-code-review
description: |
当用户要求审查 iOS/Swift 代码时使用。
覆盖架构规范、内存安全、线程安全、性能、代码质量。
---
# iOS Code Review
## 执行流程
### 第一步:了解改动范围
查看 git diff,确认改动涉及哪些文件和模块。
超过 500 行按模块分批 review。
### 第二步:架构检查
- ViewController 是否承担了过多职责
- 网络请求是否通过 Service 层发起
- Model 是否独立文件,未混在 VC 中
- 是否符合项目的分层架构
### 第三步:内存与线程安全
- 闭包是否正确使用 [weak self]
- delegate 是否声明为 weak
- 是否有主线程外的 UI 操作
- 异步回调中是否处理了生命周期
### 第四步:代码质量
- 错误处理是否完善(不要 catch {} 不处理)
- 是否滥用强制解包 `!`
- 命名是否符合 Swift API Design Guidelines
- 是否有可提取的重复代码
### 第五步:输出报告
按严重程度分级:
| 级别 | 含义 | 处理方式 |
|------|------|---------|
| P0 | 严重 | 必须修复才能合并 |
| P1 | 重要 | 建议合并前修复 |
| P2 | 建议 | 可建 follow-up |
每个问题附上:文件名 + 行号 + 问题描述 + 修复代码。
输出报告后,先等用户确认,再决定是否自动修复。
## 禁止行为
- 不要只说"代码没问题"而不给分析
- 不要只指出问题而不提供修复代码
- 不要遗漏循环引用和线程安全检查---
name: tech-design
description: |
当用户要求设计技术方案、架构设计、系统设计时使用。
---
# 技术方案设计
## 执行流程
1. **需求确认**:梳理核心需求,明确边界和约束
2. **方案设计**:模块划分、数据模型、接口定义、关键流程
3. **风险评估**:技术风险、性能瓶颈、兼容性问题
4. **里程碑拆分**:按优先级拆分为可执行的阶段
## 输出格式
使用 Markdown,包含:
- 架构图(文字描述或 Mermaid)
- 核心数据模型定义
- 关键接口设计
- 风险清单与应对策略
- 里程碑和排期建议
## 约束
- 方案必须考虑现有技术栈的兼容性
- 不要过度设计,优先满足当前需求
- 风险评估不能省略写 Skill 最大的误区是把它当文档来写——堆一大堆知识进去,期望 AI 自己消化。但 AI 已经懂很多了,它不需要你从零教。写 Skill 更像在带一个新入职但能力很强的同事:不用教他写代码,只需要告诉他「我们项目里有哪些坑、哪些特殊规矩」。
AI 对编程已经非常了解,不需要教它什么是函数、什么是 CSS。
要做的是:告诉它那些打破其默认行为的信息。
Anthropic 内部写前端 Skill 时,不是教 Claude 怎么写 CSS,而是直接写「不要用 Inter 字体」「不要用紫色渐变」。就这一句话,设计品味立刻不同。
# ❌ 教 AI 它已经知道的事
使用 Swift 5.5 的 async/await 语法进行异步编程。
async/await 是 Swift 的结构化并发模型,它可以...
# ✅ 只写你项目的特殊规矩
网络请求统一走 NetworkService,不要直接用 URLSession。
所有 ViewModel 必须继承 BaseViewModel,不要自己实现 loading 状态。
图片加载用 Kingfisher,不要用 SDWebImage(历史原因,全项目统一)。
判断标准很简单:如果把这条指令删掉,AI 大概率还是会做对,那就删掉。只留那些删掉之后 AI 会做错的内容。
这是 Skill 里价值最高的部分。
AI 经常在同一个地方反复犯错,把这些坑记录下来放进 Skill,就不会再踩。Anthropic 内部很多强大的 Skill,最开始也只有几行指令加一个空的易错点列表,后来在使用中慢慢填充,才变得强大。
## 易错点
- ❌ 生成 SwiftUI 预览时总是忘记加 #Preview 宏,还在用旧的 PreviewProvider
- ❌ 建议用 `guard let self` 时写成 `guard let self = self`(Swift 5.7 后不需要)
- ❌ 在 @MainActor 标记的类里,还画蛇添足地加 DispatchQueue.main.async
- ❌ 创建 Combine pipeline 时忘记存储 AnyCancellable,导致订阅立即释放每次 AI 犯了一个你需要纠正的错误,就往这个列表里加一条。Skill 不是写完就定稿的文档,它是活的,越用越好用。
每次对话开始时,AI 会扫描所有 Skill 的 description 字段,判断当前请求是否需要触发某个 Skill。这意味着 description 的读者不是人,是模型。
它必须精准回答一个问题:什么情况下应该用这个 Skill?
# ❌ 写给人看的功能介绍
description: 工作总结 Skill
# ❌ 勉强说了做什么,但触发条件不清楚
description: 做代码审查
# ✅ 写给模型看的触发条件
description: |
当用户要求审查代码、review 代码、检查代码质量时使用。
当用户提交 PR 并要求反馈时使用。
覆盖架构规范、内存安全、线程安全、性能检查。一个好的 description 应该让模型看完就能做出「用 / 不用」的判断,不需要再打开 SKILL.md 才知道。
两个容易忽略的细节:
触发有门槛:AI 只在自己无法轻松处理的任务上才会触发 Skill。简单的一步操作(如「读一下这个文件」)即使 description 完美匹配也可能不触发,因为 AI 用基础工具就能搞定。所以如果你发现 Skill 不生效,先看看任务是不是太简单了。
description 可以被量化验证:Anthropic 官方的 skill-creator 工具会生成 20 个模拟请求(一半应触发、一半不应触发),跑 5 轮迭代来优化 description 的触发准确率。你不一定要用这套工具,但思路值得借鉴——description 写得好不好,是可以测的。
Skill 会被反复使用,每次场景都不同。如果指令写得太死,在 A 场景完美,在 B 场景就会变成束缚。
# ❌ 写死了每一步
第一步:运行 swiftlint
第二步:检查所有 force unwrap
第三步:检查所有 retain cycle
第四步:输出报告
# ✅ 给出核心信息,让 AI 根据情况判断
重点关注:内存安全(循环引用、强制解包)和线程安全(主线程 UI 操作)。
如果改动量超过 500 行,按模块分批 review。
输出报告后先等用户确认,再决定是否自动修复。
核心原则:提供完成任务所需的关键信息和约束,执行策略让 AI 根据具体情况自己判断。
还有一个容易踩的坑:堆砌 MUST / NEVER 不如解释 why。 现在的大模型很聪明,理解力很好。与其写「MUST use async/await, NEVER use completion handlers」,不如写「项目从 iOS 15 起全面迁移到 async/await,completion handler 只在旧模块保留,新代码不再使用」。模型理解了背景,自然知道该怎么做,遇到边界情况也能合理判断。
管得太死 → AI 变成死板的脚本执行器。 完全不管 → AI 用默认行为,可能踩你项目的坑。 在「项目特殊规矩」上严格,在「具体执行方式」上宽松——这是最佳平衡点。
不要等 Skill 写完美再用。
最好的写法是这样的:
- 先写 3-5 行核心指令 + 一个空的易错点列表
- 开始使用
- AI 犯错了 → 往易错点列表里加一条
- 发现流程需要调整 → 改 SKILL.md
- 发现需要参考资料 → 加到 references/
- 循环
Skill 的质量不是写出来的,是用出来的。 你踩过的每一个坑,都是 Skill 变强的养料。
| 误区 | 改进 |
|---|---|
| 教 AI 写 Swift 语法 | 只写它会做错的事,不教它已经会的 |
| SKILL.md 塞了几千行 | 核心流程 + references 按需加载 |
| description 写成功能介绍 | 写触发条件,让模型能判断「用不用」 |
| 流程全部平铺 | 按宏观→微观编排:了解范围 → 架构 → 安全 → 输出 |
| 每一步都写死 | 关键约束严格,执行方式留空间 |
| AI 直接改代码不确认 | 加「输出报告→确认→执行」的流程 |
| 一个 Skill 包办所有事 | 按职责拆分,多个 Skill 组合使用 |
| 等写完美了再用 | 先用起来,边踩坑边迭代 |
当你对基础用法熟悉之后,可以尝试:
- 从重复中提取脚本:多次使用后观察 AI 的执行过程——如果每次都在写类似的辅助脚本(比如格式转换、数据清洗),就把它固化到
scripts/下,省得每次重新发明轮子 - 给 Skill 加记忆:用日志文件(
logs/history.jsonl)记录每次执行的输入输出,AI 可以参考历史数据做更好的判断 - 内置决策脚本:把重复性的判断逻辑写成
scripts/下的脚本,AI 调用脚本拿结果,而不是每次都自己推理 - 设置动态钩子:结合 Claude Code 的 hooks 机制,在特定事件(如提交前、文件保存后)自动触发 Skill
- 用 skill-creator 加速开发:Anthropic 官方提供的 Skill 创建工具,帮你走完「写初稿 → 跑测试 → 人工评审 → 迭代改进」的完整循环,几分钟搭出高质量骨架
~/.claude/skills/ # 全局(所有项目可用)
<项目>/.claude/skills/ # 项目级(仅当前项目)
全局放通用能力(Code Review、Git 规范),项目级放特定项目的能力(专属部署流程)。
各工具的目录略有不同(Cursor 用 .cursor/skills/,Trae 用 .trae/skills/),但部分工具会交叉读取,跨工具复用通常不需要额外操作。
手动创建:直接新建 SKILL.md,按结构填入内容。
AI 辅助生成(推荐):告诉 AI 你的需求,让它生成初稿,再迭代优化。Anthropic 官方有一个 skill-creator 工具(本身也是个 Skill),几分钟就能搭出高质量骨架。
| 资源 | 说明 |
|---|---|
| skills.sh | 社区精选,按领域分类,一键安装 |
| Anthropic 官方 Skills | 官方维护,最佳格式参考 |
| 概念 | 本质 | 回答的问题 |
|---|---|---|
| Prompt | 一次性指令 | 这次做什么? |
| Rules | 持久化约束 | 始终遵守什么? |
| Skills | 可复用流程 | 这类事怎么做? |
| MCP | 外部连接协议 | 用什么工具做? |
| Agent | 自主执行者 | 谁来做? |
协作流程:
用户说「帮我做 Code Review」(Prompt)
↓
AI 匹配到 Code Review Skill,按流程执行(Skills)
↓
执行过程中遵守项目编码规范(Rules)
↓
需要读取代码时通过文件系统工具获取(MCP)
↓
整个过程由 AI Agent 自主编排和推进(Agent)
Skills 是这个体系中的「专业能力层」— 它让 AI 从「什么都能聊两句但不深入」变成「在特定领域能按专业标准稳定输出」。