我们很容易把 AI Agent 的“能力”理解成一张功能清单。

能联网搜索,加一个工具;能查数据库,再加一个;能发邮件、读日历、操作 GitHub、执行 Shell、浏览网页、调用地图、读企业知识库……到了 MCP 时代,这件事甚至变得像装插件一样简单。

于是一个非常自然的想法出现了:

既然工具能扩展 Agent 的能力,那我把能接的工具全部接上,它是不是就会越来越强?

直觉上是。

工程上却恰恰相反:当工具数量超过某个程度以后,“拥有更多能力”与“更好地完成任务”会开始分离。

一个 Agent 可以同时拥有一百个工具,但它可能因为不知道该选哪一个、被相似工具误导、把大量上下文浪费在工具定义上,最终还不如只给它五个真正相关的工具。

这不是纯粹的理论问题。2025 到 2026 年围绕 MCP、Tool Calling 和 Agent 工具检索的工程实践与研究,已经越来越明确地指向同一个结论:

真正成熟的 Agent,不应该“始终看见所有工具”,而应该“在需要时发现少量正确工具”。


MCP 让“给 Agent 装工具”变得太容易了

MCP(Model Context Protocol)的价值非常直接:把模型和外部系统之间的连接方式标准化。

以前你想让一个 Agent 同时操作 GitHub、地图、数据库、网页抓取和企业内部 API,往往需要分别维护五套集成。现在这些能力可以被包装成 MCP Server,再以统一方式暴露给模型。

国内平台也已经把这套体验做成了“工具市场”。下面是阿里云百炼 MCP 服务页面的一个示例:

阿里云百炼 MCP 服务市场

图:阿里云开发者社区展示的百炼 MCP 服务市场。配图使用阿里云 CDN,国内访问相对稳定。

这当然是一件好事。

问题是,连接成本降低以后,人很容易开始无节制地连接。

一个开发者看到 GitHub MCP,觉得有用,接上;看到搜索 MCP,接上;看到文件系统、数据库、浏览器、邮件、日历、工单、监控平台,也全部接上。

最后 Agent 的工具列表可能变成这样:

GitHub       35 tools
Slack        11 tools
Sentry        5 tools
Grafana       5 tools
Splunk        2 tools
Jira         ...
Database     ...
Browser      ...
Filesystem   ...
Shell        ...

从产品页面看,这是“能力越来越丰富”。

从模型视角看,这是另一回事:

用户问题
   ↓
几十到几百个工具定义
   ↓
哪个工具最相关?
   ↓
参数应该怎么填?
   ↓
需不需要先调用另一个工具?
   ↓
哪个工具名字很像但其实不能用?
   ↓
执行

模型得到的不是一把更锋利的刀,而是一整面工具墙。


第一个问题:工具定义本身就在吃上下文

Tool Calling 并不是“模型知道系统里存在一个函数”这么简单。

为了让模型知道工具怎么调用,通常需要把工具名称、描述、参数 Schema、字段说明等信息提供给模型。例如:

get_document
  description: 获取指定文档
  parameters:
    document_id: string, required
    fields: string, optional

一个工具没多少。

五十个工具就完全不是一回事了。

Anthropic 在 2025 年公布过一个非常直观的实际配置:GitHub、Slack、Sentry、Grafana 和 Splunk 五个 MCP Server 合计 58 个工具,仅工具定义就大约需要 55K tokens。他们还观察过优化前工具定义占用 134K tokens 的情况。

这意味着什么?

意味着用户甚至还没开始提问,模型的上下文就已经先被“我有哪些工具、这些工具怎么用”占掉了一大块。

而且工具调用返回的结果还会继续占用上下文。

于是你会得到一种很荒诞的系统:

Agent 为了拥有更多能力,先把自己的注意力和上下文预算花在了阅读能力说明书上。

Anthropic 后来推出 Tool Search,本质上就是不再把所有工具定义一次性塞进模型,而是先提供一个“找工具”的入口,需要时再加载 3~5 个相关工具。

他们公布的内部测试中,一个场景的上下文消耗从约 77K tokens 降到了约 8.7K,减少约 85%;在其 MCP 评测中,Opus 4 的准确率从 49% 提升到 74%,Opus 4.5 从 79.5% 提升到 88.1%。

需要强调:这是厂商自己的内部评测,不应该当成所有模型、所有 Agent 框架都必然获得同样提升。

但它至少说明了一件事:

“不要让模型一次看见所有工具”已经不是一种小优化,而正在成为大规模 Agent 的基础架构问题。


第二个问题:正确工具在列表里,不等于模型能选对

有人可能会说:

“上下文够大不就行了?现在都几十万、上百万 token 了。”

问题没有这么简单。

工具越多,增加的不只是 token 数量,还增加了决策空间

2026 年的一篇研究《How Many Tools Should an LLM Agent See?》专门研究了这个问题:到底应该给 Agent 展示多少个候选工具?

结果非常有意思。

在 BFCL 的 370 个工具集合中,一种动态策略平均只向模型展示约 7 个工具,但正确工具的覆盖率达到 90.3%;一次展示 50 个工具的覆盖率是 90.8%

