Skip to content

Commit

Permalink
Merge pull request #245 from 9oormthon-univ/feat/#243
Browse files Browse the repository at this point in the history
feat: 퀘스트 추천 api 추가
  • Loading branch information
koosco authored Dec 4, 2024
2 parents 08db0d5 + b1cd73d commit be64a9a
Show file tree
Hide file tree
Showing 21 changed files with 205 additions and 516 deletions.
3 changes: 3 additions & 0 deletions src/main/java/com/groom/orbit/ai/app/AiService.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.groom.orbit.ai.app;

import com.groom.orbit.goal.app.dto.request.CreateGoalRequestDto;
import com.groom.orbit.goal.app.dto.response.RecommendQuestListResponseDto;
import com.groom.orbit.member.app.dto.response.GetFeedbackResponseDto;
import com.groom.orbit.resume.app.dto.GetResumeResponseDto;

Expand All @@ -9,4 +10,6 @@ public interface AiService {
GetFeedbackResponseDto getMemberFeedback(String interestJobs, GetResumeResponseDto dto);

CreateGoalRequestDto recommendGoal(Long memberId);

RecommendQuestListResponseDto recommendQuest(Long memberId);
}
61 changes: 53 additions & 8 deletions src/main/java/com/groom/orbit/ai/app/openai/OpenAiService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.groom.orbit.ai.app.VectorService;
import com.groom.orbit.ai.dao.vector.Vector;
import com.groom.orbit.goal.app.dto.request.CreateGoalRequestDto;
import com.groom.orbit.goal.app.dto.response.RecommendQuestListResponseDto;
import com.groom.orbit.member.app.dto.response.GetFeedbackResponseDto;
import com.groom.orbit.resume.app.dto.GetResumeResponseDto;
import com.groom.orbit.resume.app.dto.ResumeResponseDto;
Expand All @@ -37,6 +38,9 @@ public class OpenAiService implements AiService {
@Value("classpath:/templates/goal-recommend-prompt.txt")
private Resource goalRecommendPrompt;

@Value("classpath:/templates/quest-recommend-prompt.txt")
private Resource questRecommendPrompt;

private static final String PARAMETER_NEW_LINE_LIST_DELIMITER = "\n -";
private static final String PARAMETER_LIST_DELIMITER = ",";

Expand All @@ -45,7 +49,7 @@ public GetFeedbackResponseDto getMemberFeedback(String interestJobs, GetResumeRe
getConverter(GetFeedbackResponseDto.class);
String format = converter.getFormat();

PromptTemplate promptTemplate = new PromptTemplate(aiFeedbackPrompt);
PromptTemplate promptTemplate = createPromptTemplate(aiFeedbackPrompt);
String response =
callChatModel(
promptTemplate,
Expand All @@ -70,25 +74,66 @@ public CreateGoalRequestDto recommendGoal(Long memberId) {
Vector myVector = similarVectors.getFirst();
List<Vector> othersVector = similarVectors.subList(1, similarVectors.size());

PromptTemplate promptTemplate = new PromptTemplate(goalRecommendPrompt);
PromptTemplate promptTemplate = createPromptTemplate(goalRecommendPrompt);
String response =
callChatModel(
promptTemplate,
Map.of(
"job", String.join(PARAMETER_LIST_DELIMITER, myVector.interestJobs()),
"myGoal", String.join(PARAMETER_LIST_DELIMITER, myVector.goals()),
"job",
String.join(PARAMETER_LIST_DELIMITER, myVector.interestJobs()),
"myGoal",
String.join(PARAMETER_LIST_DELIMITER, myVector.goals()),
"goalList",
String.join(
PARAMETER_LIST_DELIMITER,
othersVector.stream().flatMap(vector -> vector.goals().stream()).toList()),
"format", format));
String.join(
PARAMETER_LIST_DELIMITER,
othersVector.stream().flatMap(vector -> vector.goals().stream()).toList()),
"format",
format));
return converter.convert(response);
}

@Override
public RecommendQuestListResponseDto recommendQuest(Long memberId) {
BeanOutputConverter<RecommendQuestListResponseDto> converter =
getConverter(RecommendQuestListResponseDto.class);
String format = converter.getFormat();
List<Vector> similarVectors = vectorService.findSimilarVector(memberId);

Vector myVector = similarVectors.getFirst();
List<Vector> othersVector = similarVectors.subList(1, similarVectors.size());

PromptTemplate promptTemplate = createPromptTemplate(questRecommendPrompt);
String response =
callChatModel(
promptTemplate,
Map.of(
"job",
convertListToString(myVector.interestJobs()),
"goal",
String.join(PARAMETER_LIST_DELIMITER, myVector.goals()),
"myQuest",
convertListToString(myVector.quests()),
"questList",
convertListToString(
othersVector.stream().flatMap(vector -> vector.goals().stream()).toList()),
"format",
format));
log.info("response is {}", response);
return converter.convert(response);
}

private PromptTemplate createPromptTemplate(Resource resource) {
return new PromptTemplate(resource);
}

private <T> BeanOutputConverter<T> getConverter(Class<T> converterClass) {
return new BeanOutputConverter<>(converterClass);
}

private String convertListToString(List<String> data) {
return String.join(PARAMETER_LIST_DELIMITER, data);
}

private String convertResumeDtoToString(List<ResumeResponseDto> data) {
return String.join(
PARAMETER_NEW_LINE_LIST_DELIMITER, data.stream().map(ResumeResponseDto::title).toList());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.groom.orbit.ai.app.util;

import java.util.List;

import org.springframework.ai.converter.BeanOutputConverter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public class CustomOutputConverter<T> {

private final BeanOutputConverter<T> converter;
private final ObjectMapper objectMapper;
private final Class<T> targetType;

public CustomOutputConverter(Class<T> converterClass) {
this.converter = new BeanOutputConverter<>(converterClass);
this.objectMapper = new ObjectMapper();
this.targetType = converterClass;
}

public T convertToObject(String text) {
return converter.convert(text);
}

public List<T> convertToList(String text) {
try {
// JSON 문자열을 파싱하여 리스트 형태로 변환
text = preprocessJson(text);
return objectMapper.readValue(text, new TypeReference<>() {});
} catch (JsonProcessingException e) {
throw new RuntimeException("Failed to convert text to List: " + text, e);
}
}

public String getFormat() {
return converter.getFormat();
}

private String preprocessJson(String text) {
text = text.trim();
if (text.startsWith("```") && text.endsWith("```")) {
String[] lines = text.split("\n", 2);
if (lines[0].trim().equalsIgnoreCase("```json")) {
text = lines.length > 1 ? lines[1] : "";
} else {
text = text.substring(3);
}
text = text.substring(0, text.length() - 3);
}
return text.trim();
}
}
42 changes: 0 additions & 42 deletions src/main/java/com/groom/orbit/config/openai/AiFeedbackPrompt.java

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit be64a9a

Please sign in to comment.