AI大模型探索之路-实战篇8:多轮对话与Function Calling技术应用

系列篇章💥

AI大模型探索之路-实战篇4:深入DB-GPT数据应用开发框架调研
AI大模型探索之路-实战篇5:探索Open Interpreter开放代码解释器调研
AI大模型探索之路-实战篇6:掌握Function Calling的详细流程
AI大模型探索之路-实战篇7:Function Calling技术实战自动生成函数


目录

  • 系列篇章💥
  • 一、前言
  • 二、封装调用2轮response的函数
    • 1、输出函数列表
    • 2、function函数调用封装
    • 3、定义参数数据
    • 4、测试函数tangseng_function
    • 5、测试函数sunwukong_function
    • 6、测试函数(描述中不指明信息)
  • 三、增加多轮对话的效果
    • 1、创建OpenAI客户端
    • 2、定义工具函数
    • 3、定义函数生成器
    • 4、封装大模型2次API调用
    • 5、多轮对话函数定义
    • 6、函数列表定义
    • 7、对话调用测试
  • 四、结语


一、前言

继前文深入探讨了Function Calling的操作流程并成功实验自动生成function函数之后,本文将进一步深化我们的研究,具体考察OpenAI的Function Calling技术在现实应用中的表现。此次研究的重点在于封装一个能够调用两轮response的函数,并在此基础上执行多轮对话的测试,从而全面评估该技术在实际应用中的效率和效果。

通过精心设计的实验,我们将探索这项技术的潜力及其在智能数据分析平台上的应用前景。我们的目标是为平台的顺利实施构建一个稳固且高效的技术基础。这不仅涉及到技术层面的优化,也关系到如何在实际应用中提供更流畅的用户体验和更准确的数据处理能力。

在本文中,我们将详细阐述这一过程的每个步骤,从技术选型到功能实现,再到最终的效果评估。我们希望通过对OpenAI的Function Calling技术的深入分析和应用展示,为未来相关技术的发展和应用场景的拓展提供有益的参考和启示。

二、封装调用2轮response的函数

在实现function call的过程中,我们通常需要进行两次关键的调用。
1)第一次调用:目的是让强大的大型模型协助我们识别并选择恰当的工具函数。这就像在进行一场棋局,首先需要确定使用哪个棋子。一旦选定,接下来的步骤便是实际调用该工具函数,执行具体的任务。
2)第二次调用:这一次,我们再次借助大模型的强大能力,其任务是将工具函数处理后的结果进行整合和优化,以最清晰、最易于理解的形式呈现最终输出。这可以比喻为将散落的珠子串成一串光彩夺目的项链,使其更具有观赏价值和实用价值。

在本章节中,我们将重点介绍如何将这两阶段的调用过程进行有效的封装,使其成为一个独立、可复用的模块。这种封装不仅简化了操作流程,还提高代码的可维护性和扩展性,为未来的功能拓展或技术升级提供了便利。

1、输出函数列表

继上文中,我们定义了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())#在定义一个工具函数,一起测试
def tangseng_function(data):"""唐僧算法函数,该函数定义了数据集计算过程:param data: 必要参数,表示带入计算的数据表,用字符串进行表示:return:tangseng_function函数计算后的结果,返回结果为表示为JSON格式的Dataframe类型对象"""data = io.StringIO(data)df_new = pd.read_csv(data, sep='\s+', index_col=0)res = df_new * 1000000return json.dumps(res.to_string())# 将2个函数放入函数列表
functions_list=[sunwukong_function,tangseng_function]

输出函数列表:

functions_list

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

2、function函数调用封装

