Agents Course documentation
什么是工具?
什么是工具?

AI 智能体的关键能力在于执行行动。正如前文所述,这通过工具的使用实现。
本节将学习工具的定义、有效设计方法,以及如何通过系统消息将其集成到智能体中。
通过为智能体配备合适的工具——并清晰描述这些工具的工作原理——可显著提升 AI 的能力边界。让我们深入探讨!
AI 工具的定义
工具是赋予 LLM 的函数,该函数应实现明确的目标。
以下是 AI 智能体中常用的工具示例:
工具类型 | 描述 |
---|---|
网络搜索 | 允许智能体从互联网获取最新信息 |
图像生成 | 根据文本描述生成图像 |
信息检索 | 从外部源检索信息 |
API 接口 | 与外部 API 交互(GitHub、YouTube、Spotify 等) |
以上仅为示例,实际可为任何用例创建工具!
优秀工具应能补充 LLM 的核心能力。
例如,若需执行算术运算,为 LLM 提供计算器工具将比依赖模型原生能力获得更好结果。
此外,LLM 基于训练数据预测提示的补全,意味着其内部知识仅包含训练截止前的信息。因此,若智能体需要最新数据,必须通过工具获取。
例如,若直接询问 LLM(无搜索工具)今日天气,LLM 可能会产生随机幻觉。

- 合格工具应包含:
- 函数功能的文本描述
- 可调用对象(执行操作的实体)
- 带类型声明的参数
- (可选)带类型声明的输出
工具如何运作?
正如前文所述,LLM 只能接收文本输入并生成文本输出。它们无法自行调用工具。当我们谈及为智能体提供工具时,实质是教导 LLM 认识工具的存在,并要求模型在需要时生成调用工具的文本。例如,若我们提供从互联网获取某地天气的工具,当询问 LLM 巴黎天气时,LLM 将识别该问题适合使用我们教授的”天气”工具,并生成代码形式的文本来调用该工具。智能体负责解析 LLM 的输出,识别工具调用需求,并执行工具调用。工具的输出将返回给 LLM,由其生成最终用户响应。
工具调用的输出是对话中的另一种消息类型。工具调用步骤通常对用户不可见:智能体检索对话、调用工具、获取输出、将其作为新消息添加,并将更新后的对话再次发送给 LLM。从用户视角看,仿佛 LLM 直接使用了工具,但实际执行的是我们的应用代码(智能体)。
后续课程将深入探讨该流程。
如何为 LLM 提供工具?
完整答案可能看似复杂,但核心是通过系统提示(system prompt)向模型文本化描述可用工具:

