JAVA SpringBoot deploys its own Chatgpt website record

Foreword

This is the first project I did. Post this article to record the ideas and pitfalls in the development process. The approach and thinking are not necessarily correct, and I hope that if someone sees the shortcomings, he will correct them. Welcome to private message me with any questions.

The final display form of this function is to ask questions to chatGPT and get the returned results by entering specific keywords through a preset model. All client operations will be performed on the web page.

If you want to reprint, just leave a message with me.

Needs Analysis

  • Client operations are performed on a web page, so this must be a web project.
    • Including registration server, registration domain name, server deployment.
    • Because I want the server to use the linux system, and I am lazy to install the linux virtual machine on my computer. So using java development, after all, it is easy to deploy.
    • \t

  • Need to connect to chatGPT
    • Including proxy deployment, secret key acquisition, reading api documentation
    • \t

  • development process
    • Phase zero, pre-preparation
      • Airport, Aliyun server, openai account
      • \t\t

    • The first stage, basic development.
      • 1.1. Deploy a server that can respond to requests to localhost
      • 1.2. Deploy the server to the cloud server
      • \t\t

    • The second stage, api connection
      • 2.1. Learn how to call api, and successfully call a domestic api
      • 2.2. Load the proxy and access the domestic API
      • 2.3. Based on the proxy, use the official demonstration code curl to communicate with chatGpt
      • 2.4. Call chatGpt API
      • \t\t

    • The third stage, testing and launching
      • 3.1. Local communication
      • 3.2. Deploy to the cloud server and adjust the communication
      • \t\t

    • \t

