diff --git a/src/main/java/com/going/server/domain/chatbot/controller/ChatbotController.java b/src/main/java/com/going/server/domain/chatbot/controller/ChatbotController.java index f48f0dc..f3af9a0 100644 --- a/src/main/java/com/going/server/domain/chatbot/controller/ChatbotController.java +++ b/src/main/java/com/going/server/domain/chatbot/controller/ChatbotController.java @@ -5,6 +5,9 @@ import com.going.server.domain.chatbot.service.ChatbotService; import com.going.server.global.response.SuccessResponse; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -16,25 +19,78 @@ @RestController @RequestMapping("/chatbot") @RequiredArgsConstructor -@Tag(name = "[캡스톤]Chatbot", description = "챗봇 관련 통신을 위한 API") +@Tag(name = "[캡스톤]Chatbot", description = "챗봇 관련 기능 API") public class ChatbotController { + private final ChatbotService chatbotService; + @PostMapping("/{graphId}/original") + @Operation(summary = "[챗봇] 원문 보기", description = "그래프에 포함된 원문 텍스트를 반환합니다.") + @ApiResponses({ + @ApiResponse(responseCode = "201", description = "원문 반환 성공", content = @Content(schema = @Schema(implementation = CreateChatbotResponseDto.class))), + @ApiResponse(responseCode = "404", description = "그래프를 찾을 수 없음"), + @ApiResponse(responseCode = "500", description = "서버 오류") + }) + public SuccessResponse getOriginalText(@PathVariable String graphId) { + CreateChatbotResponseDto response = chatbotService.getOriginalText(graphId); + return SuccessResponse.of(response, "201"); + } + + @PostMapping("/{graphId}/summary") + @Operation(summary = "[챗봇] 요약본 생성하기", description = "그래프의 요약 정보를 생성합니다.") + @ApiResponses({ + @ApiResponse(responseCode = "201", description = "요약본 생성 성공", content = @Content(schema = @Schema(implementation = CreateChatbotResponseDto.class))), + @ApiResponse(responseCode = "404", description = "그래프를 찾을 수 없음"), + @ApiResponse(responseCode = "500", description = "서버 오류") + }) + public SuccessResponse getSummaryText(@PathVariable String graphId) { + CreateChatbotResponseDto response = chatbotService.getSummaryText(graphId); + return SuccessResponse.of(response, "201"); + } + + @PostMapping("/{graphId}") - @Operation(summary = "[챗봇 화면] 챗봇 응답 생성", description = "챗봇 화면에서 사용자의 질문에 응답을 생성합니다.") - @ApiResponses( - @ApiResponse( - responseCode = "201", - description = "호출에 성공했습니다.", - content = @Content( - mediaType = "application/json", - schema = @Schema(example = "{\"message\":\"\"}") - ) - ) + @Operation( + summary = "[챗봇 기능] 챗봇 응답 생성", + description = """ + 사용자의 질문에 따라 다양한 응답 모드를 제공합니다. + - `default` : 일반 응답 (기존 GPT 방식) + - `rag` : 지식그래프 기반 RAG 응답 + - `cartoon` : 4컷 만화 이미지 생성 + - `video` : 질문 주제에 맞는 교육 영상 추천 + """ ) - public SuccessResponse generateChatbotAnswer(@PathVariable String graphId, - @RequestBody CreateChatbotRequestDto createChatbotRequestDto) { - CreateChatbotResponseDto result = chatbotService.createAnswer(graphId, createChatbotRequestDto); + @Parameters({ + @Parameter(name = "graphId", in = ParameterIn.PATH, description = "그래프 ID", required = true), + @Parameter(name = "mode", in = ParameterIn.QUERY, description = "응답 모드 (default, rag, cartoon, video)", required = false) + }) + @ApiResponses({ + @ApiResponse(responseCode = "201", description = "응답 생성 성공", content = @Content(schema = @Schema(implementation = CreateChatbotResponseDto.class))), + @ApiResponse(responseCode = "400", description = "잘못된 요청"), + @ApiResponse(responseCode = "500", description = "서버 오류") + }) + public SuccessResponse generateChatbotAnswer( + @PathVariable String graphId, + @RequestParam(defaultValue = "default") String mode, + @RequestBody(required = false) CreateChatbotRequestDto dto + ) { + CreateChatbotResponseDto result; + + switch (mode) { + case "rag": + result = chatbotService.createAnswerWithRAG(graphId, dto); + break; + case "cartoon": + result = chatbotService.createCartoon(graphId, dto); + break; + case "video": + result = chatbotService.recommendVideo(graphId, dto); + break; + case "default": + default: + result = chatbotService.createSimpleAnswer(graphId, dto); + } + return SuccessResponse.of(result, "201"); } } diff --git a/src/main/java/com/going/server/domain/chatbot/dto/CreateChatbotRequestDto.java b/src/main/java/com/going/server/domain/chatbot/dto/CreateChatbotRequestDto.java index cf02689..0d9631e 100644 --- a/src/main/java/com/going/server/domain/chatbot/dto/CreateChatbotRequestDto.java +++ b/src/main/java/com/going/server/domain/chatbot/dto/CreateChatbotRequestDto.java @@ -7,6 +7,5 @@ public class CreateChatbotRequestDto { @JsonProperty("isNewChat") // JSON 필드명과 강제 매핑 private boolean isNewChat; // 새로운 대화인지 여부 - private String chatContent; // 채팅 내용 } \ No newline at end of file diff --git a/src/main/java/com/going/server/domain/chatbot/dto/CreateChatbotResponseDto.java b/src/main/java/com/going/server/domain/chatbot/dto/CreateChatbotResponseDto.java index 3d8bee1..5864666 100644 --- a/src/main/java/com/going/server/domain/chatbot/dto/CreateChatbotResponseDto.java +++ b/src/main/java/com/going/server/domain/chatbot/dto/CreateChatbotResponseDto.java @@ -15,7 +15,7 @@ public class CreateChatbotResponseDto { private String graphId; // 지식그래프 ID @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm") private LocalDateTime createdAt; // 응답 생성 시각 - private List retrievedChunks; // 후) RAG: 검색된 문장들 - private List sourceNodes; // 후) RAG: 참조된 지식그래프 노드 ID - private Map ragMeta; // 후) RAG: 점수, 검색 method 등 + private List retrievedChunks; // RAG: 검색된 문장들 + private List sourceNodes; // RAG: 참조된 지식그래프 노드 ID + private Map ragMeta; // RAG: 점수, 검색 method 등 } \ No newline at end of file diff --git a/src/main/java/com/going/server/domain/chatbot/service/ChatbotService.java b/src/main/java/com/going/server/domain/chatbot/service/ChatbotService.java index 38a89f7..5668f5d 100644 --- a/src/main/java/com/going/server/domain/chatbot/service/ChatbotService.java +++ b/src/main/java/com/going/server/domain/chatbot/service/ChatbotService.java @@ -4,6 +4,16 @@ import com.going.server.domain.chatbot.dto.CreateChatbotResponseDto; public interface ChatbotService { + // 원문 반환 + CreateChatbotResponseDto getOriginalText(String graphId); + // 요약본 생성 + CreateChatbotResponseDto getSummaryText(String graphId); // RAG 챗봇 응답 생성 - CreateChatbotResponseDto createAnswer(String graphStrId, CreateChatbotRequestDto createChatbotRequestDto); + CreateChatbotResponseDto createAnswerWithRAG(String graphStrId, CreateChatbotRequestDto createChatbotRequestDto); + // RAG 사용하지 않는 응답 생성 + CreateChatbotResponseDto createSimpleAnswer(String graphId, CreateChatbotRequestDto createChatbotRequestDto); + // 4컷만화 생성 + CreateChatbotResponseDto createCartoon(String graphId, CreateChatbotRequestDto createChatbotRequestDto); + // 추천 영상 생성 + CreateChatbotResponseDto recommendVideo(String graphId, CreateChatbotRequestDto createChatbotRequestDto); } diff --git a/src/main/java/com/going/server/domain/chatbot/service/ChatbotServiceImpl.java b/src/main/java/com/going/server/domain/chatbot/service/ChatbotServiceImpl.java index 0e8d199..5e4dc17 100644 --- a/src/main/java/com/going/server/domain/chatbot/service/ChatbotServiceImpl.java +++ b/src/main/java/com/going/server/domain/chatbot/service/ChatbotServiceImpl.java @@ -7,9 +7,14 @@ import com.going.server.domain.chatbot.repository.ChattingRepository; import com.going.server.domain.graph.entity.Graph; import com.going.server.domain.graph.entity.GraphNode; +import com.going.server.domain.graph.exception.GraphContentNotFoundException; import com.going.server.domain.graph.repository.GraphRepository; import com.going.server.domain.graph.repository.GraphNodeRepository; -import com.going.server.domain.openai.service.AnswerCreateService; +import com.going.server.domain.openai.dto.ImageCreateRequestDto; +import com.going.server.domain.openai.service.ImageCreateService; +import com.going.server.domain.openai.service.RAGAnswerCreateService; +import com.going.server.domain.openai.service.SimpleAnswerCreateService; +import com.going.server.domain.openai.service.TextSummaryCreateService; import com.going.server.domain.rag.service.SimilarityFilterService; import com.going.server.domain.rag.util.PromptBuilder; import lombok.RequiredArgsConstructor; @@ -27,14 +32,49 @@ public class ChatbotServiceImpl implements ChatbotService { private final GraphRepository graphRepository; private final ChattingRepository chattingRepository; - private final AnswerCreateService answerCreateService; private final GraphNodeRepository graphNodeRepository; private final SimilarityFilterService similarityFilterService; private final PromptBuilder promptBuilder; + // openai 관련 service + private final TextSummaryCreateService textSummaryCreateService; + private final SimpleAnswerCreateService simpleAnswerCreateService; + private final RAGAnswerCreateService ragAnswerCreateService; + private final ImageCreateService imageCreateService; - // 챗봇 응답 생성 + // 원문 반환 @Override - public CreateChatbotResponseDto createAnswer(String graphStrId, CreateChatbotRequestDto createChatbotRequestDto) { + public CreateChatbotResponseDto getOriginalText(String graphId) { + Graph graph = graphRepository.getByGraph(Long.valueOf(graphId)); + + return CreateChatbotResponseDto.builder() + .chatContent(graph.getContent()) // 원문 텍스트 + .graphId(graphId) + .createdAt(LocalDateTime.now()) + .build(); + } + + // 요약본 생성 + @Override + public CreateChatbotResponseDto getSummaryText(String graphId) { + Graph graph = graphRepository.getByGraph(Long.valueOf(graphId)); + + String context = Optional.ofNullable(graph.getContent()) + .filter(s -> !s.trim().isEmpty()) + .orElseThrow(GraphContentNotFoundException::new); + + String summary = textSummaryCreateService.summarize(context); + + return CreateChatbotResponseDto.builder() + .chatContent(summary) // 요약 텍스트 + .graphId(graphId) + .createdAt(LocalDateTime.now()) + .build(); + } + + + // RAG 챗봇 응답 생성 + @Override + public CreateChatbotResponseDto createAnswerWithRAG(String graphStrId, CreateChatbotRequestDto createChatbotRequestDto) { Long graphId = Long.valueOf(graphStrId); // 404 : 지식그래프 찾을 수 없음 @@ -96,10 +136,10 @@ public CreateChatbotResponseDto createAnswer(String graphStrId, CreateChatbotReq System.out.println("[DEBUG] matchedNodes.size(): " + matchedNodes.size()); System.out.println("[DEBUG] candidateSentences.size(): " + candidateSentences.size()); System.out.println("[DEBUG] filteredChunks.size(): " + filteredChunks.size()); - chatContent = answerCreateService.chat(chatHistory, newChat); + chatContent = ragAnswerCreateService.chat(chatHistory, newChat); } else { System.out.println("[INFO] RAG 적용됨 - 유사 문장 " + retrievedChunks.size() + "개 포함"); - chatContent = answerCreateService.chatWithContext(chatHistory, finalPrompt); + chatContent = ragAnswerCreateService.chatWithContext(chatHistory, finalPrompt); } // 응답 repository에 저장 @@ -122,6 +162,123 @@ public CreateChatbotResponseDto createAnswer(String graphStrId, CreateChatbotReq .build(); } + // RAG 사용하지 않는 응답 생성 + @Override + public CreateChatbotResponseDto createSimpleAnswer(String graphStrId, CreateChatbotRequestDto createChatbotRequestDto) { + Long graphId = Long.valueOf(graphStrId); + + // 404 : 지식그래프 찾을 수 없음 + Graph graph = graphRepository.getByGraph(graphId); + + // 새로운 대화인 경우 기존 채팅 삭제 + if (createChatbotRequestDto.isNewChat()) { + deletePreviousChat(graphId); + } + + // 기존 채팅 내역 조회 + List chatHistory = chattingRepository.findAllByGraphId(graphId); + + // 사용자 입력 채팅 + String newChat = createChatbotRequestDto.getChatContent(); + + // 채팅 저장 (USER) + Chatting userChat = Chatting.builder() + .graph(graph) + .content(newChat) + .sender(Sender.USER) + .createdAt(LocalDateTime.now()) + .build(); + chattingRepository.save(userChat); + + // GPT-3.5로 응답 생성 (RAG 없이) + String chatContent = simpleAnswerCreateService.simpleChat(chatHistory, newChat); + + // 채팅 저장 (GPT) + Chatting gptChat = Chatting.builder() + .graph(graph) + .content(chatContent) + .sender(Sender.GPT) + .createdAt(LocalDateTime.now()) + .build(); + chattingRepository.save(gptChat); + + // 응답 반환 + return CreateChatbotResponseDto.builder() + .chatContent(chatContent) + .graphId(graphStrId) + .createdAt(gptChat.getCreatedAt()) + .build(); + } + + /// 4컷만화 생성 + @Override + public CreateChatbotResponseDto createCartoon(String graphId, CreateChatbotRequestDto createChatbotRequestDto) { + String concept = createChatbotRequestDto.getChatContent(); // 사용자 질문 → 개념 + + // 개선된 프롬프트 + String prompt = """ + 당신은 초등학생부터 고등학생까지의 학습자를 위한 교육용 4컷 만화를 그리는 일러스트레이터입니다. + + --- + + 📌 개념: %s + + --- + + 📋 작업 순서: + + 1. 위에 주어진 개념을 먼저 **충분히 이해**하세요. + - 해당 개념의 **의미, 특징, 맥락, 예시**를 상상하고 파악하세요. + - 개념에 대한 핵심 요소를 추출하여 시각적으로 설명 가능한 흐름을 구성하세요. + + 2. 다음 기준에 따라 **한 장의 이미지에 2x2 그리드(총 4컷)**로 그림을 설계하세요. + - 왼쪽 위: 장면 1 + - 오른쪽 위: 장면 2 + - 왼쪽 아래: 장면 3 + - 오른쪽 아래: 장면 4 + + 3. **절대 텍스트(한글, 영어, 숫자 등 어떤 형태든 포함 금지)**를 넣지 마세요. + - 라벨, 말풍선, 자막, 글자처럼 보일 수 있는 시각 요소도 금지 + - **오직 시각적 표현만으로** 의미가 전달되어야 합니다 + + 4. 스타일 조건: + - **파스텔톤의 부드럽고 따뜻한 색상** + - **iOS 이모지 스타일** 또는 **플랫한 웹툰 스타일** + - 복잡한 배경 없이 **간단한 배경과 상징**으로 표현 + - 필요한 경우 **화살표, 흐름선, 상징 기호**를 적절히 사용 (과도하게 사용하지 않음) + + --- + + 🎯 목적: + 글로만 이해하기 어려운 개념을 **누구나 직관적으로 이해할 수 있도록 시각적으로 구성된 4컷 만화로 전달**하는 것입니다. + """.formatted(concept); + + // DALL-E 이미지 요청 DTO 생성 + ImageCreateRequestDto requestDto = new ImageCreateRequestDto( + prompt, + "dall-e-3", + "vivid", + "1024x1024", + 1 + ); + + // 이미지 생성 + String imageUrl = imageCreateService.generatePicture(requestDto); + + // 응답 DTO 생성 + return CreateChatbotResponseDto.builder() + .chatContent(imageUrl) + .graphId(graphId) + .createdAt(LocalDateTime.now()) + .build(); + } + + // 추천 영상 생성 + @Override + public CreateChatbotResponseDto recommendVideo(String graphId, CreateChatbotRequestDto createChatbotRequestDto) { + return null; + } + // 채팅 삭제 메서드 private void deletePreviousChat(Long graphId) { chattingRepository.deleteByGraphId(graphId); diff --git a/src/main/java/com/going/server/domain/graph/exception/GraphContentNotFoundException.java b/src/main/java/com/going/server/domain/graph/exception/GraphContentNotFoundException.java new file mode 100644 index 0000000..ad43b97 --- /dev/null +++ b/src/main/java/com/going/server/domain/graph/exception/GraphContentNotFoundException.java @@ -0,0 +1,9 @@ +package com.going.server.domain.graph.exception; + +import com.going.server.global.exception.BaseException; + +public class GraphContentNotFoundException extends BaseException { + public GraphContentNotFoundException() { + super(GraphErrorCode.GRAPH_CONTENT_EMPTY); + } +} diff --git a/src/main/java/com/going/server/domain/graph/exception/GraphErrorCode.java b/src/main/java/com/going/server/domain/graph/exception/GraphErrorCode.java index 85b08bb..7c4b20a 100644 --- a/src/main/java/com/going/server/domain/graph/exception/GraphErrorCode.java +++ b/src/main/java/com/going/server/domain/graph/exception/GraphErrorCode.java @@ -9,7 +9,8 @@ @Getter @AllArgsConstructor public enum GraphErrorCode implements BaseErrorCode { - GRAPH_NOT_FOUND(NOT_FOUND, "GRAPH_404_1", "존재하지 않는 graph_id 입니다."); + GRAPH_NOT_FOUND(NOT_FOUND, "GRAPH_404_1", "존재하지 않는 graph_id 입니다."), + GRAPH_CONTENT_EMPTY(NOT_FOUND, "GRAPH_404_2", "그래프에 저장된 원문 텍스트가 존재하지 않습니다."); private final int httpStatus; private final String code; diff --git a/src/main/java/com/going/server/domain/openai/dto/ImageCreateRequestDto.java b/src/main/java/com/going/server/domain/openai/dto/ImageCreateRequestDto.java index 89d07c5..2ecfb39 100644 --- a/src/main/java/com/going/server/domain/openai/dto/ImageCreateRequestDto.java +++ b/src/main/java/com/going/server/domain/openai/dto/ImageCreateRequestDto.java @@ -15,8 +15,4 @@ public class ImageCreateRequestDto { private String style = "vivid"; private String size = "1024x1024"; private int n = 1; - - public ImageCreateRequestDto(String prompt) { - this.prompt = prompt; - } } diff --git a/src/main/java/com/going/server/domain/openai/service/AnswerCreateService.java b/src/main/java/com/going/server/domain/openai/service/RAGAnswerCreateService.java similarity index 91% rename from src/main/java/com/going/server/domain/openai/service/AnswerCreateService.java rename to src/main/java/com/going/server/domain/openai/service/RAGAnswerCreateService.java index 871afaf..fd98427 100644 --- a/src/main/java/com/going/server/domain/openai/service/AnswerCreateService.java +++ b/src/main/java/com/going/server/domain/openai/service/RAGAnswerCreateService.java @@ -11,17 +11,18 @@ import java.util.ArrayList; import java.util.List; +// RAG 대화 @Service @RequiredArgsConstructor -public class AnswerCreateService { +public class RAGAnswerCreateService { private final OpenAiService openAiService; // TODO : 프롬프트 튜닝 필요 // 시스템 역할 설정 private static final String SYSTEM_PROMPT = """ - 당신은 초등학생을 위한 친절한 설명을 제공하는 지식 튜터입니다. - 대답은 짧고 쉽게 설명해주세요. 다른 언급 없이 한글로 대답만을 주세요. - """; + 당신은 초등학생을 위한 친절한 설명을 제공하는 지식 튜터입니다. + 대답은 짧고 쉽게 설명해주세요. 다른 언급 없이 한글로 대답만을 주세요. + """; // 기존 채팅 이력을 기반으로 GPT 응답 생성 public String chat(List chatHistory, String question) { @@ -87,5 +88,4 @@ public String chatWithContext(List chatHistory, String finalPrompt) { .getMessage() .getContent(); } - } \ No newline at end of file diff --git a/src/main/java/com/going/server/domain/openai/service/SimpleAnswerCreateService.java b/src/main/java/com/going/server/domain/openai/service/SimpleAnswerCreateService.java new file mode 100644 index 0000000..d3925ae --- /dev/null +++ b/src/main/java/com/going/server/domain/openai/service/SimpleAnswerCreateService.java @@ -0,0 +1,61 @@ +package com.going.server.domain.openai.service; + +import com.going.server.domain.chatbot.entity.Chatting; +import com.going.server.domain.chatbot.entity.Sender; +import com.going.server.domain.openai.dto.ChatCompletionRequestDto; +import com.theokanning.openai.OpenAiService; +import com.theokanning.openai.completion.chat.ChatMessage; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class SimpleAnswerCreateService { + + private final OpenAiService openAiService; + + // 단순한 챗봇 응답 역할 프롬프트 + private static final String SIMPLE_SYSTEM_PROMPT = """ + 당신은 일반적인 잡담 챗봇입니다. + 너무 전문적인 정보는 피하고, 간단하고 짧은 응답을 한국어로 해주세요. + 최대한 가볍고 단순하게 대답하세요. + """; + + // GPT-3.5 기반 단순 응답 생성 메서드 + public String simpleChat(List chatHistory, String userInput) { + List messages = new ArrayList<>(); + + // 역할 지정 + messages.add(new ChatMessage("system", SIMPLE_SYSTEM_PROMPT)); + + // 기존 채팅 이력 + for (Chatting chat : chatHistory) { + String role = convertSenderToRole(chat.getSender()); + messages.add(new ChatMessage(role, chat.getContent())); + } + + // 새로운 질문 추가 + messages.add(new ChatMessage("user", userInput)); + + // 요청 객체 생성 + ChatCompletionRequestDto request = ChatCompletionRequestDto.builder() + .model("gpt-3.5-turbo") + .temperature(0.9) + .maxTokens(300) + .messages(messages) + .build(); + + return openAiService.createChatCompletion(request.toRequest()) + .getChoices() + .get(0) + .getMessage() + .getContent(); + } + + private String convertSenderToRole(Sender sender) { + return sender == Sender.USER ? "user" : "assistant"; + } +} diff --git a/src/main/java/com/going/server/domain/openai/service/TextSummaryCreateService.java b/src/main/java/com/going/server/domain/openai/service/TextSummaryCreateService.java new file mode 100644 index 0000000..34f1cf7 --- /dev/null +++ b/src/main/java/com/going/server/domain/openai/service/TextSummaryCreateService.java @@ -0,0 +1,68 @@ +package com.going.server.domain.openai.service; + +import com.going.server.domain.openai.dto.ChatCompletionRequestDto; +import com.theokanning.openai.OpenAiService; +import com.theokanning.openai.completion.chat.ChatMessage; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +// 요약본 생성 +@Service +@RequiredArgsConstructor +public class TextSummaryCreateService { + private final OpenAiService openAiService; + + private static final String SUMMARY_PROMPT = """ + You are an **educational summary assistant** for learners ranging from elementary to high school level. + + Please read the following text and generate a **structured summary** following these instructions: + + --- + + ### 📑 Summary Guidelines + + - Include **full content coverage** (summarize without omitting key ideas). + - Structure your summary into the following sections: + 📍 **Key Concepts** + 📍 **Core Principles / How It Works** + 📍 **Reasons / Evidence / Explanations** + 📍 **Cause-Effect Relationships** + 📍 **Examples / Case Studies** + 📍 **Related Concepts / Comparisons** + - Use Markdown formatting actively: + - Use `###` for headings, `**bold**` for emphasis, `-`, `1.` etc. for sublists + - Use `---` for section separation + - Use `
💡 Notes...
` to collapse additional info + - Only use the following emojis: + 📍🖇💡⚙🔧🔍📑✔💭✨ + - **Respond only in Korean**, and **output the summary only**, without any extra commentary. + + --- + + ### 📑 [요약할 원문 텍스트는 아래와 같습니다] + """; + + + + public String summarize(String originalText) { + List messages = List.of( + new ChatMessage("system", SUMMARY_PROMPT), + new ChatMessage("user", originalText) + ); + + ChatCompletionRequestDto request = ChatCompletionRequestDto.builder() + .model("gpt-4o") + .temperature(0.5) + .maxTokens(500) + .messages(messages) + .build(); + + return openAiService.createChatCompletion(request.toRequest()) + .getChoices() + .get(0) + .getMessage() + .getContent(); + } +} diff --git a/src/main/java/com/going/server/domain/quiz/generate/PictureQuizGenerator.java b/src/main/java/com/going/server/domain/quiz/generate/PictureQuizGenerator.java index 38236be..ccccf91 100644 --- a/src/main/java/com/going/server/domain/quiz/generate/PictureQuizGenerator.java +++ b/src/main/java/com/going/server/domain/quiz/generate/PictureQuizGenerator.java @@ -60,7 +60,12 @@ public PictureQuizDto generate(Graph graph) { String answer = new ArrayList<>(selectedSentences).get(answerIndex); String prompt = buildQuizImagePrompt(answer); - ImageCreateRequestDto requestDto = new ImageCreateRequestDto(prompt); + ImageCreateRequestDto requestDto = new ImageCreateRequestDto( + prompt, + "dall-e-3", + "vivid", + "1024x1024", + 1); String imageUrl = imageCreateService.generatePicture(requestDto); return PictureQuizDto.builder() @@ -71,41 +76,7 @@ public PictureQuizDto generate(Graph graph) { } // 이미지 생성 프롬프트 생성 메서드 - - // 버전1 -// private String buildQuizImagePrompt(String answer) { -// return "You are given an educational description in natural language.\n\n" + -// "1. First, analyze the sentence to determine what kind of relationship it contains, such as:\n" + -// "- Cause and effect\n" + -// "- Inclusion or category\n" + -// "- Example and concept\n" + -// "- Behavioral actions\n" + -// "- General explanation\n\n" + -// "2. Then, generate a **cute, warm, and educational diagram-style illustration** that reflects the structure and meaning of the sentence.\n\n" + -// "Use **flat vector illustrations inspired by iOS emojis**, with **bright and soft colors**.\n" + -// "If the sentence includes multiple ideas, arrange the illustration using diagrams, arrows, or symbolic layouts that match the logical structure.\n" + -// "Do **not include any text or labels** in the image. Use only visuals.\n\n" + -// "[Description]\n" + answer; -// } - - // 버전2 -// public String buildQuizImagePrompt(String answer) { -// return "You are given an educational description in natural language.\n\n" + -// "1. First, analyze the sentence to determine what kind of relationship it contains, such as:\n" + -// "- Cause and effect\n" + -// "- Inclusion or category\n" + -// "- Example and concept\n" + -// "- Behavioral actions\n" + -// "- General explanation\n\n" + -// "2. Then, generate a cute, warm, and educational diagram-style illustration that reflects the structure and meaning of the sentence.\n\n" + -// "Use flat vector illustrations inspired by iOS emojis, with bright and soft colors.\n" + -// "If the sentence includes multiple ideas, arrange the illustration using symbols or visual layouts like arrows, sets, or diagrams **only when necessary to express the logical relationship**.\n" + -// "Do not include any text or labels in the image. Use only visuals.\n\n" + -// "[Description]\n" + answer; -// } - - // 버전3 - public static String buildQuizImagePrompt(String answer) { + public static String buildQuizImagePrompt(String answer) { return "You are given an educational description in natural language.\n\n" + "1. First, analyze the sentence to determine what kind of relationship it contains, such as:\n" + "- Cause and effect\n" + @@ -121,4 +92,6 @@ public static String buildQuizImagePrompt(String answer) { "[Description]\n" + answer; } + // 네컷 만화 생성 프롬프트 빌드 메서드 + }