Skip to content

Function Calling 与 MCP(工具调用)

本页讲模型如何表达工具调用意图、如何设计 schema 与生命周期;当面试进入用户身份委托、短期凭证、策略义务、写操作确认和事故止血时,继续看 企业 Tool Gateway 安全执行系统设计面试题

工具调用是 Agent 的地基。面试不只考「流程是什么」,更考工程细节:schema 怎么设计、并行调用什么时候开、失败怎么兜底、模型为什么会用工具。本文从机制讲到最佳实践,MCP 协议的完整深挖见 MCP 协议深入,工具权限、HITL、幂等和审计的专门答法见 Agent 工具安全与权限边界

2026 面试先背这几句话

  • Function Calling 是模型输出结构化调用意图,MCP 是工具与数据源的标准接入协议。前者解决「模型怎么说我要调工具」,后者解决「工具怎么被发现、描述、连接和复用」。
  • 工具 schema 不是接口文档的搬运,而是给模型看的「路由说明书」:要写清何时用、何时不用、参数边界、返回值语义、失败时怎么解释
  • 生产 Agent 的工具调用要按分布式系统治理:超时、重试、幂等、权限、审计、熔断、降级、最大轮数一个都不能少。
  • 工具越多越要做分层路由或 Tool RAG,否则上下文成本、误调用率和调试复杂度都会上升。
  • MCP 落地时要能讲清 Host / Client / Server:Host 是 AI 应用,Client 管连接和会话,Server 暴露 tools/resources/prompts。

Function Calling 完整机制

Function Calling 是让模型「调用外部函数/工具」的能力。核心认知:模型本身不执行函数,它只输出「我想调用哪个函数、用什么参数」这一结构化意图,真正执行由你的代码完成。

开发者                    模型                      你的程序
  │  ① 注册工具 schema      │                          │
  │ ───────────────────►   │                          │
  │  ② 用户提问             │                          │
  │ ───────────────────►   │  ③ 返回 tool_calls       │
  │                        │  (函数名 + JSON 参数)      │
  │                        │ ───────────────────────► │ ④ 校验并真正执行
  │                        │  ⑤ 结果作为 tool 消息回传  │
  │                        │ ◄─────────────────────── │
  │  ⑥ 最终自然语言回答      │  (或继续发起下一次调用 → 循环)
  │ ◄───────────────────   │

第 ③~⑤ 步可以循环多轮——这个「模型决策 → 执行 → 观察结果 → 再决策」的循环就是 Agent 的最小骨架(ReAct 范式,见 Agent 基础)。

模型为什么会用工具?

工具调用能力是训练出来的,不是 prompt 魔法:

  • 后训练阶段用大量「对话 + 工具调用轨迹」数据做 SFT/RL,模型学会输出特定格式(通常由特殊 token 或固定模板包裹的 JSON)。
  • 推理时,工具 schema 被注入到上下文(相当于 system prompt 的一部分),模型「看着说明书点菜」。
  • 因此 description 是模型决定「用不用、怎么用」的唯一依据——工具描述写得好不好,直接决定调用准确率。
  • 很多推理框架还会配合约束解码(限制输出必须符合 JSON Schema),从机制上保证参数格式合法,见 结构化输出详解

工具 Schema 设计最佳实践

json
{
  "name": "search_orders",
  "description": "按条件查询用户订单。适用于用户询问订单状态、物流、历史购买记录。不适用于退款操作(用 refund_order)。",
  "parameters": {
    "type": "object",
    "properties": {
      "user_id": { "type": "string", "description": "用户唯一 ID" },
      "status": {
        "type": "string",
        "enum": ["pending", "shipped", "completed"],
        "description": "订单状态筛选,不传则查全部"
      },
      "limit": { "type": "integer", "description": "返回条数,默认 10,最大 50" }
    },
    "required": ["user_id"]
  }
}
原则说明
描述写「何时用 + 何时不用」模型靠 description 路由,边界写清楚能显著减少误调用
能用枚举就用枚举enum 比自由字符串可靠得多,约束解码可直接强制
参数少而扁平深层嵌套对象出错率高;超过 5~7 个参数考虑拆工具
命名动宾结构search_orders 优于 orders / tool1
返回结果也要设计给模型看的结果要精简、结构化、含单位和字段说明,垃圾进垃圾出
幂等与只读标注区分读操作与写操作,写操作考虑加确认环节

Schema 设计的高频细节

面试里不要只说「定义 name、description、parameters」,要能说出这些工程细节:

