本文介绍: 关于 GPT 中API的function参数,提供了一些能力,这个函数调用是 Open AI 在2023年的6.13号发布的新能力,根据它的官方描述, 函数调用能力可以让模型输出一个请求调用函数的消息,其中包含所需调用函数的信息,以及调用函数时所需携带的参数的信息,这种方式是一种将GPT的能力和外部的工具,外部的API连接起来的新的方式
Function Call 概念
函数调用的机制
函数的作用
函数调用的使用
- 那么我们如何去使用函数调用呢?如何在它的聊天API的接口上去添加函数相关的这些参数呢?
- 为了实现函数调用的能力, 在API里面有新的请求的参数就是function, function call等等, 在官方的API文档上可以查询
- 在使用之前,我们先来了解一下函数调用的步骤
代码实现
package com.xxx.gpt.client.entity;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ChatFunction {
String name;
String description;
ChatParameter parameters;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class ChatParameter {
String type;
List<String> required;
Object properties;
}
}
package com.xxx.gpt.client.entity;
import lombok.Data;
@Data
public class FunctionCallResult {
String name;
String arguments;
}
package com.xxx.gpt.client.test;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xxx.gpt.client.ChatGPTClient;
import com.xxx.gpt.client.entity.*;
import com.xxx.gpt.client.util.Proxys;
import org.junit.Before;
import org.junit.Test;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FunctionCallTest {
private ChatGPTClient chatGPTClient;
@Before
public void before() {
Proxy proxy = Proxys.http("127.0.0.1", 7890);
chatGPTClient = ChatGPTClient.builder()
.apiKey("sk-6kchn0DasdfqOJqkc3aI665ct") // 填入自己的 key
.timeout(900)
.proxy(proxy)
.apiHost("https://api.openai.com/")
.build()
.init();
}
// 调用gpt的时候,带上函数信息,让GPT选择是否调用
@Test
public void chat() {
List<ChatFunction> functions = new ArrayList<>();
ChatFunction function = new ChatFunction();
function.setName("getCurrentWeather"); // 设置函数信息
function.setDescription("获取给定位置的当前天气");
function.setParameters(ChatFunction.ChatParameter.builder()
.type("object")
.required(Arrays.asList("location"))
.properties(JSON.parseObject("{n" +
" "location": {n" +
" "type": "string",n" +
" "description": "The city and state, e.g. San Francisco, " +
"CA"n" +
" },n" +
" "unit": {n" +
" "type": "string",n" +
" "enum": ["celsius", "fahrenheit"]n" +
" }n" +
" }"))
.build());
// 添加到列表中
functions.add(function);
// 构造 message
Message message = Message.of("上海的天气怎么样?");
// 构造调用 api 参数
ChatCompletion chatCompletion = ChatCompletion.builder()
.model(Model.GPT_3_5_TURBO_16K.getName())
.messages(Arrays.asList(message))
.functions(functions)
.maxTokens(8000)
.temperature(0.9)
.build();
// 调用
ChatCompletionResponse response = chatGPTClient.chatCompletion(chatCompletion);
ChatChoice choice = response.getChoices().get(0);
Message res = choice.getMessage();
System.out.println(res);
// 基于 finish reason 判断,如果是 function_call 就需要调用函数
if ("function_call".equals(choice.getFinishReason())) {
FunctionCallResult functionCall = res.getFunctionCall();
String functionCallName = functionCall.getName();
// 如果需要调用的是 getCurrentWeather
if ("getCurrentWeather".equals(functionCallName)) {
String arguments = functionCall.getArguments();
JSONObject jsonObject = JSON.parseObject(arguments);
String location = jsonObject.getString("location");
String unit = jsonObject.getString("unit");
// 得到最终的结果
String weather = getCurrentWeather(location, unit);
res.setContent("");
// 将结果 weather 告诉GPT
callWithWeather(weather, res, functions);
}
}
}
// 将结果传送给GPT
private void callWithWeather(String weather, Message res, List<ChatFunction> functions) {
Message message = Message.of("上海的天气怎么样?");
Message function1 = Message.ofFunction(weather);
function1.setName("getCurrentWeather");
ChatCompletion chatCompletion = ChatCompletion.builder()
.model(Model.GPT_3_5_TURBO_16K.getName())
.messages(Arrays.asList(message, res, function1))
.functions(functions)
.maxTokens(8000)
.temperature(0.9)
.build();
ChatCompletionResponse response = chatGPTClient.chatCompletion(chatCompletion);
ChatChoice choice = response.getChoices().get(0);
Message res2 = choice.getMessage();
//上海目前天气晴朗,气温为 22 摄氏度。
System.out.println(res2.getContent());
}
// 首先我们添加一个函数,函数是获取天气的信息,这里需要传入 location
// return 我们这里的返回值是根据location构造出来的一个JSON, 这里设置的固定的,就是模拟接口,或者对接天气网站接口都可
public String getCurrentWeather(String location, String unit) {
return "{ "temperature": 22, "unit": "celsius", "description": "晴朗" }";
}
}
// 本地有一个函数,将函数信息告诉chatgpt,并告诉chatgpt什么情况需要调用这个函数。由chatgpt判断是否需要调用该函数,如果需要在交互中进行调用。类似于委托机制
- 第一步,需要告诉GPT我们有哪些函数?也就是这些函数是我们本地定义的
- 第二步,是在调用GPT的时候带上函数信息,然后让GPT选择是否调用函数
- 第三步,解析GPT的返回,如果GPT需要调用函数,我们在本地根据GPT返回的参数,调用函数获取结果,在获取结果之后,将结果告诉GPT
- 通过GPT的函数调用的一个简单的示例
- GPT根据我们的自然语言,也就是我们的 Prompt 自行去判断是不是需要调用函数
- 如果需要调用的话,然后再告诉我们,由我们完成调用
- 完成调用之后,再将调用的结果返回给它
- 整个过程是我们和GPT的程序上的密切交互
原文地址:https://blog.csdn.net/Tyro_java/article/details/134795505
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_41120.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。