【大模型面试八股 2】Function Call、MCP、Skill的区别:用TaoToken统一Key实测三者在Agent链路中的分工
1. 面试官为什么总爱把 Function Call、MCP、Skill 放一起问如果你最近在准备大模型方向的面试大概率会遇到这样一道题说说 Function Call、MCP、Skill 的区别。很多人背了概念一到追问就露馅因为这三者根本不在一个抽象层级上硬放在一起比较就像问「螺丝刀、USB 接口、宜家说明书有什么区别」。先把定位说清楚。Function Call 是模型 API 层面的原子交互机制解决的是「模型怎么结构化地请求执行一个外部函数」。MCP 是协议层的连接标准解决的是「模型怎么标准化地发现、调用、获取外部系统的能力与上下文」。Skill 是框架或产品层的能力封装体解决的是「模型应该按什么流程把一件事做完」。三者是层层包裹的关系不是三选一的替代品。我试过在一个最小 Agent 链路里把三者串起来跑才发现面试时最容易答错的点在于触发时机。Function Call 在单轮推理里被触发模型输出结构化参数宿主执行后回填结果。MCP 在会话初始化阶段就要完成握手和能力发现工具列表是提前注入上下文的。Skill 则是在意图匹配阶段被激活它可能内部同时用到 Function Call 和 MCP Tool。这篇文章不空谈概念我会用 TaoToken 作为统一 Key 和 API 通道搭一个能跑起来的最小 Agent把三者的调用日志逐项打印出来让你亲眼看到谁在什么时候被触发。面试时你只要能讲清这个链路追问基本都能接住。适合谁看正在准备大模型应用岗面试的同学、刚接触 Agent 开发想理清概念的工程师、以及需要给团队做技术选型的负责人。核心检索词就是 Function Call、MCP、Skill 的区别以及它们在 Agent 链路中的分工。2. 用 TaoToken 统一 Key 打通三种能力的接入底座在动手之前得先解决一个现实问题Function Call 的格式各家不一样。OpenAI 用 tools 数组Anthropic 用 tool_use 内容块Google 又是 function_declarations。如果你要在一个 Agent 里同时演示三种能力光是适配不同厂商的请求格式就够折腾半天。TaoToken 在这里的价值是提供一个统一的 API 通道。你只需要一个 Key、一个 Base URL就能用 OpenAI 兼容的请求格式去调用不同模型Function Call 的 JSON Schema 声明方式保持一致。这样我们搭最小 Agent 时可以把精力放在三者分工的演示上而不是浪费在格式适配上。接入前你需要准备三样东西我把它叫做三件套Base URL、API Key、Model ID。Base URL 填https://taotoken.net/apiAPI Key 在控制台的 API Keys 页面生成Model ID 根据你选的模型填比如gpt-4o或claude-3-5-sonnet这类。这三件套在后面的配置文件里会反复出现先记牢。注意API Key 属于敏感凭证不要硬编码进提交到 Git 的代码里建议用环境变量或本地配置文件管理。如果你用的是 Claude Code 这类编码工具配置方式略有不同需要写进 settings 文件。但本文的重点是演示三者分工所以我们用最通用的 HTTP 请求方式来搭链路这样你能看清每一步的原始报文。关于 Key 的获取和额度管理可以直接去控制台操作接入文档里有各语言的示例代码。我建议你先用模型对话页面手动发一条带 tools 的请求确认通道通了再往下写代码。这一步能帮你排除掉大部分环境问题。3. 可复制配置最小 Agent 链路的请求与工具声明这一节是全文的核心我会给出可以直接复制的配置片段。整个最小 Agent 包含三个部分一个 Function Call 工具查天气、一个 MCP Server 配置文件系统、一个 Skill 定义周报生成。它们会在同一个任务里被依次触发。先看 Function Call 的工具声明。这是标准的 OpenAI tools 格式通过 TaoToken 通道发送时不需要改动{ model: gpt-4o, messages: [ {role: user, content: 帮我查一下北京今天的天气然后根据结果生成一份简短周报} ], tools: [ { type: function, function: { name: query_weather, description: 查询指定城市指定日期的天气情况, parameters: { type: object, properties: { city: {type: string, description: 城市名称}, date: {type: string, description: 日期格式 YYYY-MM-DD} }, required: [city, date] } } } ], tool_choice: auto }这段请求发出去后模型不会直接回答天气而是返回一个 tool_calls 结构里面包含函数名和参数。这就是 Function Call 的触发时机模型判断需要外部信息输出结构化指令等你执行完回填。接下来是 MCP 的配置。MCP 走的是 JSON-RPC 2.0初始化阶段客户端要发 initialize 请求完成握手然后调 tools/list 做能力发现。下面是一个文件系统 MCP Server 的配置片段放在客户端的配置文件里{ mcpServers: { filesystem: { command: npx, args: [-y, modelcontextprotocol/server-filesystem, /Users/yourname/workspace], env: {} } } }这个配置告诉 Host启动一个文件系统 Server允许访问指定目录。握手完成后客户端会拿到这个 Server 暴露的工具列表比如 read_file、write_file、list_directory然后把这些定义注入到 LLM 上下文里。注意MCP 的工具发现是提前完成的不是等到用户提问才去拉。最后是 Skill 的定义。Skill 没有统一标准我用一个贴近实际的 SKILL.md 结构来演示放在~/.claude/skills/weekly-report/SKILL.md--- name: weekly-report description: 根据天气、日程、任务数据生成结构化周报适用于每周总结场景 --- # 周报生成 Skill ## 执行步骤 1. 调用 query_weather 获取本周天气概况 2. 通过 MCP filesystem 读取 workspace/tasks.md 3. 按「本周完成 / 遇到的问题 / 下周计划」三段式组织 4. 输出 Markdown 格式控制在 300 字以内 ## 输出约束 - 不使用 emoji - 每段不超过 5 行Skill 的三层加载机制在这里体现得很清楚启动时只注入 name 和 description用户提问后模型判断相关才读取完整 SKILL.md执行阶段才真正去调 Function Call 和 MCP Tool。这就是为什么 Skill 是「能力封装体」它把提示词、工具调用、执行逻辑打包成了一个可复用单元。把这三份配置放在一起你就有了一个完整的最小 Agent 链路。接下来我们跑一遍看日志。4. 验证请求逐项打印调用日志确认职责划分配置写好了现在跑一遍看结果。我用 curl 发第一条请求观察 Function Call 的返回curl https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d request.json返回的报文里choices[0].message 会包含 tool_calls 字段结构大致是这样{ role: assistant, tool_calls: [ { id: call_abc123, type: function, function: { name: query_weather, arguments: {\city\:\北京\,\date\:\2026-05-16\} } } ] }看到这个就说明 Function Call 被正确触发了。注意 arguments 是字符串形式的 JSON你需要解析后再执行真实逻辑。执行完把结果作为 role 为 tool 的消息追加到对话历史再发一次请求模型才会生成最终回复。MCP 的日志要看客户端侧。握手阶段你会看到 initialize 请求和响应能力发现阶段会看到 tools/list 的返回列表。我实测下来一个文件系统 Server 通常会暴露 5 到 8 个工具。这些工具的定义会被缓存后续 LLM 决定调用时客户端发的是 tools/call 消息Server 执行后返回 text 或 resource 内容。Skill 的日志最隐蔽因为它发生在提示词层面。你可以在系统 Prompt 里看到被注入的 Skill 列表只有 name 和 description。当模型决定激活某个 Skill它会通过一次 tool calling 去读取 SKILL.md 的完整内容。这一步在日志里表现为一次普通的工具调用但读的是本地文件。把三者的日志按时间顺序排一下分工就很清晰了MCP 在会话初始化时完成握手和工具发现Function Call 在每轮推理中按需触发Skill 在意图匹配后被激活并编排前两者。同一个任务里Skill 是总指挥Function Call 是执行单步动作的手MCP 是提供工具和上下文的插座。如果你想验证模型侧的响应可以用模型对话页面手动发请求对照看返回结构是否一致。接入文档里有完整的字段说明遇到不认识的字段可以查。5. 本篇常见错排查401、local proxy failed 与 OAuth 报错跑链路的过程中有几个报错几乎一定会遇到。我把它们和对应的排查思路列出来你对照着看。第一个是 401 Unauthorized。这个最常见原因通常是 API Key 没传对。检查三件套Base URL 是不是https://taotoken.net/apiKey 有没有多余空格请求头是不是Authorization: Bearer xxx格式。如果你用的是 Claude CodeKey 要写在 settings 的对应字段里不是环境变量。还有一种情况是 Key 过期或被禁用去控制台确认一下状态。第二个是 local proxy failed。这个报错通常出现在 MCP Server 启动阶段说明客户端连不上本地 Server 进程。排查顺序先确认 command 和 args 写对了npx 能不能手动跑起来再看路径权限文件系统 Server 访问的目录是否存在最后检查端口占用如果是 HTTP 传输的 Server端口被占也会报这个。Stdio 传输的话进程直接终止就会触发这个错误。第三个是 reading choices 相关的报错比如cannot read property choices of undefined。这通常说明返回体结构和你预期的不一样可能是请求根本没成功返回的是错误对象。打印完整响应体再解析不要直接取 choices。如果返回的是{error: {...}}先看 error.message。第四个是 OAuth 相关报错。部分 MCP Server 需要 OAuth 授权才能访问远程资源比如 GitHub、Sentry 这类。报错信息里会带 authorization 字样。这时候需要按 Server 文档完成授权流程拿到 token 后写进配置的 env 字段。注意 token 也有有效期过期了要重新授权。还有一个容易忽略的点Function Call 的 arguments 解析失败。模型返回的是字符串如果里面有转义字符没处理好JSON.parse 会抛异常。建议用 try-catch 包一层解析失败时把原始字符串打出来看。排障时建议开 verbose 日志把请求和响应都打全。很多问题看一眼原始报文就清楚了比猜快得多。如果确认是通道侧的问题可以去接入文档对照示例或者用模型对话页面发同样的请求做对比测试。6. 面试怎么答把三者串成一条链路讲回到面试场景。当面试官问 Function Call、MCP、Skill 的区别你不要平铺直叙地背定义而是用一条链路把它们串起来。我的答法是先讲抽象层级Function Call 是 API 级原子操作MCP 是协议级连接标准Skill 是框架级能力封装再讲触发时机MCP 在会话初始化时握手和发现能力Function Call 在单轮推理中按需触发Skill 在意图匹配后被激活并编排前两者最后讲协作关系Skill 是总指挥Function Call 是执行手MCP 是插座。这样答的好处是面试官能看出你真正跑过链路而不是只背了概念。如果追问「那 MCP 能不能替代 Function Call」你可以说不能MCP 的工具调用底层依然可能走 Function Call 的机制只是把发现和连接标准化了。如果追问「Skill 和 Agent 什么关系」你可以说 Skill 是 Agent 的能力单元Agent 是调度器。想自己动手复现这条链路的可以从 API Keys 页面拿一个 Key照着第 3 节的配置跑一遍。需要长期做编码和 Agent 开发的可以看看 Coding Plan额度更划算。验证模型返回结构的话模型对话页面最方便改个参数就能发请求。接入过程中遇到报错接入文档里的示例和字段说明能帮你快速定位。