Skip to content

Commit 483489d

Browse files
authored
Merge pull request #61 from Team-StudyLog/develop
main으로 병합
2 parents b094588 + cf60bb3 commit 483489d

File tree

2 files changed

+93
-5
lines changed

2 files changed

+93
-5
lines changed

src/main/java/org/example/studylog/dto/quiz/chatGPT/ChatGptRequest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111
@AllArgsConstructor
1212
public class ChatGptRequest {
1313

14-
private String model = "gpt-3.5-turbo";
14+
private String model;
1515
private List<Message> messages;
16-
private double temperature = 0.7;
16+
private double temperature;
17+
private double frequency_penalty;
1718

1819
@Data
1920
@AllArgsConstructor

src/main/java/org/example/studylog/service/QuizService.java

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@
2727
import com.fasterxml.jackson.databind.ObjectMapper;
2828

2929
import java.time.LocalDate;
30+
import java.util.Arrays;
3031
import java.util.List;
3132
import java.util.Map;
33+
import java.util.Random;
34+
import java.util.stream.Collectors;
35+
import java.util.stream.Stream;
3236

3337
@Service
3438
@RequiredArgsConstructor
@@ -61,12 +65,15 @@ public List<QuizResponseDTO> createQuiz(String oauthId, Long recordId, CreateQui
6165
Category category = studyRecord.getCategory();
6266

6367
// 프롬프트 생성
64-
String prompt = buildPrompt(requestDTO, studyRecord.getContent());
68+
String prompt_system = buildSystemPrompt(requestDTO.getLevel().getLabel());
69+
String prompt_user = buildUserPrompt(requestDTO, studyRecord.getContent());
6570

6671
// GPT에게 보낼 요청 생성
6772
ChatGptRequest request = new ChatGptRequest(
68-
"gpt-3.5-turbo",
69-
List.of(new ChatGptRequest.Message("user", prompt)),
73+
"gpt-4o-mini",
74+
List.of(new ChatGptRequest.Message("system", prompt_system),
75+
new ChatGptRequest.Message("user", prompt_user)),
76+
0.7,
7077
0.7
7178
);
7279

@@ -110,6 +117,86 @@ public List<QuizResponseDTO> createQuiz(String oauthId, Long recordId, CreateQui
110117
return quizResponseList;
111118
}
112119

120+
private String buildSystemPrompt(String level) {
121+
List<String> MID_KEYWORDS = Arrays.asList(
122+
"언제", "상황", "조건", "사례", "선택", "방법", "절차", "방식", "기준", "요건"
123+
);
124+
125+
List<String> HIGH_KEYWORDS = Arrays.asList(
126+
"차이", "왜", "예외", "한계", "내부", "구조", "원리", "특징", "문제점", "비교", "영향"
127+
);
128+
String common = (
129+
"역할: 퀴즈 생성 도우미(한국어). 출력은 오직 JSON 배열.\n" +
130+
"스키마:\n" +
131+
"[\n" +
132+
" {\"question\":\"...\", \"answer\":\"...\", \"type\":\"OX|SHORT_ANSWER\", \"level\":\"하|중|상\"}\n" +
133+
"]\n" +
134+
"공통 규칙:\n" +
135+
"- 존댓말 사용.\n" +
136+
"- answer=SHORT_ANSWER이면, 어미 제거 후 답만 반환\n" +
137+
"- 모든 항목의 level은 '" + level + "' 이어야 한다(다른 값 금지).\n" +
138+
"- 출력은 반드시 대괄호로 시작/끝나는 순수 JSON 배열. 어떤 객체/키로도 감싸지 말 것.\n" +
139+
"- 마크다운/설명/주석/코드블록 금지."
140+
);
141+
142+
String body;
143+
144+
if ("하".equals(level)) {
145+
String forbidden = Stream.concat(MID_KEYWORDS.stream(), HIGH_KEYWORDS.stream())
146+
.map(s -> "'" + s + "'")
147+
.collect(Collectors.joining(", "));
148+
body = (
149+
"레벨 규칙(하):\n" +
150+
"- type=OX 만 허용.\n" +
151+
"- question: 진술형 한 문장, 물음표 금지.\n" +
152+
"- question에 다음 단어 금지: [" + forbidden + "]\n" +
153+
"- answer는 반드시 \"O\" 또는 \"X\"."
154+
);
155+
} else if ("중".equals(level)) {
156+
String keywords = MID_KEYWORDS.stream()
157+
.map(s -> "'" + s + "'")
158+
.collect(Collectors.joining(", "));
159+
body = (
160+
"레벨 규칙(중):\n" +
161+
"- type=SHORT_ANSWER 만 허용.\n" +
162+
"- question에는 반드시 다음 키워드 중 하나 이상 포함: [" + keywords + "]\n" +
163+
"- 반드시 '?'로 끝나야 함.\n" +
164+
"- answer ≤ 20자."
165+
);
166+
} else { // "상"
167+
String keywords = HIGH_KEYWORDS.stream()
168+
.map(s -> "'" + s + "'")
169+
.collect(Collectors.joining(", "));
170+
body = (
171+
"레벨 규칙(상):\n" +
172+
"- type=SHORT_ANSWER 만 허용.\n" +
173+
"- question에는 반드시 다음 키워드 중 하나 이상 포함: [" + keywords + "]\n" +
174+
"- 반드시 '?'로 끝나야 함.\n" +
175+
"- answer ≤ 40자.\n" +
176+
"- answer는 질문의 키워드와 직접적으로 대응되는 설명을 포함해야 하며, 단순 키워드 나열 금지.\n" +
177+
"- answer는 최소 2가지 이상의 구체적 포인트(예: 구조적 특징 2개, 한계 2개)를 포함해야 함."
178+
);
179+
}
180+
181+
return common + "\n" + body;
182+
183+
}
184+
185+
private String buildUserPrompt(CreateQuizRequestDTO dto, String content) {
186+
return String.format("""
187+
생성 조건
188+
- 주제: %s
189+
- 난이도: %s
190+
- 개수: %d
191+
%s
192+
레벨 규칙과 스키마를 반드시 준수.
193+
""",
194+
content,
195+
dto.getLevel().getLabel(),
196+
dto.getQuizCount(),
197+
dto.getRequirement() != null ? "- 참고사항: " + dto.getRequirement() : "");
198+
}
199+
113200
private String buildPrompt(CreateQuizRequestDTO dto, String content){
114201
return String.format("""
115202
너는 퀴즈 생성 도우미야. 아래 내용을 바탕으로 퀴즈를 만들어줘.

0 commit comments

Comments
 (0)