能力分层与选型
核对日期:2026-08-26。
1. 定义与边界
能力分层是把 Agent 可复用的东西分成四层,避免全部叫「插件」:
| 层 | 定义 | 粒度 |
|---|---|---|
| Tool | 一次结构化调用:名称、参数、结果、错误码 | 原子操作 |
| MCP Server | 用标准协议暴露一组 tools / resources / prompts | 连接与发现 |
| Skill | 某类任务的步骤、约束、输出格式,按需加载进上下文 | 任务模板 |
| Sub-agent | 独立上下文、独立终止条件的子执行循环 | 隔离子任务 |
Skill 不是新的 RPC。Anthropic Agent Skills 的加载方式是:触发后把 SKILL.md 读进上下文;引用到的参考文件按需再读;可执行脚本跑在代码执行环境里,只有输出回到上下文。
本文件不讨论 MCP 传输帧,见 ../04-工具调用体系/MCP在Agent中的位置.md。也不把 Voyager 的 Skill Library(验证过的代码技能)与 SKILL.md 混用。
2. 为什么重要
工具一多,失败模式会从「选错函数」变成「上下文被能力清单淹死」:
- 20 个 MCP 工具的 description 全部常驻,会挤掉任务状态和检索结果。
- 每次任务都把「怎么做设计稿走查」写进 prompt,团队无法版本化。
- 把长任务丢给另一个聊天角色,却没有独立预算和权限,只是多花了一次 handoff。
分层的价值是让发现成本和执行成本分开:元数据便宜,正文按需,副作用仍走工具网关。
3. 核心机制
触发只应看到 name + description。这是 Anthropic 所说的 progressive disclosure 第一层。把整份 SKILL.md 常驻 system prompt,等于没有 Skill 系统。
4. 架构模式
4.1 选型表
| 问题 | 用 Tool | 用 MCP | 用 Skill | 用 Sub-agent |
|---|---|---|---|---|
| 一次查订单 | 是 | 仅当要跨 Host 复用 | 否 | 否 |
| 同一组 Git/CRM API 给多个 IDE 用 | 可以,但重复适配 | 是 | 否 | 否 |
| 「按团队规范做设计稿还原」有固定步骤 | 工具仍要 | 可提供原子能力 | 是 | 通常否 |
| 长测试套件会污染主对话 | 工具执行测试 | MCP 可暴露 runner | Skill 写何时跑 | 是,需要隔离上下文 |
| 路径固定、规则清晰 | Workflow 更好 | 不必 | 不必 | 不必 |
4.2 组合而不是替换
Skill: implement-from-design
1. 调用 MCP tool resolve_design_link
2. 调用 get_design_context / cache_design_assets
3. 用本地组件库实现页面
4. 调用 compare_page_to_design,未过门禁不得声称完成
Skill 规定顺序和完成定义;MCP 提供可审计的原子调用;HITL 仍卡在写仓库 / 发布。
4.3 不要默认 Sub-agent
Sub-agent 的成本是双倍上下文、双倍 trace、责任难分。仅当出现以下全部条件再拆:
- 子任务上下文会严重污染主任务(大日志、大 diff)。
- 子任务有独立退出条件和评测。
- 主 Agent 只需要摘要,不需要中间 token。
否则用 Skill + 工具结果摘要。多 Agent 判断见 ../08-多Agent系统/多Agent是否真的必要.md。
5. 工程实现
最小注册表:
interface SkillManifest {
name: string;
description: string;
version: string;
owner: string;
allowedTools: readonly string[];
requiredMcpServers?: readonly string[];
riskLevel: "low" | "medium" | "high";
}
interface SkillRegistry {
listManifests: () => readonly SkillManifest[];
loadBody: (name: string) => Promise<string>;
}
listManifests() 的结果可以进模型上下文。loadBody() 只在匹配命中后调用。allowedTools 是工程护栏,不是 Anthropic frontmatter 必填项;Host 必须在工具网关强制,不能只写在 Markdown 里。
function assertSkillToolAllowed(
manifest: SkillManifest,
toolName: string,
): void {
if (!manifest.allowedTools.includes(toolName)) {
throw new Error(`skill_tool_denied:${manifest.name}:${toolName}`);
}
}
6. 生产实践
| 实践 | 说明 |
|---|---|
| 先工具后 Skill | 没有稳定 schema 的工具,不要写 Skill 去「补描述」 |
| 一个 Skill 一类任务 | frontend-god 这种全能 Skill 无法评测 |
| description 含反例 | 「不要在用户只问 CSS 变量时加载」 |
| MCP 工具分组 | 设计稿、契约、诊断分属不同 Skill,而不是一个 Server 对应一个 Skill 硬绑 |
| 本仓库对照 | implement-from-design 与 review-design-fidelity 共用 frontend-workspace MCP,完成定义不同 |
| 与 HITL 对齐 | Skill 步骤里的写工具仍要审批,见 ../18-Agent前端与交互/HITL交互界面.md |
7. 常见反模式
| 反模式 | 表现 | 后果 | 修正 |
|---|---|---|---|
| 把 MCP 当 Skill | Server 一接上就当任务完成 | 模型乱序调 20 个工具 | Skill 写步骤和完成定义 |
| 把 Skill 当 Tool | 给 Skill 发明 JSON 参数当 RPC | 两套调用面 | Skill 只进上下文,副作用走 Tool |
| 全能 system prompt | 所有规范常驻 | 上下文爆、互相打架 | 渐进披露 |
| 先上 Sub-agent | 每个步骤一个角色 | 成本与调试爆炸 | 先单 Agent + Skill |
| 论文 Skill 与 SKILL.md 混用 | 把 Voyager 代码库当 Markdown Skill | 治理口径错乱 | 术语分开 |
8. 评测方法
| 指标 | 说明 |
|---|---|
| Layer Choice Accuracy | 给定需求,人标的层与系统实际层是否一致 |
| Skill Necessity | 去掉 Skill 后任务成功率下降才说明它有用 |
| Tool Count in Context | 未触发时不应出现 Skill 正文 |
| Sub-agent Overhead | token、延迟相对单 Agent 的倍数 |
样本应包含「只需只读工具、不该加载高风险 Skill」。
9. 安全与治理
- Skill 正文是提示词,可被投毒,按不可信模板管理,见 ../12-安全与治理/Prompt-Injection.md。
- Skill 不得授予工具网关没有的权限。
- 高风险 Skill 默认显式调用(Cursor 的
disable-model-invocation思路:不靠环境猜测自动加载)。 - MCP Server 仍要独立鉴权;Skill 引用 Server 不等于 Server 对所有用户开放。
10. 权威资料
- Anthropic Agent Skills overview: https://docs.anthropic.com/en/docs/agents-and-tools/agent-skills/overview (核对日期:2026-08-26)
- Anthropic skills README: https://github.com/anthropics/skills (核对日期:2026-08-26)
- MCP specification 2025-11-25: https://modelcontextprotocol.io/specification/2025-11-25 (核对日期:2026-08-26)
- Anthropic, Building effective agents: https://www.anthropic.com/engineering/building-effective-agents (核对日期:2026-08-26)