채용 편향에 맞서기 위해 '블라인드' AI 이력서 스크리너를 구축한 방법과 그 과정에서 AWS를 통해 배운 점
요약
채용 과정의 무의식적 편향을 제거하기 위해 CrewAI와 GPT-4o를 활용한 '블라인드' 이력서 스크리너 구축 사례를 소개합니다. 개인정보 비식별화와 에이전트 기반의 기술 역량 평가 파이프라인을 AWS 인프라 위에서 구현하는 과정을 다룹니다.
핵심 포인트
- LLM을 활용한 PII(개인정보) 자동 비식별화로 채용 공정성 확보
- CrewAI를 이용한 기술 매칭 및 면접 질문 생성 에이전트 오케스트레이션
- AWS DynamoDB와 SES를 활용한 이벤트 기반의 자동화된 결과 처리
- 실제 프로덕션 환경 적용을 통한 에이전트형 AI 구축 경험 공유
Agentic AI (에이전트형 AI), 클라우드 인프라, 그리고 그 어떤 튜토리얼에서도 다루지 않는 복잡한 세부 사항들을 다루는 실제 여정.
우리는 채용을 변화시킬 AI의 잠재력에 대해 많이 이야기합니다. 하지만 책임감이 없는 잠재력은 그저 과대광고(hype)일 뿐입니다. 채용 과정에서의 무의식적 편향(Unconscious bias)은 잘 알려진 문제이며, 이는 첫 면접이 시작되기 훨씬 전, 채용 담당자가 이력서를 훑어보는 첫 30초 만에 시작됩니다.
그래서 저는 이를 해결하기 위한 무언가를 만들었습니다.
이것은 CrewAI, OpenAI의 GPT-4o, 그리고 AWS를 사용하여 AI 기반의 '블라인드(Blind)' 이력서 스크리너(Resume Screener)를 설계한 이야기이자, 이를 프로덕션(production) 환경에 적용하며 배운 실제 교훈에 대한 이야기입니다.
문제점: 대화가 시작되기도 전에 편향이 스며든다
이름, 이메일 주소, 학교, 우편번호 — 이러한 데이터 포인트들은 후보자가 직무를 수행할 수 있는지 여부와 아무런 관련이 없습니다. 그럼에도 불구하고 연구 결과에 따르면 이러한 요소들이 채용 결정에 지속적으로 영향을 미친다는 것이 일관되게 나타납니다. '백인처럼 들리는' 이름을 가진 이력서는 '흑인처럼 들리는' 이름을 가진 동일한 이력서보다 더 많은 콜백(callback)을 받습니다. Gmail 주소는 .edu 주소와 다르게 읽힙니다.
더 공정한 채용을 원한다면, 어떤 사람(또는 AI 평가자)이 문서를 보기 전에 방정식에서 이러한 신호를 제거해야 합니다.
아키텍처: 작동 방식
1단계 — LLM을 통한 PII(개인정보) 비식별화
어떠한 평가가 이루어지기 전에, 시스템은 원문 이력서 텍스트를 LLM(대규모 언어 모델) 기반의 비식별화(redaction) 레이어를 통과시킵니다. 시스템은 다음 항목을 자동으로 식별하고 제거합니다:
이름 (이름, 성, 전체 이름)
이메일 주소
물리적 주소 및 우편번호
전화번호
그 결과, 평가자(사람 또는 AI)가 오직 익명화된 깨끗한 문서만을 바탕으로 상호작용하게 됩니다.
2단계 — CrewAI를 이용한 에이전트형(Agentic) 평가
이 부분이 흥미로운 지점입니다. 저는 CrewAI를 사용하여 두 개의 에이전트 파이프라인(pipeline)을 오케스트레이션(orchestrate)했습니다:
기술 역량 매칭 담당(Technical Skill Matcher) — 비식별화된 이력서를 직무 요구 사항과 비교하여 기술, 도구 및 경험 영역 전반에 걸친 일치도를 점수화합니다.
기술 면접관(Technical Interviewer) — 마치 1차 스크리닝을 준비하는 것처럼, 순수하게 기술적 콘텐츠만을 기반으로 타겟팅된 후속 질문을 생성합니다.
이 에이전트들은 순차적으로 실행되며, 각 에이전트가 다음 에이전트에게 컨텍스트 (Context)를 전달하여 구조화된 평가 보고서를 생성합니다. 이 모든 과정은 지원자가 누구인지 전혀 알지 못하는 상태에서 이루어집니다.
3단계 - 클라우드 스토리지 (Cloud Storage) 및 알림 (Notifications)
평가가 완료되면:
- 결과는 CandidateID를 키(Key)로 하여 AWS DynamoDB의 CandidateScores 테이블에 아카이브됩니다.
- 처리가 완료되는 즉시 Amazon SES를 통해 채용 팀에 요약 이메일이 발송됩니다.
전체 파이프라인은 이벤트 기반 (Event-driven)으로 작동합니다. 이력서를 제출하기만 하면, 구조화된 평가 보고서가 편지함으로 들어옵니다. 수동 작업은 전혀 필요 없습니다.
기술 스택 (The Tech Stack)
AI 에이전트 애플리케이션 (AI Agent Application)
│
├── 에이전트 오케스트레이션 (Agent Orchestration)
│ ├── CrewAI
│ └── LangChain
│
├── 대규모 언어 모델 (LLM)
│ └── OpenAI GPT-4o
│
├── 클라우드 스토리지 (Cloud Storage)
│ └── AWS DynamoDB
│
├── 알림 (Notifications)
│ └── Amazon SES
│
├── 보안 (Security)
│ └── AWS IAM
│ └── 커스텀 인라인 정책 (Custom Inline Policies)
│
└── 프로그래밍 언어 (Programming Language)
└── Python
└── Boto3 SDK
배운 점 - 튜토리얼에서는 다루지 않는 것들
1. 전략적 LLM 피보팅 (Pivoting): 왜 AWS Bedrock을 떠났는가
원래 저는 개인정보 (PII) 추출 레이어에 AWS Bedrock을 사용할 계획이었습니다. 이론적으로는 타당했습니다. 모든 것을 AWS 생태계 내에 유지하고, IAM을 단순화하며, 외부 의존성을 줄일 수 있기 때문입니다.
하지만 실제로 구현해보니, 제가 목표로 하는 리전 (Region)에서의 모델 가용성 제한 문제와 익명화 (Redaction) 단계를 크게 늦추는 지연 시간 (Latency) 문제에 부딪혔습니다. 벤치마킹을 거친 후, 추출 작업을 위해 OpenAI의 gpt-4o-mini로 피보팅하였고, 그 차이는 즉각적이었습니다. 더 빠른 응답, 더 깔끔한 익명화 결과물, 그리고 지역적 제한이 없었습니다.
교훈: 하나의 벤더 생태계에 머무는 것에 대해 독단적이지 마세요. 작업에 적합한 도구가 바로 올바른 도구입니다.
2. IAM: "전체 액세스 (Full Access)"를 넘어서
AWS를 배울 때 가장 쉬운 방법은 *FullAccess 정책을 연결하고 넘어가는 것입니다. 저 역시 그렇게 시작했습니다.
하지만 실제 배포에 가까워지면서, 최소 권한 원칙 (Principle of Least Privilege)을 사용하여 IAM 정책을 처음부터 다시 구축했습니다. 이제 제 에이전트의 실행 역할 (Execution Role)은 오직 다음과 같은 권한만 부여합니다:
특정 CandidateScores 테이블에 대한 dynamodb:PutItem 및 dynamodb:GetItem 권한
verified sender identity(인증된 발신자 ID)로부터의 ses:SendEmail 권한
그게 전부입니다. IAM 콘솔에서 커스텀 인라인 JSON 정책 (custom inline JSON policies)을 작성하는 것이 처음에는 지루하게 느껴졌지만, 덕분에 제 시스템에 정확히 무엇이 필요한지, 그리고 그 이상의 것은 필요하지 않다는 점을 확실히 이해할 수 있었습니다. 후보자 데이터를 다루는 실제 운영 환경 (production environment)에서 이는 선택 사항이 아닙니다. 이는 기본 중의 기본입니다.
3. DNS 및 리전 설정: gaierror이라는 함정
이 문제로 오후 시간의 대부분을 허비했습니다.
AWS 서비스 엔드포인트 (service endpoints)에 접속하려고 할 때, 제 로컬 Python 환경에서 계속해서 gaierror(소켓 수준의 DNS resolution 실패)가 발생했습니다. 근본 원인은 리전 불일치 (regional mismatch)였습니다. 제 boto3 클라이언트는 특정 리전으로 초기화되었는데, 환경 변수 (environment variables)는 다른 리전을 가리키고 있었습니다.
지나고 보니 해결책은 명확해 보입니다. 모든 계층에 걸쳐 리전 설정을 표준화하는 것입니다. 하나의 리전을 선택하여 .env 파일에 설정하고, 모든 boto3 클라이언트 인스턴스화 (instantiation) 시 해당 환경 변수를 읽어오거나 일관되게 하드코딩되도록 해야 합니다.
특히 SES의 경우 추가적인 주의 사항이 있습니다. 이메일 인증은 대소문자를 구분하며 샌드박스 범위 (sandbox-scoped) 내에서 이루어집니다. 샌드박스 모드에서는 발신자와 수신자 주소 모두 개별적으로 인증되어야 합니다. 또한 Say2Name@gmail.com은 say2name@gmail.com과 동일한 ID가 아닙니다. 콘솔에서는 메시지를 수락하겠지만, AWS는 조용히 전송에 실패할 것이며, 당신은 무엇이 잘못되었는지 고민하며 한 시간을 보내게 될 것입니다.
스팸 폴더를 확인하세요. 인증 상태를 확인하세요. 대소문자를 확인하세요.
이 프로젝트가 실제로 저에게 가르쳐준 것
이 엔드투엔드 (end-to-end) 시스템을 구축하면서, 저는 AI와 클라우드 인프라 (cloud infrastructure)를 별개의 분야로 생각하는 것을 멈춰야 했습니다. 에이전트 로직 (agent logic)의 신뢰성은 그 아래에서 실행되는 인프라만큼만 신뢰할 수 있습니다. IAM 정책은 에이전트가 실제로 할 수 있는 일을 결정합니다. 리전 설정 오류 (regional misconfigurations)는 코드상으로는 완벽해 보이는 워크플로 (workflows)를 망가뜨립니다.
더 중요한 점은, 책임감 있는 AI (responsible AI) 시스템을 구축하는 것은 유능한 시스템을 구축하는 것보다 더 의도적인 설계 (deliberate design)를 요구한다는 것입니다. 개인정보 (PII) 삭제 단계는 파이프라인 (pipeline)을 더 똑똑하게 만드는 것이 아니라, 더 공정하게 만듭니다. 이는 서로 다른 최적화 목표 (optimization target)이며, 명시적인 아키텍처 선택 (architectural choices)을 필요로 합니다.
다음 단계 (What's Next)
제가 적극적으로 탐색하고 있는 몇 가지 방향은 다음과 같습니다:
편향 감사 레이어 (Bias audit layer) - 일련의 후보자 그룹 전체에서 점수 분포가 인구통계학적 왜곡 (demographic skew)을 보이는지 확인하기 위한 사후 평가 분석 (post-evaluation analysis)
구조화된 출력 스키마 (Structured output schemas) - 자유 형식의 텍스트 평가 보고서에서 하위 ATS (Applicant Tracking System) 통합을 위한 JSON 스키마 검증 출력 (JSON-schema-validated outputs)으로 전환
멀티 모델 평가 (Multi-model evaluation) - 서로 다른 LLM (Large Language Models)을 통해 병렬 평가를 수행하고 점수 일관성 (scoring consistency)을 비교
직접 시도해 보세요 (Try It Yourself)
전체 코드베이스는 GitHub에서 확인할 수 있습니다: https://lnkd.in/dMJ-8aAH
만약 여러분이 책임감 있는 AI 애플리케이션을 작업 중이거나 AWS에서 에이전트 시스템 (agentic systems)을 구축하고 있다면, 여러분이 무엇을 만들고 있는지 듣고 싶습니다. 댓글을 남기거나 일촌을 맺어주세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기