Tool Calling 原理

为什么 LLM 需要工具、Function Calling 与 Tool Use 的区别、MCP 协议,以及如何安全地让模型调用外部能力

19 min read Part of AI Foundation · Ch. 9

Tool Calling 原理

flowchart LR
  A["Tool Calling 原理"]
  A --> B["分类:基础概念"]
  A --> C["关键词:AI"]
  A --> D["关键词:Tool Calling"]
  A --> E["关键词:Function Calling"]
  A --> F["关键词:MCP"]

模型本身只会处理上下文里的内容。它不能自己上网、不能自己查数据库、不能自己发邮件,也不能保证复杂计算永远正确。Tool Calling 的意义,就是让模型先提出“我要用哪个工具、传什么参数”,再由应用层真正执行。这个机制,是现代 Agent 的基础。 :contentReference[oaicite:0]{index=0}


这篇文章会讲什么

前面几篇文章讲了模型如何被训练、如何利用上下文、如何通过 Prompt 被稳定控制,也讲了 Embedding、向量数据库这些“检索层”的能力。但如果你想让 AI 应用真正接入现实世界,就一定会遇到一个关键问题:

模型怎么从“会说话”,变成“能做事”?

现实里的很多任务,单靠语言模型本身是做不完的。比如:

  • 查询今天的天气、汇率、股价、新闻
  • 读取企业数据库、知识库、工单系统
  • 发邮件、建日历、创建 Jira Ticket
  • 做可靠计算、执行代码、处理文件
  • 调内部 API,触发真实业务动作

这些能力都不在模型参数里,而在外部系统里。Tool Calling 就是连接这两者的桥梁。OpenAI 官方把 function calling 直接定义为让模型与外部系统交互、访问训练数据之外数据的一种方式;Anthropic 的工具使用文档也是同一思路。 :contentReference[oaicite:1]{index=1}

这篇文章想解决的,就是下面这些问题:

  • 为什么 LLM 天然需要工具
  • OpenAI 的 Function Calling 和 Anthropic 的 Tool Use 本质上在做什么
  • MCP 为什么会成为工具生态的重要协议
  • 工具 schema 应该怎么设计
  • 为什么 Tool Calling 最大的风险不在“模型会不会调”,而在“应用该不该执行”
  • 如何把工具调用做成一个可控、安全、可审计的系统

如果说 Prompt 工程解决的是“如何让模型表达得更好”,那么 Tool Calling 解决的就是:

如何让模型把外部能力纳入推理闭环。


延伸阅读

  • OpenAI Function Calling Guide
  • Anthropic Tool Use 文档
  • MCP 官方文档

先说结论:Tool Calling 不是“模型执行工具”,而是“模型生成调用意图”

很多人第一次接触 Tool Calling,容易产生一个误解:

模型会不会直接去执行函数、访问数据库、发邮件?

标准答案是:不会。

在主流设计里,模型本身只负责输出一段结构化意图,例如:

  • 要调用哪个工具
  • 工具参数是什么
  • 是否需要多个工具串联

真正执行工具的是应用层或代理层,不是模型本体。OpenAI 官方文档明确说明,function calling 的作用是让模型生成调用外部系统的结构化请求;执行和结果处理仍由你的应用负责。 :contentReference[oaicite:2]{index=2}

所以一个更准确的理解是:

Tool Calling = 模型负责“决定做什么”,应用负责“真的去做”。

这件事非常重要,因为它直接决定了安全边界:

  • 模型输出不可信
  • 工具执行必须校验
  • 权限控制必须在应用层
  • 高风险动作不能仅靠模型一句话就直接落地

理解了这个边界,后面很多设计问题就会变得清楚。


1. 为什么 LLM 需要工具

先看定义:因为 LLM 本质上是基于上下文生成文本的模型,它既无法天然访问外部世界,也无法天然保证执行能力和结果正确性,所以必须借助工具把外部数据和动作接进来。 :contentReference[oaicite:3]{index=3}


LLM 的三类天然短板

从系统能力角度看,语言模型至少有三类先天限制。

1. 知识有边界

模型的知识来自训练数据和当前上下文。
如果数据过期、缺失,或者是你企业内部从未出现在训练语料里的信息,模型就无法凭空知道。OpenAI 官方工具文档明确把“访问训练截止时间之外的数据”列为使用工具的典型原因之一。 :contentReference[oaicite:4]{index=4}