def run_conversation(messages, functions_list=None, model="gpt-3.5-turbo"):"""能够自动执行外部函数调用的对话模型:param messages: 必要参数,字典类型,输入到Chat模型的messages参数对象:param functions_list: 可选参数,默认为None,可以设置为包含全部外部函数的列表对象:param model: Chat模型,可选参数,默认模型为gpt-3.5-turbo:return:Chat模型输出结果"""# 如果没有外部函数库,则执行普通的对话任务if functions_list == None:response = client.chat.completions.create(model=model,messages=messages,)response_message = response.choices[0].messagefinal_response = response_message.content# 若存在外部函数库,则需要灵活选取外部函数并进行回答else:# 创建functions对象tools = auto_functions(functions_list)# 创建外部函数库字典available_functions = {func.__name__: func for func in functions_list}# 第一次调用大模型,寻找工具函数response = client.chat.completions.create(model=model,messages=messages,tools=tools,tool_choice="auto", )response_message = response.choices[0].messagetool_calls = response_message.tool_callsif tool_calls:messages.append(response_message) for tool_call in tool_calls:function_name = tool_call.function.namefunction_to_call = available_functions[function_name]function_args = json.loads(tool_call.function.arguments)## 真正执行外部函数的就是这儿的代码function_response = function_to_call(**function_args)messages.append({"tool_call_id": tool_call.id,"role": "tool","name": function_name,"content": function_response,}) ## 第二次调用模型,将响应结果,给到大模型进行转为为更为可视化的数据格式,再返回给用户second_response = client.chat.completions.create(model=model,messages=messages,) # 获取最终结果final_response = second_response.choices[0].message.contentelse:final_response = response_message.contentreturn final_response

3、定义参数数据

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

在这里插入图片描述

4、测试函数tangseng_function

# 定义消息列表
messages = [{"role": "system", "content": "数据集data:%s,数据集以字符串形式呈现" % df_str},{"role": "user", "content": '请在data上执行唐僧算法函数'}]# API调用测试
run_conversation(messages = messages, functions_list = functions_list)

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

5、测试函数sunwukong_function

# 定义消息列表
messages = [{"role": "system", "content": "数据集data:%s,数据集以字符串形式呈现" % df_str},{"role": "user", "content": '请在data上执行孙悟空算法函数'}]# API调用测试
run_conversation(messages = messages, functions_list = functions_list)

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

6、测试函数(描述中不指明信息)

# 定义消息列表
messages = [{"role": "system", "content": "数据集data:%s,数据集以字符串形式呈现" % df_str},{"role": "user", "content": '请解释一下data数据集'}]# API调用测试
run_conversation(messages = messages, functions_list = functions_list)

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

根据结果可以看出,大模型并没有成功调用工具函数

三、增加多轮对话的效果

在实现function call技术的过程中,我们不仅需要关注单次调用的优化,还需要注重多轮对话的效果。本章节将介绍如何通过引入两个工具函数,来测试大型模型在面对涉及工具函数的问题时,是否能准确识别并调用相应的工具。

1、创建OpenAI客户端

