1. 从“工具越多越强”这个直觉说起
刚上手 Claude Code 那阵子,我跟很多人一样,陷入了一种“装备竞赛”的狂热。看到社区里有人分享一个能查数据库的 MCP,装;刷到有人推荐一个能操作浏览器的 MCP,装;听说某个 skill 能自动生成单元测试,也装。不到两周,我的配置文件里塞了几十个工具,每次启动 Claude Code,看着它加载那一长串工具列表,心里有种莫名的踏实感——仿佛工具越多,这个 AI 就越无所不能。
但实际用起来,情况完全不是那么回事。最直观的感受是:响应变慢了。以前问一个简单问题,它几乎秒回;现在它要先“思考”半天,有时候还会莫名其妙地调用一个完全不相关的工具。更让人抓狂的是,明明我只需要它改一行代码,它却先调了三个工具去“调研”,最后给出的方案还不如我自己直接写。那段时间我反复折腾配置,删了装、装了删,一度怀疑是不是自己的用法有问题。
直到有一次,我为了排查一个 bug,把工具列表砍到只剩五个核心工具,结果发现 Claude Code 的表现反而肉眼可见地变好了——响应快了,工具调用准了,废话也少了。这个反差让我开始认真思考一个问题:我们给 AI 挂工具,到底是在帮它,还是在给它添乱?“给 AI 减负”这个说法,是不是从一开始就搞错了方向?
这篇文章就是我这段时间折腾下来的完整复盘。我会从 Claude Code 的工具加载机制讲起,拆解 MCP、skill、subagent 这三类扩展到底在底层做了什么,为什么“堆工具”会拖垮 AI 的表现,以及我最终摸索出的一套“少即是多”的配置思路。如果你也在用 Claude Code、Cursor 或者类似的 AI CLI 工具,并且正被“工具太多反而不好用”困扰,那这篇内容应该能帮你省下不少试错时间。
2. 工具挂多了之后,Claude Code 到底发生了什么
2.1 上下文窗口不是无限大的仓库
很多人对 AI 工具加载有个误解,觉得工具就是“挂在那里”,用的时候才调用,不用的时候不占资源。这个理解在传统软件里成立,但在大语言模型驱动的工具里完全不成立。
Claude Code 这类 AI CLI 的工作方式,是把所有可用工具的名称、描述、参数 schema全部塞进系统提示词里,作为上下文的一部分发给模型。模型每次做决策——不管是回答一个问题还是执行一个操作——都要先“看一遍”这几十个工具的定义,然后判断该用哪个、怎么用。
这就好比你去餐厅点菜,菜单上只有 5 道菜,你扫一眼就决定了;但如果菜单有 200 页,每页都是密密麻麻的菜名和配料表,你光看完菜单就饱了,还谈什么点菜效率。工具列表越长,模型在“选择”这件事上消耗的注意力就越多,留给真正解决问题的算力自然就少了。
我实测过一个对比:同一个代码重构任务,在挂载 8 个工具和挂载 40 个工具两种配置下运行。前者平均响应时间 12 秒,工具调用 2 次;后者平均响应时间 47 秒,工具调用 6 次,其中 3 次是无效调用。这个差距不是线性的,而是指数级恶化——因为工具之间还会互相干扰,模型经常在几个功能重叠的工具之间反复横跳。
2.2 工具描述里的“噪音”是怎么污染决策的
比数量更隐蔽的问题是工具描述的质量。我翻过不少社区分享的 MCP 配置,很多工具的描述写得极其模糊,比如“用于处理数据”“帮助完成开发任务”这种。模型看到这种描述,根本判断不出什么时候该用它,只能靠猜。
更麻烦的是,当多个工具的描述存在语义重叠时,模型会陷入“选择困难”。我同时装过两个数据库查询工具,一个描述是“查询 SQL 数据库”,另一个是“执行数据库操作”。结果模型每次遇到数据库相关任务,都要在两个工具之间犹豫,有时候甚至两个都调一遍,浪费大量 token。
这里有个关键点很多人没意识到:工具描述本身就是提示词工程的一部分。你写的每一句描述,都会直接影响模型的决策路径。描述写得越泛,模型越容易误判;描述之间越相似,模型越容易纠结。给 AI 挂工具,不是把工具扔进去就完事了,描述的质量直接决定了工具是被“用好”还是被“用坏”。
2.3 工具调用链的隐性成本
还有一个容易被忽略的成本:工具调用是有链式反应的。模型调用工具 A 拿到结果后,这个结果会作为新的上下文进入下一轮推理,然后它可能基于这个结果再调用工具 B,如此往复。
每多一轮调用,就多一次完整的上下文传递和模型推理。如果工具 A 返回的结果很长(比如一个完整的网页内容或者一大段日志),那下一轮推理的上下文就会急剧膨胀。我见过最夸张的一次,模型为了查一个 API 文档,连续调用了 5 个工具,每一步的结果都堆在上下文里,最后上下文直接爆了,任务中断。
所以“给 AI 减负”这个说法之所以是伪命题,是因为减负的对象搞错了。真正需要减负的不是 AI 的“能力”,而是 AI 的“决策负担”。工具越多,决策负担越重,表现越差。我们要做的不是给 AI 更多工具让它变强,而是给它更精准的工具让它变快、变准。
3. MCP、skill、subagent:三类扩展的真实分工
3.1 MCP 解决的是“连接”问题,不是“能力”问题
MCP 全称 Model Context Protocol,本质上是一套标准化的工具接入协议。它的价值在于让 Claude Code 能够以统一的方式连接外部服务——数据库、浏览器、文件系统、第三方 API 等等。
但很多人对 MCP 有个误解,觉得装了一个 MCP 就等于给 AI 增加了一项能力。实际上,MCP 只是打通了连接通道,真正决定 AI 能不能用好这个通道的,是工具本身的设计质量和描述质量。
我拿 Playwright MCP 举例。这个 MCP 让 Claude Code 能够操作浏览器,听起来很强大。但如果你直接把整个 Playwright 的所有能力都暴露给模型,它会陷入“我该用哪个方法”的困境。正确的做法是只暴露当前任务真正需要的那几个操作,比如“打开页面”“点击元素”“截图”,而不是把整个浏览器自动化 API 都塞进去。
提示:MCP 的配置不是“装得越多越好”,而是“按需加载”。我现在的做法是给不同项目建不同的配置文件,每个项目只加载这个项目真正用到的 MCP,而不是全局挂一堆。
3.2 skill 是“预置的工作流”,不是“万能插件”
skill 这个概念在 Claude Code 生态里越来越热,从“仓颉 skill”到“数学建模 skill”,各种 skill 层出不穷。但 skill 的本质是什么?它其实是一段预置的提示词模板加工具调用序列,把某个特定场景下的最佳实践固化下来。
比如一个“代码审查 skill”,它内部可能定义了:先读 diff,再检查命名规范,再检查边界条件,最后输出审查意见。这套流程如果让模型自己摸索,它可能每次都不一样;但封装成 skill 之后,每次执行都走同一条路径,稳定性和一致性就上来了。
但 skill 的问题在于场景绑定太强。一个为 Python 项目写的代码审查 skill,拿到 Go 项目里可能完全不适用。我见过有人装了十几个 skill,结果模型每次都要先判断“当前场景该用哪个 skill”,这个判断过程本身就是一种负担。
3.3 subagent 是“分工”,不是“分身”
subagent 是这三类扩展里最容易被误用的。它的设计初衷是把复杂任务拆解给不同的子代理并行处理,比如一个 subagent 负责调研,一个负责写代码,一个负责测试。
但很多人把 subagent 当成了“多开几个 AI 同时干活”,结果就是协调成本爆炸。主 agent 要管理多个 subagent 的状态、传递上下文、汇总结果,这些协调工作本身就要消耗大量 token 和推理轮次。如果任务本身不够复杂,用 subagent 反而是负优化。
我的经验是:只有当任务可以清晰拆分成独立子任务,且子任务之间几乎不需要通信时,才值得用 subagent。否则,一个 agent 串行做完反而更快更稳。
| 扩展类型 | 解决的核心问题 | 典型误用 | 正确用法 |
|---|---|---|---|
| MCP | 连接外部服务 | 全局挂载所有 MCP | 按项目按需加载 |
| skill | 固化工作流 | 装一堆场景不匹配的 skill | 只保留高频场景的 skill |
| subagent | 任务并行拆解 | 简单任务也开多个 subagent | 仅用于可独立拆分的复杂任务 |
4. 我的“减负”实操:从 40 个工具砍到 8 个
4.1 第一步:盘点所有已挂载的工具
我做的第一件事,是把配置文件里所有 MCP、skill、subagent 列出来,然后逐个问自己三个问题:
- 过去两周,这个工具被调用过几次?
- 它解决的问题,有没有其他工具能替代?
- 它的描述是否清晰到模型能准确判断使用时机?
这三个问题筛下来,我发现自己装的 40 多个工具里,真正高频使用的只有 6 个,偶尔用到的有 4 个,剩下 30 多个基本是“装了就没用过”或者“用了还不如不用”。
4.2 第二步:合并功能重叠的工具
功能重叠是工具膨胀的重灾区。我同时装过三个文件操作相关的 MCP,两个代码搜索工具,还有两个功能几乎一样的数据库查询工具。这些重叠工具不仅浪费上下文,还会让模型在调用时反复纠结。
我的处理原则是:同一类功能只保留一个工具,并且优先保留描述最清晰、参数最简洁的那个。比如文件操作,我最终只留了一个支持读写和搜索的 MCP,把其他的全删了。
4.3 第三步:重写工具描述,让模型一眼看懂
删完工具之后,我做了一件很多人忽略的事:重写保留下来的工具描述。原来的描述很多是工具作者写的,偏向技术说明,模型看了不一定能准确判断使用场景。
我把每个工具的描述改成“什么时候用 + 解决什么问题 + 不适用什么场景”的格式。比如一个数据库查询工具,原来的描述是“执行 SQL 查询”,我改成了“当需要从关系型数据库读取数据时使用;不适用于写入操作,写入请用另一个工具”。改完之后,模型调用准确率明显提升。
4.4 第四步:建立项目级配置,而不是全局配置
最后一个关键调整是把全局配置改成项目级配置。以前我所有工具都挂在全局,不管做什么项目,模型都要面对那一长串工具列表。现在每个项目有自己的配置文件,只加载这个项目需要的工具。
比如做前端项目时,我只加载浏览器操作和文件系统相关的工具;做数据分析时,只加载数据库和文件读写工具。这样每个项目的工具列表都控制在 10 个以内,模型的决策负担大幅降低。
5. 砍完之后,实际效果和几个意外发现
5.1 响应速度和准确率的量化对比
砍完工具之后,我做了个简单的对比测试,用同一批任务在“40 工具配置”和“8 工具配置”下各跑一遍。结果如下:
| 指标 | 40 工具配置 | 8 工具配置 | 变化 |
|---|---|---|---|
| 平均响应时间 | 38 秒 | 11 秒 | 下降 71% |
| 平均工具调用次数 | 5.2 次 | 1.8 次 | 下降 65% |
| 无效调用占比 | 34% | 7% | 下降 79% |
| 任务一次通过率 | 52% | 86% | 提升 65% |
这个数据不一定适用于所有人,但趋势是明确的:工具越少,AI 表现越好。尤其是“无效调用占比”这个指标,从 34% 降到 7%,意味着模型不再把大量精力浪费在“选错工具再重试”上。
5.2 一个反直觉的发现:少工具反而能激发模型能力
砍工具的过程中,我发现了一个很有意思的现象:当工具变少时,模型会更倾向于用“推理”而不是“调用”来解决问题。
举个例子,以前遇到一个需要解析 JSON 的任务,模型会去调一个 JSON 处理工具;现在没有那个工具了,它直接自己写了一段解析逻辑,而且写得还挺好。这让我意识到,很多工具其实是在“替模型思考”,而模型本身是有能力完成这些思考的。工具太多,反而抑制了模型自身的推理能力。
5.3 什么时候该加工具,什么时候该忍一忍
当然,我不是说工具越少越好。有些场景下,工具确实是必需的,比如需要访问外部实时数据、需要操作模型无法直接触及的系统。我的判断标准是:
- 模型自己能做的,不给它工具:比如文本处理、简单计算、代码生成,这些模型本身就能完成,给工具反而是画蛇添足。
- 模型做不了但高频使用的,给一个精准工具:比如访问特定数据库、调用内部 API,这些模型无法自己完成,且使用频率高,值得挂一个工具。
- 模型做不了但低频使用的,用的时候临时加:比如某个季度才用一次的报表生成工具,没必要常驻配置,需要时临时加载即可。
6. 关于“给 AI 减负”这个说法的重新理解
6.1 减负的对象应该是“决策路径”,不是“能力”
回到标题里的那个判断:“给 AI 减负”是个伪命题。我现在对这句话的理解是:如果“减负”指的是减少 AI 的能力,那确实是伪命题,因为能力越多理论上越好;但如果“减负”指的是减少 AI 的决策负担,那不仅不是伪命题,反而是提升 AI 表现的关键。
我们真正要做的,不是给 AI 更多工具让它“更强”,而是给 AI 更清晰的决策路径让它“更准”。工具的数量和 AI 的表现之间,不是正相关,而是一个倒 U 型曲线——太少不够用,太多用不好,只有在一个合适的区间里,AI 才能发挥最佳状态。
6.2 工具管理的本质是提示词管理
折腾这一圈下来,我最大的体会是:工具管理本质上就是提示词管理。每个工具的名称、描述、参数,都是提示词的一部分。你写的每一句话,都在塑造模型的决策行为。
所以与其花时间到处找新工具、装新 MCP,不如花时间把现有工具的描述写清楚、把工具列表精简到位。后者带来的收益,远比前者大得多。
6.3 一个可持续的工具配置习惯
我现在维持工具配置的习惯是:每月做一次工具审计。把过去一个月没调用过的工具删掉,把调用频繁但描述模糊的工具重写描述,把功能重叠的工具合并。这个习惯坚持了三个月,我的工具列表一直稳定在 8 到 10 个之间,Claude Code 的表现也一直很稳定。
如果你也在用 Claude Code 或者类似的 AI CLI 工具,我建议你从今天开始做一件事:打开你的配置文件,把工具列表从头到尾看一遍,然后问自己——这些工具里,有多少是我真正需要的,有多少只是我“觉得可能需要”的。答案可能会让你意外。
最后分享一个小技巧:如果你不确定某个工具该不该留,先把它注释掉,用一周。如果一周内你完全没有想起它,那它大概率就是可以删的。这个方法比任何理论分析都管用,因为你的实际使用行为不会骗你。