Skip to content

dongwoo46/HireLog

Repository files navigation

HireLog (채용로그)

HireLog는 채용 공고(Job Description, JD)를 AI로 분석·정리하고,
그 결과를 시간 흐름에 따라 기록(Log)으로 남기는 채용 정보 관리 시스템이다.

채용 공고를 단순히 읽고 지나가는 정보가 아니라,
분석 가능한 데이터이자 기록해야 할 이력으로 다룬다.


1. 왜 HireLog를 만들었는가

채용 준비를 하면서 가장 반복적으로 하게 되는 작업은
채용 공고를 찾고, 읽고, 분석하는 일이다.

하지만 이 과정은 항상 같은 문제를 반복한다.

  • 채용 공고는 여러 플랫폼에 흩어져 있고
  • 공고마다 표현 방식이 다르며
  • 요구사항은 명확하지 않고
  • 한 번 분석한 내용은 기록으로 남지 않는다

결국 채용 공고를 볼 때마다 다음 과정을 다시 반복하게 된다.

  • 요구사항을 다시 읽고
  • 기술 스택을 다시 정리하고
  • 이전 공고와 머릿속으로만 비교하며
  • 분석 결과는 대화나 메모 속에서 사라진다

이 과정은 분석이 아니라 반복 노동에 가깝다.

HireLog는 이 반복을 줄이기 위해 시작되었다.

“채용 공고를 매번 새로 분석하지 말고,
한 번 분석한 결과를 기록으로 남길 수 없을까?”


2. 기존 채용 서비스의 한계

현재 대부분의 채용 플랫폼은 다음 역할에 집중한다.

  • 채용 공고 모아보기
  • 검색 및 필터
  • 지원 버튼 제공

하지만 이들은 공통적으로 다음을 제공하지 않는다.

  • 채용 공고의 요구사항 구조화
  • 과거 공고와의 비교
  • 회사/직무별 채용 기준 변화 추적
  • 개인이 분석한 내용을 축적·관리하는 기능

즉, 채용 공고는 여전히
**“읽고 지나가는 정보”**로만 취급된다.

HireLog는 이 관점을 바꾼다.


3. HireLog의 핵심 개념

채용 공고는 데이터다

채용 공고에는 다음과 같은 정보가 담겨 있다.

  • 기업이 필요로 하는 기술
  • 요구하는 경험 수준
  • 협업 방식과 조직 문화
  • 암시적인 운영·책임 요구

이 정보는 단발성이 아니라
시간에 따라 변하는 시장 신호다.

HireLog는 채용 공고를 단순 텍스트가 아니라
분석 가능한 데이터 스냅샷으로 취급한다.


4. HireLog를 만들게 된 또 하나의 이유

혼자가 아니라, 함께 기록하기 위해

HireLog는 혼자 채용 공고를 정리하기 위한 도구이기도 하지만,
여러 사람이 함께 채용 공고를 기록하고 축적할 수 있다면 더 큰 가치가 생긴다는 문제의식에서 출발했다.

채용 공고는 개인이 보는 순간에는 단순한 지원 정보처럼 보이지만,
여러 사람이 같은 시기에 수집한 공고들이 모이면
그 자체로 시장과 기업의 상태를 보여주는 데이터가 된다.

혼자 공고를 모으는 것에는 분명한 한계가 있다.

  • 내가 관심 있는 회사와 직무에만 편중되고
  • 모든 공고를 직접 찾기 어렵고
  • 놓치는 정보가 많아진다

반면, 여러 사람이 채용 공고를 기록하고 공유하면
한 개인이 수집하는 것보다 훨씬 넓은 범위의 채용 정보를 다룰 수 있다.

HireLog는 이러한 집단적 기록의 가능성을 염두에 두고 설계되었다.


5. 채용 공고를 통해 알고 싶은 것은 무엇인가

채용 공고는 단순히 “사람을 뽑는다”는 안내문이 아니다.

채용 공고에는 다음과 같은 정보가 담겨 있다.

  • 현재 회사가 어떤 문제를 겪고 있는지
  • 어떤 영역에서 병목이 발생하고 있는지
  • 어떤 역할이 부족해졌는지
  • 그 문제를 해결할 사람을 어떤 기준으로 찾고 있는지

