OpenRouter实测:MCP、CLI与Skills,谁在偷走上下文?
OpenRouter 用同一项 GitHub 查询,对比 MCP、CLI 与 Skills 在不同模型上的上下文 token 和费用。默认装载 46 个工具的 MCP 成本最高,CLI 最低;结果体积与额外调用轮次,也会让差距发生变化。

- MCP 发送全部工具定义,CLI 仅提供 shell,Skills 按需加载说明。
- 相同 46 个工具在不同模型和服务商上的 token 增量差异显著。
- 完成同一查询时,CLI、Skill、两工具 MCP 分别消耗 1,421、3,315
- 工具结果和多轮调用会继续推高 MCP 开销,Tool Search 也未必降
信源为 OpenRouter 官方博客及其自建实测,测试工具、任务、模型和运行次数由 OpenRouter 选定;成本数字来自其测试环境,厂商未提供第三方复测。
你让 AI Agent 查询 GitHub 仓库的最新版本和三个 bug issue,答案看似一样,输入 token 账单却可能相差几十倍。OpenRouter 用同一道题实测 MCP、CLI 和 Skills:默认装载 46 个工具的 MCP 最费上下文,CLI 最省,Skills 居中。真正决定成本的,是模型每轮先读了多少工具说明,又额外吞进了多大的返回结果。
模型动手前,MCP、CLI 和 Skills 已经塞给它不同东西
模型还没开始查 GitHub,读到的内容已经不同:MCP 摊开整套工具目录,CLI 只给一个入口,Skills 先放一张目录,任务匹配后再展开说明书。
MCP(模型上下文协议,让模型调用外部工具的协议)会把 MCP 服务器提供的每个工具都写进请求。工具名称说明模型能调用什么,描述解释用途,JSON schema(规定工具参数的 JSON 格式)说明该填哪些字段。每次请求都会重新发送这三部分,模型每走一轮,都得再读一遍完整工具目录。
那能不能只给模型一个入口,让它自己去查?命令行工具 CLI(在终端执行命令的程序接口)走的就是这条路。接入 GitHub CLI 时,模型预先只得到一个 shell 工具(让模型运行终端命令的工具),外加一行“GitHub CLI 已安装并认证”的说明。它不用先记住每个子命令的完整定义,只要知道程序已经可用,再自行组织命令。
入口还能再省吗?Skills 连入口都不预先给全。每项 Skill 起初只占一行描述,像目录条目一样告诉模型有哪项能力;任务确实需要时,完整的 SKILL.md(Skill 的完整操作说明文件)才加载一次。它不把说明永久塞进每轮请求,而是让模型先判断要不要读。
| 接入方式 | 执行前先给模型什么 | 执行时返回什么 |
|---|---|---|
| MCP | 每个工具的名称、描述和 JSON schema,每次请求都会发送 | 服务器返回的工具结果 |
| CLI | 一个 shell 工具,以及一行“GitHub CLI 已安装并认证”的说明 | 命令输出 |
| Skills | 一行 Skill 描述;需要时加载一次完整 SKILL.md | 命令输出 |
只看首屏,MCP 是把整本工具手册摊在桌上,CLI 只递来一把终端钥匙,Skills 先给目录,命中条目再取说明书。
同一套 MCP 工具,换个模型要多付多少 token?
前面提到的 MCP 工具固定占用,在不同模型和服务商上的情况并不相同。工具数量、模型、服务商,三样都会改变这笔成本。
GitHub MCP 默认工具集包含 46 个工具。在 Claude Haiku 5.5 上,每次请求增加 19,436 个 prompt token(模型每轮收到的提示词输入量)。
同一套 46 个工具,换到 GPT-6 Luna 是 8,903 个,换到 Gemini 3.8 Flash 是 8,525 个。工具集完全不变,模型对工具定义的计数结果也会变——各服务商的提示词格式与计数方式不同,工具数量估不出占用。
同一条模型线路,落到不同服务商,结果也会变。Gemini 3.8 Flash 的同一套工具,经 Google Vertex 计为 8,525 个 token,经 Google AI Studio 计为 13,010 个。只记录模型名还不够,实际请求落到哪条服务商线路,也属于必须固定的测试条件。
以上数字来自 OpenRouter 的厂商跑分口径,未见第三方复测。工具集和服务商没固定之前,任何单点 token 数都不能当预算依据。