为确保有效性,必须精准描述:
- 工具功能
- 预期输入格式
因此工具描述通常采用结构化表达方式(如编程语言或 JSON)。虽非强制,但任何精确、连贯的格式均可。
若觉抽象,我们通过具体示例理解。
我们将实现简化的计算器工具,仅执行两整数相乘。Python 实现如下:
def calculator(a: int, b: int) -> int:
"""Multiply two integers."""
return a * b
因此我们的工具名为calculator
,其功能是将两个整数相乘,需要以下输入:
a
(int):整数b
(int):整数
工具输出为另一个整数,描述如下:
- (int):
a
与b
的乘积
所有这些细节都至关重要。让我们将这些信息整合成 LLM 可理解的工具描述文本:
工具名称: calculator,描述:将两个整数相乘。参数:a: int, b: int,输出:int
重要提示: 此文本描述是我们希望 LLM 了解的工具体系。
当我们将上述字符串作为输入的一部分传递给 LLM 时,模型将识别其为工具,并知晓需要传递的输入参数及预期输出。
若需提供更多工具,必须保持格式一致性。此过程可能较为脆弱,容易遗漏某些细节。
是否有更好的方法?
自动化工具描述生成
我们的工具采用 Python 实现,其代码已包含所需全部信息:
- 功能描述性名称:
calculator
- 详细说明(通过函数文档字符串实现):
将两个整数相乘
- 输入参数及类型:函数明确要求两个
int
类型参数 - 输出类型
这正是人们使用编程语言的原因:表达力强、简洁且精确。
虽然可以将 Python 源代码作为工具规范提供给 LLM,但具体实现方式并不重要。关键在于工具名称、功能描述、输入参数和输出类型。
我们将利用 Python 的自省特性,通过源代码自动构建工具描述。只需确保工具实现满足:
- 使用类型注解(Type Hints)
- 编写文档字符串(Docstrings)
- 采用合理的函数命名
完成这些之后,我们只需使用一个 Python 装饰器来指示calculator
函数是一个工具:
@tool
def calculator(a: int, b: int) -> int:
"""Multiply two integers."""
return a * b
print(calculator.to_string())
注意函数定义前的@tool
装饰器。
通过我们即将看到的实现,可以利用装饰器提供的to_string()
方法从源代码自动提取以下文本:
工具名称: calculator,描述:将两个整数相乘。参数:a: int, b: int,输出:int
正如所见,这与我们之前手动编写的内容完全一致!
通用工具类实现
我们创建通用Tool
类,可在需要时重复使用:
说明: 此示例实现为虚构代码,但高度模拟了主流工具库的实际实现方式。
class Tool:
"""
A class representing a reusable piece of code (Tool).
Attributes:
name (str): Name of the tool.
description (str): A textual description of what the tool does.
func (callable): The function this tool wraps.
arguments (list): A list of argument.
outputs (str or list): The return type(s) of the wrapped function.
"""
def __init__(self,
name: str,
description: str,
func: callable,
arguments: list,
outputs: str):
self.name = name
self.description = description
self.func = func
self.arguments = arguments
self.outputs = outputs
def to_string(self) -> str:
"""
Return a string representation of the tool,
including its name, description, arguments, and outputs.
"""
args_str = ", ".join([
f"{arg_name}: {arg_type}" for arg_name, arg_type in self.arguments
])
return (
f"Tool Name: {self.name},"
f" Description: {self.description},"
f" Arguments: {args_str},"
f" Outputs: {self.outputs}"
)
def __call__(self, *args, **kwargs):
"""
Invoke the underlying function (callable) with provided arguments.
"""
return self.func(*args, **kwargs)
虽然看似复杂,但逐步解析即可理解其工作机制。我们定义的Tool
类包含以下核心要素:
name
(str):工具名称description
(str):工具功能简述function
(callable):工具执行的函数arguments
(list):预期输入参数列表outputs
(str 或 list):工具预期输出__call__()
:调用工具实例时执行函数to_string()
:将工具属性转换为文本描述
可通过如下代码创建工具实例:
calculator_tool = Tool(
"calculator", # name
"Multiply two integers.", # description
calculator, # function to call
[("a", "int"), ("b", "int")], # inputs (names and types)
"int", # output
)
但我们可以利用 Python 的inspect
模块自动提取这些信息!这正是@tool
装饰器的实现原理。
若感兴趣,可展开以下内容查看装饰器具体实现:
decorator code
def tool(func):
"""
A decorator that creates a Tool instance from the given function.
"""
# Get the function signature
signature = inspect.signature(func)
# Extract (param_name, param_annotation) pairs for inputs
arguments = []
for param in signature.parameters.values():
annotation_name = (
param.annotation.__name__
if hasattr(param.annotation, '__name__')
else str(param.annotation)
)
arguments.append((param.name, annotation_name))
# Determine the return annotation
return_annotation = signature.return_annotation
if return_annotation is inspect._empty:
outputs = "No return annotation"
else:
outputs = (
return_annotation.__name__
if hasattr(return_annotation, '__name__')
else str(return_annotation)
)
# Use the function's docstring as the description (default if None)
description = func.__doc__ or "No description provided."
# The function name becomes the Tool name
name = func.__name__
# Return a new Tool instance
return Tool(
name=name,
description=description,
func=func,
arguments=arguments,
outputs=outputs
)
简而言之,在应用此装饰器后,我们可以按如下方式实现工具:
@tool
def calculator(a: int, b: int) -> int:
"""Multiply two integers."""
return a * b
print(calculator.to_string())
我们可以使用Tool
类的to_string
方法自动生成适合LLM使用的工具描述文本:
工具名称: calculator,描述:将两个整数相乘。参数:a: int, b: int,输出:int
该描述将被注入系统提示。以本节初始示例为例,替换tools_description
后的系统提示如下:

在Actions章节,我们将深入探讨智能体如何调用刚创建的这个工具。
工具在增强AI智能体能力方面至关重要。
总结本节要点:
工具定义:通过提供清晰的文本描述、输入参数、输出结果及可调用函数
工具本质:赋予LLM额外能力的函数(如执行计算或访问外部数据)
工具必要性:帮助智能体突破静态模型训练的局限,处理实时任务并执行专业操作
现在进入【智能体工作流】(agent-steps-and-structure)章节,您将看到智能体如何观察、思考与行动。这整合了当前所学全部内容,为创建功能完备的 AI 智能体奠定基础。
但在此之前,让我们先完成另一个简短测验!
< > Update on GitHub