Skip to content

Commit 6321c19

Browse files
committed
[FEAT] 헤드라인 생성을 위한 GPT 프롬포트 작성 및 파싱 메소드 구현
1 parent ac6115c commit 6321c19

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.movelog.domain.news.application;
2+
3+
import com.fasterxml.jackson.databind.JsonNode;
4+
import com.movelog.domain.gpt.application.GptService;
5+
import com.movelog.domain.news.dto.response.HeadLineRes;
6+
import lombok.RequiredArgsConstructor;
7+
import lombok.extern.slf4j.Slf4j;
8+
import org.springframework.stereotype.Service;
9+
import reactor.core.publisher.Mono;
10+
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
14+
@Service
15+
@RequiredArgsConstructor
16+
@Slf4j
17+
public class HeadlineGeneratorService {
18+
19+
private final GptService gptService;
20+
21+
public List<HeadLineRes> generateHeadLine(String option, String verb, String noun) {
22+
// 프롬프트 생성
23+
String prompt = generatePrompt(option, verb, noun);
24+
25+
// 비동기 방식으로 GPT API 호출
26+
return gptService.callChatGpt(prompt)
27+
.flatMap(response -> {
28+
if (response == null) {
29+
return Mono.error(new RuntimeException("GPT API 응답이 없습니다."));
30+
}
31+
32+
// 응답 파싱하여 List<CreatePracticeRes> 반환
33+
List<HeadLineRes> practiceResList = parseResponse(response);
34+
return Mono.just(practiceResList);
35+
})
36+
.doOnError(error -> log.error("문제 생성 중 오류 발생: ", error)).block();
37+
}
38+
39+
40+
// 프롬프트 생성
41+
private String generatePrompt(String option, String verb, String noun) {
42+
return String.format(
43+
"다음 내용을 바탕으로 뉴스 헤드라인을 생성해주세요: %s\n" +
44+
"당신은 뉴스 헤드라인을 작성하는 역할이며, 다음 형식을 엄격히 따라 뉴스 헤드라인을 제공해 주세요:\n\n" +
45+
"이 뉴스 헤드라인의 목적은 사용자의 기록을 기반으로 약간의 재미 요소가 들어간 헤드라인을 제공하는 것입니다.\n" +
46+
"각 뉴스 헤드라인은 반드시 격식있는 어체로 구성되어야 하며, 반드시 올바른 어법을 준수해야 합니다.\n" +
47+
"각 헤드라인의 내용은 주어진 옵션, 동사, 명사를 기반으로 생성되어야 하며, 헤드라인 내용에 직접적인 내용이 들어가지 않아도 됩니다." +
48+
"뉴스 헤드라인은 반드시 3개의 후보를 제공해야 하며, 각 후보는 1개의 줄바꿈으로 구분됩니다.\n" +
49+
"각 헤드라인 내용의 구조는 반드시 쉼표로 나뉘어야 하며, 쉼표 이전의 내용에는 헤드라인 강조 옵션에 대한 내용이 포함되어야 합니다." +
50+
"쉼표 앞 뒤의 내용에 대한 글자 수는 각각 16자 이하여야 하며, 쉼표는 반드시 한글자로만 구성되어야 합니다.\n\n" +
51+
52+
"다음은 제공된 정보를 통해 출력해야 하는 뉴스 헤드라인의 출력 예시입니다:\n\n" +
53+
"꾸준한 노력 끝에 완성한 마라톤 기록, 도전의 의미는?\n오랜만의 첫 도전, 무엇이 그를 움직이게 했나?\n드디어 끊어낸 술, 운동으로 극복해내" +
54+
55+
"다음은 제공된 정보를 통해 출력해야 하는 뉴스 헤드라인의 출력 형식입니다:\n\n" +
56+
"첫번째 헤드라인 후보 내용\n두번째 헤드라인 후보 내용\n세번째 헤드라인 후보 내용\n" +
57+
58+
"반드시 뉴스 헤드라인 형식을 준수해 주세요. 정해진 형식을 따르지 않으면 응답을 처리할 수 없습니다." +
59+
"만약 결과 헤드라인 내용이 위 형식과 다르다면, 다시 요청하여 주세요.",
60+
option, verb, noun
61+
);
62+
}
63+
64+
// GPT 응답 파싱
65+
private List<HeadLineRes> parseResponse(JsonNode response) {
66+
List<HeadLineRes> headLineResList = new ArrayList<>();
67+
68+
// GPT 응답에서 질문, 답변, 해설 추출
69+
String textResponse = response.path("choices").get(0).path("message").path("content").asText().trim();
70+
log.info("Full Text Response: " + textResponse); // 전체 응답 확인
71+
72+
String[] headLines = textResponse.split("\n");
73+
// 헤드라인 생성 결과가 3개가 아닌 경우 예외 처리
74+
if (headLines.length != 3) {
75+
throw new RuntimeException("생성된 헤드라인이 3개가 아닙니다.");
76+
}
77+
78+
// 헤드라인 후보 파싱 결과를 리스트에 저장 후 응답 리턴
79+
for (String headLine : headLines) {
80+
headLineResList.add(HeadLineRes.builder().headLine(headLine).build());
81+
}
82+
83+
return headLineResList;
84+
}
85+
}

0 commit comments

Comments
 (0)