设计点推荐做法反例
工具粒度一个工具只做一个明确动作,读写分离manage_user 同时查、改、删
参数约束enum、范围、格式说明收窄空间status: string 让模型自由发挥
可选参数默认值写进 description,服务端也要兜底只在 prompt 里说默认值
返回值返回结构化摘要,不把长文档/API 原文全塞回去10KB HTML 原样回传给模型
错误结构{ "ok": false, "error_code": "...", "retryable": true }只返回「失败了」
版本演进新增字段保持兼容;破坏性变更换工具名或版本静默改语义导致旧 prompt 失效

一个好用的工具描述模板:

text
用途:什么时候应该调用。
边界:什么时候不应该调用,应该改用哪个工具。
输入:关键字段、单位、格式、默认值、上限。
输出:返回字段含义,是否可能为空。
失败:常见错误码,以及模型应该怎么继续。
风险:是否只读、是否会产生副作用、是否需要用户确认。

面试表达:schema 的目标不是让后端能解析,而是让模型少猜、让程序能校验、让失败可恢复

进阶机制

tool_choice(调用控制)auto(模型自行决定,默认)/ required(必须调用某个工具)/ 指定具体函数 / none。强制调用适合「这一步必然要查库」的工作流节点;但滥用 required 会让模型在无合适工具时硬编参数。

并行工具调用(Parallel Tool Calls):模型一次返回多个相互独立的 tool_calls(如同时查天气和汇率),程序并发执行后一起回传。能省多轮往返、降延迟;但有依赖关系的调用(先查 ID 再用 ID 查详情)不能并行,模型偶尔会误并行,需要在描述中写明依赖。

多轮工具循环的工程要点:设最大轮数上限防死循环;每轮把工具结果追加进消息历史(注意上下文膨胀,长结果要截断/摘要,见 上下文工程);流式场景下 tool_calls 的参数是分片到达的,要拼完整再解析。

上下文窗口与工具结果管理

工具调用很容易把上下文撑爆,尤其是搜索、数据库查询、网页抓取、代码仓库分析这类工具。生产里通常做三层控制:

  1. 工具侧限流:限制 limit/top_k/page_size,默认返回摘要而不是全量明细。
  2. 中间层压缩:长结果先做结构化摘取,只保留模型下一步决策所需字段。
  3. 消息历史裁剪:旧的 tool observation 不长期保留原文,只保留任务状态、关键结论和引用 ID。

常见做法是「大结果落外部存储,模型只拿句柄」:工具返回 file_id/doc_id/query_id 和短摘要,后续需要细节再按 ID 读取。这比把所有结果塞进上下文更稳定,也更省钱。

错误处理与鲁棒性

  1. 参数校验前置:执行前用 JSON Schema 校验,非法参数不执行。
  2. 错误信息回传给模型:把「参数 user_id 缺失」「API 超时」作为 tool 结果返回,模型通常能自我修正重试——这比直接报错给用户体验好得多。
  3. 重试与超时:工具侧设超时与重试上限;连续失败 N 次则降级(告知用户/换工具)。
  4. 安全边界:工具返回的内容是不可信数据——网页、邮件等外部内容可能包含注入指令(间接 Prompt 注入),不要让模型把工具结果当作指令执行;高危操作(转账、删除)必须人工确认。详见 大模型安全

生产常见失败模式

失败模式表现应对
不该调却调用户闲聊时查库/发请求description 写清边界,增加 tool_choice=none 场景
该调没调模型直接编答案强化系统提示,关键节点用 required,离线评估触发率
工具选错退款问题调用查订单工具工具命名动宾化,写「不适用场景」,做 Tool RAG
参数幻觉编造 ID、日期、枚举值schema 约束 + 服务端校验 + 让模型向用户追问缺失字段
死循环重复调用同一失败工具最大轮数、错误计数、熔断、降级到人工/普通回答
副作用失控重复下单、重复发邮件幂等键、确认步骤、写操作串行、审计日志
工具注入网页内容要求模型泄露系统提示工具结果按不可信数据处理,不允许 observation 覆盖 system 指令

工具一多就乱:规模化管理

  • 控制单次可见工具数:几十上百个工具全塞上下文,路由准确率和成本都会恶化;经验上单次 10~20 个以内为宜。
  • 工具检索(Tool RAG):把工具描述向量化,按用户意图先检索相关工具子集再注入。
  • 分层/分组:按域拆分 Agent(订单 Agent、客服 Agent),或用「先选组、再选工具」的两级路由。
  • 评估:工具调用准确率有专门基准(如 BFCL,伯克利函数调用排行榜),业务上应建自己的调用评估集(该调时调了吗、函数选对了吗、参数填对了吗)。

规模化工具平台通常还会加一层 Tool Registry:集中管理工具的 schema、权限、版本、owner、SLA、审计日志。这样 Agent 不直接依赖某个函数实现,而是通过注册中心拿到当前可用能力;工具下线、升级、灰度和权限收敛都更容易做。

