개발 실험실/공고 알림봇(SBNotifier)

공고 알림봇, 혼자 만든 기록 (9편) — LM Studio 로컬 LLM으로 수집 결과를 걸렀습니다

secondbranch 2026. 8. 5. 19:29

결론부터. 내 PC에서 도는 작은 언어 모델(LM Studio + Gemma)로 수집 결과를 1차 선별하면 공짜로 무제한 돌릴 수 있어요. 다만 모델이 꺼져 있으면 전부 조용히 탈락하니, 거절된 것까지 저장해두는 게 필수입니다.

8편까지 봇은 공고를 알아서 물어옵니다. 여기까지 오니 욕심이 생겼어요. 공고 말고 "이런 앱 있으면 좋겠다"는 사람들 글도 모아보자, 앱 아이디어 수요를요. 그런데 이 수집이 공고보다 훨씬 까다로웠습니다.

지난 편 → 8편 — 윈도우 작업 스케줄러로 파이썬 봇을 자동 실행했습니다

단어로는 문맥이 안 걸러졌어요

먼저 단어로 걸렀습니다. 없나요, wish there was, need an app 같은 표현이 든 글만 남기는 식이죠.

절반은 성공이었어요. 관계없는 글은 잘 빠집니다. 그런데 남은 것들이 이랬습니다.

  • 이미 있는 앱을 두고 불만을 말하는 글
  • "없나요"가 앱과 무관한 문맥에 쓰인 글
  • 그냥 잡담

단어는 문맥을 모릅니다. 없나요가 들어갔다고 앱 수요는 아니었어요.

유료 API 대신 내 PC를 썼어요

문맥 판단이니 언어 모델을 쓰면 됩니다. 그런데 여기서 계산이 필요했어요.

이 봇은 한 시간에 한 번씩, 무한히 돕니다. 걸러야 할 글이 하루 수십 건이고 소스를 더 붙일 생각이었어요. 유료 API를 붙이면 켜두는 것 자체가 비용이 됩니다.

그래서 내 PC 안에서 돌리기로 했어요. LM Studio를 띄우고 Gemma를 올렸습니다. 이러면 이렇게 갈립니다.

클라우드 API 로컬 LLM
비용 호출당 과금 0원
호출 한도 있음 없음
데이터 외부로 나감 내 PC 안
대신 PC가 켜져 있어야 함

LM Studio는 OpenAI와 같은 형식의 API를 열어줘요. 그래서 코드에서는 주소만 내 PC로 바꾼 셈이고, 나중에 클라우드로 옮기려면 주소만 다시 바꾸면 됩니다.

점수를 매기게 시켰어요

"이 글이 좋은가?"라고 물으면 답이 제각각으로 옵니다. 그래서 형식을 못 박았어요.

SCORE: [0-10]
SUMMARY: [한 줄 요약]

0

2점은 관계없음, 3

5점은 애매함, 6

8점은 분명한 수요, 9

10점은 강한 수요. 기준을 프롬프트에 적어주고 6점 이상만 알림으로 보냅니다.

점수를 쓴 이유는 임계값을 나중에 조절할 수 있어서예요. 알림이 많으면 7점으로 올리고, 적으면 5점으로 내리면 되죠. 판단 기준을 코드가 아니라 설정에 두는 겁니다.

실제로 얼마나 걸러졌나

두 달 반 돌린 결과입니다. 288건을 평가해서 61건만 통과했어요.

점수 건수 결과
9 27 ✅ 알림
8 22 ✅ 알림
7 11 ✅ 알림
6 1 ✅ 알림
5 0
4 6
3 2
0~2 143

눈에 띈 게 있어요. 3~5점이 여덟 건뿐입니다. 0

2점에 143건, 7

9점에 60건이 몰리고 중간이 텅 비었어요.

모델이 애매하게 답하지 않았다는 뜻이에요. "관계없음"과 "이건 진짜다"로 명확히 갈렸습니다. 걱정했던 "애매한 5점짜리가 잔뜩 와서 판단이 더 힘들어지는" 상황은 안 벌어졌어요.

조용한 실패 — 평가 자체가 안 된 76건

문제는 다른 데서 나왔습니다. 거절된 227건 중 76건은 점수가 아예 없었어요. 평가에 실패한 겁니다.

원인은 대체로 하나예요. LM Studio가 안 떠 있었습니다. PC를 켜도 LM Studio는 수동 실행이라, 그걸 잊으면 봇은 계속 돌지만 판단만 못 합니다.

이게 6편에서 겪은 것과 같은 종류의 함정이었어요. 평가에 실패하면 점수가 안 나오고, 점수가 없으면 임계값을 못 넘고, 결국 조용히 탈락합니다. 에러도 안 나고 알림도 안 와요.

떨어진 것도 버리지 않았어요

이걸 알고 나서 넣은 게 있어요. 탈락한 것도 전부 파일로 남깁니다.

data/raw/2026-08-03.jsonl.gz   ← 날짜별로 압축 저장

지금 36개 파일에 227건이 들어 있어요. 압축해서 넣으니 다 합쳐도 몇십 KB입니다.

덕분에 두 가지가 가능해져요.

  • 모델이 꺼져서 놓친 것을 나중에 다시 평가할 수 있어요
  • 판단 기준이 맞았는지 되짚을 수 있어요. 0점 받은 글을 열어 "이건 걸렀어야 했나?" 확인하는 거죠

버리지 않고 옆으로 치워두는 것이 핵심이었어요. 자동 판단을 붙일 땐 그 판단이 틀렸을 경우를 대비해둬야 합니다.

응답이 텅 빈 채로 왔어요

Gemma를 붙이면서 한참 헤맨 게 있어요. 응답은 오는데 내용이 비어 있었습니다.

원인은 이 모델이 추론 과정을 먼저 쓰는 종류라서였어요. 출력 길이 제한을 걸어두면, 추론하다가 그 한도를 다 쓰고 정작 답변 자리가 안 남습니다.

해결은 길이 제한을 아예 안 거는 것이었어요. 값을 크게 늘리는 게 아니라 그 항목을 요청에서 빼버렸습니다. 그리고 응답에서 추론 부분은 무시하고 최종 답변만 읽게 했죠.

문서를 아무리 봐도 안 나오는 종류의 문제예요. 3편에서 말한 것과 같아요 — 결국 실제로 던져보고 돌아온 걸 봐야 알게 됩니다.

마무리 — 판단을 붙일 때 필요한 것

이 편에서 배운 걸 세 줄로 줄이면 이래요.

  • 비용이 0이면 판단을 아낄 필요가 없다. 무한히 도는 봇엔 이게 결정적이었어요
  • 자동 판단은 조용히 실패한다. 틀린 판단은 눈에 띄는데, 판단을 못 한 건 안 띕니다
  • 떨어진 것을 남겨둬야 판단을 고칠 수 있다. 버리면 되돌릴 방법이 없어요

지금은 아침에 PC를 켤 때 LM Studio도 같이 띄우는 게 습관이 됐어요. 근본 해결은 아니지만, 놓친 것들이 파일에 남아 있으니 급하지 않습니다.

다음 편

붙여둔 소스 하나가 갑자기 아무것도 안 가져오기 시작했어요. 코드는 그대로인데요. 상대방이 문을 닫은 것이었습니다. → 10편 — Reddit이 API를 막아서 RSS로 우회했습니다