跳转到正文
莫尔索随笔
返回

Agent Skills vs Rules vs Commands:AI 编码工具的三种上下文策略

预计 13 分钟

第一时间捕获有价值的信号

本文译自 Agent Skills vs. Rules vs. Commands。如果感觉你的 AI 编码工具正在变成一个装满神奇 markdown 文件的文件夹,这篇文章会帮你理清思路。文章详细解释了 Skills、Rules 和 Commands 三种不同的上下文策略,以及何时使用哪种,如何构建有用且可管理的上下文库。

Agent Skills vs Rules vs Commands

如果感觉你的 AI 编码工具正在变成一个装满神奇 markdown 文件的文件夹,这不是你的错觉。

不同工具的标签各不相同,但困惑是一致的。而现在每个人都在谈论的最新 markdown 文件是 Skills(技能):代理可以在相关时发现并加载的上下文。

让我们看看它们是什么,何时使用它们,以及如何构建一个有用(且可管理)的库。

Agent Skills(Claude Skills)是什么

在 Builder(以及越来越多的提供商)中,Skills 使用 Agent Skills 标准。可以把它看作是你的指令和资源的标准化运输容器。

基本上,一个 Skill 只是一个包含两样东西的文件夹:

  • 带有元数据和指令的定义 markdown 文件
  • 可选的额外内容(任何你想要的),如脚本、模板或参考文档

每个仓库中,Skills 位于 [.provider]/[skill-name]/SKILL.md

因此,在 Builder 中,你可以把一个 fireworks Skill 放在 .builder/fireworks/SKILL.md 中(你也可以把它们放在 .claude/ 中,Builder 会找到它们)。

这里是 Builder 关于 使用 Skills 的完整文档

巧妙之处在于渐进式披露。如果你来自 Web 开发背景,可以把它想象成”上下文的懒加载”。

代理不会在会话开始时读取每个 Skill 文件。相反,它会扫描 namedescription 元数据,只有当它确定该 Skill 与手头任务相关时才加载完整内容。

这让你可以保持深度专业知识可用,而不强制将其放入每个对话并污染模型的上下文。

显示代理只看到 Skill 描述(frontmatter)但可以请求 Skill 正文的图表

这种架构意味着你需要用不同的方式编写:

  1. 描述是用于路由的,不是用于阅读的。 它需要简短、具体,并充满你的任务实际会使用的关键词。如果你写一个模糊或诗意的描述,Claude 可能会直接跳过它。
  2. 正文是一个流程,不是 Wiki。 专注于检查清单和成功标准。如果你有长参考文档,将它们放在单独的文件中(可选地放在 Skill 文件夹中)并链接到它们,这样代理只在必要时才获取它们。

Skills 如何帮助代理

大语言模型(LLMs)不会因为你喂给它们更多文本就神奇地变得更聪明。事实上,更多的词通常只会制造更多的噪音。

把上下文看作一个严格的预算。如果你把所有预算都花在你没有使用的通用指令或工具上,那么留给真正重要的东西的空间就更少了。你需要那个空间来放你的代码、错误日志和你的计划。

Skills 是这个问题的解药。如果你曾经看到过代理因为关键约束被深埋在一个巨大的规则文件中而产生幻觉,这就是解决方案。

它们不会让代理变得更聪明。它们只是让信息更聚焦、更容易检索。

可以这样想:没有人会在开始工单之前记住整个内部 Wiki。你浏览、搜索,然后调出你需要解决眼前问题的特定文档。代理在集中注意力方面类似。

同样的想法也在生态系统的其他地方出现。例如,Claude Code 刚刚推出了 Tool Search,它使用渐进式披露来处理 模型上下文协议(MCP)服务器,以避免用代理可能需要也可能不需要的工具定义填满代理的上下文。

我个人希望看到随着智能体工具的成熟,更多的动态上下文管理能为我们完成。工具能越多地向代理展示_正确_的信息,代理就越少需要去寻找,你在时间、Token、模型大小和错误方面付出的代价就越少。

