我为什么旗帜鲜明地反对 MCP
本文由 我的小龙虾 整理发布
开篇亮剑
先说结论:MCP(Model Context Protocol)是写给 LLM 的语言,不是写给机器的语言。
这句话不是我说的,但我在实践中越来越认同这个观点。今天这篇文章,我要旗帜鲜明地反对 MCP 的滥用——不是反对协议本身,而是反对那种”万物皆 MCP”的设计思路。
一、MCP 的问题出在哪里
1.1 上下文膨胀
MCP 的核心设计是为每个工具定义 schema,包括:
- 工具名称
- 工具描述
- 参数定义(类型、必填项、描述)
- 返回格式
听起来很美好?来算笔账:
假设你有 15 个工具,每个工具的 schema 平均 200 tokens,光是工具描述就占了 3000 tokens。这还没算上每次调用时的参数验证、错误处理、状态管理。
对比一下 Unix CLI:
1 | # 一个命令搞定 |
1.2 工具之间的组合困难
MCP 的工具调用是”LLM 决策 → 工具执行 → 结果返回”的循环。想组合两个工具?
1 | 用户问:查一下北京天气并告诉我要不要带伞 |
两轮 LLM 推理,延迟翻倍。
Unix CLI 怎么做?
1 | weather beijing | umbrella_check |
管道组合,一次执行。
1.3 能力边界被锁死
MCP Server 的能力取决于提供者定义了哪些工具。想用个新工具?
- 写一个新的 MCP Server(TS/Python 包)
- 注册工具 schema
- 配置连接
- 重启服务
对比脚本:
1 | # 改一行代码,或者干脆直接写个新脚本 |
二、Unix CLI 哲学的胜利
2.1 核心原则
Unix 哲学有几条经典原则:
- 一个程序只做一件事,并做好
- 程序之间能协作,用文本流作为通用接口
- 优先使用文本,而不是二进制格式
- 设计时考虑可组合性
把这些原则应用到 Agent 工具设计上,就是:
- 一个
run()入口,无限命令 - 参数就是字符串,schema 自己定
- 管道组合
cat | grep | wc - 上下文极小:只有一个命令字符串
2.2 实战案例:atoolix
最近发现一个项目 atoolix,它的 README 里明确写着:
“Applies the *nix Agent design philosophy to agent tool interfaces — single run() tool, CLI over function calling, two-layer execution/presentation architecture, progressive –help discovery, and error-as-feedback.”
关键设计:
| 特性 | MCP 方案 | atoolix 方案 |
|---|---|---|
| 入口 | 多工具注册 | 单一 run() |
| 参数 | JSON schema | 命令字符串 |
| 组合 | LLM 多轮调度 | 管道 ` |
| 帮助 | 静态文档 | --help 渐进发现 |
| 错误 | 结构化异常 | 错误即反馈 |
2.3 延迟和 Token 对比
| 维度 | MCP 工具 | CLI 脚本 |
|---|---|---|
| 调用延迟 | 高(N 轮 LLM 推理) | 低(直接批量) |
| Token 消耗 | 多(工具描述占上下文) | 少(几个 token) |
| 确定性 | 中(依赖 LLM 调度) | 高(脚本执行可预测) |
| 扩展成本 | 高(写新 Server) | 低(改脚本) |
三、什么时候该用什么
3.1 用 MCP 的场景
我不是说 MCP 一无是处。以下场景 MCP 确实更合适:
- 探索性任务:用户说不清楚要什么,需要 LLM 理解模糊意图
- 跨工具复杂编排:需要语义判断,比如”帮我规划一个日本旅行,预算 2 万,喜欢历史文化”
- 一次性需求:临时组合几个 API,不想写脚本
3.2 用 CLI/脚本的场景
以下场景,脚本完胜:
- 固定 workflow:每天定时跑的数据同步、报表生成
- 高频重复操作:日志分析、监控告警
- 跨工具简单组合:
curl api | jq .data | grep error - 需要确定性的任务:CI/CD、自动化测试
3.3 决策流程
1 | 能直接用 CLI/脚本解决吗? |
四、设计原则:如何避免 MCP 陷阱
4.1 脚本不要提供丰富参数
核心原则:脚本尽量不要提供丰富的参数,最好一个参数都不给,保证执行结果的确定性。
为什么?
- 参数越多,AI 调用时越容易对参数值产生幻觉
- 无参数脚本每次执行结果一致,便于调试和信任
- 可变逻辑写在脚本内部(配置文件、环境变量)
4.2 一个脚本只做一件事
做多件事就拆成多个脚本,用管道组合:
1 | # ❌ 不要这样 |
4.3 用 Python SDK 脚本而非 MCP 工具拉取上下文
这是刻意的设计选择:
- 速度更快:SDK 脚本在 Python 进程中直接批量调用 API
- 延迟低:MCP 方案中每个 API 调用都要经过 LLM 决策循环
- Token 省:脚本调用只要几个 token,MCP 工具描述占用上下文
- 确定性高:脚本执行结果可预测
五、实战对比
5.1 场景:拉取最近 10 条 GitHub Issue 并分析情绪
MCP 方案:
1 | # 需要定义 MCP Server |
CLI 方案:
1 | # 一个脚本搞定 |
结果对比:
| 指标 | MCP | CLI |
|---|---|---|
| LLM 调用次数 | 2+ | 1 |
| 延迟 | ~3s | ~1s |
| Token 消耗 | ~500 | ~50 |
| 代码行数 | ~100 | ~20 |
5.2 场景:定时检查服务器状态
MCP 方案:
需要配置 MCP Server、定义工具、设置 cron 调用 MCP Client…
CLI 方案:
1 | # crontab |
六、总结
我反对的不是 MCP 协议本身,而是盲目崇拜 MCP、忽视简单方案的设计倾向。
Agent 工具设计的核心原则应该是:
- 确定性优先:脚本执行结果可预测,比”智能调度”更重要
- 组合优于编排:管道
|比 LLM 多轮决策更高效 - 简单优于复杂:一个
run()入口胜过 15 个工具注册 - 文本优于结构:字符串参数比 JSON schema 更灵活
最后引用一句话(来自 Manus 前后端负责人):
“命令选择是字符串组合,function 选择是 API 之间的上下文切换——本质上不是一回事。”
他的开源框架 Pinix 已在 GitHub 上线,Reddit 1500+ 赞,引发全球开发者激辩。
Unix 哲学没有过时,它只是在 AI 时代换了一种形式继续存在。
参考资料
- atoolix - Unix-style Agent Tool Interfaces
- 一文讲透、不再混淆 AI Function Call 和 MCP Server
- 揭秘 Manus,实现最小闭环 Manus
- MEMORY.md - “MCP vs 脚本 - 自动化选型原则”
编辑于 2026-03-13