例如:

  • 实时天气
  • 最新汇率
  • 今天的新闻
  • 你公司 CRM 里的客户数据
  • 某个用户刚刚下的订单

这些都需要工具去查。

2. 不能主动操作外部系统

模型本身不会真的修改数据库、发 Slack、发邮件、创建日历事件。
这些动作都必须通过外部程序或 API 完成。OpenAI 的 function calling 和 Anthropic 的 tool use 都是在为这类“外部动作委托”提供接口。 :contentReference[oaicite:5]{index=5}

3. 计算和执行不天然可靠

语言模型可以“像会算一样”回答很多问题,但在复杂计算、代码执行、严格逻辑校验上,可靠性并不等同于专门工具。
这也是为什么计算器、代码执行环境、数据库查询工具会成为 Agent 系统里的高频工具类型。MCP 官方文档也把 search engines、calculators、databases 直接列为典型外部系统。 :contentReference[oaicite:6]{index=6}


工具到底补上了什么

你可以把工具理解成一组“外接能力模块”。

模型的短板工具补上的能力
不知道最新信息搜索、数据库查询、API 查询
不能做真实动作邮件、工单、支付、CRM、日历、内部 API
计算不稳定计算器、代码执行、SQL 引擎
不能直接处理某些系统文件系统、文档平台、企业 SaaS、设备控制

所以 Tool Calling 的真正价值,不是“让模型更聪明”,而是:

让模型在需要时能借用外部系统的确定性能力。


工具让模型从“回答问题”走向“完成任务”

这也是为什么 Tool Calling 常常被视为 Agent 的基础。

没有工具时,模型更多是在:

  • 解释
  • 生成
  • 总结
  • 改写
  • 推理

有了工具以后,模型可以进入另一种工作方式:

  1. 判断当前问题缺什么信息或能力
  2. 选择合适的工具
  3. 生成调用参数
  4. 读取结果
  5. 基于结果继续决策或回答

这个闭环,才让“Agent”成为可能。


2. Function Calling:OpenAI 的做法

先看定义:OpenAI 的 Function Calling,本质上是让模型基于你提供的 JSON Schema,输出结构化的工具调用请求;你的应用再负责执行工具,并把结果送回模型。OpenAI 官方文档也明确把 function calling 称为 tool calling。 :contentReference[oaicite:7]{index=7}


工作流程到底是什么

一个典型的 OpenAI function calling 流程,大致是这样:

1. 应用把可用工具定义传给模型
2. 用户提问
3. 模型判断是否需要调用工具
4. 如果需要,模型输出工具名和参数
5. 应用执行真实工具
6. 应用把结果作为新的上下文送回模型
7. 模型基于工具结果继续回答

OpenAI 文档明确说明:tools 通过请求里的 tools 参数提供给模型,模型会根据用户请求自动决定是否调用。 :contentReference[oaicite:8]{index=8}


一个具体例子:天气查询

比如你定义了一个工具:

  • 名称:get_weather
  • 参数:city
  • 含义:根据城市获取实时天气

用户问:

北京今天天气怎么样?

模型不会直接编造天气,而是更合理地输出一个结构化调用意图,例如:

{
  "name": "get_weather",
  "arguments": {
    "city": "北京"
  }
}

然后:

  • 你的应用去调用真实天气 API
  • 拿到结果,例如“晴,25°C”
  • 再把这个结果作为工具返回消息加回上下文
  • 模型再生成面向用户的自然语言答案

所以要强调一遍:

模型不查天气;模型只决定“应该查天气”。


工具定义为什么通常是 JSON Schema

OpenAI 官方文档说明 function tools 是基于 JSON Schema 定义的,这样模型才能知道:

  • 工具叫什么
  • 每个参数是什么类型
  • 哪些参数必填
  • 可选值范围是什么
  • 工具的描述是什么 :contentReference[oaicite:9]{index=9}

例如一个天气工具的 schema 可能是:

{
  "name": "get_weather",
  "description": "获取指定城市的当前天气",
  "parameters": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "城市名称,如北京、上海"
      }
    },
    "required": ["city"]
  }
}

