사업 공고 판정을 Claude 구독으로 자동화하기
회사에서 스마트공장 지원사업 공고를 챙겨야 할 일이 생겼다. 공고 사이트를 크롤링해서 신규 공고를 메일로 쏴주는 것까지는 사무실 서버에 만들어뒀다(이건 에이전트한테 시켰음). 그런데 받아보니 문제가 하나 있다. 공고 대부분이 도입기업, 그러니까 제조사를 모집하는 공고다. 우리는 소프트웨어를 공급하는 쪽이라 공고마다 이게 신청 가능한 건지, 영업 기회인지, 아예 해당없는 건지를 사람이 읽고 판단해야 했음. 이걸 AI한테 시키기로 했다.
왜 집 서버가 끼어드나
판정에 LLM API를 쓰면 돈이 나간다. 근데 Claude Code 구독에는 headless 모드가 있다. echo 프롬프트 | claude -p 하면 터미널에서 일회성 응답을 받을 수 있음. 구독은 이미 내고 있으니 추가 비용이 없다.
문제는 그 구독이 내 개인 서버에 있다는 거. 그래서 구조가 이렇게 됐다.
사무실 서버: 크롤링 → 큐에 쌓기 (pending/*.json)
집 서버: 30분마다 큐를 가져와 판정 → 메일 발송 → done/ 업로드
둘 사이는 WireGuard로 묶고 rsync로 파일만 주고받는다. DB도 API 서버도 없다. 파일큐면 충분함.
집 서버가 죽으면 메일이 안 오나?
이 구조의 약점은 집 서버다. 집 서버가 죽으면 판정이 안 되고, 판정이 안 되면 메일이 안 간다. 회사 업무가 내 취미 서버 가동률에 묶이는 건 좀 아니다.
그래서 계약을 하나 뒀다.
- 집 서버는 메일 발송에 성공한 경우에만 done/에 결과를 올린다
- 사무실 서버는 6시간 안에 done이 없으면 정규식으로 만든 기본 비고를 달아서 자기가 메일을 보낸다
즉 집 서버가 통째로 죽어도 알림 자체는 간다. AI 판정이라는 살만 빠지는 거임. 덕분에 집 서버 쪽은 마음 편하게 만들 수 있었다.
권한은 최소로
서버 두 대를 잇는 김에 권한 정리도 해뒀다.
- 사무실 서버에 접근하는 SSH 키는 rrsync로 큐 폴더만 rsync 되게 제한
- WireGuard AllowedIPs는 사무실 서버 IP 하나만
- n8n이 쓰는 SSH 키는 authorized_keys에서 restrict에 command 고정. 이 키로는 뭘 보내든 판정기만 실행된다. from=으로 도커 대역만 허용
키가 털려도 할 수 있는 게 판정기 실행뿐이면 털릴 걱정도 별로 없다.
n8n에서 호스트 명령 실행하기
스케줄러는 crontab에 걸어도 되는데, 자동화는 n8n 대시보드에서 한눈에 보고 싶었다. 근데 n8n이 도커 컨테이너라 Execute Command 노드가 컨테이너 안에서 돈다. 호스트의 파이썬 스크립트가 안 보임.
그래서 SSH 노드로 도커 게이트웨이를 통해 호스트에 되돌아 들어가게 했다. 컨테이너에서 호스트로 SSH를 치는 게 좀 웃기긴 한데, 위에서 말한 명령 고정 키라서 위험할 건 없다.
첫 실전에서 바로 죽음
세팅 끝내고 테스트도 다 통과한 상태였다. 사무실 쪽 큐를 켜고 실제 공고 5건이 처음 넘어왔는데, 판정이 죽었다.
원인은 PATH. claude가 ~/.local/bin에 있는데 SSH로 실행되는 비대화형 세션에는 그 PATH가 없다. 손으로 테스트할 땐 로그인 셸이라 잘 되고, n8n이 SSH로 돌리면 못 찾는 거였음. 절대경로로 바꾸고 env -i로 SSH랑 같은 환경을 재현해서 확인했다.
더 기분 나쁜 건 n8n이었다. 판정기가 exit 1로 죽었는데 SSH 노드는 실행을 success로 기록한다. 대시보드는 초록불인데 실제로는 죽어있었음. 원격 명령의 exit code를 안 보는 거다. 초록불을 믿으면 안된다...
그래도 위의 6시간 계약 덕분에 이 장애로 놓친 메일은 없다. 안전장치는 이럴 때 티가 난다.
판정 프롬프트
프롬프트에서 제일 중요했던 건 관점이었다. 그냥 신청 가능한지 판정하라고 하면 공고 대부분이 도입기업 모집이라 죄다 해당없음이 나온다. 회사 프로필 파일에 이걸 박아뒀다.
- 우리는 도입기업이 아니라 공급기업이다
- 공급기업 모집 공고 → 신청가능
- 도입기업 모집인데 일반 공모 → 우리한텐 영업 기회니까 검토필요
- 사전 선정된 기업만, 특정 대기업 협력사만 → 해당없음
이거 한 파일 넣고 안 넣고의 판정 품질 차이가 크다.
사실은...
공고 하루 몇 건 읽는게 자동화 만드는 것보다 빨랐을 수도 있다. 근데 이제 안 읽어도 된다.
마치며
구독 하나로 판정 봇이 하나 생겼다. 다음 공고부터는 메일만 열어보면 된다.