import openai
import os
import numpy as np
import pandas as pd
import json
import io
from openai import OpenAI
import inspect
# 定义api key
openai.api_key = os.getenv("OPENAI_API_KEY")#创建OpenAI客户端
client = OpenAI(api_key=openai.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 * 10return json.dumps(res.to_string())def tangseng_function(data):"""唐僧算法函数,该函数定义了数据集计算过程:param data: 必要参数,表示带入计算的数据表,用字符串进行表示:return:tangseng_function函数计算后的结果,返回结果为表示为JSON格式的Dataframe类型对象"""data = io.StringIO(data)df_new = pd.read_csv(data, sep='\s+', index_col=0)res = df_new * 1000000return json.dumps(res.to_string())

3、定义函数生成器

def auto_functions(functions_list):"""Chat模型的functions参数编写函数:param functions_list: 包含一个或者多个函数对象的列表;:return:满足Chat模型functions参数要求的functions对象"""def functions_generate(functions_list):# 创建空列表,用于保存每个函数的描述字典functions = []# 对每个外部函数进行循环for function in functions_list:# 读取函数对象的函数说明function_description = inspect.getdoc(function)# 读取函数的函数名字符串function_name = function.__name__system_prompt = '以下是某的函数说明:%s' % function_descriptionuser_prompt = '根据这个函数的函数说明,请帮我创建一个JSON格式的字典,这个字典有如下5点要求:\1.字典总共有三个键值对;\2.第一个键值对的Key是字符串name,value是该函数的名字:%s,也是字符串;\3.第二个键值对的Key是字符串description,value是该函数的函数的功能说明,也是字符串;\4.第三个键值对的Key是字符串parameters,value是一个JSON Schema对象,用于说明该函数的参数输入规范。\5.输出结果必须是一个JSON格式的字典,只输出这个字典即可,前后不需要任何前后修饰或说明的语句' % function_nameresponse = client.chat.completions.create(model="gpt-3.5-turbo",messages=[{"role": "system", "content": system_prompt},{"role": "user", "content": user_prompt}])json_function_description=json.loads(response.choices[0].message.content.replace("```","").replace("json",""))json_str={"type": "function","function":json_function_description}functions.append(json_str)return functions## 最大可以尝试4次max_attempts = 4attempts = 0while attempts < max_attempts:try:functions = functions_generate(functions_list)break  # 如果代码成功执行,跳出循环except Exception as e:attempts += 1  # 增加尝试次数print("发生错误:", e)if attempts == max_attempts:print("已达到最大尝试次数,程序终止。")raise  # 重新引发最后一个异常else:print("正在重新运行...")return functions

4、封装大模型2次API调用

def run_conversation(messages, functions_list=None, model="gpt-3.5-turbo"):"""能够自动执行外部函数调用的对话模型:param messages: 必要参数,字典类型,输入到Chat模型的messages参数对象:param functions_list: 可选参数,默认为None,可以设置为包含全部外部函数的列表对象:param model: Chat模型,可选参数,默认模型为gpt-3.5-turbo:return:Chat模型输出结果"""# 如果没有外部函数库,则执行普通的对话任务if functions_list == None:response = client.chat.completions.create(model=model,messages=messages,)response_message = response.choices[0].messagefinal_response = response_message.content# 若存在外部函数库,则需要灵活选取外部函数并进行回答else:# 创建functions对象tools = auto_functions(functions_list)# 创建外部函数库字典available_functions = {func.__name__: func for func in functions_list}# 第一次调用大模型response = client.chat.completions.create(model=model,messages=messages,tools=tools,tool_choice="auto", )response_message = response.choices[0].messagetool_calls = response_message.tool_callsif tool_calls:messages.append(response_message) for tool_call in tool_calls:function_name = tool_call.function.namefunction_to_call = available_functions[function_name]function_args = json.loads(tool_call.function.arguments)## 真正执行外部函数的就是这儿的代码function_response = function_to_call(**function_args)messages.append({"tool_call_id": tool_call.id,"role": "tool","name": function_name,"content": function_response,}) ## 第二次调用模型second_response = client.chat.completions.create(model=model,messages=messages,) # 获取最终结果final_response = second_response.choices[0].message.contentelse:final_response = response_message.contentreturn final_response

5、多轮对话函数定义

def chat_with_model(functions_list=None, prompt="你好", model="gpt-3.5-turbo", system_message=[{"role": "system", "content": "你是小智助手。"}]):messages = system_messagemessages.append({"role": "user", "content": prompt})while True:           answer = run_conversation(messages=messages, functions_list=functions_list, model=model)print(f"智能助手回答: {answer}")# 询问用户是否还有其他问题user_input = input("您还有其他问题吗?(输入退出以结束对话): ")if user_input == "退出":break# 记录用户回答messages.append({"role": "user", "content": user_input})

6、函数列表定义

functions_list=[sunwukong_function,tangseng_function]

7、对话调用测试

chat_with_model(functions_list,prompt="你好")

gpt3.5生成json schema还是会不太稳定,经常会生成失败,如下:
在这里插入图片描述

调用成功效果如下:
在这里插入图片描述
以下是我测试的对话过程
问题1:你好
问题2:1+2
问题3:什么是孙悟空函数
问题4:数据集data以字符串形式呈现如下:’ x1 x2\n0 1 3\n1 2 4’,请在数据集data上执行孙悟空算法

智能助手回复结果如下:
在这里插入图片描述

四、结语

在本文中,我们深入探讨了function call技术中对大型模型API进行两次调用的进一步封装方法,并实践了这一方法以实现多轮对话的效果。通过精心设计的技术策略和实验,我们不仅优化了API调用流程,还成功地将这些技术应用于实际的对话场景中,使得交互更加流畅和自然。这一成果不仅展示了function call技术的高级应用,也为未来更复杂的应用场景提供了可能。

在这里插入图片描述

🎯🔖更多专栏系列文章:AIGC-AI大模型探索之路

如果文章内容对您有所触动,别忘了点赞、⭐关注,收藏!加入我,让我们携手同行AI的探索之旅,一起开启智能时代的大门!

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

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

相关文章

实验五:实现循环双链表各种基本运算的算法

实验五&#xff1a;实现循环双链表各种基本运算的算法 一、实验目的与要求 目的:领会循环双链表存储结构和掌握循环双链表中各种基本运算算法设计。 内容:编写一个程序cdinklist.cpp,实现循环双链表的各种基本运算和整体建表算法(假设循环双链表的元素类型ElemType为char),并…

俄罗斯半导体领域迈出坚实步伐:首台光刻机诞生,目标直指7纳米工艺

近日&#xff0c;国外媒体纷纷报道&#xff0c;俄罗斯在半导体技术领域取得了重要突破&#xff0c;首台光刻机已经制造完成并正在进行严格的测试阶段。这一里程碑式的事件标志着俄罗斯在自主发展半导体技术的道路上迈出了坚实的一步。 据俄罗斯联邦工业和贸易部副部长瓦西里-什…

【源码】2024心悦搜剧源码百万级网盘资源

1、一键转存他人链接&#xff1a;就是将别人的分享链接转为你自己的 2、转存心悦搜剧资源&#xff1a;就是将心悦搜剧平台上的所有资源都转成你自己的 3、每日自动更新&#xff1a;自动转存每天的资源并入库 前端uin-app&#xff0c;后端PHP&#xff0c;兼容微信小程序

【VTKExamples::Utilities】第一期 动画模拟Animation

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例Animation,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 1. Animation 该样例介绍如…

【设计模式深度剖析】【4】【结构型】【组合模式】| 以文件系统为例加深理解

&#x1f448;️上一篇:适配器模式 设计模式深度剖析-专栏&#x1f448;️ 目 录 组合模式定义英文原话直译如何理解&#xff1f; 3个角色UML类图代码示例 组合模式的优点组合模式的使用场景示例解析&#xff1a;文件系统 组合模式 组合模式&#xff08;Composite Pattern&a…

多段图最短路径(动态规划法)

目录 前言 一、多段图的分析 二、算法思路 三、代码如下&#xff1a; 总结 前言 问题描述&#xff1a;设图G(V, E)是一个带权有向图&#xff0c;如果把顶点集合V划分成k个互不相交的子集Vi (2≤k≤n, 1≤i≤k)&#xff0c;使得对于E中的任何一条边(u, v)&#xff0c;必有u∈Vi&…

MSI U盘重装系统

MSI U盘重装系统 1. 准备一块U盘 首先需要将U盘格式化&#xff0c;这个格式化并不是在文件管理中将U盘里面的所有东西都删干净就可以了&#xff0c;需要在磁盘管理中&#xff0c;将这块U盘格式化&#xff0c;如果这块U盘有分区的话&#xff0c;那将所有的分区都格式化并且删除…

一个专为程序员设计的精致 Java 博客系统

大家好&#xff0c;我是 Java陈序员。 今天&#xff0c;给大家介绍一个设计精致的博客系统&#xff0c;基于 Java 实现&#xff01; 关注微信公众号&#xff1a;【Java陈序员】&#xff0c;获取开源项目分享、AI副业分享、超200本经典计算机电子书籍等。 项目介绍 bolo-solo …

【C++】二叉树进阶(二叉搜索树)

目录 一、内容安排说明二、 二叉搜索树2.1 二叉搜索树概念2.2 二叉搜索树操作2.2.1 二叉搜索树的查找2.2.2 二叉搜索树的插入2.2.3 二叉搜索树的删除 2.3 二叉搜索树的代码实现2.3.1 二叉搜索树的节点设置2.3.2 二叉搜索树类的框架2.3.3 二叉搜索树的查找函数2.3.3.1 非递归方式…

简单易懂的 API 集成测试方法

简介&#xff1a;API 集成测试的重要性 API 集成测试是一类测试活动&#xff0c;用于验证 API 是否满足功能性、可靠性、性能和安全性等方面的预期要求。在多 API 协作的应用程序中&#xff0c;这种测试尤为紧要。 在这一阶段&#xff0c;我们不仅审视单个组件&#xff0c;还…

【Qt窗口】—— 菜单栏

目录 &#xff08;一&#xff09;创建菜单栏 &#xff08;二&#xff09;在菜单栏中添加菜单 &#xff08;三&#xff09;创建菜单项 &#xff08;四&#xff09;在菜单项之间添加分割线 &#xff08;五&#xff09;综合示例 Qt 窗⼝是通过 QMainWindow类 来实现的。 QMa…

【NOIP2015普及组复赛】题3:求和

题3&#xff1a;求和 【题目描述】 一条狭长的纸带被均匀划分出了 n n n 个格子&#xff0c;格子编号从 1 1 1 到 n n n。每个格子上都染了一种颜色 c o l o r i color_i colori​ &#xff08;用 [ 1 &#xff0c; m ] [1&#xff0c;m] [1&#xff0c;m]当中的一个整数表…

前端如何学会全栈分页开发?源码和思路都在这了

本项目代码已开源&#xff0c;具体见&#xff1a; 前端工程&#xff1a;vue3-ts-blog-frontend 后端工程&#xff1a;express-blog-backend 数据库初始化脚本&#xff1a;关注公众号程序员白彬&#xff0c;回复关键字“博客数据库脚本”&#xff0c;即可获取。 前言 这是博客系…

GMSL2硬件设计V1.1

一、说明 GMSL(Gigabit Multimedia Serial Links),中文名称为千兆多媒体串行链路,是Maxim公司(现属于ADI)推出的一种高速串行接口,通过同轴电缆或屏蔽双绞线(STP)传输高速串行数据,用于汽车摄像头和显示器应用。GMSL2就是指ADI专有的第二代千兆多媒体串行链路技术,传输…

RPA+AI 应用案例集合:自动推流直播

使用场景&#xff1a; 自动定时推流直播 使用技术&#xff1a; python playwright 每个解决一个小问题 During handling of the above exception, another exception occurred:Traceback (most recent call last): File "D:\pythonTryEverything\putdonwphone\not_watch_…

前端开发工程师——webpack

一.环境准备 npm init -y npm i webpack webpack-cli -D 打包命令 npx webpack ./src/main.js --modedevelopment //development开发模式 //production生产模式 npx webpack 直接运行就行 二.加载器loader 在less/stylus/css/sass/images中添加适当的样式 例如&#xff1…

Python筑基之旅-文件(夹)操作和流

目录 一、文件操作 1、文件打开与关闭 2、文件读写 3、文件操作模式 4、文件编码 二、文件夹操作 1、创建文件夹 2、删除文件夹 3、改变当前工作目录 4、获取当前工作目录 5、检查文件/文件夹是否存在 6、遍历文件夹 三、文件路径操作 1、获取绝对路径 2、构建完…

爬山算法全解析:掌握优化技巧,攀登技术高峰!

一、引言 爬山算法是一种局部搜索算法&#xff0c;它基于当前解的邻域中进行搜索&#xff0c;通过比较当前解与邻域解的优劣来更新当前解&#xff0c;从而逐步逼近最优解。本文将对爬山算法进行详细的介绍。 二、爬山算法简介 爬山算法是一种基于贪心策略的优化算法&#xff…