Claude Agent Skills四种设计模式详解:从渐进式披露到最小权限
基于渐进式披露原则,AgentSkill设计模式包括模板驱动、脚本增强、知识分层和工具隔离,分别对输出格式、计算可靠性、上下文经济性及权限安全性进行了约束,从而显著提升专业任务执行的效率与准确性。
一、地基:Agent Skill为何需要设计模式
Agent Skill的本质,是一个包含指令、脚本与资源的文件夹,让Agent能够更准确、更高效地完成某类专业工作。其最简形态仅为一个SKILL.md文件,通过YAML frontmatter中的name和description字段被发现和触发。

真正让Skill具备可扩展性的,是Anthropic反复强调的核心原则——渐进式披露(Progressive Disclosure)。该原则将信息分为三层,按需加载,从而优化上下文利用效率:
| 层级 | 内容 | 加载时机 | 体量建议 |
|---|---|---|---|
| ① 元数据 | name + description | 启动时全部载入,用于判断“何时该用” | ~100 tokens |
| ② 正文 | SKILL.md 主体指令 | 任务命中description时读入 | < 5,000 tokens |
| ③ 资源 | reference.md、脚本、模板等 | 正文指示时按需读取或执行 | 无限制 |
渐进式披露解决的是“上下文经济”问题。然而,一个成熟的Skill所面临的风险远不止上下文膨胀,还包括输出格式漂移、模型计算错误、权限越界等问题。为此,社区在这条地基之上沉淀出四种设计模式,它们彼此正交,每种模式约束一个独立的风险维度:
| 设计模式 | 约束维度 | 核心手段 |
|---|---|---|
| 模板驱动 | 输出格式 | 预定义模板严格约束结构 |
| 脚本增强 | 计算可靠性 | 确定性逻辑封装为脚本 |
| 知识分层 | 上下文经济 | 按频率与互斥性分层加载 |
| 工具隔离 | 权限安全 | allowed-tools 声明能力边界 |
以下逐一展开说明。
二、设计模式一:模板驱动(约束输出格式)
意图:通过预定义模板严格约束输出结构,使结果可预期、可对比、可自动化后处理。
适用场景:周报、事故复盘、代码审查报告、合规检查单等任何“格式必须统一且下游需机器解析”的场景。在此模式下,Claude的输出严格遵循模板骨架,不再自由发挥。
要点:模板本体应放入引用文件或assets/目录,SKILL.md正文只写明“何时套用”以及“每个字段如何填写”。这样既约束了格式,又避免整段模板挤占正文的token预算,天然与“知识分层”模式复用同一套机制。
实战示例:事故复盘报告生成器
场景:SRE团队每次线上事故后产出结构一致的复盘文档,便于归档、检索和季度汇总。
incident-postmortem/
├── SKILL.md
├── assets/
│ └── template.md
└── reference/
└── severity.md
SKILL.md
--- name: incident-postmortem description: 线上事故复盘报告生成。当用户提供事故时间线、影响范围,或要求撰写postmortem/事故报告/复盘时使用。 --- # 事故复盘报告生成 ## 何时使用 用户描述了一次线上事故并需要产出正式复盘文档时。 ## 步骤 1. 读取`assets/template.md`作为唯一输出骨架,**不得增删任何一级标题**。 2. 若用户未提供严重等级,依据`reference/severity.md`判定,并在报告中注明判定依据。 3. 按下列规则填写: - **影响范围**:必须量化(受影响用户数/请求数/时长);无数据写“待补充”,禁止编造。 - **时间线**:`HH:MM`单调递增,每行一个事件。 - **改进项**:每条含负责人占位`@owner`与截止日期`YYYY-MM-DD`,便于下游脚本抽取建单。 4. 输出纯Markdown,不要整体包进代码块。 ## 硬约束 - 不臆测未提供的数字。 - 一级标题顺序与模板完全一致(看板按标题解析)。
assets/template.md
# 事故复盘:一句话标题 ## 元信息 - 事故编号:INC- - 严重等级: - 发生时间: - 恢复时间: - 总时长: ## 影响范围 ## 时间线 ## 根因分析 ### 直接原因 ### 根本原因 ## 处置与恢复 ## 改进项 | 措施 | 负责人 | 截止日期 | 状态 | | ---- | ------ | -------- | ---- | ## 经验教训
reference/severity.md
# 严重等级判定 | 等级 | 判定标准 | | ---- | -------- | | P0 | 核心功能全站不可用,或数据丢失/泄露 | | P1 | 核心功能部分不可用,影响>10%用户 | | P2 | 非核心功能不可用,或有降级方案 | | P3 | 轻微影响,无用户可感知中断 | 判定就高不就低:同时命中多个等级时取最严重者。
小提示:将模板文件置于
assets/目录下是一种良好的实践,它不仅能保持SKILL.md的简洁,还能让模板本身独立迭代。当团队需要调整报表格式时,只需修改模板文件,而无需改动Skill的核心指令。
三、设计模式二:脚本增强(约束计算可靠性)
意图:将确定性计算逻辑封装成脚本,由Claude调用执行,而非用自然语言推导。
适用场景:财务计算、正则匹配、数据清洗与格式转换、批量文件操作。相比大模型推理,脚本执行更精准、更省token、可复现、可测试。
一条黄金法则(源自官方Skill编写最佳实践):
如果你发现自己正在
SKILL.md里写公式、让Claude去“心算”——立刻停下,这段逻辑应当被搬进脚本。
实战示例:SLA可用性计算器
场景:从停机记录CSV精确计算月度可用性、累计停机时长、错误预算消耗。数字必须精确,绝不让模型估算。
sla-calculator/
├── SKILL.md
└── scripts/
└── sla.py
SKILL.md
--- name: sla-calculator description: 根据事故记录计算SLA可用性、停机时长与错误预算。当用户提供停机CSV,或询问月度可用性、错误预算是否耗尽时使用。 allowed-tools: Bash(python3 *), Read --- # SLA可用性计算 ## 关键原则 **所有数值计算必须调用脚本完成,禁止在对话中心算。** ## 步骤 1. 确认停机记录为CSV,列:`start, end`(ISO8601)。 2. 执行: `python3 scripts/sla.py --file <路径> --target 99.9 --month 2026-07` 3. 将脚本输出的JSON转述为结论,并明确指出错误预算是否已耗尽。 4. **不要修改脚本输出的任何数字。**
scripts/sla.py
#!/usr/bin/env python3
"""从停机记录计算月度可用性与错误预算。计算集中于此以保证可复现。"""
import argparse, csv, json, calendar
from datetime import datetime
def parse(ts):
return datetime.fromisoformat(ts.replace("Z", "+00:00"))
def month_seconds(month):
year, mon = map(int, month.split("-"))
return calendar.monthrange(year, mon)[1] * 24 * 3600
def main():
p = argparse.ArgumentParser()
p.add_argument("--file", required=True)
p.add_argument("--target", type=float, required=True) # SLA目标%,如99.9
p.add_argument("--month", required=True) # YYYY-MM
a = p.parse_args()
total = month_seconds(a.month)
down = 0
with open(a.file, newline="", encoding="utf-8") as f:
for row in csv.DictReader(f):
down += (parse(row["end"]) - parse(row["start"])).total_seconds()
uptime = (total - down) / total * 100
allowed = total * (100 - a.target) / 100 # 允许停机秒数
budget_used = down / allowed * 100 if allowed else 0
print(json.dumps({
"month": a.month,
"uptime_pct": round(uptime, 4),
"target_pct": a.target,
"downtime_seconds": int(down),
"downtime_human": f"{int(down)//3600}h{int(down)%3600//60}m",
"error_budget_used_pct": round(budget_used, 2),
"budget_exhausted": budget_used >= 100,
"meets_sla": uptime >= a.target,
}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
体会一下黄金法则的价值:uptime、error budget这类公式一旦出现在正文中让Claude心算,结果就不可复现且浪费token;搬进sla.py后,它变成一次确定性的工具调用。脚本还能通过allowed-tools: Bash(python3 *)将执行面收窄到“只能运行Python”,这正好引出下一个设计模式。
小提示:脚本编写时,建议使用
argparse处理命令行参数,并确保输出为结构化的JSON格式。这样,Claude可以轻松解析结果并直接将其整合到最终回答中,避免额外的文本解析步骤。
四、设计模式三:知识分层(约束上下文经济)
意图:按使用频率组织知识,是渐进式披露原则的模式化表达。
遵循80/20法则——80%的请求只需20%的核心知识。具体做法如下:
- 高频核心内容内联进
SKILL.md; - 低频细节(如完整API参考、边缘案例、长表单说明)拆到引用文件,用一句话说明“什么情况下去读取它”。
一个常被忽略的第二维度:除了频率,还要考虑互斥性。官方建议将“mutually exclusive or rarely used”的上下文拆分到不同文件——否则Claude会同时载入相互冲突的指令。分层不仅是为了节省token,也是为了避免指令相互干扰。
实战示例:REST API设计规范
场景:统一团队API风格。90%的问题只涉及命名、状态码、版本(内联);分页、错误体、鉴权是低频且互斥的细节(外置)。
rest-api-guide/
├── SKILL.md
└── reference/
├── pagination.md
├── errors.md
└── auth.md
SKILL.md(内联20%核心内容)
---
name: rest-api-guide
description: 团队REST API设计规范。设计/评审HTTP接口、命名端点、选状态码,或问及API版本、分页、错误格式、鉴权时使用。
---
# REST API设计规范
## 核心规则(高频,直接遵循)
- **资源命名**:复数名词 + kebab-case,如`/user-groups`;不出现动词。
- **层级**:`/orders/{id}/items`,嵌套不超过两层。
- **方法语义**:GET只读且幂等;POST创建;PUT全量替换;PATCH局部更新;DELETE删除。
- **状态码**:200/201/204 · 400/401/403/404/409/422 · 500。
- **版本**:URL前缀`/v1/`,仅破坏性变更时升级版本。
## 何时查阅引用文件(低频,按需加载)
- 设计**分页/游标** → 读`reference/pagination.md`
- 定义**错误响应体** → 读`reference/errors.md`
- 涉及**鉴权/Token/权限** → 读`reference/auth.md`
> 这三个主题互斥且很少同时出现,故不内联——既节省token,也避免规则相互干扰。
reference/errors.md
# 错误响应体规范
统一使用RFC 9457(Problem Details):
```json
{
"type": "https://api.example.com/errors/out-of-stock",
"title": "库存不足",
"status": 409,
"detail": "商品SKU-123当前库存为0",
"instance": "/orders/8821"
}
```
- `type`为可跳转错误文档URL;无专属文档时用`about:blank`。
- 校验错误(422)追加`errors`数组,每项含`field`与`message`。
- 绝不在`detail`中泄露堆栈、SQL或内部主机名。
reference/pagination.md
# 分页规范
默认游标分页,大数据集禁用offset。
请求:`GET /orderslimit=50&cursor=eyJpZCI6MTAwfQ`
```json
{
"data": [ ... ],
"page": { "next_cursor": "eyJpZCI6MTUwfQ", "has_more": true }
}
```
- `limit`默认50,上限200,越界返回400。
- `next_cursor`为空表示已到末页。
reference/auth.md
# 鉴权规范 - 传输:仅HTTPS;Token放`Authorization: Bearer`。 - 过期:access token ≤ 15min,配合refresh token。 - 401 = 未认证/Token失效;403 = 已认证但无权限。二者不可混用。
小提示:在
SKILL.md中,使用清晰一致的方式(如“何时查阅引用文件”部分)引导Claude去读取外部文件。这比在正文中嵌入冗长的条件判断要高效得多,也更容易维护。
五、设计模式四:工具隔离(约束权限安全)
意图:通过allowed-tools字段明确界定Skill的能力边界。这属于安全设计,其核心价值在于声明“禁止做什么”——这往往比定义“能做什么”更为关键。
典型的最小权限实践:审计类Skill不给写权限,生成类Skill不给修改权限。
一个必须知道的边界:allowed-tools这个frontmatter字段仅在Claude Code CLI下生效,通过Agent SDK使用Skill时不生效。因此,不能仅靠Skill的allowed-tools作为安全边界。在SDK或生产Agent场景中,真正的权限边界必须落在Agent的tools白名单、权限系统或hooks上。Skill的frontmatter更像是一种“约定”加CLI层加固,并非不可绕过的沙箱。
实战示例:只读安全审计
场景:上线前执行一次安全体检,只报告不改动,防止Agent顺手“帮忙修复”反而引入风险。
security-audit/
├── SKILL.md
└── reference/
└── checklist.md
SKILL.md
--- name: security-audit description: 只读代码库安全审计。当用户要求安全体检、扫描硬编码密钥、检查危险调用或上线前安全审查时使用。 allowed-tools: Read, Grep, Glob --- # 只读安全审计 ## 能力边界(重要) 本Skill**只读**。frontmatter未授予任何写入或执行工具: - 只发现、只报告,**绝不修改文件**。 - 如需修复,输出建议交由人工或另一个具备写权限的流程处理。 ## 步骤 1. 依据`reference/checklist.md`逐项用Grep/Glob扫描。 2. 每条发现给出:`文件:行号`、风险等级、证据片段、修复建议。 3. 输出风险清单表,按严重度降序排列;无发现则明确写“未发现”。 ## CLI与SDK边界提示 `allowed-tools`仅在Claude Code CLI生效。若本Skill通过Agent SDK调用, 只读约束不由frontmatter强制,须在Agent的tools白名单或权限系统中另行限定。
reference/checklist.md
# 安全审计清单 ## 密钥与凭证 - 硬编码密钥:形如`key/secret/password/token = "长字符串"`的赋值 - 私钥文件头:出现PRIVATE KEY文件头 - 云访问密钥:符合各云厂商Access Key格式的字符串 ## 危险调用 - 命令注入:拼接用户输入调用系统命令/开启shell执行 - 不安全反序列化:对不可信数据做反序列化 - SQL拼接:用字符串拼接构造SQL而非参数化查询 ## 配置 - 生产开调试:生产配置中调试开关为开 - 过宽CORS:允许来源为通配符 ## 风险等级 Critical=可直接远程利用 · High=需前置条件 · Medium=纵深防御问题 · Low=最佳实践偏差
上表为起点清单,落地时请配合具体扫描规则,并按实际技术栈进行裁剪。
小提示:在
description中明确声明“只读”属性,既是对用户意图的清晰传达,也能帮助Claude在任务选择阶段做出正确判断。这是安全实践中的第一道防线。
六、设计模式组合与取舍:先识别最大风险维度
这四种设计模式正交且可叠加。上述四个示例分别将格式、计算、上下文、权限四类不确定性,外移到了模板、脚本、引用文件、工具白名单中。一个成熟的Skill往往是四者的组合:
分层组织正文 + 引用模板 + 关键计算走脚本 + 收紧工具权限
然而,真正的设计判断不是“全都用上”,而是先识别该任务中最大的风险维度,再优先套用对应模式:
| 最担心的问题 | 优先采用 | 关键动作 |
|---|---|---|
| 输出格式会漂移 | 模板驱动 | 模板外置,正文只写填写规则 |
| 模型会算错 | 脚本增强 | 公式一律搬进脚本 |
| 上下文会爆/指令会打架 | 知识分层 | 按频率+互斥性拆文件 |
| 会越权操作 | 工具隔离 | 最小权限;SDK场景另设边界 |
七、设计模式常见问题
问题1:如何选择使用哪种设计模式?
答案:这取决于你的Skill面临的最大风险。请参考上文的“组合与取舍”章节。首先,评估你的Skill最可能失败的地方:如果输出格式不一致,优先考虑模板驱动;如果计算容易出错,优先考虑脚本增强;如果上下文过长,优先考虑知识分层;如果涉及敏感操作,优先考虑工具隔离。一个Skill可以同时应用多种模式,但不要过度设计。
问题2:可以为一个Skill应用多种设计模式吗?
答案:当然可以。这些模式是正交且可叠加的。例如,一个成熟的Skill可以同时使用知识分层来组织内容,引用模板来约束输出,通过脚本增强来进行关键计算,并使用工具隔离来限制权限。这正是构建健壮、可靠Agent Skill的推荐做法。
问题3:在Agent SDK环境下,allowed-tools不生效,如何确保安全?
答案:这是一个非常关键的问题。在SDK或生产环境中,你必须在Agent的tools白名单、权限系统或hooks中定义真正的安全边界。Skill的allowed-tools更像是一种“约定”和CLI层加固,不应被视为不可绕过的沙箱。在SDK中,你需要通过代码来强制执行权限策略。
八、结语:掌握设计模式核心思想
渐进式披露是地基,四种设计模式是建在其上的承重墙——分别扛住格式、计算、上下文、权限四类载荷。
编写Skill的成熟标志,不是把SKILL.md写得更长、更全,而是学会用最小的正文,将不确定性外移:格式外移给模板,计算外移给脚本,细节外移给引用文件,权限外移给工具白名单。留在正文中的,只剩下那句最关键的——“什么时候,该做什么”。当你掌握了这个核心思想,你就能构建出既强大又可靠的Agent Skill。
