选择 Agent、Command 还是 Skill,取决于任务是否需要隔离上下文、如何被触发以及复用程度。核心区别在于:Agent 拥有独立进程和内存,用于复杂自主任务;Command 是用户显式触发的入口;Skill 是可被自动或手动调用的内联知识模块。本文将基于仓库中的实际文件与配置,全面解析这三种机制的差异与协作模式。
Agent vs Command vs Skill:Claude Code 三种扩展机制全面对比
Claude Code 提供了多种扩展能力,其中 Subagents(子代理)、Commands(命令)和 Skills(技能)是三种最核心的扩展机制。理解它们的区别、联系与适用场景,是从随意提示(Vibe Coding)转向结构化代理工程(Agentic Engineering)的关键一步。本文将基于项目仓库中的实际配置文件,对这三者进行全方位对比。
1. 三种机制的本质定义
在深入对比前,先明确它们各自是什么:
- Agent (子代理): 定义在
.claude/agents/目录下的独立智能体。它拥有独立的上下文窗口,可以自主执行多步骤、需要探索和决策的复杂任务,支持工具限制、模型覆盖、持久化内存和技能预加载。 - Command (命令): 定义在
.claude/commands/目录下的斜杠命令。它是用户在对话中通过/command-name显式触发的工作流入口,本身不运行在独立上下文中,非常适合用于编排和调度其他机制(如调用 Agent 或 Skill)。 - Skill (技能): 定义在
.claude/skills/<name>/SKILL.md文件中的可复用程序。它内联在主对话上下文中,既允许用户通过/skill-name调用,也允许 Claude 根据用户意图自动调用,是注入领域知识和标准化操作的理想载体。
2. 10 维核心对比表格
下表从 10 个关键维度总结了三种机制的核心差异,数据直接来源于项目的实际配置与文档。
| 维度 | Agent (子代理) | Command (命令) | Skill (技能) |
|---|---|---|---|
| Location (存储位置) | .claude/agents/<name>.md |
.claude/commands/<name>.md |
.claude/skills/<name>/SKILL.md |
| Context (执行上下文) | 独立的子代理进程 | 内联(主对话) | 内联(主对话) |
| User-invocable (用户可调用) | 否 — 无 / 菜单,由 Claude 通过 Agent 工具调用 |
是 — /command-name |
是 — /skill-name (除非 user-invocable: false) |
| Auto-invoked by Claude (自动调用) | 是 — 通过 description 字段匹配意图 |
否 | 是 — 通过 description 字段匹配意图 (除非 disable-model-invocation: true) |
| Accepts arguments (接受参数) | 通过 prompt 参数 |
$ARGUMENTS, $0, $1 |
$ARGUMENTS, $0, $1 |
| Dynamic context injection (动态上下文注入) | 否 | 是 — !`command` |
是 — !`command` |
| Own context window (独立上下文窗口) | 是 — 隔离 | 否 — 共享主上下文 | 否 — 共享主上下文 (除非设置 context: fork) |
| Model override (模型覆盖) | model: frontmatter |
model: frontmatter |
model: frontmatter |
| Tool restrictions (工具限制) | tools: / disallowedTools: |
allowed-tools: |
allowed-tools: |
| Memory (内存) | memory: frontmatter (user/project/local) |
— | — |
| Can preload skills (预加载技能) | 是 — skills: frontmatter |
— | — |
3. 如何选择:应用场景与指南
理解定义和差异后,选择哪一种取决于你的具体需求。
选择 Agent 当:
- 任务复杂、多步骤且需要自主决策,无需你逐步指导。
- 需要上下文隔离,防止任务细节污染主对话。
- 任务需要跨会话的记忆(如一个学习代码模式的代码审查代理)。
- 希望为代理预加载特定领域知识(通过
skills:字段),而不污染主上下文。 - 任务适合在后台或 Git Worktree 中运行。
- 需要施加特定的工具限制或权限模式(如
acceptEdits,plan)。
例如,仓库中的 time-agent 虽然简单,但演示了其独立进程、可指定模型(haiku)和工具限制(allowedTools)的特性。
选择 Command 当:
- 需要为用户提供一个明确的、用户触发的入口来启动一个工作流。
- 该工作流涉及编排其他代理或技能。
- 希望保持主上下文精简,直到用户主动触发时才注入命令内容。
例如,你可以创建一个 /deploy 命令,它内部依次调用测试 Agent、构建 Skill 和通知 Command。
选择 Skill 当:
- 希望 Claude 能根据用户意图自动匹配并调用,技能描述被注入上下文用于语义匹配。
- 该任务是可复用的过程,可以从多个地方(命令、其他代理或 Claude 自身)调用。
- 需要将领域知识“烘焙”到特定代理中(通过 Agent 的
skills:字段)。
例如,time-skill 的 description 字段使其能被 Claude 自动调用,同时用户也可以输入 /time-skill 手动触发。
4. 实战示例:“现在几点了?”的三种实现
仓库中为同一个任务“显示当前巴基斯坦标准时间”提供了三种机制的实现文件。这完美展示了它们的差异与调用逻辑。
.claude/commands/time-command.md: 定义了命令。用户必须输入/time-command才能执行。它永远不会被自动调用。.claude/agents/time-agent.md: 定义了子代理。其description(“Use this agent to display the current time in Pakistan Standard Time”) 使 Claude 可能自动匹配并生成它,但它会启动一个独立的上下文进程。.claude/skills/time-skill/SKILL.md: 定义了技能。其description(“Display the current time in Pakistan Standard Time…”) 同样使其能被自动调用,且因为它运行在主上下文中,是执行简单 bash 命令的最轻量方式。
当用户直接输入“现在几点了?”时,Claude 的自动调用优先级如下:
1. Skill (内联,无上下文开销) ← 最优先
2. Agent (独立上下文,自主) ← 如果技能不可用或任务复杂,则使用
3. Command (从不 — 需要显式 /) ← 只有用户输入 /time-command 才会执行
这个顺序体现了“最轻量满足需求”的原则。如果给 time-skill 设置 disable-model-invocation: true,那么 Claude 就无法自动调用它,可能会转而使用 time-agent。如果两者都被禁用,Claude 只能直接运行 bash 命令。
5. 编排工作流:Command → Agent → Skill 架构
这三种机制可以组合成强大的编排工作流,形成分层架构:
用户触发 /command
↓
Command 编排工作流
↓
Command 调用 Agent (独立上下文,自主执行)
↓
Agent 使用预加载的 Skill (领域知识)
↓
Command 调用 Skill (内联,用于输出生成)
这种模式实现了关注点分离:Command 作为协调者,Agent 作为自主执行者,Skill 作为可复用的知识单元。
FAQ
Q: 为什么 Agent 不会出现在 / 菜单里?
A: 根据设计,Agent 主要供 Claude 自动调用,或通过其他机制(如 Command 或另一个 Agent)以编程方式调用,而不是直接供用户从菜单选择。这是为了保持用户界面的简洁。
Q: 我可以让一个 Skill 在独立的上下文中运行吗?
A: 可以。在 Skill 的 Frontmatter 中设置 context: fork 字段,该技能就会在一个 fork 出的独立上下文中执行,执行完毕后再将结果合并回主对话。
Q: 如何防止 Claude 自动调用某个我定义的机制?
A: 对于 Agent,可以修改其 description 字段,使其不包含鼓励自动调用的词语(如“PROACTIVELY”)。对于 Skill,在 Frontmatter 中设置 disable-model-invocation: true。Command 本身就不能被自动调用。
Q: Command 和 Skill 都能接受 $ARGUMENTS 参数,使用上有何区别?
A: 参数语法相同,关键区别在于触发方式和上下文。Command 必须由用户显式以 /command arg 形式触发。Skill 则既可由用户显式触发,也可能被 Claude 自动调用并自动传递推断出的参数。