最近 MCP(Model Context Protocol)面试题越来越高频。前阵子我一个学员去面美团后端岗位,简历里写了"精通 MCP 协议",面试官直接顺着这条线往下挖了四十分钟。
学员回忆说前面聊框架聊项目都挺顺,面试官突然调转话头:"你 MCP 用过吧?说说模型是怎么调用工具的。"
学员心想这还不简单?上来就答:"模型发一个 JSON-RPC 请求,服务端返回工具列表,模型选一个执行,再把结果返回给模型。"
面试官点点头,没表态,接着问了一句:"那你说说,模型同时能选好几个工具的时候,它是串行调还是并行调?是它自己决定还是开发者能干预?"
学员愣了一下。他说他用人家的 SDK 写了好几个 MCP Server,但从来没有站在"模型视角"想过这个问题——工具怎么调、什么时候调、调完怎么组合,一直是 SDK 封装好的黑盒,他从来没去翻过协议层的行为。
面试官看他说不出来,往椅背上一靠:
"MCP 最核心的,不是传输格式,不是工具定义,是让模型自己管理调用策略。你把它当 RPC 用,说明还停留在"工具是函数"的思维里。MCP 的突破口是——工具变成了模型的决策空间。"
这一句话,把学员之前对 MCP 的所有理解,全推翻了。
他回来找我复盘的时候说:我背过 MCP 的协议结构、资源定义、传输层封装,却从来没想过协议层之上那个"模型怎么用工具"的机制,才是面试官真正想聊的东西。今天我就把这条追问链从头拆一遍。
一、第一个误区:MCP 不是"给 AI 调 API 的框架"
先把最根上的误解掰过来。
很多人接触 MCP 是从写 MCP Server 开始的——用 Python 或 TypeScript 的 SDK,几行代码暴露一个 get_weather 工具,然后在 Claude Desktop 里配一下,就能用自然语言查天气了。这个过程太丝滑了,以至于大部分人得出结论:MCP = 一种声明 API 的方式,让 AI 能调用它。
这个理解,只对了一半。
MCP 全称是 Model Context Protocol。注意,是 Model Context(模型上下文),不是 API Protocol。它的设计目标从来不是"给 API 加一层 AI 友好外壳",而是让模型能把工具调用当作推理的一部分——不是"先推理再调工",而是在推理中调工具,调完工具继续推理。
这两者有什么区别?区别巨大。看两张图就明白了。
❌ 你以为是这样的:
用户提问 → 模型理解 → 选工具 → 调 API → 拿结果 → 组织回答
✅ 实际是这样的:
用户提问 → 模型规划 → 调工具 A → 分析结果 → 决定调工具 B → 结合 A + B 的结果 → 再调工具 C 确认 → 综合回答
每一步之间,模型都在推理,都在决策,甚至可能推翻上一步的结论重新来过。
也就是说:工具调用不是模型回答的一个前置步骤,而是推理过程中随时可以插入的一个"暂停—获取外部信息—继续推理"的循环。MCP 整个协议的设计,都是为这个循环服务的。
这也是为什么 Anthropic 官方文档里有一句特别低调但很关键的话——"MCP 的设计优先考虑了模型行为,而不是 API 开发者体验"。不是为了让你写 Server 方便,而是为了让模型"用好"这个 Server。
二、模型面对一堆工具,是怎么决定调哪个的
这是面试官的第二问,也是真正拉开理解层次的地方。
面试官的原话是:"你写一个 MCP Server 定义了 8 个工具,模型面对这 8 个工具,它是怎么选出该调哪个的?靠什么选?如果在它看来两个工具都合适,它怎么抉择?"
很多人以为,模型就是简单地把用户请求和每个工具的 description 做匹配——哪个描述最接近就调哪个。就像 Skill 的 description 触发机制一样。
这个理解在简单场景下没错,但再深一层就经不起推敲了。因为 MCP Server 里 tools 列表是平铺的,模型看到的是 8 个并列的选项。用户说"帮我查一下北京的天气然后发给我",模型面临的选择是:
- 调
get_weather? - 调
send_message? - 两个都调——先调
get_weather拿到结果,再调send_message发出去? - 如果
get_weather返回了"北京多云 25°C",send_message是只发温度还是连风速湿度一起发?
模型每一次调用的决策,其实包含了三层判断:
| 决策层级 | 模型在做什么 | 对应工具能力 |
|---|---|---|
| 策略层 | 要不要调用工具?还是可以直接回答? | 是否需要外部信息 |
| 选择层 | 调哪个工具?调几个?顺序怎么排? | 工具定义的清晰度 |
| 执行层 | 传什么参数?结果怎么用? | 工具参数的精确性 |
就说第一层"要不要调"——很多开发者从来没想过,模型其实可以选择不调用任何工具。如果用户问"今天星期几",模型本身就有时序知识,它不会去调工具。只有当前上下文信息不足以回答时,它才会发起调用。而你是不是把该闭着眼睛能答的问题也包装成了工具,就是工具设计的第一道分水岭。
说回到面试官的问题。模型做这三层判断的依据是什么?主要靠两条:
- 工具本身的 name + description——模型靠语义匹配来判断"这个工具是干什么的";
- 参数 schema 中的 required 字段和 description——模型靠参数定义来理解"这个工具需要什么输入、输出什么"。这也是为什么 JSON Schema 写得越准确,模型调用越稳定——不是写给开发者的,是写给模型的。
这里有一个最常被忽略的细节:工具名字的权重远比你想象的高。实验数据显示,模型在有多候选工具时,工具 name 的匹配优先级高于 description。因为 name 的语义密度最高——一个叫 get_weather 的工具,模型扫一眼就知道它干嘛的;如果 description 写得很详细但 name 叫 tool_001,模型得读完所有 description 才知道该不该用它。所以 MCP Server 里给工具起名,是一门被低估的学问。
再往下,面试官问了一个更刁钻的:"那模型同时调两个工具的时候,是串行的并行的?"
答案取决于宿主端(Host)的实现。MCP 协议本身既不规定串行也不规定并行,它只定义请求和响应的格式。Claude Desktop 的实现是串行的——模型发出一个工具调用,等待结果返回,再决定下一步。而部分 Agent 框架(如 AutoGPT 的一些实现)允许并行调度——模型一次发出多个调用请求,宿主同时执行,结果回来后统一喂给模型。
这个区别非常重要,因为它直接决定了你的工具设计策略。如果是串行宿主,你的工具应该设计成原子化、粒度小的,让模型能灵活组合;如果是并行宿主,你可以设计批量操作型的工具,一次拿到多个信息减少轮次。很多人没有意识到——同一套 MCP Server 在不同宿主上表现不一样,不是因为协议变了,而是宿主的调度策略不一样。
三、MCP 协议里藏着几个关键机制
面试官第三问:"MCP 协议的几个核心机制,你给我讲讲——从模型拿到工具列表,到它执行完调用,协议层每一步在做什么?"
这道题答好了,基本功就立住了。MCP 工具调用的完整生命周期,分六步:
- 初始化(Initialize):客户端和服务端握手,交换协议版本和能力声明(Server Capabilities)——比如服务端声明自己支持 tools、resources、prompts 中的哪几项;
- 工具列表获取(Tools/List):客户端向服务端请求工具列表,拿到一份 JSON-RPC 响应,里面是 tools 数组,每个工具都有 name、description、inputSchema;
- 模型选择(Model Decision):这一步不是协议层的事,是模型层的事。模型基于当前上下文和工具列表,决定调不调、调哪个、传什么参数——这就是上一步讲的策略层 + 选择层;
- 工具调用(Tools/Call):宿主端向服务端发送 Call 请求,带上 tool name 和参数。服务端执行后返回 content(可以是文本、图片、资源引用等);
- 结果注入(Result Injection):响应结果被注入到模型的上下文中,模型"看到"了工具返回的数据;
- 继续推理(Continue Reasoning):模型拿到结果后继续推理——可能就此回答,也可能决定再调另一个工具。整个循环从第 3 步重新开始。
这里面有一个极易被忽视的点:第 3 步和第 4 步之间,MCP 协议没有规定"确认"环节。也就是说,模型决定调一个工具后,宿主端会直接发 Call 请求。没有"二次确认"。这不只是理论问题——我见过有人写了一个 delete_database 工具,被模型误触发,直接在生产环境删了一张表。所以 MCP 官方文档白纸黑字建议:写破坏性操作的工具,要在 Server 侧做二次确认,或者只暴露只读工具,修改操作走另外的安全通道。这不是开发者"多此一举",是协议设计已经把这个责任推给了你——协议不拦,你自己拦。
四、Resources 和 Prompts 被严重低估了
很多人觉得 MCP 就是"给 AI 调工具用的",所以只关注 Tools。面试官第四问就在这里等着:
"你说了半天 Tools,MCP 还有 Resources 和 Prompts,它们各自什么时候用?资源难道不能用工具返回?提示难道不能写在 system prompt 里?"
这个问题能筛掉 90% 的人。因为大部分人确实只用 Tools。
先看 Resources。它和 Tools 的核心区别是:Resource 是"推送"的,Tool 是"拉取"的。
什么意思?Resource 定义了"哪些数据可以提供给模型",但不是模型主动调用的——宿主端可以在启动时就把 Resources 列表和内容注入到上下文中。也就是说,如果有一段上下文是需要让模型"一开始就知道"的(比如公司内部的编码规范、项目文档摘要),你应该用 Resources,而不是让模型去调一个工具来"问"。
一个典型的例子:一个 MCP Server 暴露了公司的 API 风格指南。如果用 Tool,模型得记得先调工具才能知道规范——它不记得呢?它就按自己的默认风格写了。如果用 Resource,宿主在初始化时就把规范文档注入到上下文里,模型一上来就知道要遵守什么风格。一个主动注入,一个按需拉取,完全不同的模式。
再看 Prompts。MCP 里的 Prompts 不是"写好的一段话",而是可参数化的模板——有点像 VS Code 的 Snippet,但专为模型交互设计。比如你可以定义一个 code_review Prompt,参数是 {file_path},模板里写清楚"请以 security-first 的视角审查以下文件,重点关注注入风险……"。开发者或者宿主端可以基于这些 Prompt 模板快速发起标准化的对话。
三者的关系,其实也很清晰:Resources 是模型需要知道的内容;Tools 是模型能够做的事;Prompts 是和模型对话的模版。
| MCP 能力 | 使用场景 | 谁来触发 | 例子 |
|---|---|---|---|
| Resources | 模型需要预先知道的上下文 | 宿主注入 / 模型主动读 | API 文档、代码库结构 |
| Tools | 模型需要执行的动态操作 | 模型按需调用 | 查天气、发消息、查数据库 |
| Prompts | 标准化交互模板 | 开发者发起 / 用户选择 | PR 审查、Bug 分类模板 |
面试官的原话是:"你把三个东西搞混了,说明你对 MCP 的理解是偏的——不是"用 Tools 搞定一切",而是在协议层面就有不同的机制来服务不同场景。"
面试怎么答 MCP 的工具调用机制
如果面试官问到这条线,建议按下面这个节奏答:
第一步,先纠正"MCP = AI API 网关"这个前提(20 秒)。
开口就说:"MCP 最核心的设计不是传输层,是让模型把工具调用嵌入到推理循环中。模型不是在回答前调一下工具,而是在推理过程中随时可以插入'暂停→获取信息→继续推理'的循环。"这句话摆明你不是拿它当 RPC 用的。
第二步,讲清工具调用的三层决策(1 分钟)。
模型决策分策略层(要不要调)、选择层(调哪个)、执行层(怎么调)。强调工具 name 的优先级高于 description,参数 Schema 是写给模型看的不是写给开发者看的。能提到"串行宿主和并行宿主的设计差异"是加分项。
第三步,把整个生命周期串一遍(30 秒)。
Initialize → List → 模型 Decision → Call → 结果注入 → 继续推理。顺便提一句"协议层不做二次确认,破坏性操作的安全责任在 Server 端"。
第四步,讲清 Tools / Resources / Prompts 三者的区别(30 秒)。
"Resources 是模型'需要知道'的,Tools 是模型'能够做'的,Prompts 是对话模板。Resources 主动注入,Tools 按需调用。用这个区分来设计 Server,比全堆 Tools 里要合理得多。"
这四条答完,面试官基本就确认你是真做过 MCP Server 并且从模型视角去想过设计了——不是只跟着教程跑了个 Demo。
写在最后
回头看美团面试官的四连问,没有一个超纲问题。它的推进逻辑特别清晰:
先用"MCP 是什么"探你是不是停留在 API 思维→
再用"模型怎么选工具"看你想没想过模型视角→
再用"协议生命周期"看你的基本功扎不扎实→
最后用"Resources 和 Prompts"看你有没有全面理解协议的能力边界。
每一步都是上一问的自然延伸。只要真正写过几个不同场景的 MCP Server、被模型误调过工具、debug 过调用链,这些问题是一口气能答完的。
很多人学 MCP 的时候,是从"怎么写一个 Server"开始的。但面试官不关心你会不会写 Server——他关心的是:你知不知道模型是怎么"用"这个 Server 的。
开始写 Server 之前,先花十分钟理解模型视角的调用逻辑——这笔投资回报率比多写十个 Server 都高。