你以为 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 是字符串,可选,默认是 general
  • model 是字符串,可选,默认是 qwen-plus

也就是说:

别人不需要提前翻你代码,也不需要你单独发文档,现场就知道参数怎么传。

这就是 MCP 和“普通函数 / 普通接口”最容易拉开差距的地方。


namedescriptioninputSchema 又是哪里来的?

这个点真的特别多人第一次会懵。

你会发现打印工具列表的时候,会出来这些:

  • name
  • description
  • inputSchema

然后心里就会想:

“我也没手写这些字段啊,怎么自己冒出来了?”

其实一般是框架帮你整理的:

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学习

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