我用最小版本代码拆解mcp!!!
你以为 MCP 很高级,结果本质居然这么朴素?
最近不少人在聊 MCP。
但我发现,很多人第一次接触它的时候,脑子里其实都是懵的:
MCP 到底是什么?
它和普通函数、接口、工具调用有什么区别?
是不是所有能力都要写成 MCP?
我这两天专门把基础版代码跑了一遍,终于把这件事想明白了。
今天就用 0基础也能看懂 的方式,给你讲透。
一切先从“函数”开始
我们平时写代码,最熟悉的就是函数。
比如:
def add(a, b):
return a + b
你自己在项目里调用:
result = add(1, 2)
这就叫 项目内部调用。
函数写在代码里,自己知道怎么传参、怎么返回,完全没问题。
那什么叫“接口”?
如果这个能力不只是你自己代码里用,
还想让别的程序也能调用,通常就会把它做成接口。
也就是说,本来是:
result = add(1, 2)
后来变成:
POST /add
{
"a": 1,
"b": 2
}
本质没变,
只是从“函数内部调用”,变成了“对外开放调用”。
所以先记住一句很重要的话:
函数是能力,接口是把能力开放出去的一种方式。
那 MCP 又是干嘛的?
重点来了。
以前程序调函数,是人自己写死的。
但现在大模型来了,情况不一样了。
比如用户说:
- 帮我找一家西安便宜点的酒店
- 帮我取消明天的预约
- 帮我推荐一个适合两个人吃饭的川菜馆
这时候系统要先理解用户想干什么,
然后再决定调用哪个工具。
问题来了:
模型怎么知道系统里有哪些工具?
它怎么知道参数怎么传?
它怎么知道哪个参数必填、哪个参数可选?
这就是 MCP 最核心的价值。
为什么很多人第一反应会说:
“这不就是把函数封装成接口吗?”
因为表面看,真的很像。
普通函数:
def classify_intent(user_text: str):
...
MCP 写法:
@mcp.tool()
def classify_intent_tool(user_text: str):
...
看起来只是多了一个装饰器。
所以很多人就会觉得:
“没啥特别啊,不就是套了一层壳吗?”
但真正的区别,不在“能不能调”,
而在于:
MCP 不只是把函数暴露出去,还把这个函数的说明书一起暴露出去了。
什么叫“说明书一起暴露”?
比如一个 MCP tool,别人连上之后,不只是能看到名字,
还可以看到:
- 它叫啥
- 它是干什么的
- 它有哪些参数
- 哪些参数必填
- 哪些参数可选
- 默认值是什么
比如意图识别工具,别人可能拿到这样一份参数说明:
{
"properties": {
"user_text": {"type": "string"},
"scene": {"type": "string", "default": "general"},
"model": {"type": "string", "default": "qwen-plus"}
},
"required": ["user_text"],
"type": "object"
}
别被这段 JSON 吓到。
你把它翻译成人话就是:
- 要传一个对象
user_text是字符串,而且必填scene是字符串,可选,默认是generalmodel是字符串,可选,默认是qwen-plus
也就是说:
别人不需要提前翻你代码,也不需要你单独发文档,现场就知道参数怎么传。
这就是 MCP 和“普通函数 / 普通接口”最容易拉开差距的地方。
那 name、description、inputSchema 又是哪里来的?
这个点真的特别多人第一次会懵。
你会发现打印工具列表的时候,会出来这些:
namedescriptioninputSchema
然后心里就会想:
“我也没手写这些字段啊,怎么自己冒出来了?”
其实一般是框架帮你整理的:
name
通常来自函数名
description
通常来自 docstring,也就是函数下面那段三引号注释
inputSchema
通常来自函数参数、类型标注、默认值
比如你写:
def classify_intent_tool(
user_text: str,
scene: str = "general",
model: str = "qwen-plus"
) -> dict:
"""
基于大模型识别用户意图
"""
框架就会自动推出来:
- 工具名是什么
- 描述是什么
- 参数结构是什么
所以可以这么理解:
普通函数只有能力本身,MCP tool 除了能力本身,还有标准化说明书。
那是不是所有函数都应该写成 MCP?
答案是:
不是。
而且这一点我觉得特别重要。
很多人一学 MCP,最容易犯的错误就是:
什么都想 MCP 化。
但现实里,如果一个能力只是:
- 嵌在当前项目里
- 只给自己代码内部使用
- 不会被别的项目复用
- 也不需要外部客户端发现和调用
那写成 MCP 很多时候 没啥意义。
比如这些:
- 文本清洗
- prompt 拼接
- 查询语句组装
- 结果格式化
- 项目内部路由逻辑
- 中间状态处理
这些大多数都属于 项目私有逻辑。
直接写普通函数最实在。
因为你本来只需要:
result = classify_intent(text)
如果硬要搞成 MCP,就会变成:
await session.call_tool("classify_intent_tool", {"user_text": text})
业务没变,
但多了:
- 一层 server
- 一层通信
- 一层调试
- 一层部署
这时候收益其实很小。
那什么能力才适合做成 MCP?
我现在自己的判断标准很简单:
这个能力,未来除了当前项目,还有没有别的系统也会想调用它?
如果答案是:
没有
那就老老实实写普通函数。
有,而且边界比较稳定
那就值得考虑抽成 MCP。
比如这些就比较适合:
- 通用意图识别
- 通用槽位提取
- 企业知识库检索
- 酒店查询
- 预约下单
- GitHub / Slack / 数据库等通用能力连接
因为这些能力一旦抽出来,
以后别的项目也能直接接。
所以 MCP 到底该怎么理解?
我现在最认可的一句话是:
MCP 不是“高级版函数”,而是“值得独立暴露和复用的能力标准”。
它不是为了把代码写复杂,
而是为了让一个能力能被 AI 系统:
- 标准化发现
- 标准化理解
- 标准化调用
给 0 基础同学一个最实用的建议
如果你刚开始学,不要一上来就把所有东西都拆成 MCP。
正确顺序应该是:
第一步
先用普通函数把项目跑通
第二步
等你发现某个能力真的开始被多个系统复用,再考虑抽成 MCP
这样你才能真正分清楚:
- 什么是项目私有逻辑
- 什么是通用能力
- 什么值得服务化
- 什么只是过度设计
最后一句话总结
如果只是自己项目内部用,普通函数就够了。
如果这个能力未来要复用、要独立暴露、要给别的系统接入,MCP 才真正有价值。
上面的内容,都是我基于 基础版 MCP 代码 跑通之后总结出来的。
如果你想要我这套 基础版 MCP 对比代码,包括普通函数版和 MCP 版,直接在评论区留一句“要代码”。
我会直接私信发你,并顺带给你讲解说明。
#AI开发 #MCP #大模型 #Agent #工具调用 #AI工程化 #编程入门 #技术笔记 #RAG #AI学习
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)