여러 주소의 메일을 Gmail로 모으고, 분류는 맥미니에서 학습시킨 Laya에 맡겼습니다
주소마다 다르게 모이던 메일
여러 주소로 받는 메일을 Gmail 한 곳에서 보고 있었습니다. 다음 메일은 Gmail이 POP으로 가져왔고, 학교 메일과 iCloud는 자동 전달했습니다. 개인 도메인으로 온 메일은 Cloudflare가 Gmail로 넘겼습니다. Gmail은 원래 받은 주소에 따라 라벨을 붙였습니다.
모인 메일은 Gmail 웹과 맥, iPad, iPhone의 메일 앱에서 확인했습니다. 도착지는 하나였지만 모이는 방식은 주소마다 달랐습니다. 이번에 AI 에이전트와 함께 이 구조를 다시 정리했습니다.
POP 가져오기 대신 맥미니 스크립트
Gmail의 “다른 계정의 메일 확인하기” 기능은 POP으로 외부 메일을 가져옵니다. Google은 이 기능의 서드 파티 계정 POP 지원을 2027년 1월에 종료한다고 안내했습니다. 대신 원래 메일 서비스에서 Gmail로 자동 전달하라고 권합니다.
다음 메일에는 그 대안이 없습니다. 다음 고객센터에도 자동 전달 기능을 제공하지 않는다고 명시되어 있습니다. 그래서 맥미니에서 스크립트가 다음 메일을 IMAP으로 읽고 Gmail에 넣도록 바꿨습니다.
POP과 스크립트를 함께 돌리지는 않았습니다. 에이전트는 두 방식이 같은 메일을 가져오면 중복될 수 있고, POP이 먼저 원본을 지우면 스크립트가 메일을 보지 못할 수 있다고 짚었습니다. 스크립트를 먼저 검증한 뒤 POP 설정을 지우고 스크립트를 켰습니다.
받은편지함에 남길 메일
수집 방식을 바꾸는 일은 메일을 어디에 남길지 정하는 일로 이어졌습니다. POP은 다음 메일을 가져가면서 원본을 지웠지만 새 스크립트는 다르게 동작합니다. 다음 쪽 원본은 지우거나 읽음으로 바꾸지 않습니다. Gmail에서도 메일을 지우지 않습니다.
스팸도 일단 쌓아 두기로 했습니다. 명백한 스팸은 다음이 먼저 걸러서 가져오지 않습니다. Gmail 스팸함에 두면 30일 뒤 자동으로 지워지므로, Gmail이 스팸으로 판정한 메일도 받은편지함에 넣고 별도 라벨을 붙입니다. 어떤 규칙으로 정리할지는 실제 메일이 쌓인 다음 정하기로 했습니다.
라벨은 두 종류만 남겼습니다. 원래 받은 주소를 나타내는 라벨은 그대로 둡니다. 예전 주소를 아직 쓰는 서비스를 나중에 찾아 바꾸려면 전달자를 남겨야 합니다. 용도 라벨은 나중에 다시 찾을 묶음에만 붙입니다. 알림, 뉴스레터, 광고처럼 당장 할 일이 아닌 메일은 받은편지함을 건너뜁니다.
에이전트는 라벨만 늘리고 모든 메일을 받은편지함에 두는 안보다 받은편지함을 비우는 안을 제안했습니다. Gmail 카테고리 탭에 맡기는 안도 제외했습니다. 카테고리는 맥 메일 앱에서 보이지 않아 웹과 앱의 구성이 달라지기 때문입니다.
자동 보관에는 예외를 뒀습니다. 받은편지함을 건너뛸 발신처에서 왔더라도 제목에 로그인, 인증, 유출이 들어 있으면 받은편지함에 남깁니다. 발신처만 보고 분류하면 중요한 보안 알림까지 알림성 메일에 섞일 수 있어서입니다.
Gmail에서 바꾼 편지함
정리한 뒤에도 주소별 수집 방식은 하나로 통일되지 않았습니다. 다음 메일은 맥미니의 스크립트가 IMAP으로 읽고 Gmail에 넣습니다. 학교 메일과 iCloud는 자동 전달하고, 개인 도메인은 Cloudflare가 넘깁니다. 어느 방식으로 모으든 Gmail에 넣은 뒤에는 같은 규칙이 적용됩니다.
바꾼 것은 Gmail 편지함입니다. 라벨을 붙이고 받은편지함에 남길지 정하는 일이 Gmail 서버에서 일어나므로, 맥북과 맥미니의 메일 앱은 물론 iPad와 iPhone까지 Gmail에 연결된 클라이언트에는 기기마다 따로 설정하지 않아도 같은 변경이 한꺼번에 반영됩니다.
맥미니에서 학습시킨 Laya
여기까지는 분류에 모델을 쓰지 않았습니다. 필터의 용도 라벨은 발신처 목록을 기준으로 붙어서, 목록에 없는 곳에서 온 메일은 용도 라벨 없이 받은편지함에 남았습니다. 약관 개정 안내, 개인정보 이용 내역 통지, 서비스 종료 안내, 처음 보는 곳의 광고가 그랬습니다. 모델에게 맡기면 내용을 읽고 분류할 수 있지만, 메일이 도착할 때마다 생성 모델을 부르면 메일이 늘어나는 만큼 비용도 늘어납니다.
비용 부담 없이 이 분류를 하고 싶었습니다. 늘 켜져 있는 맥미니의 성능도 일부라도 쓰고 싶었습니다. 다만 생성 모델을 돌리기에는 맥미니가 늘 부담스러웠고, 제대로 돌리려면 더 좋은 장비가 필요했습니다. 글을 읽고 쓰는 일은 구독해서 쓰는 상위 모델이 이미 맡고 있으니 생성 모델을 따로 둘 이유도 없었습니다. 그래서 도착한 메일에 어떤 용도 라벨을 붙일지 정하는 라우팅만큼은 맥미니에서 직접 하는 게 의미가 있겠다고 봤습니다.
Laya가 이 조건에 맞았습니다. 글을 생성하지 않고, 미리 정한 선택지마다 확률을 돌려주는 결정 모델입니다. 가중치가 Apache 2.0으로 공개되어 있어 맥미니에서 직접 돌릴 수 있습니다. 같은 방식의 모델로는 TypeSafe AI의 Jev가 먼저 알려졌지만, Jev는 API로만 쓸 수 있어 메일 본문을 지금까지 보내지 않던 회사에 보내야 합니다. 그래서 Jev는 후보에서 빼자는 것이 에이전트의 제안이었습니다. Laya 개발사는 학습하지 않은 기본 모델이 자기들 업무 판단 벤치마크에서 무작위 선택과 비슷한 점수를 냈다고 밝히고, 쓰는 사람의 데이터로 학습해서 쓰라고 안내합니다.
학습의 설계와 실행은 에이전트가 맡았습니다. 첫 학습에서 Laya가 학습에 없던 발신처의 메일을 맞힌 비율은 66%에 그쳤습니다. 정답을 두 기준에서 가져온 것이 컸습니다. 필터 라벨이 있는 메일은 그 라벨을, 없는 메일은 구독해서 쓰는 상위 모델이 내용을 읽고 고른 답을 정답으로 삼았습니다. 필터는 누가 보냈는지로 나누고 모델은 내용으로 나눕니다. 개발 도구 회사가 보낸 제품 소식은 필터로는 개발, 내용으로는 뉴스레터였고, 필터 라벨이 붙은 메일의 3분의 1 정도에서 두 답이 달랐습니다.
그래서 정답의 기준을 내용 하나로 정하고 라벨을 열 개로 다시 짰습니다. 라벨에는 순서를 두어, 한 메일이 여러 라벨에 해당하면 위에서부터 차례대로 먼저 맞는 라벨이 붙게 했습니다.
| 순서 | 라벨 | 붙는 메일 |
|---|---|---|
| 1 | 개인 | 사람이 직접 쓴 메일과 답장 |
| 2 | 계정보안 | 로그인, 인증 코드, 새 기기 접속, 비밀번호 변경 |
| 3 | 약관고지 | 약관 개정, 개인정보 이용 내역 통지, 서비스 종료와 점검 |
| 4 | 행사컨퍼런스 | 컨퍼런스, 웨비나, 밋업의 초대와 일정 |
| 5 | 할인프로모션 | 할인, 쿠폰, 이벤트, 광고 |
| 6 | 금융 | 결제, 영수증, 청구서, 입출금 |
| 7 | 쇼핑 | 주문, 배송, 반품, 예약 |
| 8 | 개발 | 개발 서비스와 NAS 장비가 보낸 알림 |
| 9 | 뉴스레터 | 구독 소식지, 제품 소식, 글 모음 |
| 10 | 기타 | 어디에도 맞지 않는 자동 메일 |
정답은 이번에도 구독해서 쓰는 상위 모델이 메일을 한 통씩 읽고 만들었습니다. 학습 전에 이 모델이 새 기준을 제 판단대로 쓰는지부터 봤습니다. 학습에 넣지 않을 메일 100통에 이 모델이 붙인 라벨을 확인했고, 고칠 것이 없었습니다.
Laya는 질문과 선택지 설명을 합쳐 256토큰까지만 받습니다. 그래서 에이전트는 라벨별 긴 기준은 정답을 만드는 모델에게만 주고, Laya에게는 라벨마다 한 줄로 줄인 설명을 줬습니다.
학습 메일은 최근 5년 메일에서 새로 골랐습니다. 행사 안내와 사람이 보낸 메일은 드물어서, 제목에 컨퍼런스나 웨비나가 들어간 메일과 사람이 보낸 것으로 보이는 메일은 모두 넣었습니다. 평가는 두 묶음으로 했습니다. 하나는 앞에서 제가 확인한 100통이고, 다른 하나는 학습에 쓰지 않은 발신처의 메일입니다. 같은 발신처가 학습과 평가에 섞이면 모델이 내용 대신 발신처 이름만 외워도 점수가 높게 나오기 때문입니다. 학습은 맥미니(M4 Pro)에서 두 시간 남짓 걸렸습니다.
Laya가 맞힌 메일은 제가 확인한 100통에서 학습 전 27통, 학습 후 93통이었습니다. 학습에 없던 발신처의 메일 400통에서는 105통에서 322통으로 늘었습니다. 라벨 열 개 가운데 무작위로 고르면 맞힐 비율은 10%입니다. 400통의 정답은 정답을 만든 모델의 답이어서, 제 판단과 직접 견준 숫자는 100통 쪽뿐입니다.
합격선은 Laya가 라벨을 붙인 메일의 90% 이상이 맞는 것으로 정했습니다. Laya는 답마다 확신도를 함께 내므로, 확신도가 기준보다 낮은 메일에는 라벨을 붙이지 않으면 됩니다. 기준값 0.70은 에이전트가 학습에도 두 평가 묶음에도 넣지 않고 따로 떼어 둔 메일로 골랐습니다. 평가 메일로 고르면 0.60까지 내릴 수 있었지만 그때 맞은 비율이 딱 90%였고, 평가 메일에 맞춘 숫자는 실제보다 좋게 나올 수 있다는 것이 에이전트의 판단이었습니다. 0.70에서 라벨이 붙는 비율은 제가 확인한 100통에서 86%, 학습에 없던 발신처의 메일에서 68%였고, 붙은 라벨이 맞은 비율은 각각 99%와 93%였습니다.
메일 흐름에 붙인 Laya
판정을 통과한 날 Gmail에 있던 메일 전체를 새 기준으로 다시 정리했습니다. 학습에 쓴 메일에는 정답 라벨을 그대로 붙이고, 나머지는 Laya가 판단했습니다. 나머지 메일 가운데 확신도 0.70을 넘어 라벨이 붙은 것은 78%였고, 확신이 모자란 메일은 라벨 없이 남겼습니다. 필터가 붙여 두었던 용도 라벨도 내용 기준으로 바뀌었습니다. 금융에서 약관고지로 옮긴 메일과 뉴스레터에서 할인프로모션으로 옮긴 메일이 각각 백 통 남짓이었습니다.
Gmail 필터에서는 용도 라벨을 붙이는 동작을 빼고, 그 일을 Laya에 넘겼습니다. 에이전트는 처음에 필터를 그대로 두고 Laya가 빈 곳만 채우게 하자고 했지만, 저는 필터가 하던 분류를 Laya가 넘겨받는 것으로 생각하고 있었습니다. 둘을 함께 두면 첫 학습 때처럼 한 메일에 기준이 다른 라벨 두 개가 붙을 수 있습니다. 필터에는 주소 라벨과 받은편지함 건너뛰기만 남았습니다. 새 메일은 맥미니가 5분마다 확인해 라벨을 붙입니다. 한 통을 판단하는 데 0.1초가 걸리지 않고, 판단할 때마다 드는 비용도 없습니다.
Laya는 글을 쓰지 않고 정해진 열 개 라벨 가운데서만 고릅니다. 메일 본문에 모델을 속이려는 문장이 섞여 와도 바뀔 수 있는 것은 그 메일의 라벨 하나입니다.
약한 라벨도 있습니다. 학습에 없던 발신처의 메일에서 기준 0.70을 넘긴 답을 라벨별로 보면 개발이 가장 약했습니다. Laya가 개발이라고 답한 여섯 통 가운데 맞은 것은 두 통입니다. 쇼핑, 계정보안, 개인, 할인프로모션도 맞은 비율이 82%에서 89%로 90%에 못 미쳤고, 이 묶음 전체에서 맞은 비율 93%는 나머지 라벨이 끌어올린 숫자입니다. 제가 확인한 100통에서는 개발 라벨 일곱 통이 모두 맞아서, 표본이 작은 탓인지 실제로 약한지는 아직 가리지 못했습니다. 라벨 없이 남은 메일과 약한 라벨을 어떻게 다시 가르칠지는 아직 정하지 않았습니다.