급여 변동사항 수집 자동화

[이전 편: 급여명세서 발송 자동화 완성기 ↑]

급여명세서 자동 발송을 완성한 후, 가장 번거로운 업무가 남아있었습니다.

"각 매장 담당자들한테 변동사항 물어보고, 정리해서 노무사한테 보내기"

매달 25일이면 시작되는 이 루틴:

  • 📧 각 매장에 "이번 달 변동사항 있나요?" 메일

  • 📱 답장 안 오면 카톡으로 재촉

  • 📝 제각각 형식으로 온 답장들 해석하기

  • 📊 엑셀에 정리해서 노무사 전달

왜 이게 어려웠냐면

담당자들이 보내는 답장이 이런 식이거든요:

"이미 종로점 파트타이머 신봉주 총20일+추가근무45분"
"최현규 연장근무 총 29.5시간 ( 1.5계산 ) 택시비 30,900원"
"이미 연남점 휴일근무 6월3일 정윤조"
"남구로 특이사항 없음"

자유롭게 써주니까 고마운데, 이걸 일일이 정리하는 게 귀찮은 일이죠.
물론 핵심은 담당자의 퇴사지만...

그래서 이것도 자동화했습니다

사용한 도구:

  • n8n (워크플로우 엔진)

  • Notion (데이터베이스)

  • Claude MCP (설계 도우미)

  • Basic LLM Chain (자연어 → 구조화 데이터)

워크플로우:

매월 25일 10시 → 점장/팀장들에게 자동 메일 발송
↓
자유 형식 이메일 회신 수집
↓
Basic LLM Chain으로 텍스트 파싱해서 구조화
↓
매장별로 자동 그룹핑 → Notion DB 저장
↓
28일 17시 → HTML 리포트 생성해서 노무사 전달

Basic LLM Chain을 선택한 이유

지난 스터디에서 khai님이 보여준 Basic LLM Chain을 적용해봤습니다.

해야 할 일이 명확했거든요:

  • Input: 자유 형식 텍스트

  • Output: JSON 구조화 데이터

  • 처리 과정: 단순하고 명료함

굳이 복잡한 AI Agent로 처리 시간을 오래 걸리게 할 필요 없이, 간단한 Chain 하나로 충분했습니다.

System Message Prompt 설계

가장 중요했던 건 정확한 System Message 작성이었습니다:

당신은 근무 시간 관리 전문가입니다. 복잡한 이메일에서 근무 내역을 JSON으로 추출하는 것이 임무입니다.

응답은 반드시 다음 형식의 JSON만 반환하세요:
{\"workRecords\": [{\"employee\": \"직원명\", \"workType\": \"근무유형\", \"hours\": 시간, \"days\": 일수, \"details\": \"상세내용\", \"store\": \"매장명\"}]}

추출 규칙:
1. 직원명 추출: 신봉주, 최현규, 전윤지, 이사랑, 원아연, 노현종, 정윤조 등
2. 매장명 추출: 종로점, 홍대점, 연남점, 남구로점 등
3. 근무 유형 분류:
   - 파트타이머 → 파트타이머 추가 근무
   - 연장근무, 추가근무 → 추가 근무
   - 휴일근무 → 휴일 근무
   - 기타수당, 택시비, 식대 → 기타 특이사항
4. 시간/일수 추출: 29.5시간, 20일, 8시간 등
5. 상세내용: 원본 텍스트 요약

예시 입력: '이미 종로점 파트타이머 신봉주 총20일+추가근무45분'
예시 출력: {\"employee\": \"신봉주\", \"workType\": \"파트타이머 추가 근무\", \"days\": 20, \"hours\": 0.75, \"details\": \"총20일+추가근무45분\", \"store\": \"종로점\"}

모든 필드는 문자열 또는 숫자여야 합니다. null, undefined 절대 금지!

결과 비교

처음 시도했을 때:

{
  "workRecords": [
    {
      "employee": undefined,
      "workType": undefined,
      "details": "20일 - undefined"
    }
  ]
}

직원명도 매장명도 다 undefined...

System Message 개선 후:

{
  "workRecords": [
    {
      "employee": "신봉주",
      "workType": "파트타이머 추가 근무", 
      "hours": 0.75,
      "days": 20,
      "details": "총20일+추가근무45분",
      "store": "종로점"
    },
    {
      "employee": "최현규",
      "workType": "추가 근무",
      "hours": 29.5,
      "details": "연장근무 총 29.5시간 택시비 30,900원",
      "store": "매장 미확인"
    }
  ]
}

13명의 복잡한 데이터를 13개 레코드로 완벽 분리 성공!

중간에 만난 기술적 문제들

1. JSON 파싱 에러 LLM이 생성한 JSON에 이스케이프 문자가 들어가서 오류 발생

// 해결: 이스케이프 문자 제거
content = content.replace(/\\\"/g, '"');

2. Gmail 노드 검색 옵션 search operation이 없어서 헤맸는데 getMany 안에 search 옵션이 있었습니다.

3. Notion DB 저장 시 속성 타입 오류 People 타입에 텍스트 넣어서 에러 → Rich Text로 변경해서 해결

노무사용 리포트도 브랜딩 적용

회사 CI 가이드에 맞춰서 전문적인 HTML 리포트를 만들었습니다.

브랜딩 요소:

  • 색상: Deep Brown (#3D2914) 계열

  • 폰트: Noto Sans KR

  • 로고: "IMI COFFEE" 강조

  • 카드형 레이아웃, 그라데이션 효과

최종 리포트 형태:

IMI COFFEE
2025년 7월 급여 변동사항 리포트

📅 보고 기간: 2025년 7월
📊 총 데이터 수: 4개
📧 담당자: 이미커피 관리팀

1. 종로점 근무 내역 (1건)
담당자: 종로점 담당자
[종로점] 근무 내역:
• 신봉주: 0.75시간20일 - 총20일+추가근무45분

2. 연남점 근무 내역 (2건)
담당자: 연남점 담당자
[연남점] 근무 내역:
• 정윤조: 8시간0일 - 6월3일 ( 8시간 기타수당 0.5 계산)
• 정윤조: 8시간0일 - 6월 6일 ( 8시간 기타수당 0.5 계산)

최종 완성된 자동화

이제 사람이 할 일:

  • 25일: 메일 확인 (자동 발송됨)

  • 28일: 리포트 확인 (자동 생성됨)

기존 vs 현재:

  • 기존: 매월 3-4시간 수작업

  • 현재: 월 10분 확인만

느낀 점

System Message 설계가 핵심이었습니다. 예외 케이스들을 하나씩 정의하고 명확한 규칙을 만드니까 13명 데이터를 완벽하게 분리해냈습니다.

복잡해 보이는 업무도 단계별로 쪼개면 다 됩니다.

물론 중간에 JSON 파싱 에러로 머리 아팠지만, 결국 차근차근 해결했습니다.

기계 학습 시스템의 프로세스를 보여주는 다이어그램

중국 웹 사이트의 스크린 샷

드디어 완성

A. 급여 변동사항 자동 수집 ✅
B. 급여명세서 자동 발송 ✅

이제 진짜로 급여 업무 완전 자동화 완성입니다.

다음 달부터는 거의 아무것도 안 해도 알아서 돌아가는 시스템이 갖춰졌습니다.

별걸 다 하는 요즘이지만, 이런 작은 자동화가 쌓이고 쌓이면 분명 큰 변화가 될 거라고 생각합니다.

그냥… 또 해봤다는 기록입니다. ☕

8
8개의 답글

뉴스레터 무료 구독