GLM4——Function calling(函数调用)

作用:

Function Calling可以根据用户的输入自行判断何时需要调用哪些函数,并且可以根据目标函数的描述生成符合要求的请求参数。开发人员可以使用函数调用能力,通过GPT实现:

在进行自然语言交流时,通过调用外部工具回答问题(类似于ChatGPT插件);

将自然语言转换为调用API时使用的参数,或者查询数据库时使用的条件;

假设我们要创建一个具备查询航班功能的聊天机器人。我们定义如下两个外部函数供模型选择调用:

  1. 查询两地之间某日航班号函数:get_flight_number(departure: str, destination: str, date: str)

  2. 查询航班号以及日期查询票价函数:get_ticket_price(flight_number: str, date: str)

一、定义本地函数

为了向模型描述外部函数库,需要向 tools 字段传入可以调用的函数列表。参数如下表:

参数名称类型是否必填参数说明
typeString设置为function
functionObject
nameString函数名称
descriptionString用于描述函数功能。模型会根据这段描述决定函数调用方式
parametersObjectparameters Object是数所接受的参数。若调用函数时不需要传入参数,省略该参数即可

代码

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_flight_number",
            "description": "根据始发地、目的地和日期,查询对应日期的航班号",
            "parameters": {
                "type": "object",
                "properties": {
                    "departure": {
                        "description": "出发地",
                        "type": "string"
                    },
                    "destination": {
                        "description": "目的地",
                        "type": "string"
                    },
                    "date": {
                        "description": "日期",
                        "type": "string",
                    }
                },
                "required": [ "departure", "destination", "date" ]
            },
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_ticket_price",
            "description": "查询某航班在某日的票价",
            "parameters": {
                "type": "object",
                "properties": {
                    "flight_number": {
                        "description": "航班号",
                        "type": "string"
                    },
                    "date": {
                        "description": "日期",
                        "type": "string",
                    }
                },
                "required": [ "flight_number", "date"]
            },
        }
    },
] 

二、实现

import json


def parse_function_call(model_response,messages):
    # 处理函数调用结果,根据模型返回参数,调用对应的函数。
    # 调用函数返回结果后构造tool message,再次调用模型,将函数结果输入模型
    # 模型会将函数调用结果以自然语言格式返回给用户。
    if model_response.choices[0].message.tool_calls:
        tool_call = model_response.choices[0].message.tool_calls[0]
        args = tool_call.function.arguments
        function_result = {}
        if tool_call.function.name == "get_flight_number":
            function_result = get_flight_number(**json.loads(args))
        if tool_call.function.name == "get_ticket_price":
            function_result = get_ticket_price(**json.loads(args))
        messages.append({
            "role": "tool",
            "content": f"{json.dumps(function_result)}",
            "tool_call_id":tool_call.id
        })
        response = client.chat.completions.create(
            model="glm-4",  # 填写需要调用的模型名称
            messages=messages,
            tools=tools,
        )
        print(response.choices[0].message)
        messages.append(response.choices[0].message.model_dump()) 

三、大模型自动调用对应的函数
1、查询航班,并返回航班号

from zhipuai import ZhipuAI

client = ZhipuAI(api_key="") # 请填写您自己的APIKey
messages = []
messages.append({"role": "user", "content": "帮我查询从2024年1月20日,从北京出发前往上海的航班"})
response = client.chat.completions.create(
    model="glm-4",  # 填写需要调用的模型名称
    messages=messages,
    tools=tools,
)
print(response.choices[0].message)
messages.append(response.choices[0].message.model_dump()) 

执行结果

content=None role='assistant' tool_calls=[CompletionMessageToolCall(id='call_8252663420321749719', function=Function(arguments='{"date":"2024-01-20","departure":"北京","destination":"上海"}', name='get_flight_number'), type='function')]

根据航班号,查询航班票价

messages = []
messages.append({"role": "system", "content": "不要假设或猜测传入函数的参数值。如果用户的描述不明确,请要求用户提供必要信息"})
messages.append({"role": "user", "content": "帮我查询2024年1月20日1234航班的票价"})
response = client.chat.completions.create(
    model="glm-4",  # 填写需要调用的模型名称
    messages=messages,
    tools=tools,
)
print(response.choices[0].message)
messages.append(response.choices[0].message.model_dump()) 

执行结果:

content=None role='assistant' tool_calls=[CompletionMessageToolCall(id='call_8252648611274312180', function=Function(arguments='{"date":"2024-01-20","flight_number":"1234"}', name='get_ticket_price'), type='function')]

根据出发地、目的地及出发时间,自动调用2个函数返回票价(多 Function 调用)
首先,修改函数实现,get_flight_number返回date和flight_number2个结果

def get_flight_number(date:str , departure:str , destination:str):
    flight_number = {
        "北京":{
            "上海" : "1234",
            "广州" : "8321",
        },
        "上海":{
            "北京" : "1233",
            "广州" : "8123",
        }
    }
    return { "date":date,"flight_number":flight_number[departure][destination] }
def get_ticket_price(date:str , flight_number:str):
    print(date)
    print(flight_number)
    return {"ticket_price": "1000"}

其次,修改parse_function_call,支持多次调用函数

import json


def parse_function_call(model_response,messages):
    # 处理函数调用结果,根据模型返回参数,调用对应的函数。
    # 调用函数返回结果后构造tool message,再次调用模型,将函数结果输入模型
    # 模型会将函数调用结果以自然语言格式返回给用户。
    if model_response.choices[0].message.tool_calls is not None:
        tool_call = model_response.choices[0].message.tool_calls[0]
        args = tool_call.function.arguments
        print(tool_call)
        print(args)
        function_result = {}
        if tool_call.function.name == "get_flight_number":
            function_result = get_flight_number(**json.loads(args))
            print("---get_flight_number返回结果---")
            print(json.dumps(function_result))
        if tool_call.function.name == "get_ticket_price":
            function_result = get_ticket_price(**json.loads(args))
            print("---get_flight_number返回结果---")
            print(json.dumps(function_result))
        messages.append({
            "role": "tool",
            "content": f"{json.dumps(function_result)}",
            "tool_call_id":tool_call.id
        })
        print(messages)
        response = client.chat.completions.create(
            model="glm-4",  # 填写需要调用的模型名称
            messages=messages,
            tools=tools,
        )
        print("---第二次调用---")
        print(response.choices[0].message)
        messages.append(response.choices[0].message.model_dump())
        parse_function_call(response,messages) 

最后,修改大模型prompt为“帮我查询2024年3月23日,北京到广州的航班的票价”

import json
# 清空对话
messages = []

messages.append({"role": "system", "content": "不要假设或猜测传入函数的参数值。如果用户的描述不明确,请要求用户提供必要信息"})
messages.append({"role": "user", "content": "帮我查询2024年3月23日,北京到广州的航班的票价"})

response = client.chat.completions.create(
    model="glm-4",  # 填写需要调用的模型名称
    messages=messages,
    tools=tools,
    tool_choice="auto",
)
print("---第一次调用get_flight_number")
print(response.choices[0].message)
messages.append(response.choices[0].message.model_dump())
parse_function_call(response,messages) 
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gm0012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值