在上一篇原理篇里,我把 调用流程拆清楚了,但我自己回看时发现一个问题:
我解释了"流程",但没有解释"为什么它能这样工作"。
更具体一点,就是这几个关键疑问:
- 为什么 Tool 一注册,LLM 就"知道可以用"?
- 为什么模型会主动选择调用工具?
- 为什么它能输出严格的 JSON 参数?
- 这些行为到底是"训练出来的",还是"系统控制的"?
这一篇我只做一件事:
👉 把 MCP 背后真正的"智能来源"讲清楚
一、先说结论(避免理解跑偏)
如果我只用三句话总结:
- 模型并不知道"Tool 的实现",它只看到"Tool 的描述"
- 模型会调用工具,是因为它被训练成"在合适时机输出结构化调用"
- JSON 不是模型"天生会",而是被约束 + 训练 + 推理共同作用的结果
👉 换句话说:
MCP 本身没有智能,所有"像人一样会用工具"的能力,都来自 LLM
二、为什么 Tool 一注册,模型就"知道可以用"?
这是最容易被误解的一点。
❌ 错误理解
- Tool 注册到系统 → 模型自动感知 ❌
✅ 真实情况
Tool 会被"转换成文本",放进模型上下文
具体发生了什么?
当 MCP Client 获取到 Tool 列表后,会做一件关键事情:
👉 把 Tool Schema 注入到 Prompt(提示词)中
类似这样(简化版):
text
你可以使用以下工具:
工具1:
名称:get_weather
描述:根据城市查询天气
参数:
{
"city": "string"
}
关键理解
模型不是"看到代码",而是"读到说明书"
这和它平时处理自然语言没有区别。
本质是什么?
这一步本质是:
把"工具能力"转化为"语言信息"
而 LLM 最擅长的就是处理语言。
三、模型为什么会"主动调用工具"?
这是第二个核心问题。
1. 本质不是"调用",而是"生成"
模型并没有"执行调用"这个动作,它只是:
生成了一段符合格式的文本
例如:
json
{
"tool": "get_weather",
"arguments": {
"city": "北京"
}
}
2. 那它为什么会生成这个?
答案分三层:
第一层:训练(最根本)
现代 LLM 在训练或微调阶段,已经见过大量这样的数据:
text
用户:北京天气怎么样?
模型:
{
"tool": "get_weather",
"arguments": {
"city": "北京"
}
}
👉 也就是说:
"遇到某类问题 → 输出工具调用" 这个模式,是训练出来的
第二层:提示(Prompt)
系统会明确告诉模型:
text
如果问题可以通过工具解决,请调用工具,而不是直接回答
👉 这相当于"行为约束"。
第三层:推理(实时决策)
当我输入:
text
帮我查一下上海天气
模型会在内部做一个判断:
- 直接回答?
- 还是调用工具?
如果它发现:
有一个工具描述"完美匹配这个需求"
那它更可能输出工具调用。
一句话总结
模型不是"会用工具",而是"学会了在合适的时候生成工具调用格式"
四、为什么模型能输出"正确的 JSON 参数"?(重点)
这个问题比上一个更关键。
先说结论
JSON 的正确性 = 训练 + 约束 + 解码策略
1. 训练:模型学会结构
模型在训练中见过大量 JSON,例如:
json
{
"name": "xxx",
"age": 18
}
👉 所以它具备:
生成结构化文本的能力
2. Schema 约束(非常关键)
MCP 会提供参数结构:
json
{
"type": "object",
"properties": {
"city": {
"type": "string"
}
}
}
这意味着什么?
模型在生成时,其实是在"参考这个结构"。
👉 本质上是:
"按这个格式填空"
3. Prompt 强约束
系统通常会加类似提示:
text
请严格按照 JSON 格式输出,不要包含多余内容
4. 解码控制(很多人不知道这一层)
在实际系统中,往往会有:
- JSON mode
- function calling mode
- schema-based decoding
👉 这些机制会:
限制模型只能生成符合结构的 token
举个更底层的理解
模型本来可以输出:
text
北京天气很好
但在约束下,它"只能"输出:
json
{
"city": "北京"
}
总结这一段
JSON 不是模型"猜对的",而是被"限制出来的"
五、一次调用的真实"信息流"
现在我把整个过程用"信息流"再还原一遍:
Step 1:系统构造 Prompt
text
用户输入 + 工具列表(文本化) + 调用规则
Step 2:LLM 推理
输出:
json
{
"tool": "get_weather",
"arguments": {
"city": "北京"
}
}
Step 3:Client 解析
不是"理解",而是:
解析 JSON
Step 4:Server 执行
调用真实函数:
python
get_weather("北京")
Step 5:结果回注
text
工具返回:北京今天25度
Step 6:LLM 再次生成
最终回答:
text
北京今天气温25度,天气晴朗
六、最容易被忽略的本质
我把这一整套机制压缩成一句话:
LLM 从头到尾只是在"读文本 + 生成文本"
它没有:
- 调用函数的能力
- 访问网络的能力
- 操作系统的能力
👉 所有这些能力,都是:
通过"文本接口 + 外部系统"间接实现的
七、把认知再拉高一层
如果我站在系统设计角度看:
MCP 做的事情,本质是:
把"函数调用"翻译成"语言问题"
LLM 做的事情,本质是:
把"语言问题"翻译成"结构化调用"
Tool 做的事情,本质是:
执行真实世界操作
八、总结
这一篇我只想让我自己彻底搞清楚三件事:
1. Tool 为什么"能被用"
因为:
它被写进了 Prompt,而不是被模型"感知"
2. 模型为什么会调用
因为:
它被训练成"在合适场景输出调用格式"
3. JSON 为什么正确
因为:
训练 + Schema + 约束 + 解码控制共同作用
👉 一句话总结:
MCP 不是让模型"获得能力",而是让模型"学会表达调用能力"
下一步,我要做的不是继续理解,而是:
👉 把这些能力变成我自己的工具系统(实战落地)