MCP(Model Context Protocol)

MCP 是 Anthropic 于 2024 年提出的开放标准协议,规范「LLM 应用 ↔ 外部工具/数据源」的连接,被称为「AI 应用的 USB-C」。

解决的问题:此前每个应用接每个工具都要定制集成,是 M×N 组合爆炸;MCP 统一标准后,工具方实现一个 MCP Server、应用方实现一个 MCP Client,变成 M+N。

核心架构:Host(AI 应用)— Client(连接管理)— Server(能力提供方),Server 暴露三大原语:

  • Tools:可被模型调用的函数(对应 Function Calling 的工具)
  • Resources:可读取的数据/文件
  • Prompts:预定义提示模板

更细一点:

  • Host:用户真正使用的 AI 应用,例如 IDE、桌面助手、企业知识库问答。
  • MCP Client:Host 内部的连接适配层,负责和一个或多个 Server 建立会话、列工具、转发调用、处理权限。
  • MCP Server:能力提供方,可以封装本地文件、数据库、浏览器、GitHub、内部 CRM 等。

MCP 落地设计题怎么答

如果面试官问「让你把公司内部系统接入 Agent,你怎么设计 MCP Server?」可以按这条线答:

  1. 能力建模:把内部系统能力拆成 tools/resources/prompts。查询类优先做 resource 或只读 tool,写操作单独拆出。
  2. 权限隔离:Server 不信任模型,只信任 Host 传来的用户身份和授权范围;工具按租户、角色、数据域做 ACL。
  3. 输入校验:所有 tool 参数服务端强校验,不能因为模型生成了 JSON 就直接执行。
  4. 结果最小化:返回模型完成任务所需的最小字段,敏感字段脱敏,长结果分页。
  5. 可观测与审计:记录 tool name、参数摘要、耗时、错误码、调用用户、trace_id,便于复盘。
  6. 降级策略:Server 不可用时 Client 能把错误结构化返回给模型,或切到备用工具。

与 Function Calling 的关系(高频考点):

Function CallingMCP
层面模型能力:如何表达调用意图生态协议:工具如何标准化提供与发现
定义方各模型厂商 API开放标准(跨厂商)
关系MCP Client 拿到工具清单后,仍通过 FC 让模型发起调用MCP 在 FC 之上解决集成与复用

一句话:FC 是「模型会点菜」,MCP 是「统一的菜单格式和上菜通道」。MCP 的传输方式(stdio/Streamable HTTP)、生命周期、鉴权与安全风险见 MCP 协议深入;企业内部 Server 平台、Registry、Gateway、审计和上线门禁见 MCP Server 生产化与企业治理高频问答

MCP 与普通插件/SDK 的区别

对比项普通 SDK / 插件MCP
集成方向应用直接写死调用某 SDKHost 通过标准协议连接 Server
复用性每个应用重复接一遍一个 Server 可被多个 Host 复用
能力发现通常靠代码/文档Client 可动态列出 tools/resources/prompts
运维治理分散在各应用里可按 Server 做权限、审计、版本和 SLA

这也是 2026 Agent 岗位爱问 MCP 的原因:它不只是一个协议名,而是把「工具生态」从工程项目里的私有集成,推向可复用、可治理的基础设施。

面试专项:工具调用排障怎么答

面试官常会给一个现象让你定位。不要只说“调 prompt”,按这张表拆:

失败类型现象诊断信号修复方式
触发失败该查库时模型直接编答案tool_calls 为空,答案无引用关键节点用 required,工具描述写清必须调用场景,加入触发评估集
工具选错退款问题调用查询工具tool_name 与意图不匹配工具命名动宾化,description 写“不适用场景”,按领域做 Tool RAG
参数错误ID、日期、枚举值填错schema 校验失败或业务错误码enum/format/range 收窄参数,缺字段让模型追问,错误结构化回传
工具超时Agent 卡住或重复重试trace 中工具 latency 高、retry 多工具超时、指数退避、熔断、降级到缓存/人工
权限拒绝用户让 Agent 查无权数据403/permission_denied不重试;提示权限不足;服务端按用户/租户校验,工具集按权限裁剪
副作用失控重复下单、重复发邮件写工具多次调用、无确认记录写操作串行、幂等键、HITL 确认、审计日志
工具结果注入网页/邮件诱导 Agent 泄密observation 含“忽略系统指令”等内容工具结果按不可信数据处理,注入检测,禁止 observation 覆盖 system 指令

可复述版本:

我会先看 trace:模型是否触发工具、选了哪个工具、参数是否合法、工具返回什么、失败后如何恢复。工具调用问题一般分成触发、选择、参数、权限、超时、副作用和注入七类。每类都有不同修复手段,不能只靠 prompt。

