为什么上传网站模板网站上没有文字和图片,商务网站制作工程师,手机怎么访问微网站,代理公司和经纪公司的区别传统软件和AI大模型的胶水——Function Calling 浅谈GPT对传统软件的影响Function Calling做了什么#xff0c;为什么选择Function CallingFunction Calling简单例子#xff0c;如何使用使用场景 浅谈GPT对传统软件的影响
目前为止好多人对chatGPT的使用才停留在OpenAI自己提… 传统软件和AI大模型的胶水——Function Calling 浅谈GPT对传统软件的影响Function Calling做了什么为什么选择Function CallingFunction 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 testopen_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, unitfahrenheit):Get the current weather in a given locationif 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 modelmessages [{role: user, content: Whats 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(modelgpt-3.5-turbo-1106,messagesmessages,toolstools,tool_choiceauto, # auto is default, but well be explicit)response_message response.choices[0].messagetool_calls response_message.tool_calls# Step 2: check if the model wanted to call a functionif tool_calls:# Step 3: call the function# Note: the JSON response may not always be valid; be sure to handle errorsavailable_functions {get_current_weather: get_current_weather,} # only one function in this example, but you can have multiplemessages.append(response_message) # extend conversation with assistants reply# Step 4: send the info for each function call and function response to the modelfor 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(locationfunction_args.get(location),unitfunction_args.get(unit),)messages.append({tool_call_id: tool_call.id,role: tool,name: function_name,content: function_response,}) # extend conversation with function responsesecond_response client.chat.completions.create(modelgpt-3.5-turbo-1106,messagesmessages,) # get a new response from the model where it can see the function responsereturn second_response
print(run_conversation())请求prompt: 当出现天气相关的请求时 gpt会识别并触发function calling
响应参数回传
以上是openai官方的示例。 下面以软件工程角度进行模块划分以便支持代码扩展。
首先定义自己的外部函数 这里定义一个虚假的加法操作。 主要是为了填充function calling的请求参数。 这里可设计成从接口继承。
class CustomAddFuncProxy:def __init__(self):passdef get_func_name(self):return CustomAdddef get_func_desp(self):return 一个加法如果用户用到了加法请来请求这个函数def get_param_desp(self):#dict1 dict_param {lhs:{type:number,description:第一个加数},rhs:{type: number,description:第二个加数}}return dict_parampassdef do_func(self, lhs, rhs):return lhs rhspasspass封装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_functionreturn 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 []passdef 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_asciiFalse, indent4))list_tools.append(dict_function)self.tools list_tools# 注意这里的self.tools是一个list 而不是json strprint(type(self.tools))print(type(list_tools))passdef get_completion_function_calling(self, prompt, modelgpt-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(modelmodel,messagesself.vec_message,toolsself.tools#tool_choiceauto, # auto is default, but well be explicit)response_message response.choices[0].messageprint(response_message)tool_calls response_message.tool_callsprint() # 打印一行return True调用
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能得到更好的结果。