【GLM-4开发实战】Function Call进阶实战:外部函数调用回顾

news2024/9/29 13:32:57

系列篇章💥

No.文章
1【GLM-4开发实战】Function Call进阶实战:外部函数调用回顾
2【GLM-4开发实战】Function Call进阶实战:常见挑战之意图识别处理
3【GLM-4开发实战】Function Call进阶实战:常见挑战之海量函数处理
4【GLM-4开发实战】Function Call进阶实战:常见挑战之并发调用处理

目录

  • 系列篇章💥
  • 引言
  • 一、概述
  • 二、Function Call调用详细流程
    • 1、定义模型客户端
    • 2、定义工具函数
    • 3、定义数据对象
    • 4、数据转换为String类型
    • 5、函数调用测试
    • 6、定义函数的说明
    • 7、大模型调用测试(不带工具函数)
    • 8、大模型调用测试(携带工具函数)
    • 9、查看结果中的tool_calls属性
    • 10、构建字段格式函数列表
    • 11、获取执行函数并执行
    • 12、第二次调用大模型
    • 13、查看最终执行结果
  • 三、Function Call函数调用封装
  • 结语


引言

在人工智能领域,Function Call是大模型能力扩展的核心。它不仅在Retrieval-Augmented Generation(RAG)中扮演着重要角色,也是Agent智能体架构设计中不可或缺的一部分。本文将深入探讨GLM-4模型中Function Call的进阶应用,通过实战案例,回顾并总结外部函数调用的技巧与经验。

一、概述

Function Call作为模型与外部世界交互的桥梁,其重要性不言而喻。本章节旨在通过GLM-4模型的Function Call功能,为大家提供一个全面的使用回顾,帮助大家更高效地利用这一功能。

二、Function Call调用详细流程

1、定义模型客户端

首先,需要构建一个客户端,用于与GLM-4模型进行通信。

import os
import openai
from openai import OpenAI
import shutil

import numpy as np
import pandas as pd

import json
import io
import inspect
import requests
import re
import random
import string

## 初始化客户端
api_key = os.getenv("ZHIPU_API_KEY")
## pip install zhipuai

from zhipuai import ZhipuAI
client = ZhipuAI(api_key=api_key)

2、定义工具函数

定义了一个大模型里面肯定没有的算法工具函数

def sunwukong_function(data):
    """
    孙悟空算法函数,该函数定义了数据集计算过程
    :param data: 必要参数,表示带入计算的数据表,用字符串进行表示
    :return:sunwukong_function函数计算后的结果,返回结果为表示为JSON格式的Dataframe类型对象
    """
    data = io.StringIO(data)
    df_new = pd.read_csv(data, sep='\s+', index_col=0)
    res = df_new * 10
    return json.dumps(res.to_string())

3、定义数据对象

创建数据对象,为函数调用提供必要的数据支持。

df = pd.DataFrame({'x1':[1, 2], 'x2':[3, 4]})
df

输出:
在这里插入图片描述

4、数据转换为String类型

与大模型进行配合调用的时候,尽可能的让调用的函数参数和返回值都用String表示。

df_str = df.to_string()
df_str

输出:
在这里插入图片描述

5、函数调用测试

进行初步的函数调用,测试其基本功能。

result_json=sunwukong_function(df_str)
result_json

输出:
在这里插入图片描述

6、定义函数的说明

方便大模型识别函数自动完成调用,注意格式为:JSON Schema的格式

sunwukong={
        "type": "function",
        "function": {"name": "sunwukong_function",
                      "description": "用于执行孙悟空算法函数,定义了一种特殊的数据集计算过程",
                      "parameters": {"type": "object",
                                     "properties": {"data": {"type": "string",
                                                             "description": "执行孙悟空算法的数据集"},
                                                   },
                                     "required": ["data"],
                                    },
                     }
    }

定义工具列表

tools = [sunwukong]

7、大模型调用测试(不带工具函数)

在没有外部函数工具的情况下测试大模型的第一次调用并执行孙悟空算法

messages=[
    {"role": "system", "content": "数据集data:%s,数据集以字符串形式呈现" % df_str},
    {"role": "user", "content": "请在数据集data上执行孙悟空算法"}
]