与此同时,我们需要手动做一些。

Rules、Commands 和 Skills 的心智模型

那么,让我们深入探讨一个更深层次的问题:你什么时候真正想用 Skills vs Commands vs Rules?

这是我的思考方式:

  • Rules 是不变的。它们每次都适用,没有例外。
  • Commands 代表你的明确意图。你输入 /command 是因为你想掌舵。
  • Skills 是可选的专业知识。只有当特定任务需要时,代理才会从架子上取下这些。

如果你只记住本指南中的一件事,那就记住这个分类。

概念谁触发它最适合上下文成本反模式
Rules工具仓库要求总是支付把教程塞进 Rules
Commands可重复的工作流使用时支付把每个偏好都变成 Command
Skills代理特定任务的手册需要时支付把实际上是 Rules 的东西做成 Skills

这里有一个快速决策树来帮助你理清:

根据何时以及如何应用指令,将指令转换为 Rule、Command、Skill 或一次性提示的流程图

Skills vs Rules:故意让 Rules 简短

Skills 不会取代 Rules。Rules 是不可协商的。但有了可用的 Skills 应该完全改变你编写 Rules 的方式。

这里有一个很好的默认划分:

  • Rules:仓库要求、安全约束、命名约定,以及如何运行测试。
  • Skills:特定工作流、工具或评审约定的手册。

如果你在纠结某个东西属于哪里,用这个试金石测试:即使你没有想到它,你也希望这个指令适用吗?

是?Rule。否?Skill。

这里有一些更具体的例子:

  • “永远不要提交 .env 文件” 是一条 Rule
  • “当你接触账单代码时,运行这三个集成测试” 是一条 Skill
  • “设计系统使用这些 token 名称” 是一条 Rule
  • “当你编写发布说明时,遵循这个格式和检查清单” 是一条 Skill

一个实用的模式是结合 Rules 和 Skills,让你的仓库 Rules 主要是路由逻辑。例如:

  • “当你更改 UI 组件时,加载 ui-change Skill。”
  • “当你调试生产错误时,加载 incident-triage Skill。”

这让始终启用的提示保持简短,并使代理的适应性大大增强。

分层 Rules

许多工具还允许分层 Rules,代理会从它所在的目录”向上查找”其他 Rules 文件。

因此,你可以编写一组仓库特定的 Rules 以及 一组适用于你工作的每个仓库的全局 Rules。

诀窍,一如既往,是让 Rules 尽可能小且聚焦。

一个糟糕的全局 Rule 会是,“在 my-generic-saas-clone 仓库中,总是使用我们的品牌颜色,在 app.css 文件中找到。” 现在每个仓库中的每个代理都必须毫无理由地了解 my-generic-saas-clone 仓库。

一些工具,如 Cursor,允许你在仓库中有_每个文件夹_的分层 Rules。这_可以_是一个强大的模式,但随着时间的推移很难管理。在我看来,Skills 提供了一个更好的可组合替代方案来替代继承的规则集。

对比从全局/仓库/文件夹树继承的 Rules 与从 Skill 集组合选定 Skills 的并排图表

关于命名的简短说明

Cursor 很早就推广了仓库特定的 AI Rules,它支持总是应用的 Rules 和基于简短描述智能应用的 Rules。

如果你通过 Cursor 学习了 Rules 概念,你现在可能会听到 Rules 被用来指代其他工具称之为 Skills 的东西。

Skills vs Commands:可组合,但不是一回事

Command 是确定性的。你调用它,工具注入提示,代理执行它。

Skill 是一个建议。代理决定它是否需要那个上下文并在适当时加载它。

我看到的最强大的模式是结合它们:

  • 把你复杂的、长期存在的指令作为 Skills。
  • 使用 Commands 作为符合人体工程学的快捷方式来触发这些 Skills 的任意组合。

