BrainBank
AI 课堂/技能DeepLearningAI

M3 智能体式人工智能 - 将函数转化为工具

2026/8/5 17:04:19

#tool-use#skill#lab#aisuite

动手实验:用 AISuite 把 Python 函数暴露为大模型工具——先通过 max_turns 自动完成,再手动编写 schema——并给模型提供天气、文件写入与二维码生成等工具供其编排调用。

M3 智能体式人工智能 - 将函数转化为工具

1. 简介

1.1. 实验概览

在这个非评分实验中,你将使用 aisuite 创建一组工具,提供给大模型使用。你将看到大模型如何请求使用工具,也会看到大模型在任务相关时主动选择特定工具的过程。

🎯 1.2 学习目标

在智能体工作流中应用工具调用设计模式。

为此,你将通过 AISuite 让大模型能够受控地访问 Python 函数,管理参数传递与执行流程,并验证通过工具编排生成的多步骤输出。

2. 环境搭建:初始化环境与客户端

与之前的实验一样,你将从初始化环境开始。你现在会导入若干软件包,之后在为大模型构建工具时还会导入更多。

import json
import display_functions
from dotenv import load_dotenv
_ = load_dotenv()

2.1 初识 AISuite

接下来,你将初始化你在前几课中见过的 AISuite 客户端。初始化之后,它将成为你生成智能体响应和调用工具的接口。

运行下方单元格来初始化客户端。

import aisuite as ai

# Create an instance of the AISuite client
client = ai.Client()

3. 构建你的第一个工具

3.1 定义你的函数

现在你已经搭建好了环境,是时候创建你的第一个工具了。运行下方单元格,定义一个以字符串形式返回当前时间的函数。注意,这个工具包含了一段说明函数用途的 docstring。这一点对 aisuite 来说很重要,因为它会用这段说明帮助向大模型定义该工具。

from datetime import datetime

def get_current_time():
    """
    Returns the current time as a string.
    """
    return datetime.now().strftime("%H:%M:%S")

测试一下你的函数,看看它究竟会返回什么。

<div style="background-color:#ffe4e1; padding:12px; border-radius:6px; color:black;"> <strong>注意:</strong> DeepLearning.AI 平台默认使用格林尼治标准时间(GMT)。如果你在本地运行这个函数,它会返回你本地的时间。 </div>
get_current_time()

很好!正如预期的那样,该函数返回了一个包含当前时间的字符串。

3.2 把你的函数变成一个大模型工具

现在,让我们使用 aisuite 把这个工具传给大模型,并获取响应。要设置你的工具,首先需要设置来自大模型的 response。创建响应首先需要构建消息结构。这个消息结构包括用户提出的提示词,以及一个代表对话历史的字典列表,其中每条消息都有一个 role(例如 "user"、"assistant"、"system")和 content

# Message structure
prompt = "What time is it?"
messages = [
    {
        "role": "user",
        "content": prompt,
    }
]

定义好消息结构后,你就可以构建你的 chat completion 请求了。这会为你调用大模型并返回结果。让我们来看看这次调用中的各个参数。

  • model:将要使用的模型
  • messages:传给大模型的消息列表
  • tools:大模型可以访问的工具列表
  • max_turns:大模型被允许发出的最大消息数量。这有助于防止大模型陷入无限循环,反复调用某个工具。

运行下方单元格来调用大模型并查看响应。

response = client.chat.completions.create(
    model="openai:gpt-4o",
    messages=messages,
    tools=[get_current_time],
    max_turns=5
)

# See the LLM response
print(response.choices[0].message.content)

就是这样,你已经让大模型能够访问工具了!aisuite 工具把你的函数变成了一个工具,从而增强了大模型对世界的认知。

3.3 仔细观察响应内容

虽然最终响应的内容正是你所期待的,但在这个 response 背后其实发生了很多事情。让我们用一个方便的 utility 函数来仔细看看。pretty_print_chat_completion 会从响应中提取出各个步骤,并以易读的格式展示其中的关键部分。

display_functions.pretty_print_chat_completion(response)

如你所见,大模型发送了一条消息,请求使用 get_current_time。这条请求在你的机器上被执行,然后结果被发送回大模型。最后,大模型拥有了完整的对话历史,利用这些信息给出了最终响应。aisuite 帮你处理了所有的复杂细节——从提取带有工具调用的消息、在本地执行它,到在你使用 max_turns 并把函数名传给客户端时,把消息传回大模型。

3.4 手动定义工具