즉, 채용 공고는
회사가 현재 직면한 문제의 결과물이다.

예를 들어,

  • 운영 경험을 강조한다면 → 시스템 안정성 문제가 있었을 가능성
  • 특정 기술을 새로 요구한다면 → 기술 전환 또는 확장 단계
  • 협업과 커뮤니케이션을 반복 강조한다면 → 조직적 문제가 있었을 가능성

이러한 신호는 채용 공고를 단순히 “지원용 텍스트”로 읽으면 보이지 않지만,
요구사항을 분리하고 구조화하면
회사 내부 상황을 추론할 수 있는 단서가 된다.


6. 왜 자동화가 필요한가

이러한 분석은 사람이 직접 하면 가능하지만,
문제는 매번 같은 과정을 반복해야 한다는 점이다.

  • 채용 공고를 읽고
  • 요구사항을 나누고
  • 숨은 의도를 추론하고
  • 다시 정리하는 작업을

모든 공고마다 사람이 반복하는 것은
시간과 에너지가 지나치게 많이 든다.

그래서 대부분은:

  • 대충 훑어보고 넘기거나
  • ChatGPT에 복사해 한 번 분석하고 끝내거나
  • 분석 결과를 다시 찾지 못하게 된다

HireLog는 이 반복을 사람이 아닌
시스템이 대신하도록 만들기 위해 시작되었다.

한 번 분석한 채용 공고는 다시 분석하지 않아도 되도록,
그리고 그 결과가 개인의 기억이 아니라
데이터로 남도록 하기 위해서다.


7. HireLog는 무엇을 하는가

HireLog는 다음 흐름으로 동작한다.

  1. 채용 공고 URL 또는 텍스트 입력
  2. AI를 통해 공고 내용 분석
  3. 요구사항을 구조화된 형태로 정리
  4. 결과를 데이터베이스에 영구 저장
  5. 이후 검색, 비교, 히스토리 조회 가능

이를 통해 채용 공고를:

  • 다시 읽을 필요 없이
  • 다시 분석할 필요 없이
  • 다시 찾을 필요 없이

기록(Log)으로 재사용할 수 있다.


8. HireLog의 설계 원칙

  • 데이터 우선
    분석 결과는 반드시 저장된다.

  • 기록 중심
    채용 공고는 수정되지 않는 스냅샷으로 관리된다.

  • 확장 가능성
    초기에는 개인 도구로 시작하지만,
    다양한 직무와 분석 방식으로 확장 가능하도록 설계한다.

  • 실사용 기반
    실제 채용 준비 과정에서 반복적으로 사용되는 흐름을 기준으로 만든다.


9. 한 문장으로 요약하면

HireLog는
채용 공고를 AI로 분석해 구조화하고,
그 결과를 시간 흐름에 따라 기록함으로써
기업과 시장의 상태를 읽어낼 수 있게 하는
채용 로그 시스템이다.


10. 시스템 아키텍처

hirelog-web (React / TypeScript)
  │
  ▼  REST API
hirelog-api (Spring Boot / Kotlin)
  │  Outbox Pattern
  ▼
Debezium → Kafka
  │
  ▼
preprocess-pipeline (Python)
  ├── URL Worker   — HTML 크롤링 + 플랫폼별 전처리
  ├── TEXT Worker  — 직접 입력 텍스트 전처리
  └── OCR Worker   — 이미지 텍스트 전처리
  │
  ▼  Kafka response
hirelog-api consumer
  ├── LLM 요약 (Claude API)
  └── OpenSearch 인덱싱

전처리 파이프라인을 API와 비동기로 분리한 이유는 세 가지다.

  • 크롤링 + JS 렌더링 + LLM 호출은 수 초가 걸릴 수 있다. API 레이턴시에 영향을 주지 않으려면 응답과 처리를 분리해야 한다.
  • 전처리 실패 시 Kafka offset 관리로 재처리가 가능하다.
  • URL / TEXT / OCR 워커를 독립적으로 스케일할 수 있다.

11. 핵심 구현

3-track 전처리 파이프라인

채용 공고는 URL, 직접 입력(TEXT), 이미지(OCR) 세 경로로 입력된다. 경로마다 전처리 과정이 다르지만 최종 출력은 동일한 canonical_map으로 정규화된다.

