일단 OpenAI Secret API Key 가 필요합니다.
https://firstws.tistory.com/63
1. Postman으로 Test해보기
method : POST
url : https://api.openai.com/v1/chat/completions
Headers Setting
Content-Type : application/json
Authorization : ${OpenAI Secret API Key}
Body-JSON
{
"model": "gpt-3.5-turbo",
"stream" : false,
"messages": [{"role": "user", "content": "100+200=?"}]
}
다양한 모델이 있지만 GPT-3.5 중에서 가장 유능한 모델인 'gpt-3.5-turbo'를 선정하였습니다.
'Send' 클릭해서 요청보내기 - 결과
위와 같이 나오면 성공한 겁니다.
choices - message - content에 답변이 담겨 있고, 우리는 그걸 꺼내 사용하면 됩니다.
이제 DTO - Config - Controller - Service 순서로 작성해보겠습니다.
2. DTO 작성하기
@Getter
@NoArgsConstructor
//Front단에서 요청하는 DTO
public class QuestionRequest implements Serializable {
private String question;
}
@Getter
@NoArgsConstructor
//chatGPT에 요청할 DTO Format
public class ChatGptRequest implements Serializable {
private String model;
@JsonProperty("max_tokens")
private Integer maxTokens;
private Double temperature;
private Boolean stream;
private List<ChatGptMessage> messages;
//@JsonProperty("top_p")
//private Double topP;
@Builder
public ChatGptRequest(String model, Integer maxTokens, Double temperature,
Boolean stream, List<ChatGptMessage> messages
/*,Double topP*/) {
this.model = model;
this.maxTokens = maxTokens;
this.temperature = temperature;
this.stream = stream;
this.messages = messages;
//this.topP = topP;
}
}
@Getter
@NoArgsConstructor
//ChatGPT 답변을 담을 DTO
public class ChatGptResponse {
private String id;
private String object;
private long created;
private String model;
private Usage usage;
private List<Choice> choices;
@Getter
@Setter
public static class Usage {
@JsonProperty("prompt_tokens")
private int promptTokens;
@JsonProperty("completion_tokens")
private int completionTokens;
@JsonProperty("total_tokens")
private int totalTokens;
}
@Getter
@Setter
public static class Choice {
private ChatGptMessage message;
@JsonProperty("finish_reason")
private String finishReason;
private int index;
}
}
3. Config 작성하기
@Configuration
public class ChatGptConfig {
public static final String AUTHORIZATION = "Authorization";
public static final String BEARER = "Bearer ";
public static final String CHAT_MODEL = "gpt-3.5-turbo";
public static final Integer MAX_TOKEN = 300;
public static final Boolean STREAM = false;
public static final String ROLE = "user";
public static final Double TEMPERATURE = 0.6;
//public static final Double TOP_P = 1.0;
public static final String MEDIA_TYPE = "application/json; charset=UTF-8";
//completions : 질답
public static final String CHAT_URL = "https://api.openai.com/v1/chat/completions";
}
4. Controller 작성하기
@RequiredArgsConstructor
@RequestMapping("/chat-gpt")
@RestController
public class ChatGptController {
private final APIResponse apiResponse;
private final ChatGptService chatGptService;
@Operation(summary = "Question to Chat-GPT")
@PostMapping("/question")
public ResponseEntity sendQuestion(
Locale locale,
HttpServletRequest request,
HttpServletResponse response,
@RequestBody QuestionRequest questionRequest) {
String code = ResponseCode.CD_SUCCESS;
ChatGptResponse chatGptResponse = null;
try {
chatGptResponse = chatGptService.askQuestion(questionRequest);
} catch (Exception e) {
apiResponse.printErrorMessage(e);
code = e.getMessage();
}
//return 부분은 자유롭게 수정하시면됩니다. ex)return chatGptResponse;
return apiResponse.getResponseEntity(locale, code,
chatGptResponse != null ? chatGptResponse.getChoices().get(0).getMessage().getContent() : new ChatGptResponse());
}
}
5. Service 작성하기
@Slf4j
@RequiredArgsConstructor
@Service
public class ChatGptService {
private final RestTemplate restTemplate;
//api key를 application.yml에 넣어두었습니다.
@Value("${api-key.chat-gpt}")
private String apiKey;
public HttpEntity<ChatGptRequest> buildHttpEntity(ChatGptRequest chatGptRequest){
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.parseMediaType(ChatGptConfig.MEDIA_TYPE));
httpHeaders.add(ChatGptConfig.AUTHORIZATION, ChatGptConfig.BEARER + apiKey);
return new HttpEntity<>(chatGptRequest, httpHeaders);
}
public ChatGptResponse getResponse(HttpEntity<ChatGptRequest> chatGptRequestHttpEntity){
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(60000);
//답변이 길어질 경우 TimeOut Error가 발생하니 1분정도 설정해줍니다.
requestFactory.setReadTimeout(60 * 1000); // 1min = 60 sec * 1,000ms
restTemplate.setRequestFactory(requestFactory);
ResponseEntity<ChatGptResponse> responseEntity = restTemplate.postForEntity(
ChatGptConfig.CHAT_URL,
chatGptRequestHttpEntity,
ChatGptResponse.class);
return responseEntity.getBody();
}
public ChatGptResponse askQuestion(QuestionRequest questionRequest){
List<ChatGptMessage> messages = new ArrayList<>();
messages.add(ChatGptMessage.builder()
.role(ChatGptConfig.ROLE)
.content(questionRequest.getQuestion())
.build());
return this.getResponse(
this.buildHttpEntity(
new ChatGptRequest(
ChatGptConfig.CHAT_MODEL,
ChatGptConfig.MAX_TOKEN,
ChatGptConfig.TEMPERATURE,
ChatGptConfig.STREAM,
messages
//ChatGptConfig.TOP_P
)
)
);
}
}
실행 결과
테스트상 최소한의 parameter를 사용하였으며, 적용 가능한 parameter가 다양하므로 아래 공식문서를 참조해주세요.
ref : https://platform.openai.com/docs/api-reference/completions/create
'Spring & Spring Boot' 카테고리의 다른 글
[Spring&SpringBoot] ChapGPT Stream으로 응답받기 (0) | 2023.05.31 |
---|---|
[Spring&SpringBoot] OpenAI 이미지 생성 API 사용하기 (0) | 2023.05.31 |
[Spring&Spring Boot] @Transaction, rollback이 안될 때가 있다?? (0) | 2023.03.28 |
[SpringBoot] 엑셀 값 가져오기(.xls & .xlsx) (0) | 2023.03.06 |
[SpringBoot] LocalDateTime 받기(클라이언트Json→서버) (0) | 2023.01.18 |