也就是说,平均少看四十多个工具,几乎没有损失候选覆盖率。

更关键的是下游选择实验。论文使用 Claude Sonnet 4.6 验证时,较短的动态候选列表在工具选择上达到 93.1%,而固定展示 5 个工具为 87.1%;在“正确工具存在、但不是检索第一名”的中等难度任务中,两者是 76.8% 对 60.9%

这组数字真正值得关注的地方,不是“7 比 5 好”这种机械结论。

而是:

工具检索本身也需要根据问题难度动态决定深度。简单问题少给,困难问题必要时再向下找。

我们对 Agent 的设计思路因此应该从:

我有 100 个工具
→ 全部给模型
→ 让模型自己挑

变成:

我有 1000 个工具
→ 先检索相关能力
→ 当前只激活 3~10 个
→ 必要时继续搜索
→ 再让模型选择

这和搜索引擎非常像。

Google 并不会因为索引了几百亿网页,就一次把几百亿网页塞给你。

工具注册表可以无限大,但 Agent 当前看到的工具集合应该尽可能小。


第三个问题:工具之间会“撞车”

工具多以后最麻烦的事情,往往不是完全无关的工具,而是很像的工具

例如:

send_notification_to_user
send_notification_to_channel
send_message
send_direct_message
post_channel_message

人类开发者看到文档还能慢慢判断。

Agent 需要在一次推理里同时判断工具名称、描述、参数、当前任务和历史状态。

2026 年 8 月 5 日刚发布的一项研究甚至专门设计了“Canary Tools”,向 Agent 的 MCP 工具集中加入各种容易误导模型的假工具,用来诊断模型为什么选错。

研究者总结了六类典型陷阱,包括:

  • Semantic decoy:名字语义非常接近,但用途不对;
  • Parameter trap:工具看起来正确,但参数约束不匹配;
  • Capability mirage:描述声称自己更“高级”“更强”,实际上不是正确选择;
  • Prerequisite blindness:忽略调用工具之前必须完成的前置步骤;
  • Temporal decoy:忽略时间或状态条件;
  • Granularity trap:工具粒度与任务不匹配。

研究覆盖 8 个模型、120 个任务和数千次运行。不同模型差异很大,但一个值得注意的现象是:能力更强并不意味着对所有“诱饵工具”都天然免疫。

其中“Capability Mirage”尤其值得我们警惕。

假设工具列表里同时有:

convert_units
advanced_convert_units

后者的描述写着:

optimized / advanced / research-grade accuracy

模型可能因为“看起来更强”而选择它,即使它根本不是这个任务的正确工具。

这与我们上一篇讨论的 Agent Skill 供应链攻击 其实是同一个问题的另一面:

Agent 不只是在执行代码,它还在阅读并信任“能力描述”。

工具描述本身已经成为决策输入。


第四个问题更严重:工具越多,权限半径也越大

到这里还只是“模型会不会选错”。

真正危险的是:有些工具选错一次,代价完全不同。

把天气查询工具调错,可能只是回答不准确。

把下面这些工具调错呢?

filesystem.delete
shell.exec
github.merge_pull_request
mail.send
database.execute_sql
cloud.delete_instance
payment.create_transfer

Agent 能看到多少工具,是一个上下文问题;Agent 能实际执行多少工具,则是一个权限问题

这两件事经常被混在一起。

一个更合理的系统应该至少区分:

存在的工具(Registry)
        ↓
当前任务可发现的工具(Discovery)
        ↓
模型当前可选择的工具(Active Set)
        ↓
当前身份被授权执行的工具(Authorization)
        ↓
当前操作是否需要再次确认(Policy Gate)
        ↓
真正执行

而不是:

接入 MCP Server
        ↓
所有工具全开
        ↓
模型自己决定

MCP 官方安全指南现在也明确建议使用最小权限与渐进式授权,而不是给客户端一个 *allfull-access 之类的万能权限。对于高风险操作,应在真正需要时再提升权限,并保留审计记录。

原因非常现实:

如果一个 Agent 同时拥有“读文档”和“删生产数据库”的权限,那么一次 Prompt Injection、一次错误工具选择、一次被污染的网页内容,潜在影响范围就从“回答错了”变成了“系统真的被改了”。

所以:

Agent 的能力上限可以很高,但默认权限不应该等于能力上限。


国内平台其实已经在做“限制”,只是这件事经常被忽略

阿里云百炼的官方文档里有一个挺有意思的细节:在其智能体应用中,一个 Agent 可以添加多个 MCP 服务,但文档当前写明最多同时添加 5 个 MCP 服务

在百炼智能体中添加 MCP 服务

图:阿里云百炼官方文档中的 MCP 服务配置界面。

这当然不是说“五个”是什么 AI Agent 的理论最佳数字——一个 MCP Server 本身就可能暴露很多工具,不同平台架构也完全不同。

但这个产品设计至少提醒了我们:“无限接入”并不一定是好的默认体验。

百炼的 Managed Agents 文档还允许开发者挂载 MCP 服务后,按需关闭其中的单个工具。

