您的位置 首页 >  博文

使用Java在国内不翻墙调用Chatgpt API实现问答对话

OpenAI开放的api接口调用很简单,只要用post请求就可以了。但是因为地区限制,国内无法直接使用这个方法。但我们可以通过Cloudflare来进行套壳转发请求来完成国内对openai的访问。

cloudflare1250-1024x410.jpg

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托管
  1. 注册账号并登录

  2. 网站->添加站点,如下图

    1685174457652033682.png

  3. 添加站点时,选择Free免费版本,如下图

    1685174477379042288.png

  4. 继续,如图

    1685174494520044605.png

  5. 添加DNS服务器

1anderson.ns.cloudflare.com
2carol.ns.cloudflare.com

我的域名是在国内西部数码中注册的,在域名管理界面中,删除原有DNS服务,使用自定义配置即可,如图

1685174512431091435.png

配置Worker路由
  1. 点击站点->Worker路由,如图

    1685174530467096462.png

  2. 添加路由chat.wjn.info/*
    我的站点已经添加好一条,如果你是首次,则直接添加即可

  3. 管理Worker

    1685174562436066948.png

  4. 快速编辑
    将默认代码,换成如下代码

    1685174596638076966.png

 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}
测试

9.png

关于作者: 王俊南(Jonas)

昨夜寒蛩不住鸣。惊回千里梦,已三更。起来独自绕阶行。人悄悄,帘外月胧明。 白首为功名。旧山松竹老,阻归程。欲将心事付瑶琴。知音少,弦断有谁听。

热门文章