Practical steps

  • 0: preliminary preparation
    • Regarding the preparation of the airport, I spent a lot of time building an overseas server as an overseas proxy site according to the tutorial on youtube. However, in practical application, the following problems were found
      • High latency. It may be that the server was selected relatively lazily, and I found out that there were nearly 800 pings after doing it myself.
      • The ws transport protocol used for anti-blocking. This protocol is more troublesome if used, after all, okhttp only supports socks and http. It is more troublesome to use ws.
      • The cost is not worth it. More expensive than using a third-party airport.
      • \t\t

    • In the end I used a third party. The clash is deployed on linux, and the proxy is performed based on the port given by the clash. That is, when the clash service is enabled (clash for windows or clash core on linux). There are quite a lot of tutorials on how to deploy clash on the server. It is available on Zhihu and YouTube.
    • About openai and Alibaba cloud server. There is nothing to say about these two, there are many online tutorials.
    • \t

  • 1.1: Deploy a server that can respond to requests to localhost
    • The method I use here is to write front-end web pages with thymleaf.
      • There are many online tutorials about thymleaf.
      • I’m listing here a question that has been bugging me for days.
        • 1. I found that the webpage can be opened smoothly by entering the url, but it cannot be opened by clicking.
        • 2. The get request finds that the url has changed, but the address is different from the name specified in the form
        • \t\t\t

      • Finally, it was found that the target webpage (including the homepage) was placed under the resource/public and resource/static folders. It is impossible to pass the controller if placed under these two folders.
      • In the last project I deployed, all web resources were placed under the template folder. All web pages are redirected through the controller. problem solved.
      • \t\t

    • \t

  • 1.2: Deploy the server to the cloud server
    • Here is a cloud server of Alibaba Cloud, of course it is free for trial
    • I am using ubantu system. Installation with Pagoda. Very simple and convenient.
    • The pit I have stepped on here is that there is no firewall to let it go. Remember to set this. If you use a pagoda, you also need to release the security group in the pagoda.
    • \t

  • 2.1: Learn how to call api, and successfully call a domestic api
    • The behavior of calling the api can be introduced into the okhttp class library. He itself has relatively rich code.
    • If it is the first call and you don’t know how to do it, it is recommended to set up a Feishu account. Feishu has its own API debugging platform, and you can also see the demonstration code of java-okhttp on the right. In addition, it is a domestic interface, which is also free. Very good for learning.
    • Try not to use sdk. It is better to use the http connection to experience some things, the sdk is too convenient, but I learned less.
    • \t

  • 2.2: Load the proxy and access the domestic API
    • This step actually stuck with me for a long time. There are actually two ways to implement it.
    • The first is by setting a system variable. In the business logic, just write it before creating the client.
      •  System.setProperty("http.proxyHost", "127.0.0.1");
                System.setProperty("http.proxyPort", "7890");
        
                System.setProperty("https.proxyHost", "127.0.0.1");
                System.setProperty("https.proxyPort", "7890");

        \t\t\t

      • \t\t

    • The second is by editing the client in okhttp. But I think it is the first convenience.
    • Of course, if you are not sure about the quality of the proxy. There is a tool through DingTalk’s computer terminal. There is a button on it to detect proxies.
    • In fact, at the beginning, I wanted to access through the specified ip and port without installing clash. But my debugging failed repeatedly (because the ws protocol is used, not http or socks. There are quite a lot of pitfalls in this setting).
    • In the end, it was replaced by the method of relying on the port provided by clash. Its disadvantage is that it needs to be deployed on linux. This deployment is actually quite troublesome. Fortunately, the server does not need to be restarted frequently, and it is done once deployed. (Every time I update, I will restart the project directly in the pagoda. The pagoda is still very convenient, and there have been no problems so far)
    • \t

  • 2.3: Based on the proxy, use the official demonstration code to curl chatGpt
    • In fact, this step is to use the method of terminal proxy for trial and error.
    • A terminal is required. I am using git. Of course cmd is also available. Note that this step is actually tested on the server.
    • The first step requires setting up a proxy. If you use cmd, it seems that you can’t use export, use set
    • export http_proxy = http://127.0.0.1:1080
      export https_proxy = http://127.0.0.1:1080

      \t\t

    • The second step is to enter the test code: note that you must fill in your own secret key
    • curl https://api.openai.com/v1/chat/completions -H 'Content-Type: application/json' -H 'Authorization: Bearer XXXXXXX' -d '{
        "model": "gpt-3.5-turbo",
        "messages": [{"role": "user", "content": "This is a test"}],
        "temperature": 0.7
      }'

      \t\t

    • Of course, if this curl fails, you can try curl and Google it. Because the openai server is indeed a bit hard to explain. But at this time, we must be careful. Don’t proxy the ip is blocked by openai

      \t\t

    • curl -i www.baidu.com //This is Baidu, check that at least you can access the Internet
      curl -i www.google.com //This is Google, it is valid if there is a return

      \t\t

    • This step must pay attention. curl will work. It is normal that the ping fails. Don’t worry about it. The things used are different!

      \t\t

    • \t

  • 2.4: Call chatGpt API

    • This step also takes a long time. At the beginning, I wanted to use okhttp to connect. But the connection keeps failing all the time. The server returns a 400 bad request. I’ve checked many times and it’s fine. I suspect that the content item he requested is a list instead of json.

      \t\t

    • After spending a long, long time, I gave up on using okhttp to establish a connection and moved to using the sdk.

      \t\t

    • Yes, that’s right. He actually has java sdk. github address: GitHub – TheoKanning/openai-java: OpenAI GPT-3 Api Client in Java

      \t\t

    • Note that what he returns is a list of ChatCompletionChoice. Take out the content in its content, which is the last thing you want.

      \t\t

    • \t

  • 3.1 Local communication

    • I’m having a little problem with this. That is, I found that the proportion of users’ long request timeout is particularly high. Own access always fails.

      \t\t

    • This issue was resolved quickly. There is a polymorphic method in its service method that can fill in the timeout time.

      \t\t

    • Just paste the whole code

      \t\t

    •  public static String askForResult(String input,Double temperature){
              System.setProperty("http.proxyHost", "127.0.0.1");
              System.setProperty("http.proxyPort", "7890");
      
              System.setProperty("https.proxyHost", "127.0.0.1");
              System.setProperty("https.proxyPort", "7890");
              
              
              / / Configure the format that needs to be input
              List message =new ArrayList<>(0);
              message.add(new ChatMessage("user", input));
              System.out.println("Start processing request");
      
      
              //Set the timeout time
              Duration timeout = Duration.ofSeconds((long) 180.0);
      
              OpenAiService service = new OpenAiService(apiKey,timeout);//load api key
      
              // make a connection
              ChatCompletionRequest request2=ChatCompletionRequest.builder()
                      .model("gpt-3.5-turbo")
                      .temperature(temperature)
                      .messages(message)
                      .build();
      
              //Analyze the return value (the initial return is a list. Take it apart to get the value)
              List<ChatCompletionChoice> list =service.createChatCompletion(request2).getChoices();
              ChatCompletionChoice ccc = list. get(0);
              String finalAnswer = ccc. getMessage(). getContent();
      // System.out.println(finalAnswer);
              System.out.println("return success");
              return finalAnswer;
      
          }

      \t\t

    • \t

  • 3.2 Deploy to cloud server

    • This step is the easiest in my opinion. Blow the pagoda again.

      \t\t

    • I am using the ubantu system, downloaded a clash core and started it. Then modify the configuration file, and finally deploy docker. Just follow along on youtube.

      \t\t

    • \t

Summary

  • In fact, some functions have not yet been implemented, because I have not yet connected and deployed the database.
  • For example, in contextual dialogue continuation, it is necessary to obtain the unique key of the returned dialogue after each answer, and then proceed to the next question under this key. Not done yet.
  • For example, the inspection of the problem. If it is a more general question, you need to use a higher temprature, and a simpler question needs to use a lower temprature. (If the temprature is very low, you will see an ai that is too serious, so serious that it may not meet all your requirements, such as at least 200 words)