-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
224 additions
and
0 deletions.
There are no files selected for viewing
22 changes: 22 additions & 0 deletions
22
src/main/java/univ/yesummit/domain/gpt/dto/ChatRequestMsgDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package univ.yesummit.domain.gpt.dto; | ||
|
||
import lombok.*; | ||
|
||
/** | ||
* ChatGPT 신규 모델의 Request | ||
*/ | ||
@Getter | ||
@ToString | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class ChatRequestMsgDTO { | ||
|
||
private String role; | ||
|
||
private String content; | ||
|
||
@Builder | ||
public ChatRequestMsgDTO(String role, String content) { | ||
this.role = role; | ||
this.content = content; | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/main/java/univ/yesummit/domain/gpt/dto/CompletionDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package univ.yesummit.domain.gpt.dto; | ||
|
||
import lombok.*; | ||
|
||
/** | ||
* 프롬프트 요청 DTO : | ||
* gpt-3.5-turbo-instruct, babbage-002, davinci-002 | ||
*/ | ||
@Getter | ||
@ToString | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class CompletionDTO { | ||
|
||
// 사용할 모델 | ||
private String model; | ||
|
||
// 사용할 프롬프트 명령어 | ||
private String prompt; | ||
|
||
// 프롬프트의 다양성을 조절할 명령어(default : 1) | ||
private float temperature = 1; | ||
|
||
// 최대 사용할 토큰(default : 16) | ||
private int max_tokens = 16; | ||
|
||
@Builder | ||
public CompletionDTO(String model, String prompt, float temperature, int max_tokens) { | ||
this.model = model; | ||
this.prompt = prompt; | ||
this.temperature = temperature; | ||
this.max_tokens = max_tokens; | ||
} | ||
} |
169 changes: 169 additions & 0 deletions
169
src/main/java/univ/yesummit/domain/gpt/service/impl/ChatGPTServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
package univ.yesummit.domain.gpt.service.impl; | ||
|
||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.core.type.TypeReference; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.http.HttpEntity; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.HttpMethod; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.stereotype.Service; | ||
import univ.yesummit.domain.gpt.config.ChatGPTConfig; | ||
import univ.yesummit.domain.gpt.dto.ChatCompletionDTO; | ||
import univ.yesummit.domain.summit.repository.SummitRepository; | ||
import univ.yesummit.domain.gpt.service.ChatGPTService; | ||
import univ.yesummit.domain.member.repository.MemberRepository; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
/** | ||
* ChatGPT Service 구현체 | ||
*/ | ||
@Slf4j | ||
@Service | ||
@RequiredArgsConstructor | ||
public class ChatGPTServiceImpl implements ChatGPTService { | ||
|
||
private final ChatGPTConfig chatGPTConfig; | ||
private final ObjectMapper objectMapper; | ||
private final SummitRepository summitRepository; | ||
private final MemberRepository memberRepository; | ||
|
||
@Value("${openai.url.model}") | ||
private String modelUrl; | ||
|
||
@Value("${openai.url.model-list}") | ||
private String modelListUrl; | ||
|
||
@Value("${openai.url.prompt}") | ||
private String promptUrl; | ||
|
||
@Value("${openai.url.legacy-prompt}") | ||
private String legacyPromptUrl; | ||
|
||
|
||
/** | ||
* 모델이 유효한지 확인하는 비즈니스 로직 | ||
*/ | ||
@Override | ||
public Map<String, Object> isValidModel(String modelName) { | ||
log.debug("[+] 모델이 유효한지 조회합니다. 모델 : " + modelName); | ||
Map<String, Object> result = new HashMap<>(); | ||
|
||
// 토큰 정보가 포함된 Header를 가져온다. | ||
HttpHeaders headers = chatGPTConfig.httpHeaders(); | ||
|
||
// 통신을 위한 RestTemplate을 구성 | ||
ResponseEntity<String> response = chatGPTConfig | ||
.restTemplate() | ||
.exchange(modelListUrl + "/" + modelName, HttpMethod.GET, new HttpEntity<>(headers), String.class); | ||
try { | ||
// Jackson을 기반으로 응답값을 가져온다. | ||
result = objectMapper.readValue(response.getBody(), new TypeReference<>() { | ||
}); | ||
} catch (JsonProcessingException e) { | ||
log.debug("JsonMappingException :: " + e.getMessage()); | ||
} catch (RuntimeException e) { | ||
log.debug("RuntimeException :: " + e.getMessage()); | ||
} | ||
return result; | ||
} | ||
|
||
|
||
/** | ||
* 최신 모델에 대한 프롬프트 | ||
*/ | ||
@Override | ||
public Map<String, Object> prompt(ChatCompletionDTO chatCompletionDto) { | ||
log.debug("[+] 신규 프롬프트를 수행합니다."); | ||
|
||
Map<String, Object> resultMap = new HashMap<>(); | ||
|
||
// 토큰 정보가 포함된 Header를 가져온다. | ||
HttpHeaders headers = chatGPTConfig.httpHeaders(); | ||
|
||
// 통신을 위한 RestTemplate을 구성 | ||
HttpEntity<ChatCompletionDTO> requestEntity = new HttpEntity<>(chatCompletionDto, headers); | ||
ResponseEntity<String> response = chatGPTConfig | ||
.restTemplate() | ||
.exchange(promptUrl, HttpMethod.POST, requestEntity, String.class); | ||
try { | ||
// String -> HashMap 역직렬화를 구성 | ||
resultMap = objectMapper.readValue(response.getBody(), new TypeReference<>() { | ||
}); | ||
} catch (JsonProcessingException e) { | ||
log.debug("JsonMappingException :: " + e.getMessage()); | ||
} catch (RuntimeException e) { | ||
log.debug("RuntimeException :: " + e.getMessage()); | ||
} | ||
return resultMap; | ||
} | ||
|
||
// @Override | ||
// public Map<String, Object> createSummit() { | ||
// String prompt = "지속 가능한 미래를 이끄는 건, 결국 청년과 그들의 새로운 시각입니다. " + | ||
// "이 점에서 청년들이 그들의 반짝이는 아이디어를 실현하고 세상에 선보일 수 있도록 돕는 것은 " + | ||
// "청년의 창업 문제 해결을 통해 지속 가능한 미래를 만들 수 있습니다. 다만 예비 청년 창업가들에게는 " + | ||
// "자신의 창업 아이템을 전문적으로 소개할 창구가 부족합니다. 그래서 Young Entrepreneur들이 " + | ||
// "주인공인 Summit 플랫폼을 만들고자 합니다. 이를 바탕으로 써밋 주제를 5줄 정도로 만들어주세요. " + | ||
// "제목과 본문으로 구성해 주세요."; | ||
// | ||
// ChatCompletionDTO chatCompletionDto = ChatCompletionDTO.builder() | ||
// .model("gpt-3.5-turbo") | ||
// .messages(List.of( | ||
// ChatRequestMsgDTO.builder() | ||
// .role("user") | ||
// .content(prompt) | ||
// .build() | ||
// )) | ||
// .build(); | ||
// | ||
// // ChatGPT API 호출 | ||
// Map<String, Object> gptResponse = prompt(chatCompletionDto); | ||
// | ||
// // 응답 데이터 검증 | ||
// if (gptResponse == null || !gptResponse.containsKey("choices")) { | ||
// throw new RuntimeException("ChatGPT 응답이 유효하지 않습니다."); | ||
// } | ||
// | ||
// List<Map<String, Object>> choices = (List<Map<String, Object>>) gptResponse.get("choices"); | ||
// if (choices == null || choices.isEmpty()) { | ||
// throw new RuntimeException("ChatGPT 응답에서 choices가 비어 있습니다."); | ||
// } | ||
// | ||
// Map<String, Object> firstChoice = choices.get(0); | ||
// if (firstChoice == null || !firstChoice.containsKey("text")) { | ||
// throw new RuntimeException("ChatGPT 응답의 텍스트가 없습니다."); | ||
// } | ||
// | ||
// String responseText = (String) firstChoice.get("text"); | ||
// if (responseText == null || responseText.isEmpty()) { | ||
// throw new RuntimeException("ChatGPT 응답의 텍스트가 비어 있습니다."); | ||
// } | ||
// | ||
// // 텍스트 파싱 | ||
// String[] splitText = responseText.split("\n", 2); | ||
// if (splitText.length < 2) { | ||
// throw new RuntimeException("ChatGPT 응답 형식이 올바르지 않습니다."); | ||
// } | ||
// | ||
// String title = splitText[0].replace("제목:", "").trim(); | ||
// String content = splitText[1].replace("본문:", "").trim(); | ||
// | ||
// // Summit 엔티티 생성 및 저장 | ||
// Summit newSummit = new Summit(title, content); | ||
// Summit savedSummit = summitRepository.save(newSummit); | ||
// | ||
// return Map.of( | ||
// "message", "Summit has been created successfully", | ||
// "summitId", savedSummit.getId(), | ||
// "title", savedSummit.getTitle(), | ||
// "content", savedSummit.getContent() | ||
// ); | ||
// } | ||
} |