这和前面讲结构化输出时的 schema 思路是一致的:
它不是“提示模型随便调用”,而是在定义一个可执行接口契约


Function Calling 的本质不是“函数”,而是“结构化动作选择”

虽然名字叫 function calling,但它不一定真对应你代码里某个 Python 函数。
它本质上更像:

  • 一段动作名称
  • 一份参数对象
  • 一个由应用层映射到真实能力的执行协议

所以你完全可以把它背后的执行目标理解为:

  • HTTP API
  • SQL 查询
  • gRPC 服务
  • 消息队列任务
  • 内部工作流动作
  • 外部 SaaS 操作

函数只是最直观的抽象,不是唯一实现方式。


OpenAI 近两年的一个变化:工具不只是一种

OpenAI 现在的工具体系不只是“函数工具”一种,还包括内建工具,例如 file search、web search、computer use 等。官方工具文档已经把工具能力明确分成 built-in tools 与 function tools 两大类。 :contentReference[oaicite:10]{index=10}

这意味着:

  • 有些工具由平台直接提供
  • 有些工具由你自己定义 schema 和执行逻辑
  • 在 Agent 设计里,两者可以共存

所以今天再讲 Tool Calling,最好理解成更广义的“工具接口层”,而不仅仅是“函数调用”。


3. Tool Use:Anthropic 的做法

先看定义:Anthropic 的 Tool Use 和 OpenAI 的 Function Calling 在原理上高度一致:模型输出结构化调用请求,应用执行工具,再把结果回填给模型。区别主要在 API 组织方式和消息格式。 :contentReference[oaicite:11]{index=11}


它们本质上解决的是同一个问题

无论叫:

  • Function Calling
  • Tool Calling
  • Tool Use

底层逻辑都是同一个闭环:

模型决定调用
→ 应用执行
→ 结果回填
→ 模型继续处理

所以在设计系统时,不必把 OpenAI 和 Anthropic 看成两个完全不同的范式。
更实用的理解是:

厂商层面的区别,更多是接口格式不同;架构层面的原则,基本相同。


Anthropic 的“工具使用”更强调内容块结构

Anthropic 的工具调用接口通常不是把调用结果藏在一大段自由文本里,而是通过结构化的内容块来表达 tool use 和 tool result。
这意味着:

  • 工具调用和普通自然语言消息更容易区分
  • 多轮调用更适合放在统一消息流里
  • 工具请求和结果更容易被程序解析和编排

虽然具体字段和 OpenAI 不同,但工程上你要做的事几乎一样:

  • 定义工具
  • 描述参数
  • 接收模型的调用意图
  • 执行工具
  • 回填结果

不用纠结术语,重点看系统边界

很多初学者会在“Function Calling”和“Tool Use”的术语上花很多时间。
但对你搭系统来说,真正重要的不是名字,而是这几个边界是否清楚:

  • 模型负责什么
  • 应用负责什么
  • 工具 schema 由谁定义
  • 执行结果如何回填
  • 高风险操作谁批准

只要这几件事清楚,换一家模型 API,本质架构不会大改。


4. MCP(Model Context Protocol):为什么它重要

先看定义:MCP 是一个开放标准,用统一协议描述工具、资源和交互方式,目标是减少“每接一个系统就重写一套集成”的碎片化成本。Anthropic 在 2024 年公开发布了 MCP;2026 年该项目已进入正式社区治理阶段,并被官方描述为多公司参与的开放标准。 :contentReference[oaicite:12]{index=12}


MCP 试图解决什么问题

在 MCP 之前,一个很常见的现实是:

  • OpenAI 一套工具接法
  • Anthropic 一套工具接法
  • IDE 一套插件体系
  • 每个内部系统又一套自定义 API 封装
  • 每接一个新工具,都要写适配层和胶水代码

这会导致工具生态非常碎片化。

Anthropic 在发布 MCP 时,就把这个问题讲得很清楚:
AI 系统被困在数据孤岛和定制集成里,每接一个数据源都要单独开发。MCP 的目标就是用一个开放标准替代碎片化连接方式。 :contentReference[oaicite:13]{index=13}


MCP 到底是什么

MCP 官方文档把它定义为:

一个把 AI 应用连接到外部系统的数据源、工具和工作流的开放协议。 :contentReference[oaicite:14]{index=14}