response =  client.chat.completions.create(
  model="glm-4",
  messages=messages
)
response.choices[0].message

输出:

CompletionMessage(content='抱歉,但似乎有一些混淆。"孙悟空算法"并不是一个公认的数据处理或机器学习算法。孙悟空是中国古典文学作品《西游记》中的虚构人物,以其变化无常和神通广大著称。\n\n然而,根据您提供的数据集(以字符串形式表示),如果您是想要进行某种形式的数据处理或分析,下面是一个用Python实现的对给定字符串形式的数据集进行解析的简单示例:\n\n```python\n# 这是您提供的数据集字符串\ndata_str = """\nx1  x2\n0   1   3\n1   2   4\n"""\n\n# 将字符串分割成行\nlines = data_str.strip().split("\\n")\n\n# 解析标题和值\nheader = lines[0].split()\nvalues = [line.split() for line in lines[1:]]\n\n# 转换数据为字典形式\ndata_dict = {h: [] for h in header}\nfor row in values:\n    for i, value in enumerate(row):\n        data_dict[header[i]].append(int(value))\n\n# 输出字典形式的数据集\nprint(data_dict)\n\n# 如果需要转换为Pandas DataFrame(如果适用的话)\nimport pandas as pd\n\ndf = pd.DataFrame(data_dict)\nprint(df)\n```\n\n当运行这段代码时,它将输出以下字典形式的数据集:\n\n```\n{\'x1\': [0, 1], \'x2\': [1, 2]}\n```\n\n然后,它将创建一个Pandas DataFrame,如下所示:\n\n```\n   x1  x2\n0   0   1\n1   1   2\n```\n\n请注意,这段代码假设每行数据的列数是相同的,并且所有值都可以转换为整数。\n\n如果您有一个具体的任务或算法想要应用到这个数据集上,请详细描述,我将尽力提供帮助。', role='assistant', tool_calls=None)

8、大模型调用测试(携带工具函数)

第一次调用大模型,测试Funcation call流程,本次调用时,设置工具函数tools和tool_choice(由大模型自己判断选择是否需要调用外部工具函数)

messages=[
    {"role": "system", "content": "数据集data:%s,数据集以字符串形式呈现" % df_str},
    {"role": "user", "content": "请在数据集data上执行孙悟空算法"}
]
response = client.chat.completions.create(
        model="glm-4",
        messages=messages,
        tools=tools,
        tool_choice="auto",  
    )

response.choices[0].message

输出:

CompletionMessage(content='', role='assistant', tool_calls=[CompletionMessageToolCall(id='call_8822099358575188366', function=Function(arguments='{"data":"x1  x2\\n0   1   3\\n1   2   4"}', name='sunwukong_function'), type='function', index=0)])

输出结果可以看到,模型识别正确识别出来需要调用的函数,并且正确解析了参数 将第一次调用结果放入变量first_response中

first_response = response.choices[0].message
first_response

输出:

CompletionMessage(content=None, role='assistant', tool_calls=[CompletionMessageToolCall(id='call_8730210251242354639', function=Function(arguments='{"data":"x1  x2\\n0   1   3\\n1   2   4"}', name='sunwukong_function'), type='function', index=0)])

9、查看结果中的tool_calls属性

分析函数调用的结果,特别是tool_calls属性,了解函数调用的细节。

response.choices[0].message.tool_calls

输出:

[CompletionMessageToolCall(id='call_8730210251242354639', function=Function(arguments='{"data":"x1  x2\\n0   1   3\\n1   2   4"}', name='sunwukong_function'), type='function', index=0)]

10、构建字段格式函数列表

构建字典形式的函数调用列表,key为函数名,value为函数体

available_tools =  {
    "sunwukong_function": sunwukong_function,
}

11、获取执行函数并执行

根据大模型的返回值中获取到函数调用需要到的:函数名,参数,函数体,并且执行函数。

tool_calls = response.choices[0].message.tool_calls
 
for tool_call in tool_calls:
    ## 函数名
    function_name = tool_call.function.name
    ## 根据函数名获取到函数体
    function_to_call = available_tools[function_name]
    function_args = json.loads(tool_call.function.arguments)
    ## 执行函数
    function_response = function_to_call(**function_args)
 

