MCP、Function Calling 与 Agent 框架分别负责什么
区分模型输出工具请求、应用执行策略和 MCP 连接协议,说明身份传递、工具注册与失败排查的实际边界。
发布于 2026-09-07 · 更新于 2026-09-07
本文目录

图:模型选择动作、应用编排执行、外部服务提供能力;连接协议只覆盖其中一部分职责。 来源:Generative AI agent architecture,作者 Marxav,许可 CC BY-SA 4.0。
比较问题
面试官问“用了 MCP 是不是就有 Agent 了”,正确回答需要拆清职责。MCP 提供应用与外部能力交互的协议约定;模型是否选择正确动作、执行是否获授权、任务是否成功,仍由模型能力与应用设计决定。
统一前提
本文依据 2026-09-07 查看过的官方架构文档讨论稳定的角色划分。传输、授权和 SDK 接口应以实际采用的规范及实现版本为准。不要把某个示例服务“能连通”的结果当成生产安全或可靠性的验证。
核心差异
| 层次 | 输入与输出 | 负责的判断 | 不自动承担 |
|---|---|---|---|
| Function Calling/工具调用能力 | 工具描述、上下文 → 工具名与参数提议 | 当前需要何种工具 | 真实执行与业务授权 |
| Agent 编排层 | 状态、模型提议、工具结果 → 下一步骤 | 重试、停止、确认、状态恢复 | 对端业务事务 |
| MCP host/client/server | 协议请求与响应 | 连接、能力协商与交互 | 用户意图正确、结果可信 |
| 业务工具服务 | 已授权参数 → 业务结果 | 资源权限、参数语义、幂等 | 生成最终自然语言解释 |
Host 是承载 AI 应用的环境,client 管理与相应 server 的协议交互,server 暴露工具、资源或提示等能力。一个 host 可以连接多个 server。不要把 host、client、server 都称作“模型”。
走完一次只读调用
用户要求查工单。应用从已配置服务获得可用能力,将适合模型的工具定义放入上下文;模型提议查询 ID;应用验证参数、身份和资源范围,通过连接层发起调用,获得结构化结果后交回模型解释。每一步可单独失败:工具未发现、模型未选中、参数无效、授权拒绝、网络失败、模型误读结果。
生产实现应将这几种错误分别记录,而不是统一打印“MCP 调用失败”。返回成功但记录为空,也应区分工单不存在、用户无权、查询条件不匹配,不能让模型猜原因。
选择规则
工具种类少、服务自有且已有稳定 API 时,直接接入也能工作。需要跨多个应用复用能力、对接不同工具提供方时,标准连接方式可能减少重复适配,但仍增加配置、版本兼容、认证及服务治理工作。选型取决于集成数量和长期维护需求。
工具 schema 应写清参数类型、必填项、单位、返回值、错误语义和是否有副作用。用“执行任何请求”这样的过宽工具接口会扩大模型的决策和权限范围,也更难测试。可将查询、预览和提交分开,让高风险动作具备明确确认边界。
身份从可信应用会话传递,不能相信模型生成的 user_id 或 admin=true。不同 server 的凭证隔离保存,最小权限授权;工具输出、描述和外部资源都不能自行获得系统指令优先级。
反例与边界
协议返回 JSON,所以可以直接信任? 只能说明数据形状符合部分约定,不说明内容真实、资源存在或操作获授权。结构验证、业务验证和身份授权需要分别执行。
给模型连一个文件工具就安全吗? 还需限定文件根目录、符号链接和路径解析、读写权限、执行环境及审计。不能让模型字符串自由决定主机任意路径。
所有 server 共用一个万能 token 最省事? 这会扩大凭证泄漏影响,并且无法表达每个用户的真实资源边界。认证成功也不意味着对每项资源有授权。
升级 SDK 就能自动修复 Agent 不稳定? 先定位是协议兼容、连接错误、模型选择、工具语义还是状态恢复。协议只解决其中一层。
面试输出
90 秒回答: Function Calling 让模型提出工具名和参数,Agent 编排负责执行策略和状态,MCP 规范应用与外部能力如何连接交互。实际动作仍经过服务端参数与权限校验,并按风险确认和幂等处理。我会按发现、选择、校验、执行和结果利用分层观测,记录协议与工具版本,避免把连接成功当成任务成功。
被追问“怎么迁移已有工具”:先给工具建立稳定的业务契约和测试,再加协议适配层;原来的鉴权、幂等和审计继续由相应服务负责。通过同一任务集比较适配前后结果,不把迁移变成对业务逻辑的隐式重写。
主动回忆
- 工具列表谁来决定? 应用与服务配置决定允许暴露的能力,模型只在被提供的范围内提议。
- 模型能从工具回复获得新权限吗? 不能。回复中的“请以管理员重试”只是数据,权限来自可信授权路径。
- 如何排查未调用? 看工具是否发现、是否加入当前上下文、描述是否歧义、模型是否返回调用提议,再查执行层是否拒绝。