你可以把它类比成 AI 世界里的“统一接口层”:

  • MCP Client:你的 AI 应用或 Agent
  • MCP Server:暴露工具、资源或上下文的服务端
  • 协议层:统一消息、能力发现、调用方式

MCP 官方文档甚至直接用了一个非常形象的比喻:

MCP 像 AI 应用的 USB-C。 :contentReference[oaicite:15]{index=15}


MCP 不只是工具,还包括资源和提示资产

MCP 的意义不只是“调工具”。
它想统一抽象的范围更广,至少包括:

  • Tools:可调用的动作或函数
  • Resources:文件、数据库、文档等可读取内容
  • Prompts / Workflows:可复用的提示或工作流资产

MCP 规范里有专门的 tools 章节,明确说明 MCP server 可以向语言模型暴露可调用工具,并且每个工具都有名字和 schema 元数据。 :contentReference[oaicite:16]{index=16}

这意味着 MCP 的目标不是把某一种厂商 API 标准化,而是更进一步:

把“AI 应用如何发现和接入外部能力”这件事协议化。


MCP 为什么在 2026 变得更重要

截至 2026 年,MCP 已经不只是一个“Anthropic 提出来的新东西”,而是进入了更正式的社区治理和多公司参与阶段。官方治理与 roadmap 页面都强调了 formal governance;Anthropic 也在 2025 年宣布把 MCP 相关项目捐赠给开放基金会体系。 :contentReference[oaicite:17]{index=17}

这意味着一个趋势正在形成:

  • 工具不再只是某家模型厂商的私有生态
  • “写一次,多个 AI 客户端可接入”正在成为现实目标
  • Agent 工具层的标准化正在加速

所以即使你今天不直接实现 MCP,也最好理解它,因为它代表了未来工具生态的方向。


5. API 集成模式:工具背后其实就是“能力封装”

先看定义:从模型角度看,工具只是名字、描述和参数 schema;但从系统角度看,工具背后可能是 REST API、数据库查询、内部服务、工作流引擎甚至代码执行环境。


工具只是接口皮,真正重要的是后面的执行器

模型看到的通常只有:

  • name
  • description
  • parameters

但真实系统里,这个工具背后可能接的是非常不同的东西:

工具类型典型后端实现
查询类工具REST API、GraphQL、数据库、搜索服务
动作类工具邮件服务、工单系统、支付 API、内部 RPC
计算类工具计算器、Python 执行环境、SQL 引擎
文件类工具文档系统、对象存储、文件服务
多模态工具图像生成、语音合成、OCR、转录服务

所以设计工具时,最实用的思路不是“给模型几个函数”,而是:

把你的系统能力整理成一组最小、清晰、可授权的接口。


工具设计里最常见的两类错误

1. 工具过于底层

例如直接暴露一个通用 SQL 执行器、任意 HTTP 请求器、任意 shell 命令。
这在安全和可控性上都非常危险。

2. 工具过于宽泛

例如一个叫 do_business_action 的万能工具,里面塞十几个可选参数。
模型很难判断什么时候该用、参数怎么填,也很难调试。

更稳妥的原则是:

  • 工具应该语义明确
  • 参数应该尽量少且清楚
  • 每个工具只做一类动作
  • 高风险动作最好拆开,别混在一起

一个好工具更像“业务动作单元”

举例来说,相比暴露:

  • execute_sql
  • send_http_request
  • call_internal_service

更好的做法常常是暴露:

  • get_user_order_status
  • create_support_ticket
  • send_refund_confirmation_email

原因很简单:

  • 模型更容易选对
  • 参数更容易校验
  • 权限更容易控制
  • 审计更容易做
  • 失败更容易处理

这也是 Tool Calling 从“技术接口”走向“Agent 工程”的关键一步。


6. 工具描述设计:为什么 schema 和 description 决定调用质量

先看定义:模型能否正确调用工具,很大程度上不取决于模型“够不够聪明”,而取决于你有没有把工具的用途、边界和参数描述清楚。OpenAI 官方文档明确建议工具要写清函数描述和 JSON Schema,Structured Outputs 也支持更严格的 schema 约束。 :contentReference[oaicite:18]{index=18}


模型其实是在“读接口文档”