print(function_name)
print(function_args)
print(function_response)

输出:
在这里插入图片描述

查询执行函数,执行效果

function_response = function_to_call(**function_args)
function_response

输出:
在这里插入图片描述

12、第二次调用大模型

把结果给到大模型,大模型进行增强生成
在第一次调用的基础上,进行第二次调用,观察是否有性能提升或结果优化。

messages.append(response.choices[0].message.model_dump())
for tool_call in tool_calls:
    
    function_name = tool_call.function.name
    function_to_call = available_tools[function_name]
    function_args = json.loads(tool_call.function.arguments)
    ## 真正执行外部函数的就是这儿的代码
    function_response = function_to_call(**function_args)
    messages.append(
        {
            "role": "tool",
            "content": function_response,
            "tool_call_id": tool_call.id,
        }
    ) 
## 第二次调用模型
second_response = client.chat.completions.create(
    model="glm-4",
    messages=messages,
    tools=tools
    ) 
# 获取最终结果
final_response = second_response.choices[0].message.content

13、查看最终执行结果

分析第二次调用的结果,评估Function Call的整体表现和可能的改进空间。

final_response

输出:

'根据孙悟空算法执行结果,数据集data经过计算后的结果为:\n```\n   x1  x2\n0  10  30\n1  20  40\n```'

三、Function Call函数调用封装

Function Call相关业务逻辑整体封装调用;封装Function Call不仅可以提高代码的可读性和可维护性,还可以在不同场景下复用函数调用逻辑。本部分将对Function Call相关使用代码进行封装,将Function Call封装为可复用的模块,以及如何通过封装提高开发效率。

from openai import OpenAI
import json

## 步骤1:构建函数
def sunwukong_function(data):
    """
    孙悟空算法函数,该函数定义了数据集计算过程
    :param data: 必要参数,表示带入计算的数据表,用字符串进行表示
    :return:sunwukong_function函数计算后的结果,返回结果为表示为JSON格式的Dataframe类型对象
    """
    data = io.StringIO(data)
    df_new = pd.read_csv(data, sep='\s+', index_col=0)
    res = df_new * 10
    return json.dumps(res.to_string())


available_tools =  {
    "sunwukong_function": sunwukong_function,
}


df_str=pd.DataFrame({'x1':[1, 2], 'x2':[3, 4]}).to_string

def run_conversation():
    # Step 1: send the conversation and available functions to the model
    messages=[
    {"role": "system", "content": "数据集data:%s,数据集以字符串形式呈现" % df_str},
    {"role": "user", "content": "请在数据集data上执行孙悟空算法"}  
        ]
    ## 步骤2:函数说明  JSON Schema格式
    tools = [
    {
        "type": "function",
        "function": {"name": "sunwukong_function",
                      "description": "用于执行孙悟空算法函数,定义了一种特殊的数据集计算过程",
                      "parameters": {"type": "object",
                                     "properties": {"data": {"type": "string",
                                                             "description": "执行孙悟空算法的数据集"},
                                                   },
                                     "required": ["data"],
                                    },
                     }
    }]
    ## 步骤3:第一次调大模型
    response = client.chat.completions.create(
        model="glm-4",
        messages=messages,
        tools=tools,
        tool_choice="auto",  # auto is default, but we'll be explicit
    )
    response_message = response.choices[0].message
    tool_calls = response_message.tool_calls
    # Step 2: check if the model wanted to call a function
    if tool_calls:
        messages.append(response.choices[0].message.model_dump())
     
        for tool_call in tool_calls:
            function_name = tool_call.function.name
            function_to_call = available_tools[function_name]
            function_args = json.loads(tool_call.function.arguments)
            function_response = function_to_call(**function_args)
            messages.append({
                "role": "tool",
                "content": f"{json.dumps(function_response)}",
                "tool_call_id":tool_call.id
            })
        ## 步骤四:第二次调用大模型
        second_response = client.chat.completions.create(
            model="glm-4",  # 填写需要调用的模型名称
            messages=messages,
            tools=tools,
        )
        return second_response
    
result=run_conversation()

查看调用结果

result.choices[0].message.content

