Function Call实践(一)——调用国内大模型测试 #126

Open
opened 2024-09-26 10:21:37 +08:00 by 12390900721cs · 0 comments

Function Call实践的学习流程仍然是从调用国内外大模型API进行大模型测试开始的。由于原理类似,而我们的平台环境只方便用国内大模型API进行测试,这里就对国内大模型API调用流程和代码进行一下分析。

Function Call:

函数调用功能可以增强模型推理效果或进行其他外部操作,包括信息检索、数据库操作、知识图谱搜索与推理、操作系统、触发外部操作等工具调用场景。

在ChatGLM中,tools 是内容生成 API 中的可选参数,用于向模型提供函数定义。通过此参数,模型能够生成符合用户所提供规范的函数参数。(在ChatGPT中也兼容tools参数,但更多的使用functions参数。)** 请注意,API 实际上不会执行任何函数调用,仅返回调用函数所需要的参数。开发者可以利用模型输出的参数在应用中执行函数调用。

步骤:

  1. 使用Chat Completion接口向模型描述外部函数;

  1. 与模型交互,触发模型对函数的调用;

在 tools 参数中,如果填写了 functions 参数,则默认情况下模型将决定何时适合使用其中一个函数。 如果要控制模型如何选择函数调用,需要设置 tool_choice 参数。参数默认值为auto,此时模型根据上下文信息自行选择是否返回函数调用。将其设置为 {“name”: “your_function_name”} 时,可以强制 API 返回特定函数的调用。还可以通过将 tool_choice 参数设置为 “none” 来强制 API 不返回任何函数的调用。目前函数调用仅支持 auto 模式。

  1. 使用模型生成的结果调用外部函数。

首先将所需的函数实现;

随后定义处理 Function call 的函数即可,具体流程为:

# 处理函数调用结果,根据模型返回参数,调用对应的函数;
# 调用函数返回结果后构造tool message,再次调用模型,将函数结果输入模型;
# 模型会将函数调用结果以自然语言格式返回给用户。

调用GLM4-plus

了解Function Call运行流程后,我们对调用GLM4-plus的代码进行分析。

设置网络代理;

定义模型可读的tools,zhipu不兼容functions,需要使用tools;

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather_info",
            "description": "Get the weather information of a city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "The name of the city, e.g. Shanghai",
                    },
                },
                "required": ["city"],
            },
        }
    }
]

使用Chat Completion接口向模型描述外部函数

初始化ZhipuAI,调用大模型,让大模型指导调用哪个function以及输入的参数是什么;

from zhipuai import ZhipuAI
# 创建智普大模型的客户端实例
client = ZhipuAI(api_key="xxx")

query = "What is the weather like in Beijing?"
messages=[{"role": "user", "content": query}]
response = client.chat.completions.create(
        model="GLM-4-Plus",
        messages=messages,
        tools=tools,
        tool_choice="auto",
    )
message = response.dict()["choices"][0]["message"]
print(message)

这里的“指导”即大模型会根据tools自动选择function并识别输入的参数;输出结果为:

{'content': None, 'role': 'assistant', 'tool_calls': [{'id': 'call_9053597030834077390', 'function': {'arguments': '{"city": "Beijing"}', 'name': 'get_weather_info'}, 'type': 'function', 'index': 0}]}

调用大模型,查看结果

#message["tool_calls"][0]['function']['name']即之前的'name': 'get_weather_info',指的是函数名称
func_name = message["tool_calls"][0]['function']['name']

#message["tool_calls"][0]['function']["arguments"]则是参数,用json格式传入
func_args = json.loads(message["tool_calls"][0]['function']["arguments"])

#打印函数名称和参数
print("func name and args: ", func_name, func_args)

#这里的get_weather_info就不重写了,总之就是调用该函数
func_response = get_weather_info(**func_args)

这一步就是之前的与模型交互,触发模型对函数的调用;

使用大模型组织语言将结果以自然语言返回

这一步也就是之前的****处理函数调用结果,根据模型返回参数,调用对应的函数;

调用函数返回结果后构造tool message,再次调用模型,将函数结果输入模型;模型会将函数调用结果以自然语言格式返回给用户。

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 #获得arguments
        function_result = {}
        if tool_call.function.name == "get_weather_info":
            function_result = func_response #根据模型返回参数,调用对应的函数
        messages.append({
            "role": "tool",
            "content": f"{json.dumps(function_result)}",
            "tool_call_id":tool_call.id
        }) #调用函数返回结果后构造tool message,json格式
        response = client.chat.completions.create(
            model="GLM-4-Plus",  
            messages=messages,
            tools=tools,
        ) # 再次调用模型,将函数结果输入模型,模型会将函数调用结果以自然语言格式返回给用户。
        print(response.choices[0].message)
        messages.append(response.choices[0].message.model_dump())

总的来说这个其实类似于教程吧,但是第一次接触很多地方没有理解,这里结合zhipu:function call梳理了一下。

