Agents 课程文档
什么是工具?
并获得增强的文档体验
开始使用
什么是工具?

AI Agent 的一个关键方面是它们采取行动的能力。正如我们所见,这通过使用工具来实现。
在本节中,我们将学习什么是工具,如何有效地设计工具,以及如何通过系统消息将它们集成到您的 Agent 中。
通过为您的 Agent 提供正确的工具——并清楚地描述这些工具的工作原理——您可以极大地提高您的 AI 可以完成的任务。让我们深入了解一下!
什么是 AI 工具?
工具是提供给 LLM 的函数。此函数应实现一个明确的目标。
以下是 AI Agent 中一些常用的工具
工具 | 描述 |
---|---|
网络搜索 | 允许 Agent 从互联网获取最新的信息。 |
图像生成 | 根据文本描述创建图像。 |
检索 | 从外部来源检索信息。 |
API 接口 | 与外部 API 交互(GitHub、YouTube、Spotify 等)。 |
这些只是一些示例,实际上您可以为任何用例创建工具!
一个好的工具应该是对 LLM 的能力进行补充的东西。
例如,如果您需要执行算术运算,为您的 LLM 提供一个计算器工具将比依赖模型的原生能力提供更好的结果。
此外,LLM 根据其训练数据预测提示的完成情况,这意味着它们的内部知识仅包括训练之前的事件。因此,如果您的 Agent 需要最新的数据,您必须通过一些工具来提供。
例如,如果您直接询问 LLM(没有搜索工具)今天的天气,LLM 可能会幻觉出随机的天气。

一个工具应该包含
- 函数作用的文本描述。
- 一个 Callable(用于执行操作的东西)。
- 带有类型的参数。
- (可选)带有类型的输出。
工具如何工作?
正如我们所见,LLM 只能接收文本输入并生成文本输出。它们无法自行调用工具。当我们谈论为 Agent 提供工具时,我们指的是教会 LLM 这些工具的存在,并指示它在需要时生成基于文本的调用。
例如,如果我们提供一个工具来检查某个位置的互联网天气,然后询问 LLM 关于巴黎的天气,LLM 将识别出这是一个使用“天气”工具的机会。LLM 不会自己检索天气数据,而是会生成表示工具调用的文本,例如 call weather_tool(‘Paris’)。
然后 Agent 读取此响应,识别出需要工具调用,代表 LLM 执行该工具,并检索实际的天气数据。
工具调用步骤通常不会向用户显示:Agent 将它们作为新消息附加,然后再将更新后的对话传递给 LLM。然后,LLM 处理此附加上下文,并为用户生成自然的响应。从用户的角度来看,这看起来好像 LLM 直接与工具交互,但实际上,是 Agent 在后台处理了整个执行过程。
我们将在以后的课程中更多地讨论此过程。
我们如何给 LLM 提供工具?
完整的答案可能看起来令人难以承受,但我们基本上使用系统提示来向模型提供可用工具的文本描述

为了使其工作,我们必须非常精确和准确地说明
- 工具的作用
- 它期望的确切输入
这就是为什么工具描述通常使用表达性但精确的结构(例如计算机语言或 JSON)来提供的原因。不一定要这样做,任何精确且连贯的格式都可以。
如果这看起来太理论化,让我们通过一个具体的例子来理解它。
我们将实现一个简化的计算器工具,它将只乘以两个整数。这可能是我们的 Python 实现
def calculator(a: int, b: int) -> int:
"""Multiply two integers."""
return a * b
因此,我们的工具名为 calculator
,它将两个整数相乘,并且需要以下输入
a
(int): 一个整数。b
(int): 一个整数。
工具的输出是另一个整数,我们可以这样描述它
- (int):
a
和b
的乘积。
所有这些细节都很重要。让我们将它们放在一起,用一个文本字符串来描述我们的工具,以便 LLM 理解。
Tool Name: calculator, Description: Multiply two integers., Arguments: a: int, b: int, Outputs: int
提醒: 此文本描述是我们希望 LLM 了解的关于工具的信息。
当我们将之前的字符串作为输入的一部分传递给 LLM 时,模型将识别它为工具,并将知道它需要传递什么作为输入以及期望从输出中获得什么。
如果我们想提供其他工具,我们必须保持一致并始终使用相同的格式。此过程可能很脆弱,我们可能会意外地忽略一些细节。
有没有更好的方法?
自动格式化工具部分
我们的工具是用 Python 编写的,并且实现已经提供了我们需要的一切
- 对其作用的描述性名称:
calculator
- 更长的描述,由函数的文档字符串注释提供:
Multiply two integers.
(乘以两个整数。) - 输入及其类型:该函数清楚地期望两个
int
。 - 输出的类型。
人们使用编程语言是有原因的:它们具有表达性、简洁性和精确性。
我们可以提供 Python 源代码作为 LLM 工具的规范,但工具的实现方式并不重要。重要的是它的名称、它的作用、它期望的输入和它提供的输出。
我们将利用 Python 的内省功能来利用源代码并自动为我们构建工具描述。我们所需要的只是工具实现使用类型提示、文档字符串和合理的函数名称。我们将编写一些代码来从源代码中提取相关部分。
完成之后,我们只需要使用 Python 装饰器来指示 calculator
函数是一个工具
@tool
def calculator(a: int, b: int) -> int:
"""Multiply two integers."""
return a * b
print(calculator.to_string())
请注意函数定义之前的 @tool
装饰器。
通过我们接下来将看到的实现,我们将能够通过装饰器提供的 to_string()
函数从源代码中自动检索以下文本
Tool Name: calculator, Description: Multiply two integers., Arguments: a: int, b: int, Outputs: 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
装饰器的作用。
如果您有兴趣,可以公开以下部分以查看装饰器实现。
装饰器代码
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 工具描述的文本
Tool Name: calculator, Description: Multiply two integers., Arguments: a: int, b: int, Outputs: int
该描述注入到系统提示中。以我们开始本节的示例为例,以下是替换 tools_description
后的外观

在行动部分中,我们将了解有关 Agent 如何调用我们刚刚创建的工具的更多信息。
模型上下文协议 (MCP):统一的工具接口
模型上下文协议 (MCP) 是一种开放协议,它标准化了应用程序向 LLM 提供工具的方式。MCP 提供
- 不断增长的预构建集成列表,您的 LLM 可以直接插入其中
- 在 LLM 提供商和供应商之间切换的灵活性
- 在您的基础设施中保护数据的最佳实践
这意味着任何实现 MCP 的框架都可以利用协议中定义的工具,从而无需为每个框架重新实现相同的工具接口。
工具在增强 AI Agent 的能力方面起着至关重要的作用。
总结一下,我们学习了
什么是工具:为 LLM 提供额外功能的函数,例如执行计算或访问外部数据。
如何定义工具:通过提供清晰的文本描述、输入、输出和可调用函数。
为什么工具至关重要:它们使 Agent 能够克服静态模型训练的局限性,处理实时任务并执行专门的操作。
现在,我们可以继续学习Agent 工作流程,您将在其中看到 Agent 如何观察、思考和行动。这将我们到目前为止涵盖的所有内容结合在一起,并为创建您自己的全功能 AI Agent 奠定基础。
但首先,是时候进行另一个简短的测验了!
< > 在 GitHub 上更新