-
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.
Browse files
Browse the repository at this point in the history
feat: 사용자 목표 추천 api 추가
- Loading branch information
Showing
25 changed files
with
300 additions
and
170 deletions.
There are no files selected for viewing
5 changes: 4 additions & 1 deletion
5
...in/java/com/groom/orbit/ai/AiService.java → ...ava/com/groom/orbit/ai/app/AiService.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 |
---|---|---|
@@ -1,9 +1,12 @@ | ||
package com.groom.orbit.ai; | ||
package com.groom.orbit.ai.app; | ||
|
||
import com.groom.orbit.goal.app.dto.request.CreateGoalRequestDto; | ||
import com.groom.orbit.member.app.dto.response.GetFeedbackResponseDto; | ||
import com.groom.orbit.resume.app.dto.GetResumeResponseDto; | ||
|
||
public interface AiService { | ||
|
||
GetFeedbackResponseDto getMemberFeedback(String interestJobs, GetResumeResponseDto dto); | ||
|
||
CreateGoalRequestDto recommendGoal(Long memberId); | ||
} |
This file was deleted.
Oops, something went wrong.
7 changes: 6 additions & 1 deletion
7
...ava/com/groom/orbit/ai/VectorService.java → ...com/groom/orbit/ai/app/VectorService.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
105 changes: 105 additions & 0 deletions
105
src/main/java/com/groom/orbit/ai/app/openai/OpenAiService.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,105 @@ | ||
package com.groom.orbit.ai.app.openai; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.springframework.ai.chat.model.ChatModel; | ||
import org.springframework.ai.chat.model.ChatResponse; | ||
import org.springframework.ai.chat.prompt.Prompt; | ||
import org.springframework.ai.chat.prompt.PromptTemplate; | ||
import org.springframework.ai.converter.BeanOutputConverter; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.core.io.Resource; | ||
import org.springframework.stereotype.Service; | ||
|
||
import com.groom.orbit.ai.app.AiService; | ||
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.member.app.dto.response.GetFeedbackResponseDto; | ||
import com.groom.orbit.resume.app.dto.GetResumeResponseDto; | ||
import com.groom.orbit.resume.app.dto.ResumeResponseDto; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@Slf4j | ||
@Service | ||
@RequiredArgsConstructor | ||
public class OpenAiService implements AiService { | ||
|
||
private final ChatModel chatModel; | ||
private final VectorService vectorService; | ||
|
||
@Value("classpath:/templates/ai-feedback-prompt.txt") | ||
private Resource aiFeedbackPrompt; | ||
|
||
@Value("classpath:/templates/goal-recommend-prompt.txt") | ||
private Resource goalRecommendPrompt; | ||
|
||
private static final String PARAMETER_NEW_LINE_LIST_DELIMITER = "\n -"; | ||
private static final String PARAMETER_LIST_DELIMITER = ","; | ||
|
||
public GetFeedbackResponseDto getMemberFeedback(String interestJobs, GetResumeResponseDto dto) { | ||
BeanOutputConverter<GetFeedbackResponseDto> converter = | ||
getConverter(GetFeedbackResponseDto.class); | ||
String format = converter.getFormat(); | ||
|
||
PromptTemplate promptTemplate = new PromptTemplate(aiFeedbackPrompt); | ||
String response = | ||
callChatModel( | ||
promptTemplate, | ||
Map.of( | ||
"job", interestJobs, | ||
"academy", convertResumeDtoToString(dto.academyList()), | ||
"career", convertResumeDtoToString(dto.careerList()), | ||
"qualification", convertResumeDtoToString(dto.qualificationList()), | ||
"experience", convertResumeDtoToString(dto.experienceList()), | ||
"etc", convertResumeDtoToString(dto.etcList()), | ||
"format", format)); | ||
|
||
return converter.convert(response); | ||
} | ||
|
||
@Override | ||
public CreateGoalRequestDto recommendGoal(Long memberId) { | ||
BeanOutputConverter<CreateGoalRequestDto> converter = getConverter(CreateGoalRequestDto.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 = new PromptTemplate(goalRecommendPrompt); | ||
String response = | ||
callChatModel( | ||
promptTemplate, | ||
Map.of( | ||
"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)); | ||
return converter.convert(response); | ||
} | ||
|
||
private <T> BeanOutputConverter<T> getConverter(Class<T> converterClass) { | ||
return new BeanOutputConverter<>(converterClass); | ||
} | ||
|
||
private String convertResumeDtoToString(List<ResumeResponseDto> data) { | ||
return String.join( | ||
PARAMETER_NEW_LINE_LIST_DELIMITER, data.stream().map(ResumeResponseDto::title).toList()); | ||
} | ||
|
||
private String callChatModel(PromptTemplate promptTemplate, Map<String, Object> variables) { | ||
Prompt prompt = promptTemplate.create(variables); | ||
ChatResponse response = chatModel.call(prompt); | ||
|
||
log.info("prompt is {}", prompt.getContents()); | ||
|
||
return response.getResult().getOutput().getContent(); | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
...rbit/ai/app/PineconeEmbeddingService.java → ...pp/pinecone/PineconeEmbeddingService.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
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
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,16 @@ | ||
package com.groom.orbit.ai.dao; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
import com.google.protobuf.Struct; | ||
import com.groom.orbit.ai.dao.vector.Vector; | ||
|
||
public interface VectorStore { | ||
|
||
void save(Long key, List<Float> vectors, Struct metadata); | ||
|
||
Optional<Vector> findById(Long id); | ||
|
||
List<Vector> findSimilar(List<Float> vector); | ||
} |
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
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
Oops, something went wrong.