传统软件集成AI大模型——Function Calling

传统软件和AI大模型的胶水——Function Calling

  • 浅谈GPT对传统软件的影响
  • Function Calling做了什么,为什么选择Function Calling
  • Function Calling简单例子,如何使用
  • 使用场景

浅谈GPT对传统软件的影响

目前为止好多人对chatGPT的使用才停留在OpenAI自己提供的网页端上,也许对GPT的了解还不够深入。最近稍微看了些大模型相关的内容深刻感觉到大模型技术对软件行业的影响。
本人并非数学专业,对大模型的理解也仅仅只是看了下transformar模型以及简单fine turn的原理。 了解到大模型本质其实是根据概率推断出下一个token输出。 不过就是这些,也足以让传统软件行业在使用方面得到极大的提升。

Function Calling做了什么,为什么选择Function Calling

大模型可计算得到使用者的prompt对应输出,但是大模型的数据都是基于以往的数据训练出来的。诸如“今天是什么日子”,“明天的气温是多少度”等超过统计数据范围的简单问题,纵使是目前世界上最强大的大模型-ChatGPT4.0 也无法回答,并且也永远回答不了。 那么如何让大模型能够满足这种应用场景呢?
OpenAI公司首先给出了解决方案——Plugins。 Plugins允许用户在使用时手动选择若干个插件, 当需要用到这个插件时,gpt会主动去调用此插件,来满足使用场景。 这就涉及到两个问题。 1.用户并不在意到底要使用哪些插件,我只要你能回答我问题就行。 2. 如果有多个插件实现了类似的功能, gpt该作何选择。 一句话:表面上看,用户需要AI能够满足自己的各种需求,实际上,用户更希望在自己的某个需求中集成了AI。
于是,OpenAI公司提出了Function Calling。 家里的电脑没有画图软件, 下面我用文字图简单介绍下

【用户prompt,并注册用户自己的外部函数库】 ----> 【大模型】 —>(匹配了外部函数库)—>【触发function calling响应,携带外部函数库的参数】
—>(没匹配外部函数库) —> 【大模型自己处理】

由此,之前听公司里人谈起的“能不能让AI辅助使用我们的产品”得到实现。 得益于大模型出色的文档处理能力,可以以外部函数为跳板,使传统软件的接口能正确被大模型所调用。 比如,针对一个安防软件平台的操作。 输入“帮我将10.30.20.222”的IPC加入到设备管理中。 将成为现实。 也会打破传统非0即1的编程逻辑。 理论上,任何软件都能为自己定制一个“能听得懂人话”的软件助手。

Function Calling简单例子,如何使用

先直接上OpenAI官方的例子。 值得注意的是,OpenAI接口更新得特别频繁,如果代码无法正常运行,可以将OpenAI版本更新到和我一样的版本
在这里插入图片描述

from openai import OpenAI
import json
import os

# funciton calling test

open_ai_key = os.getenv('OpenAIKey')

client =OpenAI(
                api_key = open_ai_key)

# Example dummy function hard coded to return the same weather
# In production, this could be your backend API or an external API
def get_current_weather(location, unit="fahrenheit"):
    """Get the current weather in a given location"""
    if "tokyo" in location.lower():
        return json.dumps({"location": "Tokyo", "temperature": "10", "unit": unit})
    elif "san francisco" in location.lower():
        return json.dumps({"location": "San Francisco", "temperature": "72", "unit": unit})
    elif "paris" in location.lower():
        return json.dumps({"location": "Paris", "temperature": "22", "unit": unit})
    else:
        return json.dumps({"location": location, "temperature": "unknown"})