例如:

  • 一个 /release Command:“加载 release Skill,然后遵循检查清单。”
  • 一个 /refactor Command:“加载 tanstackpanda-css Skills,将这个 Next.js 组件重构为 TanStack 和 Panda CSS。如果你有 Skills 中未涵盖的文档问题,可以使用 Context7 MCP 服务器。”

你的 Command 列表应该简短易记,而你的 Skills 应该让你的逻辑结构化且可重用。毕竟,Commands 是为了人体工程学,所以你希望它们稳定。Skills 是为了策略;它们需要可审查。

当你更新一个 Skill 时,你改变了行为而不需要记住一个新的咒语。当你更新一个 Command 时,你是在改变咒语本身。

Command 参数

在许多工具中,Commands 可以接受任意数量的参数,模板可以通过 $1$2 等按位置引用它们。Claude Code 自定义斜杠命令支持相同的模式。

这让你可以表达意图而不用重新输入整个提示。你可以输入这样的内容:

/pr 123 bot-integration
- Load the `pr` skill
- Create a pull request that fixes issue #$1 and targets the $2 branch

Command 保持简短,变量部分保持明确,而 Skill 仍然处理困难的部分:定义、约定,以及确切的”完成”意味着什么。

额外内容:Skills vs Agents

最后一场对决:你什么时候使用可组合的 Skill,什么时候干脆换掉整个 Agent?

Skills 改变代理知道的内容。Agents 改变谁在做工作以及他们可以访问什么。

可以把 Agent 看作是一个完全独立的工作者配置文件。它使用不同的系统提示、不同的工具访问,并且通常有不同的模型配置或温度设置。

当你希望当前助手遵循更好的流程时,请使用 Skill。当你需要隔离或专门的专家时,请使用单独的 Agent。

你可能有:

  • 一个”计划”Agent,它对工具有只读访问权限,并有一个系统提示鼓励它向你提出澄清问题并制定详细的实现计划。
  • 一个”构建”Agent,它使用更快、更便宜的模型,并被简化为实现计划。
  • 一个”评审”Agent,它使用慢速、昂贵的模型来评审代码差异。

Subagents(子代理)

代理生态系统中还有一个更新的模式:子代理。“父”代理(你在聊天中实际与之交谈的代理)可以调用并并行运行任意数量的子代理,以更快地完成工作。

父代理与用户通信并将工作委托给多个子代理的图表

大多数工具都捆绑了”探索”子代理,其主要工作是被优化为尽可能快地找到相关的仓库上下文(通常在底层使用像 ripgrep 这样的 bash 工具)。

当你告诉代理,“某个地方有一个文件处理我们的深色模式”时,它可以向你翻个不存在的白眼,然后启动 10 个子代理来搜索”深色模式”、“主题”、“系统”等变体,直到找到正确的文件。

一些工具,如 Claude Code 和 OpenCode,实际上允许你创建自己的子代理,并在聊天时 @ 提及它们。我个人发现这是一个有用的模式,可以(再次)通过让主代理使用,比如说,一个知道如何使用 Exa、Context7 和……互联网的专门网络研究代理来节省主代理的上下文。

从使用 Skills 开始而不是 Agents

话虽如此,进入 Agents 和 subagents 可能会变得非常棘手。_从_你的主代理可以在需要时调用的可组合 Skill 开始,会为你节省大量时间。

只有当你遇到以下情况时才升级到单独的 Agent:

  • 需要一个完全不同的 LLM 来完成任务
  • 权限范围问题
  • 主代理明显的上下文污染

但在大多数情况下,保持你的理智,只需使用 Skills。

如何编写一个好的 Skill

Skills 有一种以与文档完全相同的方式变坏的坏习惯。你从干净的意图开始,突然间你有了一堵没有人,甚至你的 AI 代理,都不想阅读的文本墙。