输出:

'根据您的请求,我已经在数据集data上执行了孙悟空算法。执行结果如下:\n\n"   x1  x2\n0  10  30\n1  20  40"\n\n这是数据集经过孙悟空算法处理后的结果。如果您还有其他问题或需要进一步的帮助,请随时告诉我。'

结语

Function Call作为连接人工智能模型与外部世界的纽带,其应用广泛且深入。通过本文的深入分析与实战回顾,我们希望能够为读者提供Function Call使用的宝贵经验和策略,助力开发者们在AI领域的进一步探索和实践。随着技术的不断进步,Function Call的应用也将更加多样化和高效,期待与大家共同见证这一领域的未来发展。

在这里插入图片描述

🎯🔖更多专栏系列文章:AI大模型提示工程完全指南AI大模型探索之路(零基础入门)AI大模型预训练微调进阶AI大模型开源精选实践AI大模型RAG应用探索实践🔥🔥🔥 其他专栏可以查看博客主页📑

😎 作者介绍:我是寻道AI小兵,资深程序老猿,从业10年+、互联网系统架构师,目前专注于AIGC的探索。
📖 技术交流:欢迎关注【小兵的AI视界】公众号或扫描下方👇二维码,加入技术交流群,开启编程探索之旅。
💘精心准备📚500本编程经典书籍、💎AI专业教程,以及高效AI工具。等你加入,与我们一同成长,共铸辉煌未来。
如果文章内容对您有所触动,别忘了点赞、⭐关注,收藏!加入我,让我们携手同行AI的探索之旅,一起开启智能时代的大门!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1980361.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【STM32】GPIO和AFIO标准库使用框架

本篇博客重点在于标准库函数的理解与使用,搭建一个框架便于快速开发 目录 GPIO简介 GPIO时钟使能 GPIO初始化 工作模式 选择引脚 输出速度 函数应用 GPIO初始化框架 8个电平读写函数 写端口电平 读端口电平 GPIO框架汇总 AFIO简介 AFIO时钟使能 函数应…

【Material-UI】深入理解useAutocomplete Hook:自定义与高级用法

文章目录 一、什么是useAutocomplete?导入useAutocomplete 二、基本用法代码解析 三、高级定制1. 自定义选项渲染2. 分组和排序3. 自定义输入框行为4. 与其他组件集成 四、注意事项1. 类型安全2. 性能优化 五、总结 Material-UI提供了强大的Autocomplete组件&#x…

Stable Diffusion绘画 | 图生图-基础使用介绍—重绘幅度与缩放模式

重绘幅度 重绘幅度越大,出图与原图差异越大。 重绘幅度0.7 重绘幅度0.3 缩放模式 目前有以下四种缩放模式: 原图的宽高是1080x1440,当修改宽高,与原图不一致时,可选择其中一种缩放模式来处理图片。 仅调整大小 缩放…

C++入门基础(上篇)

C入门基础(上篇) hello everybody!经历了C语言和初阶数据结构的头脑风暴,相信大家对于编程的学习更加开心,所以说接下来我们将迎来C的学习与探索,话不多说让我们开始吧 namespace的价值 在C/C中,变量、函…

计算机毕业设计选题推荐-自习室座位预约系统-Java/Python项目实战

✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

GD32 MCU硬件I2C不可靠不如软件I2C?

在一个评论中,看到网友对硬件I2C的讨论,硬件I2C Busy找不到原因、软件I2C稳得一批。 那么为什么会出现I2C BUSY?硬件I2C真的不如软件I2C吗?怎么让硬件I2C也稳得一批,让我们来一探究竟。 首先我们从I2C时序分析下I2C总…

基于pytorch的steam游戏评分的线性回归问题分析

前言 相信已经暑假一个月的大家肯定并不陌生上面这个学习软件(),面对琳琅满目的游戏总是让人不知道挑选什么,这时候一个游戏的评分往往便成为了一个玩家选择下载的原因,那么今天我们就来研究研究,steam上一个游戏的种种数据&…

Celery注册装饰器@app.task和@shared_task