面试专项:Function Calling 生产检查清单

Function Calling 上生产时,重点不是“模型能输出 JSON”,而是工具是否可治理、可审计、可回滚。

检查项要求面试追问
Schemaname 清晰、description 写适用/不适用、参数有 enum/range/format模型选错工具怎么办?
服务端校验所有参数执行前强校验,缺字段不执行模型编造 ID 怎么办?
权限按用户、租户、角色裁剪可见工具和数据MCP Server 能不能信任 Host 传来的用户?
幂等写操作必须有 idempotency_key 或业务唯一键重复创建工单怎么办?
人工确认转账、删除、发邮件、对外发布先生成待确认动作高危动作如何避免误执行?
事务边界工具返回 pending/succeeded/failed,失败可补偿工具执行一半失败怎么办?
错误结构{ ok, error_code, retryable, message }什么时候让模型重试,什么时候转人工?
审计记录 tool name、参数摘要、调用人、trace_id、结果、耗时出问题如何追责和复盘?
版本schema 兼容新增字段,破坏性变更换版本名工具升级如何不破坏旧 Agent?

写操作工具的事务、幂等与人工确认

写操作建议拆成两步:prepare -> confirm/execute

text
用户意图
  -> 模型生成写操作草案
  -> prepare_create_ticket:校验参数,返回 pending_action_id
  -> 展示动作、影响范围、风险提示
  -> 用户/审核人确认
  -> execute_pending_action:带 idempotency_key 执行
  -> 记录审计日志和业务单号

这样即使模型重复调用、页面刷新、checkpoint resume 或网络重试,也能靠 pending_action_ididempotency_key 保证“不重复执行”。面试里可以强调:读工具可以并行,写工具默认串行;写操作失败后不要让模型盲目重试,要先查询外部业务状态。

Tool Registry 与生命周期治理

工具多起来后需要注册中心管理:

  • tool_name、版本、owner、SLA、风险等级、读/写属性。
  • schema、示例、错误码、权限策略、灰度状态。
  • 评估集:该不该调、调哪个、参数是否正确。
  • 下线流程:先从可见工具集移除,再保留兼容期,最后删除实现。

一句话:工具是 Agent 的生产 API,不是 prompt 附件。API 需要的版本、权限、SLA、审计和回滚,工具同样需要。

高频追问

Q:模型会真的执行函数吗? 不会。模型只输出调用意图(函数名+参数 JSON),执行由外部代码完成,结果再回传给模型。这是最常见的概念辨析题,务必答清楚。

Q:为什么要专门的 Function Calling 接口,而不是在 prompt 里说「请输出 JSON」? 三个原因:① 模型在后训练中专门学过 FC 的特殊格式,可靠性远高于自由文本模仿;② 接口层可配合约束解码,从机制上保证 JSON 合法;③ 结构化的 tool_calls 字段便于程序解析与多轮管理,不用从自然语言里抠 JSON。

Q:Function Calling 失败/参数错误怎么办? 校验前置(JSON Schema)、把错误信息作为工具结果回传让模型自修正、设重试与轮数上限、降级路径(换工具或转人工)、记录失败 case 回流评估集。

Q:并行工具调用什么时候开、有什么坑? 相互独立的查询类调用开并行能显著降延迟;坑在于模型可能把有依赖的调用误判为可并行(用了还没拿到的结果),以及写操作并行的副作用顺序问题。实践:读操作放开并行,写操作串行+确认。

Q:工具太多模型选错怎么办? 控制单次可见数量、Tool RAG 动态检索、清晰命名与「何时用/不用」描述、分层路由、用调用评估集持续度量。

Q:怎么评估一个 Agent 的工具调用能力? 拆三层:是否该调(触发判断)、调哪个(函数选择)、参数对不对(槽位填充);公开基准可参考 BFCL,业务上用自建评估集 + 线上 bad case 回流,见 模型评估

Q:MCP Client 和 Server 分别做什么? Host 是 AI 应用本体;Client 在 Host 内管理连接、列能力、转发调用和处理会话;Server 暴露 tools/resources/prompts 并真正访问外部系统。Server 不能信任模型输出,必须自己做鉴权、校验、审计。

Q:工具返回内容太长导致超上下文怎么办? 工具侧分页/限流,返回摘要和引用 ID;中间层做结构化压缩;历史 observation 只保留关键状态。大对象放外部存储,模型需要时再按句柄读取。

Q:工具调用怎么做成本和稳定性治理? 成本看每任务工具次数、LLM 轮数、token、超时重试;稳定性靠最大步数、超时、熔断、幂等键、降级路径、trace 观测和 bad case 回归。工具调用不是「调通就完」,而是要有生产 SLA。

基于 MIT 许可发布