From 10f6c03ee256ec9e25926be124aac82f69b77318 Mon Sep 17 00:00:00 2001 From: wooh Date: Tue, 26 May 2026 14:49:41 +0900 Subject: [PATCH 1/5] =?UTF-8?q?[Fix]=20=EC=9E=90=EC=86=8C=EC=84=9C=20?= =?UTF-8?q?=EB=B6=84=EC=84=9D=20=EA=B0=9C=EC=84=A0=20=EC=98=88=EC=8B=9C=20?= =?UTF-8?q?=EB=AC=B8=EC=9E=A5=20=EC=83=9D=EC=84=B1=20=EB=B0=A9=EC=8B=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - LLM 프롬프트에서 improvement를 완성된 개선 예시 문장으로 생성하도록 지시 강화 - improvement에 첨삭 조언이나 지시문이 들어오지 않도록 금지 규칙 추가 - 지시문 형태의 improvement가 반환되면 빈 값으로 정규화하도록 방어 로직 추가 - improvement 정규화 테스트 추가 --- .../analysis/service/AnalysisAiClient.java | 7 ++++- .../analysis/service/AnalysisService.java | 24 ++++++++++++++++- .../analysis/service/AnalysisServiceTest.java | 27 +++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisAiClient.java b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisAiClient.java index 3318d87..1afe3f8 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisAiClient.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisAiClient.java @@ -81,7 +81,7 @@ private String buildPrompt(JobPosting jobPosting, List questions) { "sentence": "자소서 답변 안에 실제 존재하는 정확한 부분 문자열", "status": "mentioned", "reason": "문제 이유", - "improvement": "개선 예시 문장" + "improvement": "사용자가 그대로 붙여 넣을 수 있는 완성된 개선 예시 문장" } ] } @@ -134,6 +134,11 @@ private String buildPrompt(JobPosting jobPosting, List questions) { - questionAnalyses의 questionId는 입력된 questionId 중 하나만 사용한다. - questionAnalyses의 status는 proven, mentioned, missing, fabricated 중 하나만 사용한다. - sentence는 answer에 포함된 정확한 substring만 사용한다. + - improvement는 첨삭 조언이 아니라 sentence를 대체할 수 있는 완성된 예시 문장이어야 한다. + - improvement에는 "추가하세요", "명확히 하세요", "보완하세요", "필요합니다" 같은 지시문을 쓰지 않는다. + - improvement는 반드시 한국어 평서문으로 작성하고, 가능하면 수치/성과/행동을 포함한다. + - 좋은 improvement 예: "저는 쿼리 실행 계획을 분석해 누락된 인덱스를 추가했고, 평균 응답 시간을 1.8초에서 0.6초로 단축했습니다." + - 나쁜 improvement 예: "성과 수치를 추가하여 문제 해결의 효과를 명확히 하세요." - start/end index는 출력하지 않는다. 서버가 Java에서 계산한다. - 원문 매칭이 불확실하면 questionAnalyses에 포함하지 않는다. """.formatted( diff --git a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java index 8d66f33..8262df2 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java @@ -149,7 +149,7 @@ private List buildQuestionAnalyses( analysis, sentence, defaultString(item.reason()), - defaultString(item.improvement()), + normalizeImprovement(item.improvement()), normalizeStatus(item.status()), start, start + sentence.length() @@ -219,6 +219,28 @@ private String defaultString(String value) { return value == null ? "" : value; } + private String normalizeImprovement(String improvement) { + if (!StringUtils.hasText(improvement)) { + return ""; + } + + String normalized = improvement.trim(); + if (isInstructionLikeImprovement(normalized)) { + return ""; + } + return normalized; + } + + private boolean isInstructionLikeImprovement(String improvement) { + return improvement.endsWith("하세요.") + || improvement.endsWith("해주세요.") + || improvement.endsWith("해야 합니다.") + || improvement.endsWith("필요합니다.") + || improvement.contains("추가하여") + || improvement.contains("명확히 하세요") + || improvement.contains("보완하세요"); + } + private QuestionAnalysisStatus normalizeStatus(String status) { if (!StringUtils.hasText(status)) { return QuestionAnalysisStatus.MENTIONED; diff --git a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java index 58c88be..e9e261e 100644 --- a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java +++ b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java @@ -236,6 +236,33 @@ void analyzeSkipsSentenceNotInAnswer() { assertThat(questionAnalysisRepository.findAllByAnalysisId(analysis.getId())).isEmpty(); } + @Test + @DisplayName("LLM improvement가 첨삭 지시문이면 빈 값으로 저장한다") + void analyzeNormalizesInstructionLikeImprovement() { + User user = saveUser("analysis-instruction-improvement@example.com"); + MockApply mockApply = saveMockApply(user); + Question question = saveQuestion(mockApply, "문제 해결 경험", "저는 로그를 확인하고 쿼리 실행 계획을 분석했습니다."); + when(analysisAiClient.analyze(any(), any())).thenReturn(new AnalysisLlmResponse( + 64, + 70, + 55, + 67, + "개선 예시 문장 검증입니다.", + List.of(new AnalysisLlmResponse.QuestionAnalysisItem( + question.getId(), + "저는 로그를 확인하고 쿼리 실행 계획을 분석했습니다.", + "mentioned", + "성과 수치가 부족합니다.", + "성과 수치를 추가하여 문제 해결의 효과를 명확히 하세요." + )) + )); + + AnalysisResponse response = analysisService.analyze(user, mockApply.getId()); + + assertThat(response.questions().get(0).analyses()).hasSize(1); + assertThat(response.questions().get(0).analyses().get(0).improvement()).isEmpty(); + } + @Test @DisplayName("재분석 시 기존 분석과 문항 분석을 새 결과로 교체한다") void analyzeReplacesExistingAnalysis() { From 85dd5d1f10b879abc08972a5df2052843deacb0d Mon Sep 17 00:00:00 2001 From: wooh Date: Tue, 26 May 2026 15:05:02 +0900 Subject: [PATCH 2/5] =?UTF-8?q?[Fix]=20=EC=9E=90=EC=86=8C=EC=84=9C=20?= =?UTF-8?q?=EB=B6=84=EC=84=9D=20=EA=B0=9C=EC=84=A0=20=EC=98=88=EC=8B=9C=20?= =?UTF-8?q?=EB=AC=B8=EC=9E=A5=20=ED=95=84=ED=84=B0=EB=A7=81=20=EC=A0=95?= =?UTF-8?q?=EA=B5=90=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - improvement 지시문 판별 로직에서 과도한 contains 조건 제거 - 명령형/지시문 어미 중심으로 improvement 필터링 기준 수정 - 정상적인 평서문 개선 예시가 빈 값으로 정규화되지 않도록 보완 - LLM 프롬프트의 improvement 금지 표현을 서버 검증 기준과 일치하도록 수정 - 완성된 평서문 improvement 보존 테스트 추가 --- .../analysis/service/AnalysisAiClient.java | 3 +- .../analysis/service/AnalysisService.java | 6 ++-- .../analysis/service/AnalysisServiceTest.java | 29 +++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisAiClient.java b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisAiClient.java index 1afe3f8..710b3bb 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisAiClient.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisAiClient.java @@ -135,7 +135,8 @@ private String buildPrompt(JobPosting jobPosting, List questions) { - questionAnalyses의 status는 proven, mentioned, missing, fabricated 중 하나만 사용한다. - sentence는 answer에 포함된 정확한 substring만 사용한다. - improvement는 첨삭 조언이 아니라 sentence를 대체할 수 있는 완성된 예시 문장이어야 한다. - - improvement에는 "추가하세요", "명확히 하세요", "보완하세요", "필요합니다" 같은 지시문을 쓰지 않는다. + - improvement에는 "하세요.", "해주세요.", "해야 합니다.", "필요합니다."로 끝나는 지시문을 쓰지 않는다. + - improvement에는 "추가하세요.", "보완하세요.", "수정해주세요.", "명확히 해야 합니다." 같은 첨삭 조언 표현을 쓰지 않는다. - improvement는 반드시 한국어 평서문으로 작성하고, 가능하면 수치/성과/행동을 포함한다. - 좋은 improvement 예: "저는 쿼리 실행 계획을 분석해 누락된 인덱스를 추가했고, 평균 응답 시간을 1.8초에서 0.6초로 단축했습니다." - 나쁜 improvement 예: "성과 수치를 추가하여 문제 해결의 효과를 명확히 하세요." diff --git a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java index 8262df2..00408ab 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java @@ -236,9 +236,9 @@ private boolean isInstructionLikeImprovement(String improvement) { || improvement.endsWith("해주세요.") || improvement.endsWith("해야 합니다.") || improvement.endsWith("필요합니다.") - || improvement.contains("추가하여") - || improvement.contains("명확히 하세요") - || improvement.contains("보완하세요"); + || improvement.matches(".*[을를]\\s+(추가|보완|수정)하(세요|십시오).*") + || improvement.matches(".*명확히\\s+(하|해)(세요|야 합니다).*") + || improvement.matches("^(추가|보완|수정).*(하세요|해주세요)\\.$"); } private QuestionAnalysisStatus normalizeStatus(String status) { diff --git a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java index e9e261e..631cc4b 100644 --- a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java +++ b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java @@ -263,6 +263,35 @@ void analyzeNormalizesInstructionLikeImprovement() { assertThat(response.questions().get(0).analyses().get(0).improvement()).isEmpty(); } + @Test + @DisplayName("완성된 평서문 improvement는 그대로 저장한다") + void analyzePreservesDeclarativeImprovement() { + User user = saveUser("analysis-declarative-improvement@example.com"); + MockApply mockApply = saveMockApply(user); + Question question = saveQuestion(mockApply, "문제 해결 경험", "저는 로그를 확인했습니다."); + String validImprovement = "저는 로그를 분석하고 누락된 인덱스를 추가하여 응답 시간을 1.8초에서 0.6초로 단축했습니다."; + when(analysisAiClient.analyze(any(), any())).thenReturn(new AnalysisLlmResponse( + 70, + 75, + 65, + 70, + "평서문 검증입니다.", + List.of(new AnalysisLlmResponse.QuestionAnalysisItem( + question.getId(), + "저는 로그를 확인했습니다.", + "mentioned", + "성과가 부족합니다.", + validImprovement + )) + )); + + AnalysisResponse response = analysisService.analyze(user, mockApply.getId()); + + assertThat(response.questions().get(0).analyses()).hasSize(1); + assertThat(response.questions().get(0).analyses().get(0).improvement()) + .isEqualTo(validImprovement); + } + @Test @DisplayName("재분석 시 기존 분석과 문항 분석을 새 결과로 교체한다") void analyzeReplacesExistingAnalysis() { From e11ccd62126087da6b5e4f4e33e3307347a62e01 Mon Sep 17 00:00:00 2001 From: wooh Date: Tue, 26 May 2026 15:11:05 +0900 Subject: [PATCH 3/5] =?UTF-8?q?[Fix]=20=EC=9E=90=EC=86=8C=EC=84=9C=20?= =?UTF-8?q?=EB=B6=84=EC=84=9D=20=EA=B0=9C=EC=84=A0=20=EC=98=88=EC=8B=9C=20?= =?UTF-8?q?=EC=A7=80=EC=8B=9C=EB=AC=B8=20=EA=B0=90=EC=A7=80=20=EB=B3=B4?= =?UTF-8?q?=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - improvement 지시문 감지 로직에 띄어쓰기 포함 표현 추가 - 해 주세요, 해 주십시오 형태의 지시문 어미를 필터링하도록 수정 - 명령형 정규식에서 하세요/하십시오 앞 공백을 허용하도록 보완 - 띄어쓰기 포함 첨삭 지시문 정규화 테스트 추가 --- .../analysis/service/AnalysisService.java | 6 +++-- .../analysis/service/AnalysisServiceTest.java | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java index 00408ab..92adfc8 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java @@ -234,10 +234,12 @@ private String normalizeImprovement(String improvement) { private boolean isInstructionLikeImprovement(String improvement) { return improvement.endsWith("하세요.") || improvement.endsWith("해주세요.") + || improvement.endsWith("해 주세요.") + || improvement.endsWith("해 주십시오.") || improvement.endsWith("해야 합니다.") || improvement.endsWith("필요합니다.") - || improvement.matches(".*[을를]\\s+(추가|보완|수정)하(세요|십시오).*") - || improvement.matches(".*명확히\\s+(하|해)(세요|야 합니다).*") + || improvement.matches(".*[을를]\\s+(추가|보완|수정)하\\s*(세요|십시오).*") + || improvement.matches(".*명확히\\s+(하|해)\\s*(세요|야 합니다).*") || improvement.matches("^(추가|보완|수정).*(하세요|해주세요)\\.$"); } diff --git a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java index 631cc4b..049758e 100644 --- a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java +++ b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java @@ -292,6 +292,33 @@ void analyzePreservesDeclarativeImprovement() { .isEqualTo(validImprovement); } + @Test + @DisplayName("띄어쓰기가 포함된 첨삭 지시문도 빈 값으로 저장한다") + void analyzeNormalizesSpacedInstructionLikeImprovement() { + User user = saveUser("analysis-spaced-instruction-improvement@example.com"); + MockApply mockApply = saveMockApply(user); + Question question = saveQuestion(mockApply, "문제 해결 경험", "저는 로그를 확인했습니다."); + when(analysisAiClient.analyze(any(), any())).thenReturn(new AnalysisLlmResponse( + 64, + 70, + 55, + 67, + "띄어쓰기 지시문 검증입니다.", + List.of(new AnalysisLlmResponse.QuestionAnalysisItem( + question.getId(), + "저는 로그를 확인했습니다.", + "mentioned", + "성과가 부족합니다.", + "성과 수치를 추가해 주세요." + )) + )); + + AnalysisResponse response = analysisService.analyze(user, mockApply.getId()); + + assertThat(response.questions().get(0).analyses()).hasSize(1); + assertThat(response.questions().get(0).analyses().get(0).improvement()).isEmpty(); + } + @Test @DisplayName("재분석 시 기존 분석과 문항 분석을 새 결과로 교체한다") void analyzeReplacesExistingAnalysis() { From 612e8158a404bb0fa8fc75ae383a5171959e677b Mon Sep 17 00:00:00 2001 From: wooh Date: Tue, 26 May 2026 15:29:40 +0900 Subject: [PATCH 4/5] =?UTF-8?q?[Fix]=20=EC=B2=A8=EC=82=AD=20=EC=A7=80?= =?UTF-8?q?=EC=8B=9C=EB=AC=B8=20improvement=20=ED=95=84=ED=84=B0=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 하십시오, 해주십시오 형태의 격식체 지시문 필터링 추가 - 명확히 하십시오 등 누락된 명령형 표현 정규식 보완 - 격식체 첨삭 지시문이 빈 improvement로 저장되는 회귀 테스트 추가 --- .../analysis/service/AnalysisService.java | 6 ++- .../analysis/service/AnalysisServiceTest.java | 38 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java index 92adfc8..91577bc 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java @@ -235,12 +235,14 @@ private boolean isInstructionLikeImprovement(String improvement) { return improvement.endsWith("하세요.") || improvement.endsWith("해주세요.") || improvement.endsWith("해 주세요.") + || improvement.endsWith("하십시오.") + || improvement.endsWith("해주십시오.") || improvement.endsWith("해 주십시오.") || improvement.endsWith("해야 합니다.") || improvement.endsWith("필요합니다.") || improvement.matches(".*[을를]\\s+(추가|보완|수정)하\\s*(세요|십시오).*") - || improvement.matches(".*명확히\\s+(하|해)\\s*(세요|야 합니다).*") - || improvement.matches("^(추가|보완|수정).*(하세요|해주세요)\\.$"); + || improvement.matches(".*명확히\\s+(하\\s*(세요|십시오|야 합니다)|해\\s*(주세요|주십시오|야 합니다)).*") + || improvement.matches("^(추가|보완|수정).*(하세요|해주세요|해 주세요|하십시오|해주십시오|해 주십시오)\\.$"); } private QuestionAnalysisStatus normalizeStatus(String status) { diff --git a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java index 049758e..a6acfb5 100644 --- a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java +++ b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisServiceTest.java @@ -319,6 +319,44 @@ void analyzeNormalizesSpacedInstructionLikeImprovement() { assertThat(response.questions().get(0).analyses().get(0).improvement()).isEmpty(); } + @Test + @DisplayName("하십시오와 해주십시오 형태의 첨삭 지시문도 빈 값으로 저장한다") + void analyzeNormalizesFormalInstructionLikeImprovement() { + User user = saveUser("analysis-formal-instruction-improvement@example.com"); + MockApply mockApply = saveMockApply(user); + Question firstQuestion = saveQuestion(mockApply, "문제 해결 경험", "저는 로그를 확인했습니다."); + Question secondQuestion = saveQuestion(mockApply, "성과 경험", "저는 API 응답 속도를 개선했습니다."); + when(analysisAiClient.analyze(any(), any())).thenReturn(new AnalysisLlmResponse( + 64, + 70, + 55, + 67, + "격식체 지시문 검증입니다.", + List.of( + new AnalysisLlmResponse.QuestionAnalysisItem( + firstQuestion.getId(), + "저는 로그를 확인했습니다.", + "mentioned", + "성과가 부족합니다.", + "문장을 명확히 하십시오." + ), + new AnalysisLlmResponse.QuestionAnalysisItem( + secondQuestion.getId(), + "저는 API 응답 속도를 개선했습니다.", + "mentioned", + "성과 수치가 부족합니다.", + "수정해주십시오." + ) + ) + )); + + AnalysisResponse response = analysisService.analyze(user, mockApply.getId()); + + assertThat(response.questions()).hasSize(2); + assertThat(response.questions().get(0).analyses().get(0).improvement()).isEmpty(); + assertThat(response.questions().get(1).analyses().get(0).improvement()).isEmpty(); + } + @Test @DisplayName("재분석 시 기존 분석과 문항 분석을 새 결과로 교체한다") void analyzeReplacesExistingAnalysis() { From ebd881b0fb89030b88a9f742610c51d594b88e71 Mon Sep 17 00:00:00 2001 From: wooh Date: Tue, 26 May 2026 15:38:22 +0900 Subject: [PATCH 5/5] =?UTF-8?q?[Fix]=20=EB=A7=88=EC=B9=A8=ED=91=9C=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=EC=B2=A8=EC=82=AD=20=EC=A7=80=EC=8B=9C?= =?UTF-8?q?=EB=AC=B8=20=ED=95=84=ED=84=B0=EB=A7=81=20=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - improvement 지시문 정규식의 마침표 조건을 선택 처리 - 수정해주십시오 / 수정해주십시오. 형태 모두 필터링되도록 수정 --- .../jobdri_api/domain/analysis/service/AnalysisService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java index 91577bc..abd654b 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/AnalysisService.java @@ -242,7 +242,7 @@ private boolean isInstructionLikeImprovement(String improvement) { || improvement.endsWith("필요합니다.") || improvement.matches(".*[을를]\\s+(추가|보완|수정)하\\s*(세요|십시오).*") || improvement.matches(".*명확히\\s+(하\\s*(세요|십시오|야 합니다)|해\\s*(주세요|주십시오|야 합니다)).*") - || improvement.matches("^(추가|보완|수정).*(하세요|해주세요|해 주세요|하십시오|해주십시오|해 주십시오)\\.$"); + || improvement.matches("^(추가|보완|수정).*(하세요|해주세요|해 주세요|하십시오|해주십시오|해 주십시오)(\\.|$)"); } private QuestionAnalysisStatus normalizeStatus(String status) {