OpenAI开放的api接口调用很简单,只要用post请求就可以了。但是因为地区限制,国内无法直接使用这个方法。但我们可以通过Cloudflare来进行套壳转发请求来完成国内对openai的访问。
Open AI提供的API
1curl https://api.openai.com/v1/chat/completions \
2 -H "Content-Type: application/json" \
3 -H "Authorization: Bearer **" \
4 -d '{
5 "model": "gpt-3.5-turbo",
6 "messages": [{"role": "user", "content": "Say this is a test!"}],
7 "temperature": 0.7
8 }'
域名申请
在使用Cloudflare进行转发请求时,我们首选需要一个域名,可以从下面两个网站中进行申请,首年免费。
1Freenom:https://www.freenom.com
2硅云:https://www.vpsor.cn/
这两个网站都可以获得免费域名,我使用的是硅云,注册信息要用身份证实名认证,大概信息填写后等2-4个小时就有结果了。
Cloudflare托管
注册账号并登录
网站->添加站点,如下图
添加站点时,选择Free免费版本,如下图
继续,如图
添加DNS服务器
1anderson.ns.cloudflare.com
2carol.ns.cloudflare.com
我的域名是在国内西部数码中注册的,在域名管理界面中,删除原有DNS服务,使用自定义配置即可,如图
配置Worker路由
点击站点->Worker路由,如图
添加路由chat.wjn.info/*
我的站点已经添加好一条,如果你是首次,则直接添加即可管理Worker
快速编辑
将默认代码,换成如下代码
1const TELEGRAPH_URL = 'https://api.openai.com';
2
3addEventListener('fetch', event => {
4 event.respondWith(handleRequest(event.request))
5})
6
7async function handleRequest(request) {
8 console.log('hello');
9 const url = new URL(request.url);
10 url.host = TELEGRAPH_URL.replace(/^https?:\/\//, '');
11console.log(request.headers);
12 const modifiedRequest = new Request(url.toString(), {
13 headers: request.headers,
14 method: request.method,
15 body: request.body,
16 redirect: 'follow'
17 });
18
19 const response = await fetch(modifiedRequest);
20 const modifiedResponse = new Response(response.body, response);
21
22 // 添加允许跨域访问的响应头
23 modifiedResponse.headers.set('Access-Control-Allow-Origin', '*');
24
25 return modifiedResponse;
26}
Java中调用
pom.xml
1<dependency>
2 <groupId>org.projectlombok</groupId>
3 <artifactId>lombok</artifactId>
4 <optional>true</optional>
5</dependency>
6
7<dependency>
8 <groupId>cn.hutool</groupId>
9 <artifactId>hutool-all</artifactId>
10 <version>5.8.16</version>
11</dependency>
12
13<dependency>
14 <groupId>com.alibaba</groupId>
15 <artifactId>fastjson</artifactId>
16 <version>2.0.10</version>
17</dependency>
Main.java
1package cc.iteachyou.chatgpt.controller;
2
3import java.io.IOException;
4import java.util.Scanner;
5
6import cc.iteachyou.chatgpt.ChatGPTUtil;
7
8public class Main{
9 public static void main(String[] args) throws IOException {
10 while (true) {
11 System.out.print("\n请输入问题(q退出):");
12 String question = new Scanner(System.in).nextLine();
13 if ("q".equals(question)) break;
14 long start = System.currentTimeMillis();
15 String answer = ChatGPTUtil.getAnswer(question);
16 long end = System.currentTimeMillis();
17 System.out.println("该回答花费时间为:" + (end - start) / 1000.0 + "秒");
18 System.out.println(answer);
19 }
20 }
21}
ChatGPTUtil.java
1package cc.iteachyou.chatgpt;
2import java.io.IOException;
3
4import com.alibaba.fastjson.JSON;
5import com.fasterxml.jackson.databind.ObjectMapper;
6
7import cc.iteachyou.chatgpt.entity.ChatGPTMessage;
8import cc.iteachyou.chatgpt.entity.ChatGPTRequestParameter;
9import cc.iteachyou.chatgpt.entity.ChatGPTResponseParameter;
10import cc.iteachyou.chatgpt.entity.Choices;
11import cn.hutool.http.Header;
12import cn.hutool.http.HttpRequest;
13import cn.hutool.http.HttpResponse;
14
15/**
16 * @author ttpfx
17 * @date 2023/3/23
18 */
19public class ChatGPTUtil {
20 /**
21 * 自己chatGpt的ApiKey
22 */
23 private static String API_KEY = "";
24 /**
25 * 对应的请求接口
26 */
27 private static String URL = "https://chat.t-nn.com/v1/chat/completions";
28
29 /**
30 * 创建一个ChatGptRequestParameter,用于携带请求参数
31 */
32 private static ChatGPTRequestParameter chatGptRequestParameter = new ChatGPTRequestParameter();
33
34 /**
35 * 相应超时时间,毫秒
36 */
37 private int responseTimeout = 60000;
38
39 public static String getAnswer(String question) {
40 // 创建一个HttpPost
41 chatGptRequestParameter.addMessages(new ChatGPTMessage("user", question));
42
43 String raw = JSON.toJSONString(chatGptRequestParameter);
44
45 HttpRequest request = HttpRequest.post(URL)
46 .body(raw)
47 .header(Header.CONTENT_TYPE.getValue(), "application/json")
48 .header(Header.AUTHORIZATION.getValue(), "Bearer " + API_KEY);
49
50 HttpResponse response = request.execute();
51 try {
52 String body = response.body();
53
54 ObjectMapper objectMapper = new ObjectMapper();
55 // 转换为对象
56 ChatGPTResponseParameter responseParameter = objectMapper.readValue(body, ChatGPTResponseParameter.class);
57 String ans = "";
58 // 遍历所有的Choices(一般都只有一个)
59 for (Choices choice : responseParameter.getChoices()) {
60 ChatGPTMessage message = choice.getMessage();
61 chatGptRequestParameter.addMessages(new ChatGPTMessage(message.getRole(), message.getContent()));
62 String s = message.getContent().replaceAll("\n+", "\n");
63 ans += s;
64 }
65 // 返回信息
66 return ans;
67 } catch (IOException e) {
68 e.printStackTrace();
69 }
70 // 发生异常,移除刚刚添加的ChatGptMessage
71 chatGptRequestParameter.getMessages().remove(chatGptRequestParameter.getMessages().size()-1);
72 return "您当前的网络无法访问";
73 }
74}
ChatGPTMessage.java
1package cc.iteachyou.chatgpt.entity;
2
3import lombok.AllArgsConstructor;
4import lombok.Data;
5import lombok.NoArgsConstructor;
6
7@Data
8@NoArgsConstructor
9@AllArgsConstructor
10public class ChatGPTMessage {
11 private String role;
12 private String content;
13}
ChatGPTRequestParameter.java
1package cc.iteachyou.chatgpt.entity;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import lombok.Data;
7
8@Data
9public class ChatGPTRequestParameter {
10 private String model = "gpt-3.5-turbo-0301";
11 private List<ChatGPTMessage> messages = new ArrayList<>();
12
13 public void addMessages(ChatGPTMessage message) {
14 this.messages.add(message);
15 }
16}
ChatGPTResponseParameter.java
1package cc.iteachyou.chatgpt.entity;
2
3import java.util.List;
4
5import lombok.Data;
6
7@Data
8public class ChatGPTResponseParameter {
9 private String id;
10 private String object;
11 private String created;
12 private String model;
13 private Usage usage;
14 private List<Choices> choices;
15}
Choices.java
1package cc.iteachyou.chatgpt.entity;
2
3import lombok.Data;
4
5@Data
6public class Choices {
7 ChatGPTMessage message;
8 String finish_reason;
9 Integer index;
10}
Usage.java
1package cc.iteachyou.chatgpt.entity;
2
3import lombok.Data;
4
5@Data
6public class Usage {
7 String prompt_tokens;
8 String completion_tokens;
9 String total_tokens;
10}