Function Call实践的学习流程仍然是从调用国内外大模型API进行大模型测试开始的。由于原理类似,而我们的平台环境只方便用国内大模型API进行测试,这里就对国内大模型API调用流程和代码进行一下分析。 ## Function Call: <font style="color:rgb(94, 94, 102);">函数调用功能可以增强模型推理效果或进行其他外部操作,包括信息检索、数据库操作、知识图谱搜索与推理、操作系统、触发外部操作等工具调用场景。</font> <font style="color:rgb(94, 94, 102);">在ChatGLM中,tools 是内容生成 API 中的可选参数,用于向模型提供函数定义。通过此参数,模型能够生成符合用户所提供规范的函数参数。(在ChatGPT中也兼容tools参数,但更多的使用functions参数。)</font>_<font style="color:rgb(94, 94, 102);">** 请注意,API 实际上不会执行任何函数调用,仅返回调用函数所需要的参数。开发者可以利用模型输出的参数在应用中执行函数调用。</font>_ <font style="color:rgb(94, 94, 102);"></font> <font style="color:rgb(94, 94, 102);">步骤:</font> 1. 使用Chat Completion接口向模型描述外部函数; ![](https://cdn.nlark.com/yuque/0/2024/png/48516026/1727237754962-0922af35-ab54-4d08-b8d8-8b852e4242bb.png) 2. 与模型交互,触发模型对函数的调用; <font style="color:rgb(94, 94, 102);">在 tools 参数中,如果填写了 functions 参数,则默认情况下模型将决定何时适合使用其中一个函数。 如果要控制模型如何选择函数调用,需要设置 tool_choice 参数。参数默认值为auto,此时模型根据上下文信息自行选择是否</font>**<font style="color:rgb(94, 94, 102);">返回函数调用</font>**<font style="color:rgb(94, 94, 102);">。将其设置为 {“name”: “your_function_name”} 时,可以强制 API 返回特定函数的调用。还可以通过将 tool_choice 参数设置为 “none” 来强制 API 不返回任何函数的调用。目前函数调用仅支持 auto 模式。</font> <font style="color:rgb(94, 94, 102);"></font> 3. 使用模型生成的结果调用外部函数。 <font style="color:rgb(94, 94, 102);">首先将所需的函数实现;</font> <font style="color:rgb(94, 94, 102);">随后定义处理 Function call 的函数即可,具体流程为:</font> ```plain # 处理函数调用结果,根据模型返回参数,调用对应的函数; # 调用函数返回结果后构造tool message,再次调用模型,将函数结果输入模型; # 模型会将函数调用结果以自然语言格式返回给用户。 ``` ## **<font style="color:#1a1a1a;">调用GLM4-plus</font>** 了解Function Call运行流程后,我们对调用GLM4-plus的代码进行分析。 ### 设置网络代理; ### <font style="color:rgba(0, 0, 0, 0.87);">定义模型可读的tools,zhipu不兼容functions,需要使用tools;</font> ```plain tools = [ { "type": "function", "function": { "name": "get_weather_info", "description": "Get the weather information of a city", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "The name of the city, e.g. Shanghai", }, }, "required": ["city"], }, } } ] ``` 即**使用Chat Completion接口向模型描述外部函数** ### <font style="color:rgba(0, 0, 0, 0.87);">初始化ZhipuAI,调用大模型,让大模型指导调用哪个function以及输入的参数是什么;</font> ```plain from zhipuai import ZhipuAI # 创建智普大模型的客户端实例 client = ZhipuAI(api_key="xxx") query = "What is the weather like in Beijing?" messages=[{"role": "user", "content": query}] response = client.chat.completions.create( model="GLM-4-Plus", messages=messages, tools=tools, tool_choice="auto", ) message = response.dict()["choices"][0]["message"] print(message) ``` 这里的“指导”即大模型会根据tools自动选择function并识别输入的参数;输出结果为: ```plain {'content': None, 'role': 'assistant', 'tool_calls': [{'id': 'call_9053597030834077390', 'function': {'arguments': '{"city": "Beijing"}', 'name': 'get_weather_info'}, 'type': 'function', 'index': 0}]} ``` ### 调用大模型,查看结果 ```plain #message["tool_calls"][0]['function']['name']即之前的'name': 'get_weather_info',指的是函数名称 func_name = message["tool_calls"][0]['function']['name'] #message["tool_calls"][0]['function']["arguments"]则是参数,用json格式传入 func_args = json.loads(message["tool_calls"][0]['function']["arguments"]) #打印函数名称和参数 print("func name and args: ", func_name, func_args) #这里的get_weather_info就不重写了,总之就是调用该函数 func_response = get_weather_info(**func_args) ``` 这一步就是之前的**与模型交互,触发模型对函数的调用;** ### <font style="color:rgba(0, 0, 0, 0.87);">使用大模型组织语言将结果以自然语言返回</font> **这一步也就是之前的****处理函数调用结果,根据模型返回参数,调用对应的函数;** **调用函数返回结果后构造tool message,再次调用模型,将函数结果输入模型;模型会将函数调用结果以自然语言格式返回给用户。** ```plain 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 #获得arguments function_result = {} if tool_call.function.name == "get_weather_info": function_result = func_response #根据模型返回参数,调用对应的函数 messages.append({ "role": "tool", "content": f"{json.dumps(function_result)}", "tool_call_id":tool_call.id }) #调用函数返回结果后构造tool message,json格式 response = client.chat.completions.create( model="GLM-4-Plus", messages=messages, tools=tools, ) # 再次调用模型,将函数结果输入模型,模型会将函数调用结果以自然语言格式返回给用户。 print(response.choices[0].message) messages.append(response.choices[0].message.model_dump()) ``` 总的来说这个其实类似于教程吧,但是第一次接触很多地方没有理解,这里结合[zhipu:function call](https://open.bigmodel.cn/dev/howuse/functioncall)梳理了一下。
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: HswOAuth/llm_course#126
No description provided.