这其实比“能不能接更多 MCP”更重要。

因为工程实践真正需要的是:

大能力池 + 小激活集。

例如一个校园 Agent 平台可能拥有:

全局能力池:
  教务系统
  学工系统
  知识库
  日历
  消息通知
  工单
  文件系统
  数据分析
  搜索
  审批
  ...

但当学生问:

“我明天下午有什么课?”

这一次任务真正需要暴露给模型的可能只有:

get_student_identity
query_timetable
get_calendar_date

它根本不应该同时看到:

send_school_notice
delete_knowledge_base
modify_student_status
export_all_students
execute_admin_sql

不仅没必要,而且危险。


一个更合理的 Agent 工具架构应该是什么样?

如果现在让我设计一个拥有大量 MCP、插件和内部 API 的 Agent,我不会把所有工具直接注册到模型上下文。

我会把整个工具系统至少拆成六层:

┌──────────────────────────────┐
│ 1. Tool Registry            │
│ 所有可用工具,数量可以很多      │
└──────────────┬───────────────┘
               ↓
┌──────────────────────────────┐
│ 2. Tool Retrieval           │
│ 根据任务、身份、场景检索候选工具 │
└──────────────┬───────────────┘
               ↓
┌──────────────────────────────┐
│ 3. Active Tool Set          │
│ 当前只给模型 3~10 个相关工具    │
└──────────────┬───────────────┘
               ↓
┌──────────────────────────────┐
│ 4. Authorization            │
│ 检查用户/Agent 是否有执行权限   │
└──────────────┬───────────────┘
               ↓
┌──────────────────────────────┐
│ 5. Policy / Confirmation    │
│ 高风险操作二次确认、参数约束     │
└──────────────┬───────────────┘
               ↓
┌──────────────────────────────┐
│ 6. Execution + Audit        │
│ 沙箱执行、记录调用、结果与责任链  │
└──────────────────────────────┘

这里面最重要的变化是:

“模型能发现一个工具”不再自动意味着“模型有权执行这个工具”。

工具检索解决的是准确率和上下文效率。

权限系统解决的是风险边界。

Policy Gate 解决的是“即使有权限,这一次到底应不应该执行”。

审计解决的是出问题以后“谁、为什么、通过什么工具、改了什么”。

这几层不能互相替代。


工具数量不是 KPI

Agent 产品很容易陷入一种和传统软件类似的功能竞赛:

支持 20 个插件。

支持 100 个 MCP。

支持 1000 个工具。

接入全套办公软件。

这些数字适合写在发布会上,却不直接等于 Agent 更好用。

真正应该测的是:

指标 真正要回答的问题
Tool Recall 正确工具有没有被检索出来?
Tool Precision 给模型看的工具里有多少真正相关?
Selection Accuracy 正确工具出现以后,模型能不能选对?
Parameter Accuracy 参数能不能填对?
Task Success Rate 最终任务有没有完成?
Token Overhead 为工具定义和结果付出了多少上下文?
Latency 为选工具多花了多少时间?
Unauthorized Call Rate 有没有尝试调用不该调用的能力?
Confirmation Rate 高风险动作是否按策略进入确认?
Audit Completeness 事后能不能完整解释发生了什么?

如果“工具数量”从 20 增加到 200,但任务成功率没涨、token 翻倍、延迟增加、误调用变多,那么这不是 Agent 升级。

只是工具列表变长了。


最后

工具当然非常重要。

没有工具的 LLM 很多时候只能“告诉你怎么做”;有工具以后,它才能真正查询数据库、修改文件、提交代码、发送消息和操作现实系统。

但这也意味着我们不能再用“插件越多越强”的思路设计 Agent。

传统软件里,功能菜单多一点,最多让 UI 更乱。

Agent 里,工具多一点,会同时影响:

  • 上下文;
  • 推理;
  • 工具选择;
  • 参数生成;
  • 成本;
  • 延迟;
  • 权限;
  • 攻击面;
  • 最终执行结果。

所以我越来越认同一种设计原则:

一个强大的 Agent,不是任何时候都能使用所有能力,而是拥有一个很大的能力池,却能在每一次任务中只获得恰好够用的那一小部分能力。

真正的智能,不是面对一百把工具然后勉强挑中正确的一把。

而是系统在正确的时间,只把那几把真正需要的工具放到它面前。


参考资料

  1. Anthropic, Introducing advanced tool use on the Claude Developer Platform
  2. Anthropic, Code execution with MCP: Building more efficient AI agents
  3. Repantis et al., How Many Tools Should an LLM Agent See? A Chance-Corrected Answer
  4. Anand & Chattaraj, Diagnosing Tool-Selection Reasoning in LLM Agents with Canary Tools
  5. Model Context Protocol, Security Best Practices
  6. 阿里云百炼, 模型上下文协议(MCP)
  7. 阿里云百炼, 官方 MCP 服务
  8. 阿里云百炼, Agent MCP

注:文中论文数据来自公开预印本,Anthropic 的部分数字来自其内部评测;它们适合说明趋势和工程问题,不应被理解为所有模型、所有工具集合下都能复现的固定结论。