Skip to content

Commit f5513b6

Browse files
author
guorutao
committed
feature 1.0.14 支持最新的3.5-0613、4.0-0613模型,支持最新的chat接口function call功能
1 parent fb3293c commit f5513b6

1 file changed

Lines changed: 178 additions & 0 deletions

File tree

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
package com.unfbx.chatgpt;
2+
3+
import cn.hutool.json.JSONObject;
4+
import cn.hutool.json.JSONUtil;
5+
import com.unfbx.chatgpt.entity.chat.*;
6+
import com.unfbx.chatgpt.function.KeyRandomStrategy;
7+
import com.unfbx.chatgpt.interceptor.DynamicKeyOpenAiAuthInterceptor;
8+
import com.unfbx.chatgpt.interceptor.OpenAILogger;
9+
import com.unfbx.chatgpt.interceptor.OpenAiResponseInterceptor;
10+
import lombok.Builder;
11+
import lombok.Data;
12+
import lombok.extern.slf4j.Slf4j;
13+
import okhttp3.OkHttpClient;
14+
import okhttp3.logging.HttpLoggingInterceptor;
15+
import org.junit.Before;
16+
import org.junit.Test;
17+
18+
import java.net.InetSocketAddress;
19+
import java.net.Proxy;
20+
import java.util.*;
21+
import java.util.concurrent.TimeUnit;
22+
23+
/**
24+
* 描述: 测试类
25+
*
26+
* @author https:www.unfbx.com
27+
* 2023-06-14
28+
*/
29+
@Slf4j
30+
public class OpenAiClientFunctionTest {
31+
32+
private OpenAiClient v2;
33+
34+
@Before
35+
public void before() {
36+
//可以为null
37+
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890));
38+
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger());
39+
//!!!!千万别再生产或者测试环境打开BODY级别日志!!!!
40+
//!!!生产或者测试环境建议设置为这三种级别:NONE,BASIC,HEADERS,!!!
41+
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
42+
OkHttpClient okHttpClient = new OkHttpClient
43+
.Builder()
44+
// .proxy(proxy)
45+
.addInterceptor(httpLoggingInterceptor)
46+
.addInterceptor(new OpenAiResponseInterceptor())
47+
.connectTimeout(10, TimeUnit.SECONDS)
48+
.writeTimeout(30, TimeUnit.SECONDS)
49+
.readTimeout(30, TimeUnit.SECONDS)
50+
.build();
51+
v2 = OpenAiClient.builder()
52+
//支持多key传入,请求时候随机选择
53+
.apiKey(Arrays.asList("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"))
54+
//自定义key的获取策略:默认KeyRandomStrategy
55+
.keyStrategy(new KeyRandomStrategy())
56+
// .keyStrategy(new FirstKeyStrategy())
57+
.authInterceptor(new DynamicKeyOpenAiAuthInterceptor())
58+
.okHttpClient(okHttpClient)
59+
//自己做了代理就传代理地址,没有可不不传,(关注公众号回复:openai ,获取免费的测试代理地址)
60+
.apiHost("https://dgr.life/")
61+
.build();
62+
}
63+
64+
@Test
65+
public void chatFunction() {
66+
67+
//模型:GPT_3_5_TURBO_16K_0613
68+
Message message = Message.builder().role(Message.Role.USER).content("给我输出一个长度为2的中文词语,并解释下词语对应物品的用途").build();
69+
//属性一
70+
JSONObject wordLength = new JSONObject();
71+
wordLength.putOpt("type", "number");
72+
wordLength.putOpt("description", "词语的长度");
73+
//属性二
74+
JSONObject language = new JSONObject();
75+
language.putOpt("type", "string");
76+
language.putOpt("enum", Arrays.asList("zh", "en"));
77+
language.putOpt("description", "语言类型,例如:zh代表中文、en代表英语");
78+
//参数
79+
JSONObject properties = new JSONObject();
80+
properties.putOpt("wordLength", wordLength);
81+
properties.putOpt("language", language);
82+
Parameters parameters = Parameters.builder()
83+
.type("object")
84+
.properties(properties)
85+
.required(Arrays.asList("wordLength")).build();
86+
Functions functions = Functions.builder()
87+
.name("getOneWord")
88+
.description("获取一个指定长度和语言类型的词语")
89+
.parameters(parameters)
90+
.build();
91+
92+
ChatCompletion chatCompletion = ChatCompletion
93+
.builder()
94+
.messages(Arrays.asList(message))
95+
.functions(Arrays.asList(functions))
96+
.functionCall("auto")
97+
.model(ChatCompletion.Model.GPT_3_5_TURBO_16K_0613.getName())
98+
.build();
99+
ChatCompletionResponse chatCompletionResponse = v2.chatCompletion(chatCompletion);
100+
101+
ChatChoice chatChoice = chatCompletionResponse.getChoices().get(0);
102+
log.info("构造的方法值:{}", chatChoice.getMessage().getFunctionCall());
103+
log.info("构造的方法名称:{}", chatChoice.getMessage().getFunctionCall().getName());
104+
log.info("构造的方法参数:{}", chatChoice.getMessage().getFunctionCall().getArguments());
105+
WordParam wordParam = JSONUtil.toBean(chatChoice.getMessage().getFunctionCall().getArguments(), WordParam.class);
106+
String oneWord = getOneWord(wordParam);
107+
108+
FunctionCall functionCall = FunctionCall.builder()
109+
.arguments(chatChoice.getMessage().getFunctionCall().getArguments())
110+
.name("getOneWord")
111+
.build();
112+
Message message2 = Message.builder().role(Message.Role.ASSISTANT).content("方法参数").functionCall(functionCall).build();
113+
String content
114+
= "{ " +
115+
"\"wordLength\": \"3\", " +
116+
"\"language\": \"zh\", " +
117+
"\"word\": \"" + oneWord + "\"," +
118+
"\"用途\": [\"直接吃\", \"做沙拉\", \"售卖\"]" +
119+
"}";
120+
Message message3 = Message.builder().role(Message.Role.FUNCTION).name("getOneWord").content(content).build();
121+
List<Message> messageList = Arrays.asList(message, message2, message3);
122+
ChatCompletion chatCompletionV2 = ChatCompletion
123+
.builder()
124+
.messages(messageList)
125+
.model(ChatCompletion.Model.GPT_3_5_TURBO_16K_0613.getName())
126+
.build();
127+
ChatCompletionResponse chatCompletionResponseV2 = v2.chatCompletion(chatCompletionV2);
128+
log.info("自定义的方法返回值:{}",chatCompletionResponseV2.getChoices().get(0).getMessage().getContent());
129+
130+
/**
131+
* [main] INFO com.unfbx.chatgpt.OpenAiClientFunctionTest - 自定义的方法返回值:词语:苹果
132+
*
133+
* 用途:苹果是一种水果,具有多种用途。以下是苹果的几种常见用途:
134+
*
135+
* 1. 直接吃:苹果可以直接食用,具有清爽的口感和丰富的营养成分,是一种健康的零食选择。
136+
*
137+
* 2. 做沙拉:苹果可以切成块状或丝状,加入其他蔬菜和调味料,制作成沙拉。苹果的甜脆口感可以为沙拉增添口感和风味。
138+
*
139+
* 3. 售卖:苹果是一种常见的水果,可以被商家售卖。人们可以购买苹果作为食物或礼物,满足自己或他人的需求。
140+
*
141+
* 总之,苹果是一种多功能的水果,可以直接食用,也可以用于制作沙拉,同时也是一种常见的商业商品。
142+
*/
143+
}
144+
145+
public String getOneWord(WordParam wordParam) {
146+
147+
List<String> zh = Arrays.asList("大香蕉", "哈密瓜", "苹果");
148+
List<String> en = Arrays.asList("apple", "banana", "cantaloupe");
149+
if (wordParam.getLanguage().equals("zh")) {
150+
for (String e : zh) {
151+
if (e.length() == wordParam.getWordLength()) {
152+
return e;
153+
}
154+
}
155+
}
156+
if (wordParam.getLanguage().equals("en")) {
157+
for (String e : en) {
158+
if (e.length() == wordParam.getWordLength()) {
159+
return e;
160+
}
161+
}
162+
}
163+
return "西瓜";
164+
}
165+
166+
@Test
167+
public void testInput() {
168+
System.out.println(getOneWord(WordParam.builder().wordLength(2).language("zh").build()));
169+
}
170+
171+
@Data
172+
@Builder
173+
static class WordParam {
174+
private int wordLength;
175+
@Builder.Default
176+
private String language = "zh";
177+
}
178+
}

0 commit comments

Comments
 (0)