跳到主内容
AI Agent
文章阅读

Tool Calling:为什么工具调用才是 Agent 真正的能力来源

2026/10/012 次阅读10 分钟

在上一篇文章里,我从 Agent Loop 的角度简单拆解了 AI Agent 的运行方式。

如果把 Agent 简化来看,它大概可以写成:


Agent
=
LLM
+
Context
+
Tools
+
Loop

其中,LLM 负责理解和决策,Context 负责保存当前状态,Loop 负责不断推进任务。

那么还剩下一个非常关键的部分:

Tools。

实际上,我认为如果没有工具调用,很多所谓的 Agent 最终仍然只是一个“更会聊天的大语言模型”。

真正让 Agent 从“会说”变成“会做”的,是 Tool Calling。


什么是 Tool Calling

Tool Calling,简单来说,就是让大语言模型不仅能够生成自然语言,还能够选择并调用外部工具。

普通的大语言模型调用通常是:


用户输入
    ↓
LLM
    ↓
文本输出

例如用户问:


帮我看看当前项目目录里面有哪些文件。

如果只是普通 LLM,它可能会回答:


你可以使用 ls 命令查看当前目录。

这里模型只是告诉你“应该怎么做”。

但是 Agent 不一样。

如果它拥有一个:


list_files

工具,那么模型就可以直接选择调用:


list_files(".")

然后工具真正读取目录,并把结果返回给 Agent。

例如:


src/
config/
README.md
package.json

模型再根据这些结果继续分析。

这时,AI 就不再只是告诉用户如何操作,而是真的开始执行任务。


Tool Calling 为什么这么重要

大语言模型本身其实有一个非常明显的限制:

它本身只能生成内容,不能直接影响外部世界。

例如,大模型可以告诉你:


应该读取 config.yaml。

但是它不能凭空读取你电脑中的文件。

模型也可以告诉你:


应该执行 npm install。

但它自己并不能真的启动一个 Shell。

同样,大模型可以分析数据库结构,但如果没有数据库工具,它也无法真正查询数据库。

因此,从能力上来说,大模型本身更像一个:


决策系统

而工具则是:


执行系统

两者组合之后,Agent 才完整。

可以理解为:


LLM = 大脑
Tools = 手和脚
Agent = 大脑 + 手和脚

如果只有 LLM,那么 Agent 再聪明,也只能提出建议。

有了 Tool Calling 之后,它才真正拥有了行动能力。


一个工具到底包含什么

从实现角度来看,一个 Tool 通常并不复杂。

它本质上就是一个可以被调用的函数。

例如:


read_file(path)

它接收一个路径参数,然后返回文件内容。

或者:


shell(command)

接收一个命令,然后返回程序执行结果。

一个工具通常需要向模型描述几个内容:


工具名称
工具用途
参数定义
返回结果

例如:


Tool: read_file

Description:
读取指定路径的文件内容。

Parameters:
path: string

这样模型才能知道:

这个工具是做什么的,

什么时候应该使用它,

以及调用时需要提供哪些参数。

因此,Tool Calling 并不是模型随便输出一段字符串,而是模型按照约定好的结构,告诉 Agent Runtime:


我要调用某个工具
并且参数是什么

然后 Runtime 再真正执行。


Tool Calling 的完整流程

假设用户输入:


帮我检查 config.yaml 里面的数据库配置。

模型首先看到当前可用工具:


read_file
write_file
shell

模型判断:


我需要先读取 config.yaml。

于是生成 Tool Call:


read_file("config.yaml")

这时候并不是 LLM 自己读取文件。

而是 Agent Runtime 接收到这个 Tool Call,再真正执行:


open config.yaml

然后返回:


database:
  host: localhost
  port: 3306

Runtime 把 Tool Result 放入 Context。

下一轮模型再看到:


用户想检查数据库配置

工具返回:
host = localhost
port = 3306

模型才开始分析。

因此,一个完整流程其实是:


User
 ↓
LLM
 ↓
Tool Call
 ↓
Agent Runtime
 ↓
Tool
 ↓
Tool Result
 ↓
Context
 ↓
LLM

这也是 Agent Loop 和 Tool Calling 联系最紧密的地方。


Tool Calling 和传统函数调用有什么区别

看到这里,可能会觉得:

这不就是普通程序里的函数调用吗?

某种程度上确实很像。

传统程序可能写:


if user_wants_file:
    read_file()

但是这里最关键的区别是:

谁决定调用哪个函数。

传统程序中,是程序员提前写好逻辑。

例如:


if task == "read":
    read_file()

if task == "search":
    search()

if task == "run":
    shell()

但是在 Agent 中,通常是 LLM 根据当前上下文动态决定。

例如同样一个任务:


帮我修复这个项目。

模型可能第一步选择:


list_files

第二步选择:


read_file

第三步选择:


shell

第四步又选择:


write_file

这些步骤并不是程序员提前固定好的。

这也是 Tool Calling 真正强大的地方。

它把:


固定流程

变成了:


动态决策

为什么工具设计非常重要

很多人做 Agent 时,会特别关注模型够不够强。

但实际上,一个 Agent 好不好用,和 Tool 的设计也有非常大的关系。

假设我们提供一个工具:


execute_anything(input)

看起来很万能。

但是问题也很明显:

模型可能很难准确理解参数应该怎么写。

而且这种工具权限范围太大,出错风险也更高。

反过来,如果工具设计成:


read_file
write_file
list_files
run_command
search_text