你已经看到,我们工具中提供的 docstring 帮助 aisuite 自动把你的函数变成了大模型可用的工具。这非常方便。但在幕后,把你的函数变成工具,实际发生了什么?

实际上,大模型看到的工具形态要更复杂一些。让我们来看看大模型是真正如何被赋予一个工具的。像之前一样,工具是以列表形式提供的。但在那个列表中,工具有着预设的 schema,其中包含几个重要部分:

  • name:你本地定义的对应函数的名称
  • description:一段说明函数功能的描述,供大模型判断何时使用它
  • parameters:如果你的函数带有参数,这里也会用参数名和参数说明加以描述。

运行下方单元格,用 schema 定义你的工具。

tools = [{
    "type": "function",
    "function": {
        "name": "get_current_time", # <--- Your functions name
        "description": "Returns the current time as a string.", # <--- a description for the LLM
        "parameters": {}
    }
}]

在这种你自己定义 schema 的情况下,aisuite 会期望由你自己来处理执行过程。因此你不会使用 max_turns,而是要自己处理执行逻辑。我们来定义这个响应,把这一切搭建起来。

response = client.chat.completions.create(
    model="openai:gpt-4o",
    messages=messages,
    tools=tools, # <-- Your list of tools with get_current_time
    # max_turns=5 # <-- When defining tools manually, you must handle calls yourself and cannot use max_turns
)

现在你可以查看大模型的响应了。

print(json.dumps(response.model_dump(), indent=2, default=str))

注意,在 responsemessage 下方,你可以看到 tool_calls。大模型的这个响应表示,它现在想要调用一个工具,具体来说,是 get_current_time。你可以添加一些逻辑来处理这种情况,然后把结果传回模型,获取最终响应。

运行下方单元格,在本地运行该函数,把结果返回给大模型,并接收最终响应。

response2 = None

# Create a condition in case tool_calls is in response object
if response.choices[0].message.tool_calls:
    # Pull out the specific tool metadata from the response
    tool_call = response.choices[0].message.tool_calls[0]
    args = json.loads(tool_call.function.arguments)

    # Run the tool locally
    tool_result = get_current_time()

    # Append the result to the messages list
    messages.append(response.choices[0].message)
    messages.append({
        "role": "tool", "tool_call_id": tool_call.id, "content": str(tool_result)
    })

    # Send the list of messages with the newly appended results back to the LLM
    response2 = client.chat.completions.create(
        model="openai:gpt-4o",
        messages=messages,
        tools=tools,
    )

    print(response2.choices[0].message.content)

现在你已经实现了对大模型工具调用的手动处理。你可以选择用 max_turns 让工具自动交给大模型处理,也可以自己编写 schema、手动处理中间过程。

4. 给大模型更多工具

现在你已经探索了工具是如何被创建、又是如何在本地被处理的,接下来我们再创建几个工具。

4.1 三个新工具