注册装饰器 app.task和shared_task是Celery中用于定义任务的两种不同装饰器, 它们之间存在明显的区别.from celery import Celery app Celery(my_app, brokeramqp://guestlocalhost//) app.task def my_task(): # 任务逻辑 passfrom celery import shared_task shared…

数据结构——双链表详解(超详细)

前言: 小编在之前已经写过单链表的创建了,接下来要开始双链表的讲解了,双链表比单链表要复杂一些,不过确实要比单链表更好进行实现!下面紧跟小编的步伐,开启今天的双链表之旅! 目录 1.概念和结构…

Pixart LED调变开发笔记

Pixart提供基础的鼠标和键盘代码, 开发者可以基于此快速的建置自己的firmware, application, 以下介绍代码中用来控制LED的API函式. 常亮模式 (Always on) 常亮模式, 调用API "pwm_led_set_always_on" 及 channel 来设置对应LED常亮. 闪烁模式 (Flash mode) 闪烁模…

华为OD机试 - 字符串编码校验(Java 2024 D卷 100分)

华为OD机试 2024D卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(D卷C卷A卷B卷)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华…

Unity3D 物体圆周运动

Unity3D 实现一个 2D 物体沿着圆周进行运动。 物体圆周运动 前段时间在开发一个小游戏时,需要实现火箭沿着一个圆形轨道进行圆周运动。 以前面试的时候也被问到过这类问题(如何让一个 2D 物体做圆周运动),所以还是记录一下实现…

ICML 2024 | 矛与盾的较量!北大提出提示无关数据防御保护算法PID

文章链接:https://arxiv.org/pdf/2406.15305 代码地址:https://github.com/PKU-ML/Diffusion-PID-Protection 亮点直击 本文在实证观察中发现,保护阶段和利用阶段之间的提示不匹配可能会削弱当前数据保护算法的有效性。本文深入探讨了利用LDM…

【机器学习第7章——贝叶斯分类器】

机器学习第7章——贝叶斯分类器 7.贝叶斯分类器7.1贝叶斯决策论7.2 朴素贝叶斯分类器条件概率的m估计 7.3 极大似然估计优点基本原理 7.4 贝叶斯网络7.5 半朴素贝叶斯分类器7.6 EM算法7.7 EM算法实现 7.贝叶斯分类器 7.1贝叶斯决策论 一个医疗判断问题 有两个可选的假设&#…

从日常到专业,2024年必备在线翻译神器

现在全球交流越发的简单、频繁,很多时候外语成为了我们汲取新鲜知识的绊脚石。这时候我们就可以借助一些翻译在线的工具来解决这个问题。这次我们一起探索几款我搜集到的翻译工具。 1.福晰在线翻译 链接直通:https://fanyi.pdf365.cn/doc 这个工具支…

本地部署启动PmHub

文章目录 相关配置版本关系拉取代码使用Git clone下载源码 MYSQL配置Nacos配置Windows本地下载也可以Docker部署Nacos持久化配置启动Nacos访问Nacos Redis配置RocketMQ配置新建相应目录rocketmq, 然后在里面新建broker文件夹, 放broker.conf在 rocketmq 新建 data 文件夹&#…

MRAM FRAM在医疗设备场景的应用

便携式超声波扫描仪是一种检测从物体反射的声波并将其转换为实时图像的设备。通常使用配置存储器和图像/报告存储器两种类型的存储器。配置存储器存储来自外部硬件的标识和配置信息,图像/报告存储器存储图像和相应的报告数据。这些存储器即使在突然断电的情况下&…

MySQL介绍和安装与配置

文章目录 MySQL介绍什么是数据库什么是关系型数据库什么是非关系型数据库MySQL概述和历史 MySQL安装和配置在线安装方式MySQL5.7的安裝1.下载yum Repository2.安装yum Repository3.安装mysql5.7的服务3.后续命令 离线安装方式1、卸载已有的MySQL文件2、安装mysql3、后续命令 修…

详细分析Python生成项目依赖包的工具

目录 前言1. pipreqs2. pip freeze3. poetry4. conda5. 总结 前言 在Python项目开发中,管理依赖包是确保项目正常运行的关键步骤 本博客将详细分析几种流行的依赖管理工具,包括 pipreqs、pip freeze、poetry 和 conda,以及它们的使用场景和…