对模型来说,一个工具就是一小段文档:

  • 这个工具是干什么的
  • 什么时候该用
  • 参数有哪些
  • 参数是什么格式
  • 输出大概是什么

所以工具描述写得差,模型就会像人类程序员看糟糕 API 文档一样:

  • 不知道什么时候该调
  • 不知道参数怎么填
  • 不知道返回什么
  • 不知道哪些情况不该用

好描述和坏描述的差别

坏描述

get_weather: 获取天气

问题在于:

  • 不知道输入是什么
  • 不知道是当前天气还是未来天气
  • 不知道返回哪些字段
  • 不知道城市名格式
  • 不知道单位

好描述

get_weather: 获取指定城市的当前天气。输入城市名称,返回当前气温(摄氏度)、天气状况和简短体感描述。仅用于查询当前天气,不用于未来天气预报。

这段描述至少帮模型解决了:

  • 什么时候该用
  • 该传什么
  • 会得到什么
  • 不适用什么场景

参数 schema 最好足够严格

如果一个参数只允许固定选项,就用枚举。
如果一个字段必填,就明确 required。
如果日期有格式要求,就写清格式。
如果单位只能是摄氏度或华氏度,就不要让模型自由发挥。

OpenAI 的 Structured Outputs 指南明确把 JSON Schema 约束和 strict: true 当作提升可靠性的核心手段之一。 :contentReference[oaicite:19]{index=19}

所以一个很实用的原则是:

能靠 schema 约束的,就不要只靠自然语言提醒。


工具描述其实也是一种 Prompt 工程

你可以把工具 schema 看成 Prompt Engineering 的延伸。

因为你本质上还是在做同一件事:

  • 减少模型猜测空间
  • 明确输入和输出
  • 限制错误自由度
  • 提升调用稳定性

区别只在于,这次 Prompt 的对象不是“最终回答格式”,而是“工具调用格式”。


7. 安全考量:真正的风险不在模型“会不会调”,而在“调了以后要不要执行”

先看定义:模型输出的工具调用请求本质上是不可信输入。所有执行必须经过应用层校验、权限控制、参数约束、必要时人工确认。MCP 规范也专门定义了授权能力;OpenAI 和 Anthropic 的工具机制都默认由应用负责执行与安全边界。 :contentReference[oaicite:20]{index=20}


第一原则:模型输出不能直接信任

这是 Tool Calling 里最重要的一条安全原则。

因为模型可能会:

  • 理解错用户意图
  • 填错参数
  • 选择错工具
  • 生成不存在或越权的请求
  • 被 prompt injection 诱导做危险动作

所以从系统角度看,模型生成的工具调用,本质上和用户输入一样,都应该被视为:

不可信请求。


主要风险有哪些

1. 越权访问

例如模型试图读取不属于当前用户的数据。

2. 参数注入

例如把恶意字符串塞进 SQL、命令、路径或模板参数里。

3. 高风险动作被误触发

例如发邮件、下单、退款、删数据、改配置。

4. 工具滥用

例如高频调用昂贵 API、无限循环调用、批量误操作。

5. 幻觉式调用

模型编出并不存在的工具名,或给出不符合 schema 的参数。

这些都不是理论风险,而是实际系统里很常见的问题。


最有效的防线都在应用层

一个稳妥的工具系统,通常至少需要这些防线:

参数校验

严格按 schema 验证字段、类型、枚举、范围、长度。

权限注入

不要让模型自己决定用户身份、租户范围、资源边界。
这些应由后端根据当前会话上下文强制注入。

最小权限

每个工具只暴露完成任务所需的最小动作面。

白名单执行

尤其是 SQL、shell、代码执行、文件操作类工具,必须限制允许的命令和资源。

预算和速率限制

防止模型被诱导连续调用昂贵工具。

高风险动作确认

发送邮件、付款、提交工单、删除数据等动作,很多场景下都应要求二次确认或人工批准。


代码执行类工具为什么特别危险

代码执行环境确实很强,因为它可以补上:

  • 复杂计算
  • 数据清洗
  • 表格处理
  • 文件转换
  • 多工具编排

但它也天然高风险。
Anthropic 关于“code execution with MCP”的工程文章就特别强调,把工具交给代码环境可以降低上下文成本,但同时也意味着更需要良好的隔离和状态管理。 :contentReference[oaicite:21]{index=21}