你将为你的大模型定义三个新工具:

  • 天气工具(get_weather_from_ip 通过外部 API 调用检测用户所在位置,并返回当前温度、最高温度和最低温度:先检测你的 IP 地址,再把它发送给一个天气 API 来获取当前天气。

  • 文件写入工具(write_txt_file 在你的本地环境中创建一个包含指定内容的文本文件。该函数接受两个参数:file_pathcontent

  • 二维码生成器(generate_qr_code 根据数据生成一张二维码图片,并可选择嵌入图片。该函数接受三个参数:datafilenameimg_path

运行下方单元格,导入一些新的软件包并定义这些工具。

import requests
import qrcode
from qrcode.image.styledpil import StyledPilImage


def get_weather_from_ip():
    """
    Gets the current, high, and low temperature in Fahrenheit for the user's
    location and returns it to the user.
    """
    # Get location coordinates from the IP address
    lat, lon = requests.get('https://ipinfo.io/json').json()['loc'].split(',')

    # Set parameters for the weather API call
    params = {
        "latitude": lat,
        "longitude": lon,
        "current": "temperature_2m",
        "daily": "temperature_2m_max,temperature_2m_min",
        "temperature_unit": "fahrenheit",
        "timezone": "auto"
    }

    # Get weather data
    weather_data = requests.get("https://api.open-meteo.com/v1/forecast", params=params).json()

    # Format and return the simplified string
    return (
        f"Current: {weather_data['current']['temperature_2m']}°F, "
        f"High: {weather_data['daily']['temperature_2m_max'][0]}°F, "
        f"Low: {weather_data['daily']['temperature_2m_min'][0]}°F"
    )

# Write a text file
def write_txt_file(file_path: str, content: str):
    """
    Write a string into a .txt file (overwrites if exists).
    Args:
        file_path (str): Destination path.
        content (str): Text to write.
    Returns:
        str: Path to the written file.
    """
    with open(file_path, "w", encoding="utf-8") as f:
        f.write(content)
    return file_path


# Create a QR code
def generate_qr_code(data: str, filename: str, image_path: str):
    """Generate a QR code image given data and an image path.

    Args:
        data: Text or URL to encode
        filename: Name for the output PNG file (without extension)
        image_path: Path to the image to be used in the QR code
    """
    qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_H)
    qr.add_data(data)

    img = qr.make_image(image_factory=StyledPilImage, embedded_image_path=image_path)
    output_file = f"{filename}.png"
    img.save(output_file)

    return f"QR code saved as {output_file} containing: {data[:50]}..."

4.2 使用你的新工具

现在是使用你新工具的时候了!response 看起来会和之前几乎一样,但不同的是,这次你会把所有工具都传给大模型。大模型会根据你发送的提示词选择合适的工具。我们先从 get_weather_from_ip 工具开始。

prompt = "Can you get the weather for my location?"

response = client.chat.completions.create(
    model="openai:o4-mini",
    messages=[{"role": "user", "content": (
        prompt
    )}],
    tools=[
        get_current_time,
        get_weather_from_ip,
        write_txt_file,
        generate_qr_code
    ],
    max_turns=5
)

display_functions.pretty_print_chat_completion(response)

你可以看到,尽管大模型能访问其他工具,它依然根据提示词的意图正确选择了对应的工具。

现在,运行下方单元格,提示大模型帮你创建一条便签。

prompt = "Can you make a txt note for me called reminders.txt that reminds me to call Daniel tomorrow at 7PM?"

response = client.chat.completions.create(
    model="openai:o4-mini",
    messages=[{"role": "user", "content": (
        prompt
    )}],
    tools=[
        get_current_time,
        get_weather_from_ip,
        write_txt_file,
        generate_qr_code
    ],
    max_turns=5
)

display_functions.pretty_print_chat_completion(response)

现在你有了一个包含提醒事项的文本文件。你可以看到,大模型把正确的参数传给了这个工具,工具在本地运行,随后打印出一条响应,说明该操作已完成。你甚至可以打开这个文本文件,读取其内容,确认它确实已经存在。

with open('reminders.txt', 'r') as file:
    contents = file.read()
    print(contents)

最后,让我们使用这个二维码生成工具,制作一个能带用户跳转到 DeepLearning.AI 网站的漂亮二维码。

运行下方单元格来创建这个二维码。

prompt = "Can you make a QR code for me using my company's logo that goes to www.deeplearning.ai? The logo is located at `dl_logo.jpg`. You can call it dl_qr_code."

response = client.chat.completions.create(
    model="openai:o4-mini",
    messages=[{"role": "user", "content": (
        prompt
    )}],
    tools=[
        get_current_time,
        get_weather_from_ip,
        write_txt_file,
        generate_qr_code
    ],
    max_turns=5
)

display_functions.pretty_print_chat_completion(response)

大模型同样成功地把正确的参数传给了这个函数,随后这些信息被用来运行你的函数并创建这个二维码。运行下方单元格来查看这个二维码,并试着扫描它,看它是否真的能带你跳转到 DeepLearning.AI 网站。

from IPython.display import Image, display

# Display image directly
Image('dl_qr_code.png')

4.3 同时使用多个工具

最后,重要的是要记住,大模型可以同时使用多个工具,并按顺序完成一连串工具调用来达成多个目标。我们来使用你的工具,并检查一下 response,看看会发生什么。你将使用一条复杂的提示词:

Can you help me create a qr code that goes to www.deeplearning.com from the image dl_logo.jpg? Also write me a txt note with the current weather please.

这条提示词需要相当多的逻辑推理,才能理解该调用什么、何时调用。举例来说,虽然你要求它先写一条文本便签,然后再描述其内容,但大模型需要先获取相关信息,才能把它写进文本便签中。如果大模型先调用 write_txt_file,它就还没有来自 get_weather_from_ip 的信息。这很好地展示了大模型解析自然语言、并按照正确顺序使用合适工具来完成各种任务的能力。

<div style="background-color: #ffe4e1; padding: 12px; border-radius: 6px; color: black;">
<h4>🔍 值得留意的地方</h4>
<ul> <li>大模型会<b>自动选择</b>要使用的工具,依据是用户的请求</li> <li><b>参数是从用户的消息中推断出来的</b>(例如文件名、内容、网址)</li> <li>每个工具都会<b>返回信息</b>,供大模型整合进它的响应中</li> <li><b>无参数工具</b>(如天气和时间)非常适合用于快速的信息查询</li> <li>尽管背后进行着复杂的操作,整个对话依然显得<b>自然流畅</b></li> </ul>
</div>
prompt = "Can you help me create a qr code that goes to www.deeplearning.com from the image dl_logo.jpg? Also write me a txt note with the current weather please."

response = client.chat.completions.create(
    model="openai:o4-mini",
    messages=[{"role": "user", "content": (
        prompt
    )}],
    tools=[
        get_weather_from_ip,
        get_current_time,
        write_txt_file,
        generate_qr_code
    ],
    max_turns=10
)

display_functions.pretty_print_chat_completion(response)

就是这样,从工具调用序列中你可以看到,它按照正确的顺序调用了这些工具来完成任务,但响应内容是按你请求的顺序给出的。

模型选项

在运行这些工具调用工作流时,你可以尝试不同的 OpenAI 模型。每种模型在能力、成本和速度之间都有不同的平衡:

  • openai:gpt-4o — 针对推理能力和速度做了优化
  • openai:gpt-4.1 — 推理性能强,适合处理复杂任务
  • openai:gpt-4.1-mini — 比完整版 GPT-4.1 更轻量、更快、更便宜
  • openai:gpt-3.5-turbo — 适合处理简单任务和快速迭代

选择哪个模型取决于你的目标:

  • 对于快速、低成本的原型验证,使用更小的模型
  • 当任务需要更强的推理能力或多步骤编排时,切换到更强大的模型

最终总结

  • 工具调用让大模型不再局限于生成文本——它们现在可以把函数用作推理过程的一部分。
  • 清晰、有良好文档说明的函数(配有精确的 docstring)能帮助模型判断何时、如何使用每个工具。
  • AISuite 负责处理把 Python 函数转化为工具 schema、并编排多步骤工作流的复杂性。
  • 选择合适的模型很重要:更小的模型在处理简单任务时更快、更便宜,而更强大的模型更适合以推理为主的工作流。
  • 观察对话的完整流程(提示词、工具调用、结果、最终响应)对于调试和改进智能体行为至关重要。

有了这些要素,你现在已经具备了设计能够将大模型推理与外部工具结合起来、完成更复杂任务的智能体的基础。

<div style="border:1px solid #22c55e; border-left:6px solid #16a34a; background:#dcfce7; border-radius:6px; padding:14px 16px; color:#064e3b; font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;">

🎉 <strong>恭喜!</strong>

你已经完成了使用 AISuite 将函数转化为工具的实验。 在此过程中,<strong></strong>把 Python 函数暴露为工具,让大模型能够选择并调用它们,并观察了多步骤工具编排的过程。

有了这些技能,<strong></strong>就能设计出将大模型推理与真实操作结合起来的智能体工作流——可靠、可审计,且易于扩展。🌟

</div>

学习地图

本页是「DeepLearningAI > Agentic AI Lab」的第 3 / 7 页——这是一份真实的 DeepLearning.AI 笔记本(代码 + 讲解文字),而非「Agentic AI」板块中那种模板化内容。顺序上接在「M2 - 智能体式人工智能 - 用反思改进 SQL 生成」之后。完成后可继续阅读「M3 智能体式人工智能 - 邮件助手工作流」。代码单元格完全保留了源笔记本中的原样——请在你自己的 Python 环境中按顺序运行它们(它们依赖 utils.py 等本地辅助模块,这里并未包含)。

动手实践——分步指南

搭建好这份笔记本所需的本地依赖(代码单元格中导入的辅助模块,例如 utils.py、display_functions.py,以及文中引用的各个工具模块),然后按照「M3 智能体式人工智能 - 将函数转化为工具」自身的分步讲解,从上到下依次运行每个代码单元格。在进入下一个实验之前,先尝试文中建议的实验(更换模型、修改提示词、提出你自己的请求)。

三大推荐资源

  1. 1
    aisuite (GitHub)

    The unified multi-provider LLM client used throughout these labs for chat completions and tool calling.

    https://github.com/andrewyng/aisuite

  2. 2
    Claude Docs: Tool Use

    Anthropic's reference for defining and orchestrating tool calls, the same pattern these labs implement with aisuite.

    https://docs.claude.com/en/docs/agents-and-tools/tool-use/overview

链接由 AI 推荐——使用前建议快速核实。