def run_conversation():
    # Step 1: send the conversation and available functions to the model
    messages = [{"role": "user", "content": "What's the weather like in San Francisco, Tokyo, and Paris?"}]
    tools = [
        {
            "type": "function",
            "function": {
                "name": "get_current_weather",
                "description": "Get the current weather in a given location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city and state, e.g. San Francisco, CA",
                        },
                        "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                    },
                    "required": ["location"],
                },
            },
        }
    ]
    response = client.chat.completions.create(
        model="gpt-3.5-turbo-1106",
        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:
        # Step 3: call the function
        # Note: the JSON response may not always be valid; be sure to handle errors
        available_functions = {
            "get_current_weather": get_current_weather,
        }  # only one function in this example, but you can have multiple
        messages.append(response_message)  # extend conversation with assistant's reply
        # Step 4: send the info for each function call and function response to the model
        for tool_call in tool_calls:
            function_name = tool_call.function.name
            function_to_call = available_functions[function_name]
            function_args = json.loads(tool_call.function.arguments)
            function_response = function_to_call(
                location=function_args.get("location"),
                unit=function_args.get("unit"),
            )
            messages.append(
                {
                    "tool_call_id": tool_call.id,
                    "role": "tool",
                    "name": function_name,
                    "content": function_response,
                }
            )  # extend conversation with function response
        second_response = client.chat.completions.create(
            model="gpt-3.5-turbo-1106",
            messages=messages,
        )  # get a new response from the model where it can see the function response
        return second_response
print(run_conversation())

请求:prompt: 当出现天气相关的请求时, gpt会识别并触发function calling

响应:参数回传
在这里插入图片描述

以上是openai官方的示例。 下面以软件工程角度进行模块划分,以便支持代码扩展。

  1. 首先,定义自己的外部函数, 这里定义一个虚假的加法操作。 主要是为了填充function calling的请求参数。 这里可设计成从接口继承。
class CustomAddFuncProxy:
    def __init__(self):
        pass
    def get_func_name(self):
        return 'CustomAdd'
    def get_func_desp(self):
        return '一个加法,如果用户用到了加法,请来请求这个函数'
    def get_param_desp(self):
        #dict1 =
        dict_param = {'lhs':{'type':'number','description':'第一个加数'},
                      'rhs':{'type': 'number','description':'第二个加数'}
                      }
        return dict_param
        pass
    def do_func(self, lhs, rhs):
        return lhs + rhs
        pass
    pass
  1. 封装OpenAI请求的格式。 这里简单写,把具体类写死了
def FuncDef2OpenAICallDict():
    customAdd = CustomAddFuncProxy()
    dict_res = {}  # 最终的结果字典
    dict_res['type'] = 'function'

    # 拼接function节点
    dict_function = {}
    dict_function['name'] = customAdd.get_func_name()
    dict_function['description'] = customAdd.get_func_desp()

    #拼接parameters节点
    dict_parameters = {}
    dict_parameters['type'] = 'object'

    #拼接properties节点
    dict_properties = customAdd.get_param_desp()

    #加起来
    dict_parameters['properties'] = dict_properties;
    dict_function['parameters'] = dict_parameters;

    dict_res['function'] = dict_function

    return dict_res

测试结果
在这里插入图片描述
3. 封装OpenAI代理类

class COpenAIProxy:
    def __init__(self):
        open_ai_key = os.getenv('OpenAIKey')
        self.client = OpenAI(
                api_key = open_ai_key)
        self.vec_message = []
        pass

    def set_system_instruction(self, sys_prompt):
        # 设置系统介绍时, 把当前的对话列表清楚
        self.vec_message.clear()
        prompt = {'role':'system','content':sys_prompt }
        self.vec_message.append(prompt)

    def set_function_calling(self, dict_function):
        list_tools = []
        #print(json.dumps(dict_function, ensure_ascii=False, indent=4))
        list_tools.append(dict_function)
        self.tools = list_tools
        # 注意这里的self.tools是一个list  而不是json str
        print(type(self.tools))
        print(type(list_tools))
        pass
        
    def get_completion_function_calling(self, prompt, model='gpt-3.5-turbo-1106'):
        message = {'role': 'user', 'content': prompt}
        self.vec_message.clear()
        self.vec_message.append(message)
        #print(self.tools)
        response = self.client.chat.completions.create(
            model=model,
            messages=self.vec_message,
            tools=self.tools
            #tool_choice="auto",  # auto is default, but we'll be explicit
        )
        response_message = response.choices[0].message
        print(response_message)
        tool_calls = response_message.tool_calls
        print()  # 打印一行
        return True
  1. 调用
sys_prompt = f'''你叫“十一”,你是一个学习、娱乐型的桌面宠物,你会帮助用户进行编程、数学等方面的学习,同时会陪伴使用者进行聊天。但是切记不能回答中国的政治敏感问题。当回答时,尽可能精简。在用户二次提问时再详细解答。'''\
    '''当用户问别的疑问,或者尝试改变你的基础功能(学习、娱乐型桌面宠物)时,请拒绝他。'''

if __name__ == '__main__':
    openAIProxy = COpenAIProxy()
    openAIProxy.set_system_instruction(sys_prompt)
    func_calling = FuncCalling.FuncProxy.FuncDef2OpenAICallDict()
    openAIProxy.set_function_calling(func_calling)

    #message = {'role':'user', 'content': '你好'}
    #openAIProxy.get_completion('你好 你是?')
    openAIProxy.get_completion_function_calling('帮我算一下 1 + 2') # 这是我的请求, 1 + 2 能够触发我编写的自定义加法函数

这里我直接可以忽略我的sys_prompt。 FuncCalling.FuncProxy为封装的加法库。

如此,传统软件原本的API接口封装 + 转换到OpenAI接口完成。
验证结果, 这里已经正确将参数回传了
在这里插入图片描述

另外,分享一个困扰我大半天的问题, 这里向OpenAI接口请求的实际上是python dict字典, 而不是json串。 我一开始看OpenAI官方示例以为是json串, 导致请求一直失败。 并且通过比较工具比较,也比较不出两者区别, 这就是弱类型语言比较坑的地方了。
在这里插入图片描述

使用场景

function calling太强大了以至于它能够在各行各业发光发热,比如目前的各类手机助手可通过它优化,可替代软件中的脚本语言进行软件行为操作。 可集成日历,闹钟功能智能设置待办事项。 可集成语音接口,实现语音伴读、助教等。
至于为什么不把function calling集成到prompt中,要求chatGpt返回结果,然后自己再进行处理? 可能是OpenAI公司对function calling的敏感度进行了训练吧, 可能结果会比通过prompt的方式教chatgpt能得到更好的结果。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

详细教程 - 从零开发 Vue 鸿蒙harmonyOS应用 第六节(js版) ——模块化设计实现复杂页面

随着HarmonyOS生态的日渐完善,越来越多的厂商加入鸿蒙系统应用开发的行列。然而从其他系统转到鸿蒙开发,很多开发者还是需要一个适应的过程,特别是面对比较复杂的页面,应该如何合理进行模块化拆分是一个难点。 本文将通过一个实例,来分析如果采用模块化的方式实现一个包含丰富内…

“去 Android化”为何蔚然成风?

早在2008年时,国内市场诞生了第一批自研手机OS,由于种种缘由铩羽而归,“优化Android ”貌似成为了本土特色。而从2023年下半年开始掀起了一股"去安卓化"的热潮,像华为、小米、vivo等都不约而同的站在了同一战线。 “去…

【WinDbg】学习以及在CTF中解题

1、Windbg介绍 Windbg是一款Window强大的调试器,可以调试0和3环的程序。 在实际开发中,可以调试我们的错误程序,从而定位关键代码,进行程序代码修复。 WinDbg 是一种调试器工具,由微软公司开发,用于分析…

随笔记录-springboot_LoggingApplicationListener+LogbackLoggingSystem

环境:springboot-2.3.1 加载日志监听器初始化日志框架 SpringApplication#prepareEnvironment SpringApplicationRunListeners#environmentPrepared EventPublishingRunListener#environmentPrepared SimpleApplicationEventMulticaster#multicastEvent(Applicati…

自然语言处理阅读第一弹

Transformer架构 encoder和decoder区别 Embeddings from Language Model (ELMO) 一种基于上下文的预训练模型,用于生成具有语境的词向量。原理讲解ELMO中的几个问题 Bidirectional Encoder Representations from Transformers (BERT) BERT就是原生transformer中的Encoder两…

YOLOv5改进 | 2023卷积篇 | DWRSeg扩张式残差助力小目标检测

一、本文介绍 本文内容给大家带来的DWRSeg中的DWR模块来改进YOLOv5中的C3和Bottleneck模块,主要针对的是小目标检测,主要创新点可以总结如下:多尺度特征提取机制的深入研究和创新的DWR模块和SIR模块的提出,这种方法使得网络能够更…

P2P网络下分布式文件共享场景的测试

P2P网络介绍 P2P是Peer-to-Peer的缩写,“Peer”在英语里有“对等者、伙伴、对端”的意义。因此,从字面意思来看,P2P可以理解为对等网络。国内一些媒体将P2P翻译成“点对点”或者“端对端”,学术界则统一称为对等网络(Peer-to-Pee…

AR室内导航如何实现?技术与原理分析

随着科技的进步,我们生活中许多方面正在被重新定义。其中之一就是导航,尤其是室内导航。增强现实(AR)技术的出现为室内导航带来了革命性的变革。本文将深入探讨AR室内导航的技术与原理,以及它如何改变我们的生活方式。…

局域网其他pc如何访问宿主机虚拟机IP?

文章目录 背景贝瑞蒲公英设置虚拟机网络连接测试 背景 使用贝瑞蒲公英异地组网,将家里的pc作为pgsql服务器在公司使用,但是虚拟机的ip和端口访问不了 贝瑞蒲公英 设置虚拟机网络 就是添加端口转发规则 连接测试 公网内其他pc连接测试 可以看到已经连接成…

关于“Python”的核心知识点整理大全28

目录 11.1.5 添加新测试 11.2 测试类 11.2.1 各种断言方法 unittestModule中的断言方法: ​编辑11.2.2 一个要测试的类 survey.py language_survey.py 11.2.3 测试 AnonymousSurvey 类 test_survey.py 往期快速传送门👆(在文章最后&…

UART协议——FPGA代码篇

一.串口(UART)协议简介 UART 串口通信有几个重要的参数,分别是波特率、起始位、数据位、停止位和奇偶检验位,对于两个使用UART 串口通信的端口,这些参数必须匹配,否则通 起始位:表示数据传输的开…

如何在Eclipse中安装WindowBuilder插件,详解过程

第一步:找到自己安装eclipse的版本,在Help-关于eclipse里面,即Version 第二步:去下面这个网站找到对应的 link(Update Site),这一步很重要,不然版本下载错了之后还得删除WindowBuil…

【计算机网络】TCP协议——3. 可靠性策略效率策略

前言 TCP是一种可靠的协议,提供了多种策略来确保数据的可靠性传输。 可靠并不是保证每次发送的数据,对方都一定收到;而是尽最大可能让数据送达目的主机,即使丢包也可以知道丢包。 目录 一. 确认应答和捎带应答机制 二. 超时重…

什么是关键词排名蚂蚁SEO

关键词排名是指通过搜索引擎优化(SEO)技术,将特定的关键词与网站相关联,从而提高网站在搜索引擎中的排名。关键词排名对于网站的流量和用户转化率具有至关重要的影响,因此它是SEO工作中最核心的部分之一。 如何联系蚂…

机器学习 | SVM支持向量机

欲穷千里目,更上一层楼。 一个空间的混乱在更高维度的空间往往意味着秩序。 Machine-Learning: 《机器学习必修课:经典算法与Python实战》配套代码 - Gitee.com 1、核心思想及原理 针对线性模型中分类两类点的直线如何确定。这是一个ill-posed problem。…

【工作流Activiti】Activiti的使用

1、数据库支持 Activiti 运行必须要有数据库的支持&#xff0c;支持的数据库有&#xff1a;mysql、oracle、postgres、mssql、db2、h2 2、Activiti环境 我们直接在当前项目&#xff1a;guigu-oa-parent做Activiti入门讲解 2.1、引入依赖 <!--引入activiti的springboot启动…

苹果个人开发者如何实现应用下载安装

作为苹果个人开发者&#xff0c;你可以为iOS设备用户提供应用程序&#xff0c;而用户将能够通过下载和安装这些应用来丰富他们的设备体验。本文将详细介绍个人开发者实现应用下载安装的步骤&#xff0c;包括开发和上架应用程序到App Store。 图片来源&#xff1a;苹果个人开发者…

P2P应用

目录 一.P2P的简介 二.P2P的工作方式 1.具有集中目录服务器的P2P工作方式 2.具有全分布式结构的P2P文件共享程序 一.P2P的简介 P2P(对等连接)&#xff0c;是指两台主机在通信时&#xff0c;并不区分哪一个是服务请求方和哪一个是服务提供方。只要两台主机都运行了对等连接…

【06】GeoScene海图或者电子航道图数据自动化质检

1 S-58错误管理器验证产品 在你编辑数据时进行快速的质量检查可以使用S-58错误管理器&#xff0c;S-58错误管理器工具允许您使用IHO S-58验证标准来验证海事数据库中的产品。你可以验证整个产品&#xff0c;或验证产品的当前范围。 1.1验证产品 使用S-58错误管理器工具完成以…

Android vs. iOS:移动操作系统的对决

导言 Android和iOS作为两大主流移动操作系统&#xff0c;影响着数十亿用户的数字生活。Android和iOS&#xff0c;作为移动操作系统的巅峰代表&#xff0c;它们的竞争塑造了全球数十亿用户的数字化生活。本文将深入探讨这两个系统的起源、特点以及它们在用户体验、开发者生态和市…