所以代码执行工具通常必须:

  • 跑在沙箱里
  • 限制文件系统
  • 限制网络
  • 限制执行时间和资源
  • 审计输入与输出

先看定义:

越通用的工具,越危险;越危险的工具,越不能完全放权给模型。


8. 实战闭环:一个天气 + 计算器 Agent 是怎么工作的

先看定义:最小可用的 Tool-Using Agent,至少包括五个部分:工具定义、模型调用、执行器、结果回填、循环控制。


一个最小系统长什么样

假设你有两个工具:

  • get_weather(city)
  • calculator(expression)

用户问:

北京今天多少度?如果再加 10 度是多少?

一个典型执行流会是:

1. 把两个工具的 schema 传给模型
2. 模型先决定调用 get_weather(city="北京")
3. 应用执行天气 API,得到 25
4. 把结果作为 tool result 传回模型
5. 模型再决定调用 calculator(expression="25+10")
6. 应用执行计算器,得到 35
7. 把结果传回模型
8. 模型输出最终自然语言回答

这里最关键的不是“调用了两个工具”,而是:

模型在一个循环里,把工具结果当成新的上下文继续思考。

这正是 Agent loop 的雏形。


为什么需要循环,而不是一次调用结束

因为很多真实问题不是“一步到位”的。

模型经常需要:

  • 先查一个信息
  • 再根据结果决定第二个动作
  • 可能再做一次转换或确认
  • 最后再面向用户作答

这意味着工具调用系统通常不是:

问题 → 调一次工具 → 结束

而更像:

问题 → 判断 → 调工具 → 读结果 → 再判断 → 再调工具 → 总结

这也是为什么现代 Agent 框架通常都会有一个消息循环,而不仅仅是一次函数调用。


一个实用的系统分层方式

很多生产系统会把 Tool Calling 设计成四层:

1. Tool Registry

存放工具定义、schema、权限信息。

2. Planner / Model Layer

让模型决定该调用什么。

3. Executor

真正执行工具,处理异常、重试和权限。

4. Orchestrator

控制循环、消息拼接、结果回填、停止条件。

这样做的好处是:

  • 工具和模型解耦
  • 执行和决策解耦
  • 安全校验集中化
  • 更容易做日志和审计

9. 一个最好记住的原则:Tool Calling 让模型获得“接口感”,不是“直接控制权”

如果你只想记住一句话,那就是:

Tool Calling 的本质,不是让模型直接接管系统,而是让模型在推理中学会请求外部能力。

这句话的含义有两层:

第一层:能力扩展

模型可以借助外部系统补足知识、动作和计算能力。

第二层:边界保留

真正的执行权、权限判断和风险控制,仍然掌握在应用层。

这正是一个好 Agent 系统应有的平衡:

  • 让模型负责高层决策和语言理解
  • 让程序负责确定性执行和安全控制

理解这一点,你就不会把 Tool Calling 神化成“模型开始自己做事了”,而会更准确地看到:

模型是在一个被严格包裹的接口世界里,学习如何请求和组合能力。


核心概念速查

概念一句话
Tool Calling模型输出工具调用意图,应用执行工具并回填结果 :contentReference[oaicite:22]{index=22}
Function CallingOpenAI 对工具调用的实现名称,基于 schema 定义函数工具 :contentReference[oaicite:23]{index=23}
Tool UseAnthropic 的工具调用机制,本质与 function calling 类似 :contentReference[oaicite:24]{index=24}
Tool Schema描述工具名称、用途和参数结构的接口契约 :contentReference[oaicite:25]{index=25}
MCP连接 AI 应用与外部工具、资源、工作流的开放协议 :contentReference[oaicite:26]{index=26}
Tool Result Loop工具结果回填模型上下文,再继续决策的循环
Least Privilege工具只暴露最小必要权限,避免越权和滥用
Human-in-the-loop对高风险动作加入人工确认或审批的控制机制

下一篇

有了 Embedding、向量数据库、Tool Calling,你已经掌握了 AI 应用的三大基础能力:
能表示语义、能高效检索、能调用外部系统。

下一篇我们把这些能力真正拼成一个完整系统:
前端、后端、检索层、工具层、模型层、状态层分别负责什么,怎样才能搭出一套靠谱的 AI 应用系统架构