AI 채용 정보 추적 서비스에 매달 월 40달러를 지불하느라 지쳐서 Python으로 로컬 커맨드 센터를 직접 만들었습니다 (API 키 필요
요약
구직 활동을 자동화하고 개인 정보 보호 문제를 해결하기 위해 Python으로 로컬 커맨드 센터인 Remote Job Hunter (`rjh`)를 개발했습니다. 이 도구는 51개 이상의 채용 공고 출처를 병렬 스캔하며, API 키 없이도 작동하는 것이 특징입니다.
핵심 포인트
- Python 기반의 로컬 커맨드 센터로 구축됨.
- API 키나 클라우드 서비스 의존성이 없어 사적임.
- 51개 이상의 다양한 채용 정보 출처를 병렬 스캔함.
- ATS 안전한 1페이지 PDF 이력서 생성을 지원함.
최근 원격 근무(remote role) 자리를 찾아본 경험이 있다면, 그 루틴을 알고 있을 겁니다.
잠에서 깨어나 Ashby, Lever, Greenhouse, Remotive, Welcome to the Jungle, We Work Remotely, 그리고 매달 올라오는 Hacker News의 Who is Hiring 스레드까지 40개의 브라우저 탭을 열어봅니다. '원격'이라고 표시된 공고 중 절반은 네 번째 단락에서 비밀리에 '미국 거주자 한정 - 텍사스에 거주해야 함'이라는 문구를 담고 있습니다. 또 다른 3분의 1은 매주 화요일마다 재게시되는 유령(ghost) 채용 정보입니다.
이 과정을 자동화할 도구를 찾아봤을 때, 상업적인 'AI 잡 코파일럿(job copilot)'들은 모두 세 가지 공통된 문제를 가지고 있었습니다:
- 구직 활동을 하는 바로 그 순간에 또다시 $29~$49/월 구독료를 요구합니다.
- 이력서와 개인 데이터가 다른 사람의 클라우드에 저장됩니다.
- 이중 청구 함정: 오픈 소스 도구를 찾아보면, 거의 모두 유료 토큰당 과금 방식의 OpenAI 또는 Anthropic API 키를 요구합니다. 심지어 사용자가 이미 ChatGPT Plus, Claude Pro, 또는 Gemini 구독을 통해 월 $20을 지불하고 있음에도 불구하고 말입니다.
저는 로컬에서 빠르고 사적이며 작동하는 무언가를 원했습니다. 그래서 지난 몇 주 동안 **Remote Job Hunter (rjh)**를 구축하여 오픈 소스로 공개했습니다.

이 도구는 Python으로 작성된 로컬 커맨드 센터입니다 (핵심 엔진은 표준 라이브러리 사용 + FastAPI 및 SQLite WAL). 이 도구는 51개 이상의 채용 정보 출처를 병렬로 스캔하고, 모든 공고를 단일 profile.yaml과 비교하여 점수를 매기며, 회사별로 ATS(Applicant Tracking System) 안전한 1페이지 PDF 이력서를 생성합니다. 게다가 API 키가 없어도 작동한다는 것이 특징입니다.
방금 GitHub에 v0.2를 푸시했으며, 제가 v0.3을 더 좋게 만들기 위해 개발자와 구직자들의 테스트와 비판을 기다리고 있습니다.
모든 직업군(기술 또는 비기술, 원격 또는 현장 근무)을 위해 구축되었습니다
저장소 이름(remote-job-hunter)에도 불구하고, 이 엔진은 완전히 도메인에 구애받지 않습니다. 소프트웨어 엔지니어여야 한다고 가정하지 않으며, 원격 근무 역할만 찾도록 강요하지도 않습니다:
search: # 리옹의 간호사 (현장 근무)
titles: {primary: [infirmier, IDE]} # 헬스케어, 금융, 영업, HR 등...
work_mode: {remote: any, cities: [Lyon]} # 현장 근무, 하이브리드 또는 100% 원격
당신이 리옹의 간호사(profile.non-tech.example.yaml)인지, 파리의 회계사인지, 영업 관리자인지, 백엔드 엔지니어인지에 관계없이, PDF 이력서를 Command Center에 넣기만 하면 도메인별 기술을 자동으로 추출하고 검색 및 1페이지 ATS 이력서 생성기를 해당 분야에 맞춰 조정합니다.
1.
rjh scan은 설정된 모든 소스에서 채용 공고를 병렬로 가져와 빠르고 결정론적인 로컬 스코러(rjh/heuristic.py)를 실행합니다. 이 스코러는 직무명 일치 여부, 근무지 적합성(Europe,Global,US Restricted), 경력 수준, 언어, 그리고 사용자가 정의한 엄격 규칙을 검사합니다.- API 키(
Gemini,OpenAI,Anthropic,Groq,Mistral,OpenRouter) 또는 로컬Ollama모델이 있는 경우, 상위 후보들을 자동으로 평가합니다. - API 키가 없는 경우(또는 무료 할당량이
429에 도달한 경우), 자동으로 수동 모드(Manual Mode)로 전환됩니다. 사용자 인터페이스에서 **배치 내보내기(Export a batch)**를 클릭하고, 프롬프트를 이미 사용 중인 ChatGPT/Claude/Gemini 탭에 붙여넣은 다음, JSON 응답을 다시 붙여넣으면 됩니다.
잘린 채팅 응답 처리로 작업 손실 방지
웹 채팅창에 긴 프롬프트를 붙여넣어 본 사람이라면 누구나 주요 실패 모드를 알고 있습니다. 바로 모델이 3,800 토큰에서 생성을 중단하고 절반만 된 JSON 배열을 남기는 것입니다.
rjh/analysis.py의 파서는 JSONDecodeError로 실패하는 대신, 잘린 스트림에서 완성된 모든 JSON 객체를 복구(salvage)하여 즉시 SQLite에 점수를 저장하고, 누락된 직무 ID만 포함하는 후속 티켓을 생성합니다:
def salvage_json_objects(raw_text: str) -> list[dict]:
"""잘린 LLM 배열에서 모든 완전한 최상위 JSON 객체를 추출합니다."""
decoder = json.JSONDecoder()
...
아무것도 손실되지 않으며, 이미 점수가 매겨진 공고는 다시 실행할 필요가 없습니다.
2. 2단계 분류(Two-Stage Triage) + 작업 증명 아키텍처 다이어그램
초기에는 LLM에게 하나의 패스에서 직무를 평가하고 사용자 지정 피치까지 작성하도록 요청했습니다. 이는 느렸고, 평범한 역할에 토큰을 소모했으며, 일반적인 피치를 생성했습니다.
저는 파이프라인을 두 개의 뚜렷한 단계로 분리했습니다:
- Stage 1 (Fast Triage): 최대 20개의 사전 필터링된 채용 공고를 배치(batch) 단위로 평가합니다.
fit_score(0.0에서10.0)와 감지된 기술 스택, 그리고 1문장짜리 이유를 반환합니다. - Stage 2 (Deep Dossier for scores >= 7.5): 지원할 가치가 있는 역할에 한해서만 엔진이 다음을 생성합니다:
profile.yaml의 실제 지표(metrics)를 기반으로 작성된 3단락 맞춤형 피치(pitch).- 해당 회사의 스택에 대한 구체적인 기술 워크플로우를 제안하는 작업 증명(Proof-of-Work,
Mermaid.js) 아키텍처 다이어그램을 모달 내부에 직접 렌더링하여 면접 중에 설명할 수 있게 합니다. - 1클릭 LinkedIn X-Ray 검색 링크가 포함된 짧은 창립자/채용 관리자 DM(Direct Message).
3. ATS 이력서 문제 해결 (cv_tailor.py)
Workday, Taleo, Greenhouse, Lever 또는 Ashby에서 지원할 때, 사이드바, 진행 표시줄(progress bar), 플로팅 박스 등이 포함된 화려한 2단 구성의 이력서는 종종 읽기 어려운 텍스트 스트림으로 뒤섞입니다.
반면에, 일반적인 .txt 스타일의 이력서는 사람이 실제로 PDF를 열어보면 매우 보기 좋지 않습니다.
저는 이 두 가지 문제를 동시에 해결하기 위해 cv_tailor.py를 만들었습니다:
- 100% 단일 컬럼 선형 DOM 흐름 (
Header -> Summary -> Core Stack -> Experience -> Education)을 구현하여 레거시 및 최신 ATS 파서가 모든 줄을 정확한 순서로 읽게 합니다. - 편집 디자인 타이포그래피 (Newsreader 세리프 헤더 + Plus Jakarta Sans 본문)를 사용하여 A4 용지 1페이지에 엄격하게 맞춥니다.
- 환각(hallucination) 제로 규칙: 채용 공고에서 정확한 기술 키워드(
n8n,Python,PostgreSQL,HubSpot,REST APIs)를 추출하고, 기존의 글머리 기호(bullet points) 순서를 재배열하여 가장 관련성 높은 내용이 상단에 오도록 하며, 가지고 있지 않은 스킬이나 지표를 발명하지 않고 일치하는 용어만 굵게 표시합니다. - 내장된 7점 ATS 자체 감사: 생성되는 모든 PDF는 반환되기 전에
pypdf로 검사되어 점수(100/100, A4 1페이지 확인)를 받고, 1클릭 Playwright 양식 사전 채우기 기능과 자동으로 동기화됩니다.
4. 나만의
고백할 게 있습니다: 대시보드의 첫 번째 버전은 마치 1990년대 해커 영화 같았습니다. 모든 것이 네온 그린색, 대문자 고정폭 글꼴(monospace), 빛나는 텍스트 그림자, [어디에나 중괄호] 그리고 버튼마다 이모지로 가득했습니다.
이것을 사흘 동안 바라보고 나니 눈이 아팠습니다. 매일 아침 사용하는 도구가 비디오 게임의 HUD처럼 느껴져서는 안 됩니다.
저는 모든 네온 빛, 중괄호, 가짜 해커 용어를 제거하고, 차분한 Linear / Raycast / Editorial 미학을 중심으로 인터페이스를 재구축했습니다:
- 브라우저 View Transitions API의 원형 물결 효과로 **다크 모드(
#09090B)**와 **따뜻한 종이 라이트 모드(#FAF8F5)**를 전환할 수 있습니다. - UI 가독성을 위해 Plus Jakarta Sans, 편집 콘텐츠에 Newsreader, 그리고 점수, 카운터, 키보드 단축키(카드 탐색은
J/K, 상세 정보는Enter, 미리 채우기는A, 검색은/)에는 엄격하게 **JetBrains Mono (tabular-nums)**를 사용했습니다. - 마스코트(Noir Webling)와 배경의 상호작용하는 이중 레이어 HTML5 캔버스 거미줄은 유지하되, 보는 사람에게 부담이 적도록 은은한 시계 제작(horology)에서 영감을 받은 세공 장식으로 조정했으며, 이는 사용자가 검토 중인 직무 카드에 연결되는 탄성 실크 실로 표현했습니다.
60초 만에 사용해 보세요
전체 프로젝트는 MIT 라이선스가 적용되었으며 Linux, macOS, Windows에서 로컬로 실행됩니다 (Python 3.11+):
git clone https://github.com/manny-ruesch/remote-job-hunter.git
cd remote-job-hunter
pip install -e .
...
GitHub 저장소: [https://github.com/manny-ruesch/remote-job-hunter]
피드백이 필요합니다 (v0.2 버전을 망가뜨리는 것을 도와주세요!)
이것은 v0.2 릴리스이며, 저는 공허한 추측보다는 실제 사용 사례를 중심으로 로드맵을 만들고 싶습니다.
만약 3분 정도 시간을 내어 테스트해 주신다면, 댓글(또는 GitHub Issue)에 솔직한 피드백을 남겨주시면 정말 감사하겠습니다:
- 본인의 구직 활동에
rjh init을 시도해 보세요 (백엔드, DevOps, AI/자동화, 프론트엔드 또는 비기술 직무를 찾고 있든 상관없이). 휴리스틱 스코어러가 기대했던 방식으로 채용 공고를 순위 매겼나요, 아니면 노이즈가 많은 공고들이 걸러지지 않고 지나갔나요? - 일반 ChatGPT / Claude / Gemini 채팅을 사용하여 'Zero-API-Key 수동 모드'를 테스트해 보세요. 복사-붙여넣기 흐름이 원활했나요, 아니면 제가 제거해야 할 마찰 지점이 있나요?
- 실제 채용 공고에 '1페이지 ATS CV Tailor' 기능을 적용해 보세요. 생성된 PDF가 본인의 프로필과 잘 어울렸나요?
- 어떤 구인 게시판이나 지역별 소스가 빠져 있나요? 현재는 Greenhouse, Ashby, Lever, Welcome to the Jungle, Remotive, We Work Remotely, Jobicy, Adzuna, 그리고 Hacker News를 지원합니다. 매주 확인하는 다른 게시판이 있다면 알려주세요.
v0.3에서 해당 커넥터를 추가해 드리겠습니다.
이것이 유용하다고 생각되시면 **GitHub**에 별점을 주시는 것이 큰 도움이 되며, 아래 댓글에 남겨주신 모든 버그 보고나 비평은 다음 릴리스에 바로 반영됩니다!
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기