大模型工具调用详解

大模型具有一个十分强大的功能就是可以自主调用外部工具函数,以自主意识的形式借用工具,完成使用者发布的命令。这意味着大模型不再只是一个被动的执行者,而是一个具有主动性的智能助手。

大模型的工具调用功能是一项具有划时代意义的进步。这一功能的实现,使得大模型不再局限于自身数据库知识的回答,而是跃进到了一个全新的层次调用外部函数,其调用流程如图9-1 所示。

                                              

9-1  大语言模型的工具调用功能

这意味着大语言模型在与用户交互时,可以实时检索外部函数库。当用户提问时,模型不再仅从自身知识库中寻找答案,而是会根据实际需求,在外部函数库中进行检索,找出合适的函数并调用它。这种调用外部函数的能力,使得大语言模型可以获取到函数的运行结果,并基于这些结果进行回答。

9.1.1  Python 调用工具的基本原理

工具的使用是一项非常简单的事情,从我们祖先钻木取火,到现在人类飞上月球在太空建立永=久基地,这些都离不开工具的使用。在现实生活中,决定今天出门要不要带上雨伞,都需要借助网络信息或者广播工具了解今天的天气情况。

Python 同样也可以使用工具来完成对外部API 的调用,所需要的仅仅是一个函数名称而已。示例代码如下:


# 创建了一个简单的查询天气的 API

def get_weather(location = ""):

    " 读者可以编写对应的天气查询 API ,这里仅作为演示 "

    if location == "ShangHai":

        return 23.0

    elif location == "TianJin":

        return 25.0

    else:

        return " 未查询相关内容 "

location = "ShangHai"

# 注意写法格式,里面的单引号不能少

result = eval(f"get_weather(location='{location}')")# 使用 eval 调用字符串名称对应的函数

print(" 查询到的结果是: ", result)


最终打印结果如下:

查询到的结果是: 23.0

可以看到,Python 中提供的eval() 函数可以根据传入的字符串自动运行对应的函数。在这个示例中,我们将location 变量的值嵌入字符串中,然后将该字符串作为代码传给eval() 函数执行。注意,在嵌入变量值时,我们使用了单引号将变量值引起来,以确保代码的正确解析。

eval() 函数是Python 的一个内置函数,它的功能是将字符串作为Python 代码执行。其工作原理可以简单概括为“字符串解析和执行”。

当我们调用eval() 函数并传入一个字符串时,函数会尝试解析这个字符串,将它转换成Python 的表达式或语句,然后在当前的命名空间中执行这些表达式或语句。

例如,我们传入字符串"1+2"


print(eval("1+2"))


eval() 函数会将这个字符串解析为Python 的加法表达式,然后计算这个表达式的值,并返回结果3

9.1.2   使用Qwen3 演示大模型工具 调用方法

在上一小节中,我们展示了如何在Python 中调用函数,但是,我们面临一个更复杂的问题:如何在大模型Qwen3 中调用工具?这个问题看似简单,实则涉及许多深层次的技术与思考。就如同多年前人们询问计算机“今天是晴天还是雨天”一样,我们如今要探讨的是如何让大模型调用工具来解决问题。

先回到日常生活中的一个例子。在决定今天的穿着之前,我们通常会有一个明确的前置任务:了解今天的天气。那么,如何获取天气信息呢?以下是一些可能的方法:

Ÿ   A :对着衣橱问自己应该穿什么衣服。这显然不是获取天气信息的正确途径。

Ÿ   B :使用互联网登录天气网站,输入本地名称查询。这是一个有效且常用的方法。

Ÿ   C :打开一本书阅读任意一页。这与获取天气信息无关。

Ÿ   D :打开空调。这同样不能告诉我们今天的天气情况。

对于大多数读者来说,选择B 是显而易见的,这是基于我们的常识和日常经验。然而,这种基于目标寻找最合适解决方案的能力并非天生,而是需要我们后天的学习和积累。我们需要知道哪些工具或方法可以帮助我们实现目标,这通常需要一个知识库或他人的指导。

9-2 所示是一个基于常识的决策过程,同时也是我们在日常生活中做出明智决策并取得良好结果的通用步骤。在每次决策之前,我们依赖的是深厚的知识储备或知识库,它们如同明灯,照亮我们前行的道路,引导我们做出最优决策。

9-2  有知识库辅助研判的任务流程

当我们回到大模型调用工具的问题时,面临的挑战是如何让大模型也具备这样的决策能力,即根据给定的任务,它能知道应当调用哪些工具。作为AI 应用开发人员,我们的责任不仅是开发模型,更要引导模型使用工具。我们可以提供格式化的API 信息,这种方式就像给大模型提供一本详细的程序文档。在这份文档中,我们详细描述每个工具API 的功能、参数以及返回值,告诉大语言模型在何时、何地可以调用这些API ,并且当API 被调用后,返回相应的API JSON 对象。

