ChatGPT

Chat GPT API 이용 #3

Chris.Ko 2023. 6. 21. 11:00

하고 싶은 것 : gpt model text-davinci-003 => 더 좋은 것으로 변경 될 수 있도록 + endPoint는 model에 맞게

prompt 언어 영어만 되고 있는걸 한국어/베트남어로도 가능하도록 + 결과도 prompt에 입력한 언어로 보여지도록

 

 

여러 곳에서 찾아보니 현재 내 소스는 조금 엉망인 느낌?

모델마다 endPoint의 정보도 알고 있는데 접속이 불가능하다는 에러만 나오고...

OpenAI API 참조 문서를 보니 choices에 message로 나오고(나는 text로만 나오고),

chat completion/completion/Edits/Imanges/.. 등 원하는 것을 만들어야할때 POST 요청 url을 제공해주고

Request Body 또한 조건들이 다 다르다.

 

 

https://platform.openai.com/docs/api-reference/introduction

 

OpenAI API

Explore developer resources, tutorials, API docs, and dynamic examples to get the most out of OpenAI's platform.

platform.openai.com

 

#수정본

 

POST 요청 방식에 endPoint만 넣어주고, Request body에 모델을 따로 적어서 요청한다.

public static String createPostRequest(String prompt, String apiKey) {
        String responseString = "";
        String gptResponseString = "";
        String url = "https://api.openai.com/v1/chat/completions"; //각 model에 따른 endPoint에 맞게 작성할 것

        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);

        httpPost.setHeader("Content-Type", "application/json");
        httpPost.setHeader("Authorization", "Bearer " + apiKey);

        // Create request body
        JsonObjectBuilder systemMessageBuilder = Json.createObjectBuilder()
                .add("role", "system")
                .add("content", prompt);

        JsonArrayBuilder messagesBuilder = Json.createArrayBuilder()
                .add(systemMessageBuilder);

        JsonObjectBuilder requestBodyBuilder = Json.createObjectBuilder()
                .add("model", "gpt-3.5-turbo")
                .add("messages", messagesBuilder)
                .add("max_tokens", 500);
		//model 부분에 gpt-4도 가능, 실행해보면 gpt-4-0314 로 나온다. 
        
        JsonObject requestBody = requestBodyBuilder.build();

        try {
            StringEntity requestEntity = new StringEntity(requestBody.toString());
            httpPost.setEntity(requestEntity);

            CloseableHttpResponse response = client.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();

            if (responseEntity != null) {
                responseString = EntityUtils.toString(responseEntity);
                JsonObject responseObject = Json.createReader(new StringReader(responseString)).readObject();
                JsonArray choicesArray = responseObject.getJsonArray("choices");
                JsonObject firstChoice = choicesArray.getJsonObject(0);
                gptResponseString = firstChoice.getJsonObject("message").getString("content");
            }

            response.close();
            client.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return gptResponseString;
    }

 

모델과 엔드포인트 편하게 바꿀수 있도록 만들어진 코드이다. Request Body 필요한 조건들은 .add로 추가해주면 된다.

 

현재는 영어로만 prompt를 작성할 수 있는데 여러 언어로 응답이 되도록 변경해보자.

request body에 prompt를 보낼때 StringEntity 클래스의 생성자에서 StandardCharsets.UTF_8을 사용하여 문자열을 UTF_8 형식으로 인코딩해준다.

또한, response에 message 부분도 StandardCharsets.UTF_8 인코딩으로 디코딩하여 문자열로 변환한다.

이를 통해 서버가 반환한 데이터를 문자열 형태로 가져올 수 있습니다.

 

public static String createPostRequest(String prompt, String apiKey) {
        String responseString = "";
        String gptResponseString = "";
        String url = "https://api.openai.com/v1/chat/completions";

        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);

        httpPost.setHeader("Content-Type", "application/json");
        httpPost.setHeader("Authorization", "Bearer " + apiKey);

        // Create request body
        JsonObjectBuilder systemMessageBuilder = Json.createObjectBuilder()
                .add("role", "system")
                .add("content", prompt);

        JsonArrayBuilder messagesBuilder = Json.createArrayBuilder()
                .add(systemMessageBuilder);

        JsonObjectBuilder requestBodyBuilder = Json.createObjectBuilder()
                .add("model", "gpt-4")
                .add("messages", messagesBuilder)
                .add("max_tokens", 500);

        JsonObject requestBody = requestBodyBuilder.build();

        try {
            StringEntity requestEntity = new StringEntity(requestBody.toString(), StandardCharsets.UTF_8);
            httpPost.setEntity(requestEntity);

            CloseableHttpResponse response = client.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();

            if (responseEntity != null) {
                responseString = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
                JsonObject responseObject = Json.createReader(new StringReader(responseString)).readObject();
                JsonArray choicesArray = responseObject.getJsonArray("choices");
                JsonObject firstChoice = choicesArray.getJsonObject(0);
                gptResponseString = firstChoice.getJsonObject("message").getString("content");
            }

            response.close();
            client.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Convert the gptResponseString from Unicode back to the appropriate language
        gptResponseString = normalizeString(gptResponseString);
        
        return gptResponseString;
    }

최종 OpenAiServlet이다.

public class OpenAiServlet extends HttpServlet {
	 private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String prompt = request.getParameter("prompt");
        String apiKey = "api - key 입력하는 곳";
        String result = createPostRequest(prompt, apiKey);

        // send the result back as the response
        response.setContentType("text/plain");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(result);
    }
    
    public static String createPostRequest(String prompt, String apiKey) {
        String responseString = "";
        String gptResponseString = "";
        String url = "https://api.openai.com/v1/chat/completions";

        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);

        httpPost.setHeader("Content-Type", "application/json");
        httpPost.setHeader("Authorization", "Bearer " + apiKey);

        // Create request body
        JsonObjectBuilder systemMessageBuilder = Json.createObjectBuilder()
                .add("role", "system")
                .add("content", prompt);

        JsonArrayBuilder messagesBuilder = Json.createArrayBuilder()
                .add(systemMessageBuilder);

        JsonObjectBuilder requestBodyBuilder = Json.createObjectBuilder()
                .add("model", "gpt-4")
                .add("messages", messagesBuilder)
                .add("max_tokens", 500);

        JsonObject requestBody = requestBodyBuilder.build();

        try {
            StringEntity requestEntity = new StringEntity(requestBody.toString(), StandardCharsets.UTF_8);
            httpPost.setEntity(requestEntity);

            CloseableHttpResponse response = client.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();

            if (responseEntity != null) {
                responseString = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
                JsonObject responseObject = Json.createReader(new StringReader(responseString)).readObject();
                JsonArray choicesArray = responseObject.getJsonArray("choices");
                JsonObject firstChoice = choicesArray.getJsonObject(0);
                gptResponseString = firstChoice.getJsonObject("message").getString("content");
            }

            response.close();
            client.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Convert the gptResponseString from Unicode back to the appropriate language
        gptResponseString = normalizeString(gptResponseString);
        
        return gptResponseString;
    }
    
    private static String normalizeString(String input) {
        return Normalizer.normalize(input, Normalizer.Form.NFC);
    }
}

 

결과

한국어로 질문
베트남어로 질문

다국어로 질문해서 다국어로 결과를 보여주는 것으로 마무리!

 

추가적으로 response를 받는 시간이 너무 오래걸리고 있는데 어떻게 하면 더 빨리 받을수 있을지 찾아봐야겠다...