每个工具的职责更加清晰。

模型通常也更容易正确使用。

所以工具设计一个很重要的原则就是:

能力明确,边界清晰。

一个工具最好只解决一类问题。

这样既方便模型调用,也方便开发者做权限控制和错误处理。


Tool Description 决定模型会不会用

Tool Calling 还有一个经常被忽略的问题:

工具描述非常重要。

例如有两个工具:


Tool A:
get_data

描述:


获取数据。

这种描述其实很模糊。

模型并不知道:

获取什么数据?

从哪里获取?

什么时候应该调用?

相比之下:


Tool:
search_project_files

Description:
根据关键词搜索当前项目目录中的文件内容,
适合用于定位函数、变量、配置项或错误信息。

这种描述就清楚得多。

LLM 使用工具的时候,本质上也是在做语义判断。

因此,Tool Description 某种程度上也可以理解为一种 Prompt。

描述越准确,模型调用正确工具的概率通常越高。


Tool Result 同样重要

不仅工具输入重要,工具输出也很重要。

例如 Shell 执行失败时,如果工具只返回:


failed

模型很难判断发生了什么。

如果返回:


exit_code: 1

stderr:
ModuleNotFoundError: No module named 'requests'

模型就可以立即理解错误原因。

所以一个好的 Tool Result 应该做到:


清晰
结构化
信息充分
不过度冗余

尤其是在 Coding Agent 中,这一点非常重要。

因为 Tool Result 会被不断加入 Context。

如果每次工具执行都返回几万行无关日志,很快就会浪费大量 Token。

因此,Tool 系统实际上还承担着一个任务:

帮助模型获得高质量环境反馈。


工具越多越好吗

直觉上看,好像 Agent 拥有的工具越多,能力越强。

但实际情况并不一定如此。

假设一个 Agent 有:


100 个 Tools

模型每次决策时,都要理解这些工具分别是干什么的。

工具之间如果功能相似,比如:


search_file
find_file
lookup_file
query_file
scan_file

模型反而可能不知道应该使用哪个。

因此工具设计还需要控制数量。

我的理解是:

不是工具越多越好,而是工具覆盖任务所需能力即可。

对于一个简单的 Coding Agent 来说,可能几个工具已经能完成很多任务:


read_file
write_file
search
shell

这些工具组合起来,就已经拥有非常强的能力。


Tool Calling 和安全问题

Tool Calling 在带来能力的同时,也带来了风险。

例如如果 Agent 拥有 Shell 权限,它理论上可能执行:


rm -rf

或者修改重要系统文件。

如果拥有数据库工具,也可能误删除数据。

所以一个真实可用的 Agent,通常不能简单地:


模型想执行什么
就执行什么

而需要增加权限控制。

例如:


只允许访问指定目录
禁止危险命令
重要操作需要确认
限制网络访问
限制执行时间
限制工具调用次数

也就是说:


Tool Capability

和:


Tool Permission

应该是两个不同概念。

Agent 可以“知道”某个工具存在,

但不代表它在任何情况下都有权限执行。


Tool Calling 如何改变传统软件

我觉得 Tool Calling 最有意思的地方,还不只是 Agent 可以调用几个函数。

它实际上改变了软件的控制方式。

传统软件是:


代码决定调用哪个 API

而 Agent 软件更像:


模型决定调用哪个 API

过去我们可能写:


用户点击按钮
↓
程序调用接口

未来可能变成:


用户描述目标
↓
LLM 理解目标
↓
自动选择工具
↓
调用一个或多个 API
↓
完成任务

例如用户不再需要点:


打开文件
搜索关键词
复制内容
打开终端
运行命令

而只需要说:


帮我找到这个 Bug 出现的原因。

Agent 会自己组织工具调用流程。

从这个角度来看,Tool Calling 实际上是在把很多软件的操作逻辑,从:


GUI

逐渐转向:


自然语言 + Agent

Tool Calling 为什么是 Agent 的能力来源

如果只从语言能力来看,现在的大语言模型已经非常强。

它们可以:


写代码
分析代码
总结文章
解释问题
制定计划

但这些能力仍然主要停留在信息层面。

真正让 Agent 可以进入现实软件环境的是 Tool Calling。

有了工具之后,它可以:


读取真实文件

可以:


运行真实程序

可以:


查询真实数据库

可以:


调用真实 API

也可以:


修改真实环境

所以我更愿意把:


LLM

看成 Agent 的智能来源,

而把:


Tools

看成 Agent 的能力来源。


我的理解

如果把 Agent 比作一个人,那么:


LLM

决定这个人会不会思考。

而:


Tools

决定这个人到底能做什么。

一个模型即使推理能力很强,如果没有任何工具,它仍然只能停留在聊天窗口里。

但当它拥有:


Shell
File System
Browser
Database
API

之后,它就开始真正进入软件世界。

因此,我认为构建 Agent 时,有一个很重要的问题不是:

模型还能有多聪明?

而是:

我应该给这个模型提供什么工具?

以及:

这些工具应该如何设计,才能让模型稳定、安全地使用?

很多时候,一个 Agent 的能力上限,并不只是由模型决定的。

它还取决于:


模型能看到什么
模型能调用什么
工具能执行什么
系统允许执行到什么程度

从这个角度来看,Tool Calling 才真正完成了从 LLM 到 Agent 的关键一步。

它让 AI 从:


理解世界

走向:


操作世界

这也是为什么,我认为工具调用才是 Agent 真正的能力来源。

返回顶部