这样的方式能够让大模型更加智能化地运用工具,进而提升其解决问题的效率和准确性。想象一下,当大模型遇到问题时,它可以像人类一样查阅“工具书”,找到最合适的工具,然后利用这个工具解决问题。

一个可供大模型调用的简单函数如下:


# 定义工具函数

def get_weather(function_params):

    """ 模拟获取天气的工具函数 """

    location = function_params[0]

    # 这里可以调用真实的天气 API

    return f"{location} 的天气晴朗 "


上述函数对象描述了一个名为get_weather 的工具API 。通过这个API ,大模型可以根据输入的城市名称获取当前的天气情况。这样的描述方式清晰明了,使得大模型能够准确理解并调用这个API 。因此,通过对工具API 中的描述进行甄别,可以判定最合适使用哪一个工具,再加上合理的引导和训练,可以使大模型更加智能化,从而完成对工具的使用。

下面是一个基于Qwen3 的大语言模型工具调用的完整示例。与前面介绍的Qwen3 原生模型工具调用不同,这里演示的是基本工具调用的方法。代码如下:


from openai import OpenAI

import json

import re  # 添加正则表达式模块

 

client = OpenAI(

    api_key="sk-17f687f6c5ac4647a9d9f649598a7cfe",

    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",

)

 

def get_weather(function_params):

    # 处理中英文城市名

    city = function_params[0]

    if city.lower() in ["shanghai", " 上海 "]:

        return " 上海:多云转晴, 25 "

    elif city.lower() in ["tianjin", " 天津 "]:

        return " 天津:晴朗, 28 "

    return f"{city} :天气数据暂缺 "

 

def send_messages(messages):

    response = client.chat.completions.create(

        model="qwen-plus",

        messages=messages

    )

    return response.choices[0].message

 

# 优化后的系统提示

system_prompt = """

你是一个严格遵循 " 思考→工具调用→响应 " 工作流的 AI 助手。请按以下格式响应:

 

思考: [ 你的思考过程 ]

Action {

    "function_name": " 函数名 ",

    "function_params": [" 参数 1", " 参数 2"]

}

响应: [ 最终给用户的回答 ]

 

可用工具:

- get_weather(city): 查询城市天气

 

注意:

1. 只使用上述工具

2. 城市名请使用中文

3. Action 部分必须是纯 JSON 格式

"""

 

question = "Shanghai 的天气怎么样 "

 

messages = [{"role": "system", "content": system_prompt},

            {"role": "user", "content": question}]

 

message = send_messages(messages)

response = message.content

print(" 模型原始响应 :")

print(response)

print("-" * 50)

 

# 使用正则表达式提取 JSON 部分

try:

    # 查找 {...} 格式的 JSON 对象

    json_match = re.search(r'\{[\s\S]*\}', response)

    if json_match:

        action_str = json_match.group(0)

        action = json.loads(action_str)

        print(" 解析后的 Action:")

        print(action)

 

        # 执行函数调用

        function_name = action["function_name"]

        function_params = action["function_params"]

        result = globals()[function_name](function_params)

        print("\n 工具调用结果 :", result)

 

        # 获取最终响应

        if " 响应: " in response:

            final_response = response.split(" 响应: ")[-1].strip()

        else:

            final_response = " 查询完成 "

 

        print("\n 最终回复 :", final_response)

    else:

        raise ValueError(" 未找到有效的 JSON 格式 Action")

 

except Exception as e:

    print(" 处理出错 :", str(e))

    print(" 建议检查模型响应格式是否符合要求 ")


这段代码实现了一个简单的对话系统,该系统能够根据用户的问题调用相应的工具并生成回答。首先,通过OpenAI 库初始化了一个客户端,并设置了API 密钥和基础URL 。接着,定义了一个get_weather() 函数,用于模拟获取天气的功能,返回固定的“天气晴朗”结果。send_messages() 函数则负责向模型发送消息并获取模型的响应。系统提示(system_prompt )中详细描述了对话系统的三个阶段:思考、工具调用和响应,并提供了一个示例说明如何调用get_weather 工具,以回答天气相关的问题。

生成结果如下:


ModelResponse:

 {'function_name': 'get_weather', 'function_params': [' 上海 ']}

get_weather([' 上海 '])

天气晴朗


具体来看,在代码的执行部分,用户提出了一个关于上海天气的问题。系统通过send_messages 函数将问题发送给模型,模型根据系统提示生成一个包含工具调用信息的响应。代码通过解析响应中的Action 部分,提取出需要调用的工具名称和参数,并生成相应的调用代码。最后,使用eval 函数执行生成的代码,模拟工具调用的过程,并输出结果。整个过程展示了如何通过模型生成工具调用指令,并动态执行这些指令来完成用户请求。


=========================================

本文节选自《AI Agent智能体与MCP开发实践:基于Qwen3大模型》,获得出版社和作者授权发布。





请使用浏览器的分享功能分享到微信等