同一项 GitHub 查询,三种方式谁更省 token?
在 Claude Sonnet 5.5 上完成同一项 GitHub 查询,输入 token 差距明显:CLI 最低,Skill 次之,限定为两个工具的 MCP 最高。差距有多大,看下面三个数字。
OpenRouter 的对比测试把三种接入方式放进同一项 GitHub 任务。CLI 合计使用 1,421 个输入 token,Skill 使用 3,315 个,作用域限定为两个工具的 MCP 使用 23,228 个。这里的“输入 token”指模型读取并计费的提示内容(模型接收并计费的上下文文本),不只是用户输入的那句话。
| 接入方式 | 输入 token | 相对 CLI |
|---|---|---|
| CLI | 1,421 | 基准 |
| Skill | 3,315 | 多 1,894 |
| 限定两个工具的 MCP | 23,228 | 多 21,807 |
差距有多大?Skill 的输入 token 是 CLI 的 2.3 倍,限定两个工具的 MCP 是 CLI 的 16 倍出头。不过,这组结果只覆盖这项任务在 Sonnet 5.5 上的表现,不能直接当成所有 GitHub 查询或其他模型的固定比例。
每种组合都运行了三次,文中展示的是中位数,也就是三次结果里的中间值。它比单次运行更能代表这组任务的典型输入用量,但不是三次成本的累计账单。
Claude Haiku 5.5 对 prompt 的计数方式与 Sonnet 5.5 相同,两者的输入 token 数值可以按同一口径理解。部分 Haiku 5.5 运行用了更多轮次,轮次一变,两个模型的账单就不能并排看。

一次工具返回,可能抵过整套工具目录
GitHub 的 release 对象只返回一条工具结果,就约占 20,400 个 token,超过 GitHub MCP 默认 46 个工具定义合计增加的 19,436 个 token。一次工具返回,就可能抵过整套工具目录。
prompt token(模型处理时读取的输入文本单位)在 Claude Sonnet 5.5 上的这笔账,先看单次:一条 release 结果的体积,已经压过全部定义。
开销还会随调用轮次累积。第一轮要携带工具定义,工具返回 release 对象后,数据进入上下文;模型再调用另一个工具,后续请求仍会带着此前的定义与结果。累计开销取决于调用次数和每次结果大小,不只取决于挂载了多少工具。
工具定义是固定账单,工具结果才是可能随任务扩大的账单。
Tool Search 省下了起步钱,账单却不一定更少
Tool Search 能把 MCP 首批工具定义压到很小,却不保证让整项 GitHub 查询更省钱。
Tool Search 是 OpenRouter 的 server tool(由服务器托管并调用)。原先一并交给模型的 46 个工具,经过搜索后,首批定义压到 600 个 token 以下。模型起步时不用先读完整套工具目录。
但一正一负的实测摆在这里:在 Sonnet 5.5 上,使用 Tool Search 后,整套任务成本减半;在 Haiku 5.5 上,成本反而提高。同项优化没有在两个模型上得到同方向的结果。
初始成本不等于最终账单。任务开始后,模型仍要找到合适工具、发起调用、接收结果,省下的只是起步那一段。它缩短的是工具定义这一段,不会自动重写后续执行过程。
这些数字来自 OpenRouter 自建测试,文中未提供第三方复测。它能说明该工具在这组模型与任务中的表现,不能直接当作所有工作流的固定比例。
回到这项 GitHub 查询:同一个答案可以走 MCP、CLI 或 Skills,上下文账单却不同。在工具集没固定、模型没选定的情况下,全量装载 MCP 默认工具集,是账单最不可控的一种接法。
信源:OpenRouter 官方博客《MCP vs CLI vs Skills: What Each Costs in Context》;口径为 OpenRouter 选定的 GitHub 查询、工具配置和模型环境下三次运行取中位数,输入 token 与费用均来自其测试,未提供第三方复测。
术语小典 · 本篇出现的人话注解
深度、研究解读、工具教程的全文和全部播客,都在会员区。