这里有一些方法可以让事情保持在控制之下:

  1. 编写一个实际能路由的描述。 如果你的代理不能根据你的提示找到 Skill,里面的代码就无关紧要。
  2. 保持 Skill 定义文件最小。 把这个文件当作快速入门指南,而不是数据转储。
  3. 链接到大型工件。 使用渐进式披露。把大模板和长参考文档放在单独的文件中,这样上下文窗口保持干净。
  4. 明确定义”完成”。 Skills 是为了减少歧义。不要添加更多噪音。

一个最小的 Skill 示例:UI 更改

---
name: ui-change
description: Use this skill when you're changing UI components, styling, layout, or interaction behavior.
---

This skill helps you to review and implement UI changes using the design system.

## Constraints

- Important: Use existing design tokens and components
- Do not use magic numbers or raw pixel values
- Keep accessibility intact: keyboard, labels, focus, contrast
- Keep diffs small and avoid unrelated refactors

## Tokens

The repo's global tokens are in `variables.css`.

### Spacing

[info about when to use which spacing]

### Color

[info about using color tokens]

### [etc.]

[]

## Components

[]

## Workflow

1. Restate the change in one sentence.
2. Identify the closest existing component patterns.
3. Implement the smallest diff that matches the spec.
4. Verify responsive behavior, focus states, and keyboard navigation.
5. If anything is ambiguous, stop and ask for confirmation.
6. Ensure your change meets the below success criteria.

## Success Criteria

- Your change does not use new tokens, magic numbers, raw pixel values, or new design components unless the user explicitly asked you for this.
- Your change does not break on mobile, table, or desktop viewports.
- Your change can be completely usable if the end user does not have a mouse or is using a screen reader.
- You have told the user exactly what you changed and confirmed verbally with them the above three points.

值得拥有的入门 Skill 库

如果你正在为实际生产工作构建 AI 编码设置,你最终会重新发明同样的几个轮子。

节省一些时间,从这些基础开始:

  • 仓库介绍:入口点在哪里,测试住在哪里,约定是什么?
  • UI 更改:你如何处理设计 token 和可访问性检查?
  • 调试:你如何重现问题并决定哪些日志重要?
  • 验证:运行哪些确切的命令来证明更改有效?
  • PR 卫生:你如何格式化提交消息并更新变更日志?
  • 安全:边界是什么?(请不要删除生产数据库。)

这些不需要是小说。胜利不是字数;而是代理停止猜测并开始遵循你的标准。

好 Skills 的检查清单

如果你想要一个保持小而有用的结构,用这个检查清单运行你的 Skills。

每个 Skill 都需要回答六个具体问题:

  • 触发(描述):代理究竟应该什么时候加载这个?
  • 输入:在开始之前,它需要从你或仓库获得什么信息?
  • 步骤:流程是什么?
  • 检查:你如何证明它有效?
  • 停止条件:它什么时候应该暂停并询问人类?
  • 恢复:如果检查失败会发生什么?

常见的失败模式(Skill 问题)

每个人都会犯这些错误。以下是如何发现它们:

  • 百科全书:如果一个 Skill 读起来像 Wiki 页面,把它切碎。把它分成更小的文件,让 Skill 只提取当前需要的内容。
  • 一切百吉饼:如果一个 Skill 适用于每一个任务,它不是一个 Skill。它是一个 Rule 或仓库约定。
  • 秘密握手:如果代理从不加载 Skill,你的描述可能太抽象了。重写它以匹配你实际谈论任务的方式。
  • 脆弱的 Skill:如果每次仓库更改它都会坏掉,你硬编码了太多。把具体细节移到引用的文件中,保持 Skill 逻辑是流程性的。

去吧,使用 Skill

Skills 不是魔法。它们只是打包和加载指令的策略。

将 Rules 用于你的不变量,Commands 用于显式工作流。将 Skills 保留给那些可选的、特定的专业知识。并将 Agents/子代理保留给你已经尝试过 Skill 但它一直失败的情况。

如果你坚持这种划分,你将用更少的提示污泥发布更好的自动化。你的代理将停止感觉像一个脆弱的脚本,并开始表现得像一个真正的协作者。