2026-10-20 · 实测 · MCP

省了 55% 的词元
没省下时间

学 Codex 时有个问题一直没答好:既然它已经能读写文件、能跑命令,为什么还要 MCP? 「多一层协议总归更规范」这个回答我不满意——规范不值钱,省下来的东西才值钱。 于是做了个对照实验:同一件活,两种接入方式,各跑三遍。

这篇文章只想回答一件事:把一条常用的接口包成工具,到底换来了什么,又付出了什么。 结论不复杂——它省词元、省一致性,不省时间;有 shell 权限的时候,它不是必需品。 但「省了 55%」这个数字是怎么来的、又被什么抵消,值得把过程摊开。

怎么测

场景选每天都用得到的:检索本机知识库,问「MCP 审批策略」,返回命中的笔记文件名。 同一件活,两种接法:

甲:让模型自己写一条 PowerShell 命令,去调本机的检索接口。

乙:把同一个接口包成一个工具,模型只填两个参数。

同一个模型、同一句问题、同一个后端,各跑 3 次,取中位数。

这一轮,甲其实是占便宜的
接口地址、参数名、令牌从哪个文件读,我全都写进了提示词。 真实场景里,这些信息要靠模型自己翻代码、试出来。

结果

同一后端、同一句问题,各 3 次取中位数
指标命令行工具调用
每任务词元(中位数)1,278575
三次原始值1,273 / 1,463 / 1,278648 / 541 / 575
模型需要写的胶水363–394 字符20 字符
工具调用次数11
端到端耗时13–15 秒12–13 秒

省了 55%,两边都一次做对,延迟没差别。

三个发现

一、省的是「每次重新交代」。 命令行那一侧,模型每轮都要现编一条近 400 字符的命令:接口路径、参数名、 令牌从哪个文件读、中文和引号怎么不炸、返回的 JSON 里哪个字段才算命中。 工具那一侧,它只写 {"query":"..."}。

这不是模型笨,是知识没地方放。同一段交代,写了一百遍,就是一百遍的账单。

二、正确性可以从提示词搬进代码。 指令模糊、只说「只输出命中的」时,命令行版把 8 个文件全列了出来, 其中 5 个相关度是 0;工具版只给 3 个——因为「相关度大于 0」这条过滤 写死在工具里,模型说什么都不会错。

换成精确指令后,命令行版也能做对。所以差别不在能力,在 规则放在哪儿:放在提示词里靠自觉,放在代码里靠执行。

三、它并不更快。 单次调用,命令行 296 毫秒,工具 8 毫秒——差的全是 PowerShell 每次启动的开销。 可到了整轮对话,两边都被模型推理吃掉,13 秒对 12 秒。

所以「用 MCP 提速」这个理由站不住。它省的是词元和一致性,不是时间。

结论

有 shell 权限的时候,MCP 不是必需品。它在两种时刻回本: 一是这件事你每周要做几十遍,省的是重复交代; 二是这件危险的事你只想让 AI 碰其中一小块,用窄接口替代全权 shell,省的是失控的风险。 其余时候,写条命令就够了。

真正决定要不要包的,是「重复」和「失控」这两件事
重复得多,工具替你记住怎么做;风险高,工具替你划出边界。 两个都不占的时候,多一层协议只是多一层要维护的东西。

还有个容易被忽略的代价:工具声明会随每一轮请求常驻,每个会话还要多起一个进程。 给一个会话挂十个工具,这部分会积少成多。工具不是越多越好,是越准越好。

实测环境:Windows、Codex CLI 0.162.1、模型 deepseek-flash(reasoning high), 检索后端为本机知识库接口(12 篇笔记)。对照组使用同一后端、同一句问题, 各 3 次取中位数;词元数取自 codex exec 输出。 工具这件事还能接着读 工具链不是装得越多越好 和 什么该自己跑,什么必须停一下。 回到笔记