Spring boot + Chatgpt openAPI

호수·2023년 9월 27일
0

Spring

목록 보기
5/5
post-thumbnail

키워드(Keyword) : chatGPT/ openapi

GPT-3: https://platform.openai.com/account/api-keys

무료 크레딧

OpenAI 의 ChatGPT 3.5는 무료
현재 처음 회원 가입을 하면 3개월 동안 사용이 가능한 5달러의 무료 크레딧을 줍니다.
Usage에서 확인할 수 있습니다.
무료가 만료되어 있어서 카드 등록을 통하여 사용하기로 결정하였습니다.

결제

billing - Overview - Payment methods

결제수단으로 해외결제(마스터, 비자 등)가 가능한 카드를 등록할 수 있습니다.카드 등록 후 초기값 10달러, 자동결제 여부가 나와있는데 5달러(백만 토큰 당 2달러) 를 초기값으로 설정 총 5.5달러가 결제되었습니. 테스트용이라면 자동결제는 하지 않는게 좋을 것 같습니다.

limit설정

API Key 발급

Create new secret key버튼을 누르면 API Key가 생성되는데요. 생성할 때만 볼 수 있고 이후에는 가려져서 보이지 않으니 어딘가 잘 복사해 두도록 합니다.

ChatGPT의 이용요금을 결정하는 요인

API 호출 횟수

API란 다른 프로그램과 상호작용할 수 있도록 만든 인터페이스입니다. 예를 들어, 챗봇을 만들고 싶다면 챗봇 앱과 ChatGPT 모델 사이에 API를 통해 연결하면 됩니다. API 호출 횟수는 챗봇 앱이 ChatGPT 모델에게 질문을 보내거나 답변을 받는 횟수를 의미합니다.

API 요청 수
API 요청 수는 한 번의 API 호출에서 보내거나 받는 데이터의 양을 의미합니다. 예를 들어, 챗봇 앱이 ChatGPT 모델에게 "안녕하세요"라는 질문을 보내면 그것은 한 번의 API 호출이고, "안녕하세요"라는 데이터는 한 번의 API 요청입니다.

매개 변수 수
매개 변수란 인공지능 모델이 학습하는 과정에서 조정되는 값들입니다. 매개 변수가 많으면 모델이 더 복잡하고 정교하게 학습할 수 있습니다. ChatGPT Plus는 약 1,200억 개의 매개 변수를 가지고 있으며, 무료 버전은 약 175억 개의 매개 변수를 가지고 있습니다.

Spring으로 시작하기!

ChatGptConfig

package dwu.swcmop.trippacks.config;

public class ChatGptConfig {
    public static final String AUTHORIZATION = "Authorization";
    public static final String BEARER = "Bearer ";
    public static final String API_KEY = "123"; //실행시 원래 api key로 바꾸고, git에 올릴 때에는 임의 값으로 다시 설정!
    public static final String MODEL = "text-davinci-003";
    public static final Integer MAX_TOKEN = 300;
    public static final Double TEMPERATURE = 0.0;
    public static final Double TOP_P = 1.0;
    public static final String MEDIA_TYPE = "application/json; charset=UTF-8";
    public static final String URL = "https://api.openai.com/v1/completions";
}

ChatGptController

package dwu.swcmop.trippacks.controller;

import dwu.swcmop.trippacks.dto.ChatGptResponse;
import dwu.swcmop.trippacks.dto.QuestionRequest;
import dwu.swcmop.trippacks.service.ChatGptService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/chat-gpt")
public class ChatGptController {

    private final ChatGptService chatGptService;

    public ChatGptController(ChatGptService chatGptService) {

        this.chatGptService = chatGptService;
    }

    @PostMapping("/question")
    public ChatGptResponse sendQuestion(@RequestBody QuestionRequest requestDto) {
        return chatGptService.askQuestion(requestDto);
    }
}

ChatGptService 추가

package dwu.swcmop.trippacks.service;

import dwu.swcmop.trippacks.config.ChatGptConfig;
import dwu.swcmop.trippacks.dto.ChatGptRequest;
import dwu.swcmop.trippacks.dto.ChatGptResponse;
import dwu.swcmop.trippacks.dto.QuestionRequest;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class ChatGptService {

    private static RestTemplate restTemplate = new RestTemplate();

    public HttpEntity<ChatGptRequest> buildHttpEntity(ChatGptRequest requestDto) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType(ChatGptConfig.MEDIA_TYPE));
        headers.add(ChatGptConfig.AUTHORIZATION, ChatGptConfig.BEARER + ChatGptConfig.API_KEY);
        System.setProperty("https.protocols", "TLSv1.2"); //TLS 버전을 맞추기 위함
        return new HttpEntity<>(requestDto, headers);
    }

    public ChatGptResponse getResponse(HttpEntity<ChatGptRequest> chatGptRequestDtoHttpEntity) {
        ResponseEntity<ChatGptResponse> responseEntity = restTemplate.postForEntity(
                ChatGptConfig.URL,
                chatGptRequestDtoHttpEntity,
                ChatGptResponse.class);

        return responseEntity.getBody();
    }

    public ChatGptResponse askQuestion(QuestionRequest requestDto) {
        return this.getResponse(
                this.buildHttpEntity(
                        new ChatGptRequest(
                                ChatGptConfig.MODEL,
                                requestDto.getQuestion(),
                                ChatGptConfig.MAX_TOKEN,
                                ChatGptConfig.TEMPERATURE,
                                ChatGptConfig.TOP_P
                        )
                )
        );
    }
}

dto

ChatGptRequest

package dwu.swcmop.trippacks.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.List;

@Getter
@NoArgsConstructor
public class ChatGptRequest implements Serializable {

    private String model;
    private String prompt;
    @JsonProperty("max_tokens")
    private Integer maxTokens;
    private Double temperature;
    @JsonProperty("top_p")
    private Double topP;

    @Builder
    public ChatGptRequest(String model, String prompt,
                             Integer maxTokens, Double temperature,
                             Double topP) {
        this.model = model;
        this.prompt = prompt;
        this.maxTokens = maxTokens;
        this.temperature = temperature;
        this.topP = topP;
    }
}

ChatGptResponse

package dwu.swcmop.trippacks.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.Serializable;
import java.time.LocalDate;
import java.util.List;

@Getter
@NoArgsConstructor
public class ChatGptResponse implements Serializable {

    private String id;
    private String object;
    private LocalDate created;
    private String model;
    private List<Choice> choices;

    @Builder
    public ChatGptResponse(String id, String object,
                              LocalDate created, String model,
                              List<Choice> choices) {
        this.id = id;
        this.object = object;
        this.created = created;
        this.model = model;
        this.choices = choices;
    }
}

Choice

package dwu.swcmop.trippacks.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.Serializable;

@Getter
@NoArgsConstructor
public class Choice implements Serializable {

    private String text;
    private Integer index;
    @JsonProperty("finish_reason")
    private String finishReason;

    @Builder
    public Choice(String text, Integer index, String finishReason) {
        this.text = text;
        this.index = index;
        this.finishReason = finishReason;
    }
}

QuestionRequest

package dwu.swcmop.trippacks.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Getter
public class QuestionRequest implements Serializable {
    private String question;
}

Usage

package dwu.swcmop.trippacks.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Usage {
    @JsonProperty("prompt_tokens")
    private int promptTokens;
    @JsonProperty("completion_tokens")
    private int completionTokens;
    @JsonProperty("total_tokens")
    private int totalTokens;
}

chatGPT는 질문을 잘 던져주는게 중요하다.

profile
Back-End개발자 입문 과정 블로그🚀

0개의 댓글