# 모든 파이프라인의 공통 출력 구조
{
  "responsibilities": [...],  # 주요업무
  "requirements":    [...],  # 자격요건
  "preferred":       [...],  # 우대사항
  "process":         [...],  # 채용절차
  "company":         [...],  # 회사소개
  "benefits":        [...],  # 복지
  "skills":          [...],  # 기술스택
  "experience":      [...],  # 경력
  "others":          [...],  # 미분류
}

URL 파이프라인은 가장 복잡하다.
정적 크롤링 → JS 렌더링(Playwright) fallback → HTML 파싱 → 노이즈 제거 → 섹션 추출 → semantic zone 태깅 → canonical 정규화 순으로 처리된다.


플랫폼별 전처리 분리 (Strategy Pattern)

처음에는 모든 플랫폼을 단일 전처리 로직으로 처리했다.
리멤버(remember.co.kr) 파싱을 개선하는 과정에서 원티드(wanted.co.kr) 섹션 분리가 깨지는 회귀가 발생했다.

원인은 플랫폼마다 HTML 구조가 근본적으로 다르다는 점이었다.

항목 원티드 리멤버
연속 섹션 헤더 5개 실제 섹션 헤더 → 보존 탭 내비게이션 → 전체 제거
헤더 keyword 중복 중복 제거 불필요 탭 nav + 본문 중복으로 제거 필수
고유 UI 노이즈 채용중인 포지션, 연봉상위 합격 보상금, 현직자에게

단일 휴리스틱으로는 커버가 불가능하다고 판단해 전처리 전략을 플랫폼별로 분리했다.

preprocess-pipeline/src/url/platforms/
  ├── wanted.py    — 원티드 전용 전처리 전략
  ├── remember.py  — 리멤버 전용 전처리 전략
  └── generic.py   — 기본 전략 (기타 플랫폼)

platform 필드를 Kafka 메시지에 추가하고 Spring → Python 전체 스택에 전파했다.
신규 플랫폼 추가 시 platforms/ 아래 파일 하나만 추가하면 된다.


섹션 추출 정확도 문제 해결

채용 공고 텍스트에서 섹션을 정확히 추출하는 것이 파이프라인의 핵심 난관이다.
단순 키워드 매칭만으로는 오탐이 발생한다.

오탐 사례: [MissionoftheRole] → "role"(4자) 부분일치 → 가짜 섹션 생성
→ 대괄호 구문 + 키워드 길이 < 6 + 부분일치 조합은 skip 처리. URL/TEXT/OCR 파이프라인 모두 적용.

추출 후에는 3가지 후보정 규칙을 적용한다.

  1. intro 흡수 — 첫 keyword-match 섹션 이전의 미매칭 헤더를 __intro__로 처리 (coverage ≥ 40% 조건으로 오탐 방지)
  2. 빈 header 병합 — content가 없는 header는 다음 섹션 내용을 흡수 (연속 체인 처리 가능)
  3. 푸터 노이즈 제거 — 마지막 섹션 끝 연속 짧은 라인(≤15자, 2개 이상) 제거

채용 단계 이력 관리

지원한 공고에 대해 채용 단계와 합불 결과를 기록한다.

enum class HiringStageResult { PASSED, FAILED, PENDING }

class HiringStageRecord(
    val stage: HiringStage,
    var note: String,
    var result: HiringStageResult? = null,
    var recordedAt: LocalDateTime
)

초기에는 PATCH(수정)에서만 result를 저장할 수 있고, POST(신규 추가) 시에는 result를 전달하지 못하는 버그가 있었다. AddStageReqresult 필드를 추가하고 도메인 레이어까지 전파해 수정했다.


12. 기술 스택

레이어 기술
Backend Spring Boot, Kotlin, JPA
Messaging Apache Kafka, Debezium (Outbox Pattern)
Search OpenSearch
AI Claude API
Frontend React, TypeScript
Pipeline Python, Playwright, BeautifulSoup
Infra Docker

About

HireLog는 채용 공고를 AI로 구조화해 저장하고, 기업의 채용 기준 변화를 추적할 수 있게 해주는 도구

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors