지난 4편에서 Qwen2.5 모델을 통해 이력서의 핵심 성과를 성공적으로 요약했습니다. 하지만 그래프를 그리기 위해서는 "성공적인 프로젝트 수행"이라는 말보다 "85점"이라는 **숫자(Score)**가 필요합니다. 오늘은 텍스트 데이터를 좌표값으로 변환하는 과정을 다뤄봅니다.
Antigravity 에이전트와 새 세션을 시작할 때는, 이전 단계의 결과물을 다시 알려주는 과정이 필요합니다. 저는 4편에서 AI가 출력했던 분석 결과 샘플을 에이전트에게 전달하며 질문을 던졌습니다.
지난번에 네가 분석해준 이력서 요약 결과가 아래와 같아
- **경력 항목**:
- 2021.03 - 2022.12: (주)레몬소프트 인턴 및 주임
- 활동 기간: 2021년부터 2022년까지
- 주요 성과: 파이썬 기반 레거시 시스템 리팩토링 및 API 성능 개선, Redis 캐싱 도입으로 데이터 조회 속도 25% 향상
- **경력 항목**:
- 2023.01 - 2025.02: 파인애플 테크놀로지 대리
- 활동 기간: 2023년부터 2025년까지
- 주요 성과: MSA 기반 결제 서비스 마이크로서비스 설계 및 구축, Kafka를 활용한 실시간 결제 로그 수집 파이프라인 개발
- 성공적인 활동: 클라우드 아키텍처 최적화 및 주니어 개발자 멘토링
- **경력 항목**:
- 현재: 스타트업 '오렌지랩' 백엔드 리드
- 활동 기간: 2025년까지
- 주요 성과: 클라우드 아키텍처 최적화 및 주니어 개발자 멘토링
- 성공적인 활동: 클래스 제안 및 프로그래밍 교육 제공
**총 경험**: [모든 경력 항목의 핵심 성과]
위와 같이 나온 요약된 내용을 기반으로 각 항목의 '성취도 점수(0~100)'를 매기는 파이썬 함수를 `utils.py`에 작성해줘. '설계', '최적화' 같은 핵심 키워드가 있거나 숫자로 된 성과(예: 25% 개선)가 있으면 가산점을 줬으면 좋겠어. 결과는 시각화하기 좋게 `{'year': 2023, 'score': 85}` 형태의 리스트로 반환해줘."
에이전트는 단순히 텍스트를 읽는 수준을 넘어, **정규표현식(Regex)**을 활용해 날짜 패턴을 분석하고 연도별로 점수를 매핑하는 꽤나 본격적인 로직을 제안했습니다. 특히 AI 요약문의 특징적인 구분자들을 기준으로 데이터를 쪼개는 방식이 인상적입니다.
import re
def calculate_achievement_scores(summary_text: str):
"""
이력서 요약 텍스트를 분석하여 연도별 성취도 점수를 계산합니다.
"""
# 1. 경력 항목별로 텍스트 분할 (AI 요약 형식 지원)
blocks = re.split(r'- \*\*경력 항목\*\*:|- 기간:', summary_text)
blocks = [b.strip() for b in blocks if b.strip()]
year_scores = {}
current_year = 2026 # 현재 시점 기준
# 가산점 키워드 설정
core_keywords = ['설계', '최적화', '구축', '아키텍처', '리팩토링', 'MSA', '파이프라인']
performance_keywords = ['성능 개선', '향상', '절감', '단축', '증가', '속도']
for block in blocks:
active_years = set()
# 패턴 1: 2021.03 - 2022.12 형태 추출
range_match = re.findall(r'(\d{4})\.\d{2}', block)
if len(range_match) >= 2:
start_y, end_y = int(range_match[0]), int(range_match[1])
for y in range(start_y, end_y + 1): active_years.add(y)
elif len(range_match) == 1:
# 패턴 2: 현재 진행형 경력 처리
if '현재' in block:
start_y = int(range_match[0])
for y in range(start_y, current_year + 1): active_years.add(y)
else:
active_years.add(int(range_match[0]))
else:
# 패턴 3: '2021년부터'와 같은 한글 표현 추출
year_mentions = re.findall(r'(\d{4})\ub144', block)
if year_mentions:
y_list = sorted(map(int, set(year_mentions)))
for y in range(y_list[0], y_list[-1] + 1): active_years.add(y)
if not active_years: continue
# 점수 계산 루틴 (기본 60점)
score = 60
for kw in core_keywords:
if kw in block: score += 10
for kw in performance_keywords:
if kw in block: score += 5
# 수치형 성과 가산점 (25%, 3배 등)
if re.search(r'\d+(?:\.\d+)?%', block) or re.search(r'\d+\s*\ubc30', block):
score += 15
score = min(max(score, 0), 100)
# 연도별 매핑 (중복 연도 발생 시 최고점 유지)
for y in active_years:
if y not in year_scores or score > year_scores[y]:
year_scores[y] = int(score)
results = [{'year': y, 'score': s} for y, s in year_scores.items()]
results.sort(key=lambda x: x['year'])
return results
이제 하드코딩된 텍스트가 아니라, analyzer.py의 AI 결과물이 utils.py로 막힘없이 흘러가는지 확인하기 위해 통합 테스트(utils-test.py)를 수행했습니다.
from analyzer import ResumeAnalyzer
from utils import calculate_achievement_scores
def run_integration_test():
# 1. 분석기 초기화
print("="*50)
print("ResumeAnalyzer 초기화 중...")
analyzer = ResumeAnalyzer()
print("모델 로드 완료!")
print("="*50)
# 2. 테스트용 Mock 데이터 (김철수 님)
# 이 데이터는 analyzer.py의 AI를 거쳐 요약 텍스트로 변환될 것입니다.
mock_resume_data = [
"김철수 | 백엔드 개발자",
"2021.03 - 2022.12: (주)망고소프트 인턴 및 주임",
"파이썬 기반 레거시 시스템 리팩토링 및 API 성능 개선",
"Redis 캐싱 도입으로 데이터 조회 속도 25% 향상",
"2023.01 - 2025.02: 파인애플 테크놀로지 대리",
"MSA 기반 결제 서비스 마이크로서비스 설계 및 구축",
"Kafka를 활용한 실시간 결제 로그 수집 파이프라인 개발",
"2025.03 - 현재: 스타트업 '오렌지랩' 백엔드 리드",
"클라우드 아키텍처 최적화 및 주니어 개발자 멘토링"
]
# 3. AI를 통한 요약 결과 추출 (analyzer.py)
print("\n[Step 1] AI 분석을 통해 이력서 요약을 생성합니다...\n")
try:
summary_result = analyzer.extract_achievements(mock_resume_data)
print("=== AI 요약 결과 ===")
print(summary_result)
print("-" * 30)
# 4. 요약 결과를 기반으로 성취도 점수 계산 (utils.py)
print("\n[Step 2] 요약된 텍스트에서 연도별 성취도 점수를 계산합니다...\n")
scoring_results = calculate_achievement_scores(summary_result)
print("=== 최종 성취도 분석 결과 ===")
for item in scoring_results:
print(f"연도: {item['year']} | 성취도 점수: {item['score']}")
print("\n데이터 구조 결과:", scoring_results)
except Exception as e:
print(f"테스트 진행 중 오류가 발생했습니다: {e}")
if __name__ == "__main__":
run_integration_test()
==================================================
ResumeAnalyzer 초기화 중...
Loading model on cpu...
Loading weights: 100%|█| 290/290 [00:00<00:00, 2851.96it/s, Materializing
모델 로드 완료!
==================================================
[Step 1] AI 분석을 통해 이력서 요약을 생성합니다...
=== AI 요약 결과 ===
- 기간: 2021.03 - 2022.12, 2023.01 - 2025.02
성과: 파이썬 기반 레거시 시스템 리팩토링 및 API 성능 개선, MSA 기반 결제 서비스 마이크로서비스 설계 및 구축, Kafka를 활용한 실시간 결제 로그 수집 파이프라인 개발
- 기간: 2025.03 - 현재
성과: 스타트업 '오렌지랩' 백엔드 리드, 클라우드 아키텍처 최적화 및 주니 어 개발자 멘토링
------------------------------
[Step 2] 요약된 텍스트에서 연도별 성취도 점수를 계산합니다...
=== 최종 성취도 분석 결과 ===
연도: 2021 | 성취도 점수: 100
연도: 2022 | 성취도 점수: 100
연도: 2025 | 성취도 점수: 80
연도: 2026 | 성취도 점수: 80
데이터 구조 결과: [{'year': 2021, 'score': 100}, {'year': 2022, 'score': 100}, {'year': 2025, 'score': 80}, {'year': 2026, 'score': 80}]
단순히 글을 요약하는 수준을 넘어, 당신의 2023년 성취도는 100점입니다라고 숫자로 말해줄 수 있는 엔진이 완성되었습니다.
정성적인 이력서 텍스트가 정량적인 데이터 좌표로 변하는 과정을 보며, 사이드 프로젝트의 기술적 뼈대가 단단해졌음을 느낍니다.
이제 이 숫자들을 시각화할 차례입니다. 다음 6편에서는 이 좌표들을 바탕으로 실제 '인생 그래프' 이미지를 그려내는 시각화 로직을 구현해 보겠습니다.