Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ services:
restart: unless-stopped

postgres:
image: postgres:16-alpine
image: pgvector/pgvector:pg16@sha256:1d533553fefe4f12e5d80c7b80622ba0c382abb5758856f52983d8789179f0fb
container_name: jobdri-postgres
environment:
POSTGRES_DB: ${POSTGRES_DB:-jobdri}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ public record AnalysisLlmResponse(
Integer impact,
Integer completeness,
String feedback,
List<HighlightItem> keyStrengths,
List<HighlightItem> keyWeaknesses,
List<MissingKeywordItem> missingKeywords,
List<QuestionAnalysisItem> questionAnalyses
) {
Expand All @@ -15,9 +17,26 @@ public AnalysisLlmResponse(
Integer impact,
Integer completeness,
String feedback,
List<MissingKeywordItem> missingKeywords,
List<QuestionAnalysisItem> questionAnalyses
) {
this(jobFit, impact, completeness, feedback, List.of(), questionAnalyses);
this(jobFit, impact, completeness, feedback, List.of(), List.of(), missingKeywords, questionAnalyses);
}

public AnalysisLlmResponse(
Integer jobFit,
Integer impact,
Integer completeness,
String feedback,
List<QuestionAnalysisItem> questionAnalyses
) {
this(jobFit, impact, completeness, feedback, List.of(), List.of(), List.of(), questionAnalyses);
}

public record HighlightItem(
String title,
String quote
) {
}

public record MissingKeywordItem(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.jobdri.jobdri_api.domain.analysis.dto.response;

public record AnalysisHighlightResponse(
String title,
String quote
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ public record AnalysisResponse(
int impact,
int completeness,
String feedback,
List<AnalysisHighlightResponse> keyStrengths,
List<AnalysisHighlightResponse> keyWeaknesses,
List<MissingKeywordResponse> missingKeywords,
List<AnalysisQuestionResponse> questions
) {
public static AnalysisResponse of(
Analysis analysis,
MockApplyStatus status,
int sequence,
List<AnalysisHighlightResponse> keyStrengths,
List<AnalysisHighlightResponse> keyWeaknesses,
List<MissingKeywordResponse> missingKeywords,
List<AnalysisQuestionResponse> questions
) {
Expand All @@ -35,6 +39,8 @@ public static AnalysisResponse of(
analysis.getImpact(),
analysis.getCompleteness(),
analysis.getFeedback(),
keyStrengths == null ? List.of() : keyStrengths,
keyWeaknesses == null ? List.of() : keyWeaknesses,
missingKeywords == null ? List.of() : missingKeywords,
questions
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ public class Analysis extends BaseEntity {
@Column(name = "missing_keywords", nullable = false, columnDefinition = "TEXT DEFAULT '[]'")
private String missingKeywordsJson = "[]";

@Builder.Default
@Column(name = "key_strengths", nullable = false, columnDefinition = "TEXT DEFAULT '[]'")
private String keyStrengthsJson = "[]";

@Builder.Default
@Column(name = "key_weaknesses", nullable = false, columnDefinition = "TEXT DEFAULT '[]'")
private String keyWeaknessesJson = "[]";

@Builder.Default
@OneToMany(mappedBy = "analysis", cascade = CascadeType.ALL, orphanRemoval = true)
private List<QuestionAnalysis> questionAnalyses = new ArrayList<>();
Expand All @@ -66,6 +74,20 @@ public static Analysis create(
int completeness,
String feedback,
String missingKeywordsJson
) {
return create(mockApply, score, jobFit, impact, completeness, feedback, missingKeywordsJson, "[]", "[]");
}

public static Analysis create(
MockApply mockApply,
int score,
int jobFit,
int impact,
int completeness,
String feedback,
String missingKeywordsJson,
String keyStrengthsJson,
String keyWeaknessesJson
) {
return Analysis.builder()
.mockApply(mockApply)
Expand All @@ -75,6 +97,8 @@ public static Analysis create(
.completeness(completeness)
.feedback(feedback)
.missingKeywordsJson(missingKeywordsJson == null ? "[]" : missingKeywordsJson)
.keyStrengthsJson(keyStrengthsJson == null ? "[]" : keyStrengthsJson)
.keyWeaknessesJson(keyWeaknessesJson == null ? "[]" : keyWeaknessesJson)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ public class AnalysisAiClient {
"impact": 55,
"completeness": 67,
"feedback": "한 줄 피드백",
"keyStrengths": [
{
"title": "직무 연관 경험이 명확하게 드러나요",
"quote": "자소서 답변 안에 실제 존재하는 정확한 부분 문자열"
}
],
"keyWeaknesses": [
{
"title": "SQL 활용 경험이 보강되면 더 설득력 있어요",
"quote": "JD 또는 자소서 답변 안에 실제 존재하는 정확한 부분 문자열"
}
],
"missingKeywords": [
{
"keyword": "SQL 활용 경험",
Expand All @@ -63,8 +75,9 @@ public class AnalysisAiClient {
4. jobFit, impact, completeness를 각각 평가한다.
5. 감점 금지 조건과 status 오남용 여부를 확인한다.
6. 보완이 필요한 원문 문장을 문항당 최대 3개만 추출한다.
7. JD에는 있지만 자소서에 충분히 드러나지 않은 역량을 missingKeywords로 최대 3개 추출한다.
8. 지정된 JSON만 반환한다.
7. 총점 한 줄 평가 feedback과 핵심 강점/약점 카드를 작성한다.
8. JD에는 있지만 자소서에 충분히 드러나지 않은 역량을 missingKeywords로 최대 3개 추출한다.
9. 지정된 JSON만 반환한다.

[jobFit 평가 기준]
JD가 요구하는 역량, 경험, 기술을 자기소개서가 얼마나 증명하는지 평가한다.
Expand Down Expand Up @@ -152,6 +165,17 @@ public class AnalysisAiClient {
- 중복되거나 유사한 keyword는 하나로 묶고, 대표 문구는 자격요건 표현을 우선한다.
- source는 qualification, preference, mainTask 중 하나만 사용한다.

[핵심 강점/약점 작성 규칙]
- keyStrengths와 keyWeaknesses는 각각 최대 3개만 반환한다.
- title은 화면 카드 제목으로 바로 노출할 짧은 한국어 문장으로 작성한다.
- quote는 반드시 실제 텍스트에서 가져온 짧은 직접 인용이어야 하며 새로 만들거나 요약하지 않는다.
- keyStrengths의 quote는 자소서 answer에 실제 포함된 정확한 부분 문자열만 사용한다.
- keyWeaknesses의 첫 항목들은 missingKeywords와 같은 누락 요건을 다룬다.
- missingKeywords 기반 keyWeaknesses의 quote는 JD의 주요 업무, 자격 요건, 우대 사항에 실제 포함된 표현을 사용한다.
- missingKeywords가 없으면 keyWeaknesses는 questionAnalyses의 보완 대상 문장 quote를 우선 사용한다.
- quote는 너무 길게 붙이지 말고 사용자가 근거를 확인할 수 있는 핵심 구절만 사용한다.
- 적절한 강점이나 약점이 없으면 null이나 필드 생략이 아니라 빈 배열 []을 반환한다.

[reason 작성 규칙]
- 사용자가 왜 해당 문장이 보완 대상인지 이해할 수 있게 작성한다.
- 가능하면 JD의 어떤 업무, 자격요건, 우대사항과 관련된 문제인지 설명한다.
Expand Down Expand Up @@ -328,6 +352,9 @@ String buildPrompt(
- questionAnalyses의 status는 proven, mentioned, missing, fabricated 중 하나만 사용한다.
- sentence는 answer에 포함된 정확한 substring만 사용한다.
- missing 상태를 questionAnalyses에 넣기 위해 원문에 없는 sentence를 만들지 않는다.
- keyStrengths와 keyWeaknesses는 각각 최대 3개이며, 없으면 []로 출력한다.
- keyStrengths의 quote는 answer에 실제 포함된 substring만 사용한다.
- keyWeaknesses에서 missingKeywords를 다루는 항목의 quote는 실제 JD 문구만 사용한다.
- missingKeywords는 최대 3개이며, 없으면 []로 출력한다.
- missingKeywords의 source는 qualification, preference, mainTask 중 하나만 사용한다.
- improvement가 지시문이 아닌 완성된 한국어 평서문인지 확인한다.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ public final class AnalysisResultConstants {
public static final int MIN_SCORE = 0;
public static final int MAX_SCORE = 100;
public static final int MAX_ANALYSES_PER_QUESTION = 3;
public static final int MAX_HIGHLIGHTS = 3;
public static final int MAX_HIGHLIGHT_TITLE_LENGTH = 80;
public static final int MAX_HIGHLIGHT_QUOTE_LENGTH = 200;
public static final int MAX_MISSING_KEYWORDS = 3;
public static final int MAX_MISSING_KEYWORD_LENGTH = 60;
public static final double JOB_FIT_WEIGHT = 0.50;
Expand Down
Loading
Loading