1. 从“工具越多越强”说起:我为什么给 Claude Code 挂了三十多个工具
最开始用 Claude Code 的时候,我的心态特别简单——工具越多,能力越强。MCP 协议出来之后,我像集邮一样往配置里塞各种 server:文件系统、浏览器自动化、数据库查询、API 调试、文档检索、代码分析,前前后后挂了三十多个。每次看到启动日志里一长串工具加载成功,心里就有种莫名的安全感,觉得这下 AI 总算“武装到牙齿”了。
结果用了不到两周,我就发现事情不对劲。响应变慢只是最表面的问题,真正让我警觉的是:Claude Code 开始频繁选错工具。明明我只是让它读一个本地文件,它却去调浏览器 MCP;明明一个简单的代码搜索,它绕了三四个工具才找到答案。更离谱的是,有时候它会在工具列表里“迷路”,反复尝试几个功能重叠的 server,最后给我一个四不像的结果。
那段时间我一直在想一个问题:是不是我给 AI 的东西太多了?于是我开始做减法实验,把工具从三十多个砍到十几个,再砍到七八个。有意思的事情发生了——响应速度回来了,工具选择准确率明显提升,输出质量反而更稳定。这让我意识到,“给 AI 减负”这个说法本身可能就是个伪命题。真正的问题不在于工具数量多少,而在于工具的组织方式、上下文管理和调用策略。
这篇文章我想把这段时间的踩坑经验完整梳理出来。如果你也在用 Claude Code,也在折腾 MCP、skill、subagent 这些概念,也在纠结到底该挂多少工具、怎么挂、怎么管,那这篇内容应该能帮你少走不少弯路。我会从整体设计思路讲起,然后拆解核心细节,再给出一套可以直接抄的实操方案,最后把常见问题和排查技巧整理成速查表。不管你是刚安装 Claude Code 的新手,还是已经挂了一堆 MCP server 的老玩家,都能从中找到对自己有用的部分。
2. 整体设计与思路拆解:工具不是越多越好,而是越“可预测”越好
2.1 工具膨胀的根源:把“能力覆盖”当成了“能力提升”
我复盘了一下自己当初疯狂加工具的心理,本质上是一种“能力覆盖焦虑”。看到别人分享一个蓝湖 MCP,赶紧加上;看到 playwright MCP 能做浏览器自动化,也加上;看到有人推荐 burpsuite MCP 做安全测试,继续加。每个工具单独看都有明确价值,但放在一起就变成了一个巨大的、互相干扰的工具池。
这里有个很关键的认知误区:工具数量增加带来的是能力覆盖面的扩大,但不等于 AI 实际解决问题能力的提升。Claude Code 在每次对话开始时,需要把可用工具的元信息(名称、描述、参数 schema)加载到上下文里。三十多个工具意味着几千甚至上万 token 的工具描述常驻上下文,这些 token 会挤占真正用于理解任务、推理和生成代码的空间。
更麻烦的是工具之间的语义重叠。比如文件读取,文件系统 MCP 能做,某些代码分析 skill 也能做,浏览器 MCP 在某些场景下也能间接做到。当多个工具都能完成同一类任务时,模型需要在它们之间做选择,而这个选择过程本身就会消耗推理资源,还容易选错。
我实测过一个对比:同样一个“读取项目里所有 Python 文件的 import 语句并整理成表格”的任务,在挂载 30+ 工具时,Claude Code 平均需要 4-5 轮工具调用才能完成,而且有大约三成概率会绕路;在精简到 8 个工具后,平均 2 轮就能完成,准确率接近百分之百。这个差距不是模型能力变了,而是工具环境变了。
2.2 核心思路:分层组织 + 按需加载 + 明确边界
想明白上面的问题之后,我给自己定了一套工具管理原则,核心就三条。
第一条是分层组织。我把工具分成三层:基础层、领域层、临时层。基础层是几乎每个任务都会用到的,比如文件读写、代码搜索、终端执行,这些常驻加载。领域层是按项目类型选择的,比如做前端项目就加载浏览器自动化和组件分析工具,做数据项目就加载数据库和数据处理工具。临时层是特定任务才用的,比如一次性调用某个 API 做数据迁移,用完就撤。
第二条是按需加载。Claude Code 支持通过配置动态管理 MCP server,我不再让所有 server 在启动时全部加载,而是根据当前项目目录和任务类型,用不同的配置文件切换。这样每次对话的上下文里只有当前真正需要的工具。
第三条是明确边界。每个工具只负责一类事情,功能重叠的工具只保留一个。比如文件操作我只用官方文件系统 MCP,不再额外挂其他能读文件的 skill。浏览器自动化我只用 playwright MCP,不再同时挂 chrome devtools MCP。边界清晰之后,模型的选择成本大幅下降。
2.3 为什么“减负”是伪命题:真正要减的是“认知负荷”而不是“工具数量”
回到标题里的那个判断——“给 AI 减负”是个伪命题。我的理解是,如果只是机械地减少工具数量,而不改变工具的组织方式和调用策略,那减负只是把问题从“选择太多”变成“能力不够”。真正有效的做法不是单纯做减法,而是做结构化。
打个比方,一个厨房里堆了三十口锅,厨师做菜时确实会犹豫用哪口。但解决办法不是把锅扔到只剩三口,而是把锅按功能分区挂好:炒锅区、汤锅区、蒸锅区,每个区里只放最常用的那口。厨师需要炒菜时直接去炒锅区,不需要在三十口锅里翻找。工具管理也是一样,数量本身不是问题,无序才是问题。
所以我的整体设计思路可以总结成一句话:用分层和按需加载,把工具从“一堆散落的选项”变成“一组有组织的模块”。这样既保留了能力覆盖面,又降低了模型的认知负荷,响应速度和准确率都能回来。
3. 核心细节解析与实操要点:MCP、skill、subagent 到底怎么配合
3.1 MCP 协议的本质:它解决的是“连接”,不是“智能”
很多人对 MCP 的理解有偏差,觉得挂上 MCP 就等于给 AI 加了新能力。其实 MCP 协议本身只做一件事:标准化 AI 与外部工具之间的通信接口。它定义了一套描述工具、调用工具、返回结果的格式,让不同的工具提供方可以用统一的方式接入。
这意味着 MCP 不负责决定“什么时候该用哪个工具”,那是模型自己的事。MCP 只负责“当模型决定要用某个工具时,能顺利调用并拿到结果”。理解这一点很重要,因为它解释了为什么工具挂多了会出问题——问题不在 MCP 协议本身,而在模型面对大量工具时的选择困难。
我在配置 MCP server 时,会特别关注每个 server 暴露的工具描述。描述写得越清晰、边界越明确,模型选择时就越不容易出错。有些第三方 MCP server 的工具描述写得很模糊,比如“处理数据”这种,模型根本不知道它和别的工具有什么区别,这种 server 我一般会直接换掉或者自己改描述。
3.2 skill 的定位:把“怎么做”固化下来,减少重复推理
skill 和 MCP 是两种不同的东西。MCP 提供的是工具调用能力,skill 提供的是任务执行的知识和流程。你可以把 skill 理解成一份“操作手册”,告诉 Claude Code 遇到某类任务时应该按什么步骤、用什么工具、注意什么细节。
我举个例子。我经常需要把一份 Markdown 文档转换成特定格式的 HTML,里面涉及代码高亮、表格样式、图片路径处理等一堆细节。如果每次都让模型自己推理,它每次的做法可能都不一样,质量也不稳定。后来我写了一个 skill,把整个转换流程、用到的工具、参数配置、常见问题都固化进去。之后每次触发这个 skill,输出质量就非常稳定。
skill 的价值在于减少重复推理。模型不需要每次都从零开始想“这个任务该怎么做”,而是直接调用已经验证过的流程。这比单纯增加工具更能提升实际效率。我目前维护了十几个 skill,覆盖代码审查、文档生成、数据清洗、API 测试等高频场景。每个 skill 都经过多次迭代,把踩过的坑都写进去了。
3.3 subagent 的用法:把复杂任务拆出去,保持主上下文干净
subagent 是我最近才开始重度使用的功能,用下来感觉是被低估了。它的核心价值是隔离上下文。当主对话需要处理一个复杂子任务时,如果直接在主上下文里做,会产生大量中间结果和工具调用记录,把上下文撑得很满。而 subagent 可以在一个独立的上下文里完成子任务,只把最终结果返回给主对话。
我举个实际场景。我需要让 Claude Code 分析一个大型项目的代码结构,找出所有循环依赖。这个任务需要遍历大量文件、构建依赖图、做图分析。如果直接在主对话里做,光是文件读取的记录就能把上下文占满。我的做法是启动一个 subagent,给它明确的指令和必要的工具,让它在独立上下文里完成分析,最后只返回一份依赖关系报告。主对话的上下文始终保持干净,后续还能继续做别的事情。
subagent 的另一个好处是并行。有些任务之间没有依赖关系,可以同时启动多个 subagent 分别处理,最后汇总结果。比如同时分析前端和后端的代码质量,两个 subagent 各管一摊,效率比串行高很多。
3.4 三者配合的实操要点
把 MCP、skill、subagent 配合起来用,有几个关键点需要注意。
第一,MCP 工具要精简到当前任务真正需要的。我现在的做法是每个项目目录下放一个.claude/settings.json,里面只配置这个项目需要的 MCP server。全局配置里只保留最基础的文件系统和终端工具。
第二,skill 要写得具体,包含失败处理。一个好的 skill 不只是“第一步做什么、第二步做什么”,还要写清楚“如果第一步失败了怎么办”“某个工具返回异常时怎么降级”。这些细节才是 skill 真正省时间的地方。
第三,subagent 的指令要自包含。因为 subagent 在独立上下文里运行,它看不到主对话的历史。所以给 subagent 的指令必须包含完成任务所需的全部背景信息、工具权限和输出格式要求。我一般会写一个模板,每次启动 subagent 时填充具体内容。
第四,定期清理不再使用的工具和 skill。我每个月会 review 一次自己的配置,把过去一个月没调用过的 MCP server 和 skill 标记出来,确认不需要后就移除。这个习惯帮我避免了很多“僵尸工具”占用上下文。
注意:MCP server 的加载顺序也会影响模型的选择倾向。我实测发现,排在工具列表前面的 server 被选中的概率略高。所以我会把最常用、最基础的工具放在配置的前面,把领域专用的放在后面。
4. 实操过程与核心环节实现:一套可直接抄的配置方案
4.1 环境准备与基础配置
先说安装。Claude Code 的安装方式根据操作系统不同略有差异。在 Ubuntu 上,我一般用官方提供的安装脚本,装完之后用claude --version确认版本。在 VS Code 里配置 Claude Code 的话,需要先装对应的扩展,然后在设置里指定 Claude Code 的可执行文件路径。Windows 用户如果遇到“claude code might not be available in your country”这类提示,通常是网络环境或账号区域的问题,需要检查自己的账号设置和网络配置。
安装完成后,第一件事是创建全局配置文件。我一般放在~/.claude/settings.json,里面只保留最基础的工具:
{ "mcpServers": { "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"] }, "terminal": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-terminal"] } } }这个配置只加载文件系统和终端两个 server,覆盖了最基础的读写和执行需求。其他所有工具都按项目需要动态添加。
4.2 按项目类型配置领域工具
接下来是领域层配置。我在每个项目根目录下创建.claude/settings.json,根据项目类型配置不同的 MCP server。比如前端项目:
{ "mcpServers": { "playwright": { "command": "npx", "args": ["-y", "@playwright/mcp-server"] }, "chrome-devtools": { "command": "npx", "args": ["-y", "chrome-devtools-mcp"] } } }数据项目则换成数据库相关的 server。这样切换项目时,Claude Code 自动加载对应的工具集,不需要手动改配置。
这里有个细节:项目级配置会和全局配置合并,所以基础的文件系统和终端工具始终可用,领域工具按项目叠加。这个机制很实用,避免了重复配置。
4.3 编写高价值 skill 的完整流程
skill 的编写我总结了一个模板,包含五个部分:触发条件、前置检查、执行步骤、失败处理、输出格式。
以我常用的“代码审查 skill”为例:
# 代码审查 Skill ## 触发条件 当用户要求审查代码、检查代码质量、或提交 PR 前检查时触发。 ## 前置检查 1. 确认当前目录是 Git 仓库 2. 确认有未提交的变更或指定了审查范围 3. 确认项目有 lint 配置(没有则跳过 lint 步骤) ## 执行步骤 1. 用 git diff 获取变更内容 2. 按文件类型分组,Python 文件检查 PEP8,JS 文件检查 ESLint 规则 3. 检查常见问题:未处理的异常、硬编码密钥、SQL 注入风险、未使用的变量 4. 对每个问题标注严重程度(高/中/低)和修复建议 ## 失败处理 - 如果 git diff 为空,提示用户没有变更 - 如果 lint 工具未安装,跳过该步骤并在报告中说明 - 如果文件过大导致分析超时,分块处理 ## 输出格式 按文件分组,每个问题包含:文件路径、行号、问题描述、严重程度、修复建议这个 skill 写完之后,我每次做代码审查只需要说一句“审查当前变更”,Claude Code 就会按这个流程走,输出格式统一,不会漏掉关键检查项。
4.4 subagent 的启动与结果回收
subagent 的使用需要明确指定任务边界。我一般用这样的指令模板:
启动一个 subagent,任务是:[具体任务描述] 可用工具:[列出该 subagent 需要的工具] 背景信息:[完成任务所需的上下文] 输出要求:[格式、详细程度、保存位置] 完成后返回:[需要返回给主对话的内容摘要]举个例子,我需要分析一个模块的测试覆盖率:
启动一个 subagent,任务是:分析 src/payment 目录下所有模块的测试覆盖率,找出覆盖率低于 80% 的文件 可用工具:filesystem, terminal 背景信息:项目使用 pytest + coverage,测试文件在 tests/ 目录下 输出要求:生成一份 Markdown 报告,包含每个文件的覆盖率、未覆盖的函数列表、改进建议 完成后返回:覆盖率低于 80% 的文件列表和对应的改进优先级这样启动的 subagent 会在独立上下文里完成分析,主对话只收到一份精简的结果。我实测下来,这种方式处理大型分析任务时,主对话的响应速度能提升一倍以上。
4.5 工具调用的监控与调优
配置好之后,还需要持续监控工具调用情况。Claude Code 会在对话中显示每次工具调用的名称和参数,我会定期检查这些记录,找出几类问题:频繁选错的工具、从未被调用的工具、调用耗时过长的工具。
对于频繁选错的工具,我会调整它的描述或者直接移除。对于从未被调用的工具,说明当前项目不需要它,从配置里删掉。对于耗时过长的工具,我会看看有没有更轻量的替代方案,或者给它设置超时限制。
这个监控习惯帮我保持配置的精简和高效。我现在的原则是:任何一个工具,如果连续两周没有被调用,就考虑移除。
5. 常见问题与排查技巧实录:那些文档里不会写的坑
5.1 工具选择混乱的排查思路
工具选择混乱是最常见的问题,表现是模型反复调用不相关的工具,或者在同一类工具之间来回切换。排查时我会按这个顺序检查:
先看工具描述是否有重叠。如果两个工具的描述都包含“读取文件”这类字眼,模型就会犹豫。解决办法是修改描述,让每个工具的职责更具体,比如一个写“读取本地文件系统中的文件”,另一个写“从远程 URL 获取文件内容”。
再看工具数量是否超过当前任务需要。如果当前只是改一个 CSS 文件,却加载了数据库、浏览器、API 测试等一堆工具,模型的选择空间就太大了。解决办法是按任务类型切换配置,只加载必要的工具。
最后看工具加载顺序。前面提到过,排在前面的工具更容易被选中。如果发现模型总是优先调用某个不合适的工具,可以调整配置顺序,把更合适的工具放前面。
5.2 上下文被工具描述撑满的解决
当工具数量多到一定程度,工具描述本身就会占用大量上下文。我遇到过最夸张的情况是,三十多个工具的描述加起来超过两万 token,导致模型几乎没有空间处理实际任务。
解决办法有三个。一是精简工具描述,把不必要的参数说明和示例删掉,只保留核心信息。二是用按需加载,不用的工具不加载。三是把一些低频工具改成通过 skill 调用,skill 只在触发时才加载相关工具,平时不占用上下文。
我实测过一个对比:把 30 个工具的描述精简后,上下文占用从两万多 token 降到八千左右,模型的响应质量和速度都有明显提升。
5.3 skill 不生效的常见原因
skill 写了但没被触发,通常有几个原因。一是触发条件写得太窄,模型判断当前任务不匹配。解决办法是把触发条件写得更宽泛一些,覆盖更多相关场景。二是 skill 文件位置不对,Claude Code 找不到。需要确认 skill 放在正确的目录下,一般是.claude/skills/。三是 skill 内容太长,模型在加载时截断了。解决办法是把 skill 拆成多个小文件,或者精简内容。
我踩过的一个坑是 skill 文件名带了特殊字符,导致加载失败。后来统一用英文小写加连字符命名,再没出过问题。
5.4 subagent 结果不符合预期的处理
subagent 返回的结果不符合预期,最常见的原因是指令不够自包含。因为 subagent 看不到主对话的历史,如果指令里缺少必要的背景信息,它就会按自己的理解去做。
我的解决办法是写一个 subagent 指令模板,每次启动时填充。模板里强制包含:任务描述、可用工具、背景信息、输出格式、返回内容要求。这五个要素缺一不可。
另一个原因是 subagent 的工具权限没给够。如果任务需要读取文件但没给 filesystem 工具,subagent 就会卡住或者返回错误。启动前一定要确认工具列表覆盖了任务所需的所有操作。
5.5 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| 响应变慢 | 工具描述占用上下文过多 | 查看启动日志中的 token 数 | 精简工具描述,按需加载 |
| 工具选错 | 工具描述重叠或数量过多 | 检查工具描述关键词 | 明确边界,减少同类工具 |
| skill 不触发 | 触发条件太窄或文件位置错误 | 检查 skill 目录和内容 | 放宽触发条件,确认路径 |
| subagent 结果偏差 | 指令不自包含 | 检查指令是否包含背景信息 | 使用指令模板,补全五要素 |
| 工具调用超时 | 工具本身性能问题或网络延迟 | 查看调用耗时记录 | 设置超时,寻找替代方案 |
| 配置不生效 | 配置文件位置或格式错误 | 检查 JSON 语法和路径 | 用claude config验证 |
提示:每次修改配置后,建议重启 Claude Code 会话,确保新配置生效。有些配置项是启动时加载的,热更新可能不生效。
5.6 我踩过的三个典型坑
第一个坑是盲目追求工具数量。刚开始我觉得工具越多越厉害,结果上下文被撑满,模型反而变笨了。后来砍到十几个,效果明显好转。这个教训让我明白,工具管理的核心是“组织”而不是“堆砌”。
第二个坑是 skill 写得太笼统。我早期写的 skill 都是“检查代码质量”这种大而全的描述,模型触发后不知道具体该做什么。后来改成具体流程,每个步骤都写清楚用什么工具、检查什么、怎么判断,效果才出来。
第三个坑是 subagent 指令太简略。我以为 subagent 能自己理解上下文,结果它经常跑偏。后来强制自己写完整的指令模板,问题就解决了。这个经验告诉我,subagent 不是“更聪明的助手”,而是“需要完整交代任务的执行者”。
6. 工具管理的长期维护与迭代策略
6.1 建立工具使用日志
我现在的做法是每周花十分钟 review 一次工具调用记录。Claude Code 的会话日志里会记录每次工具调用的名称、参数、耗时和结果状态。我会把这些信息整理成一个简单的表格,统计每个工具的使用频率和成功率。
这个习惯帮我发现了很多问题。比如某个 MCP server 的成功率只有六成,经常返回超时错误,我就把它换掉了。又比如某个 skill 一个月只触发了一次,说明它的触发条件写得太窄,需要调整。
6.2 定期做配置减法
工具配置容易只增不减,时间长了就变得臃肿。我给自己定了一个规则:每个月做一次配置减法,把过去一个月没调用过的工具和 skill 全部标记出来,确认不需要后移除。
这个规则执行下来,我的工具数量从最高峰的三十多个稳定在现在的十个左右。每次减法之后,响应速度和准确率都会有一波提升。这让我更加确信,工具管理的本质是持续做减法和结构化,而不是一次性配置好就不管了。
6.3 根据项目阶段调整工具集
同一个项目在不同阶段需要的工具也不一样。项目初期需要代码生成和文档工具,中期需要测试和调试工具,后期需要部署和监控工具。我会根据项目阶段调整配置,而不是一套配置用到底。
比如项目进入测试阶段时,我会把 playwright MCP 和测试相关的 skill 加进来,同时把一些初期用的代码生成工具移除。这样每个阶段加载的工具都是当前最需要的,上下文利用率最高。
6.4 保持对新技术的好奇但克制
AI 工具生态变化很快,几乎每周都有新的 MCP server 和 skill 出现。我的态度是保持关注,但不轻易往生产配置里加。看到新工具时,我会先在一个隔离的测试环境里试用,确认它确实能解决我的某个具体问题,并且不会和现有工具冲突,才会考虑加入正式配置。
这个习惯帮我避免了很多“尝鲜一时爽,维护火葬场”的情况。工具管理的目标不是拥有最多工具,而是拥有最合适的工具组合。
6.5 一个具体的迭代案例
最后分享一个我最近做的迭代。我原来有一个“API 测试 skill”,里面调用了三个不同的 MCP server 来完成请求构造、发送和结果验证。用了一段时间后发现,这三个 server 的功能有重叠,而且经常互相干扰。
我的迭代方案是:只保留一个最稳定的 HTTP 请求 MCP server,把请求构造和结果验证的逻辑全部写进 skill 里,用 skill 的流程来控制,而不是依赖多个工具。改完之后,API 测试的成功率从七成提升到九成五,而且调试起来简单多了,出问题时只需要看 skill 的日志,不用在多个 server 之间排查。
这个案例让我更加确信,工具和 skill 的边界要清晰:工具负责“能做什么”,skill 负责“怎么做”。把流程逻辑放在 skill 里,把执行能力交给工具,两者各司其职,整体效率最高。
我在实际使用中的体会是,Claude Code 的工具管理没有一劳永逸的方案。项目在变,工具生态在变,自己的使用习惯也在变。关键是建立一套可持续的维护机制:定期 review、持续做减法、按需调整。做到这三点,工具数量多少就不再是问题,因为你知道每一个工具为什么在那里,也知道什么时候该让它离开。