본문 바로가기
AI 코딩/클로드 코드

AI 자동 발송에 검증을 붙이는 법 — 휴장일에 빈 브리핑이 나간 뒤

by 아트스탁 2026. 8. 22.
한눈에
  • 장이 끝나면 AI가 시황을 써서 텔레그램으로 보냅니다. 어려운 건 잘 쓰게 하는 게 아니라 이상한 게 나갔을 때 막는 것이었습니다.
  • 휴장일에 속 빈 브리핑이 나갔습니다. 막는 장치가 있었는데, 제가 다른 설정을 바꾸는 바람에 그 장치의 전제가 깨졌습니다 — 장치는 자기 전제가 깨진 걸 모릅니다.
  • 「80자보다 길면 통과」라는 검사는 「길기만 한 헛소리」를 못 걸렀습니다. AI가 한 문장만 답했는데 통과할 뻔했습니다.
  • 그래서 관문을 세 겹으로 만들었습니다 — ①휴장일 달력 ②지수 종가와 공통 종목으로 대조 ③답의 길이와 필수 항목 검사. 세 겹이 된 이유는 전부 사고가 났기 때문입니다.

앞 두 편이 남이 쓴 리포트를 모으는 이야기였다면, 이번 편은 AI가 직접 글을 쓰게 하는 이야기입니다.

매일 장이 끝나면 그날 시황을 정리한 브리핑이 텔레그램으로 옵니다. 국내장은 저녁에, 미국장은 아침에 옵니다. 제가 아무것도 안 눌러도 옵니다.

여기서 배운 건 「AI에게 글을 잘 쓰게 하는 법」이 아니었습니다. 「AI가 이상한 걸 내놨을 때 그게 나가지 않게 막는 법」이었습니다. 막는 장치를 세 겹으로 만들었는데, 세 겹이 된 이유는 전부 사고가 났기 때문입니다.

사고 ① 휴장일에 속 빈 브리핑이 나갔습니다

가장 아팠던 사고입니다. 대체공휴일이라 장이 안 열린 날, 저녁에 브리핑이 발송됐습니다. 내용은 텅 비어 있었습니다.

막는 장치는 이미 있었습니다. 「오늘 목록이 직전 거래일과 거의 같으면 휴장일이다」라는 규칙이었습니다. 장이 안 열리면 데이터가 안 바뀌니, 같은 값이 다시 나오면 휴장일이라는 논리입니다. 잘 동작하고 있었습니다.

휴장일에 안전장치가 뚫린 이유

그런데 제가 그 전제를 깼습니다. 며칠 전에 목록에 담을 종목의 기준을 조정했습니다. 브리핑에 나오는 종목 수를 줄이려고 한 것이고, 그 자체는 잘한 변경이었습니다.

문제는 비교 대상이 옛 기준으로 뽑힌 목록이었다는 것입니다. 기준이 다르니 목록도 달라집니다. 겹치는 비율이 90%는 되어야 「같은 날」로 판정하는데, 63%밖에 안 겹쳤습니다.

장치는 「데이터가 안 변했다」를 보려 했는데, 실제로 잰 건 「목록이 안 변했다」였습니다. 그리고 목록은 데이터 말고 제 설정으로도 변합니다. 그걸 제가 바꾼 것입니다.

내가 다른 곳을 손대서 안전장치의 전제가 깨졌고, 장치는 그걸 알 방법이 없었습니다.

그래서 휴장일인데 "다른 날"로 판정됐고, 수집과 AI 작성이 그대로 진행됐습니다. AI는 데이터를 보고 "오늘은 휴장일입니다"라고만 답했습니다. AI는 정확했습니다. 그런데 그 짧은 답이 본문 자리에 들어가 발송됐습니다.

사고 ② 앱 버튼이 유령 데이터를 만들었습니다

다른 프로그램에 「브리핑 만들기」 버튼을 하나 붙여뒀습니다. 그런데 그 버튼에는 시간 검사가 없었습니다.

자정이 갓 넘은 시각에 그 버튼이 눌렸고, 프로그램은 「오늘」의 데이터를 모으려 했습니다. 그 시각엔 오늘 장이 아직 안 열렸으니 데이터가 있을 리 없습니다. 그래서 전날 값을 그대로 오늘 것으로 저장했습니다. 30개 종목이 통째로 복제됐습니다.

오류는 없었습니다. 데이터베이스에는 멀쩡해 보이는 행 30개가 늘어 있었습니다. 나중에 통계를 낼 때 그게 섞였으면 결과가 조용히 틀어졌을 겁니다.

사고 ③ AI가 한 줄만 답했는데 통과할 뻔했습니다

AI가 만든 본문이 제대로 된 것인지 검사하는 장치도 있었습니다. 기준은 「80자보다 길면 통과」였습니다.

어느 날 AI가 이렇게 답했습니다. "이 알림 역시 추가 조치는 필요 없습니다." 150자쯤 되는 한 문장이었습니다. 80자보다 기니까 통과했습니다. 하마터면 그게 그날의 시황 브리핑이 될 뻔했습니다.

검사가 있었는데 기준이 너무 헐거웠습니다. 「길이만 재는 검사」는 「길기만 한 헛소리」를 못 걸러냅니다.

그래서 관문을 세 겹으로 만들었습니다

자동 발송을 막는 관문 세 겹

① 달력. 휴장일 목록을 파일로 넣어뒀습니다. 가장 먼저 검사해서 걸리면 아무것도 시작하지 않습니다. 데이터도 안 받고 AI도 안 부르고 알림도 안 보냅니다. 조용히 넘어갑니다.

② 데이터 지문. 달력에 없는 날을 위한 두 번째 관문입니다. 사고 ①을 겪고 나서 비교 방식을 바꿨습니다. 목록 전체를 견주는 대신 양쪽에 다 있는 종목끼리만 견줍니다. 그러면 제가 기준을 바꿔도 판정이 흔들리지 않습니다. 여기에 지수 종가도 같이 봅니다.

③ 답의 형태 검사. 길이 기준을 크게 올리고, 본문에 반드시 있어야 할 항목이 들어 있는지도 봅니다. 통과 못 하면 한 번 다시 시켜보고, 그래도 안 되면 본문 대신 데이터 표만 보냅니다. 잘못된 글을 보내느니 표가 낫습니다.

여기에 요일 검사도 따로 붙였습니다. 토요일에 리포트 브리핑이 한 번 나간 적이 있었습니다. 컴퓨터를 켤 때 밀린 작업을 대신 실행하는 기능이 있는데, 거기엔 요일 조건이 안 걸려 있었습니다.

사고를 겪을 때마다 백업을 남겼습니다

위 사고들은 전부 데이터베이스에 잘못된 행을 남겼습니다. 휴장일에 쌓인 것, 복제된 30개 — 지워야 하는데, 지우다 멀쩡한 것까지 지우면 더 큰일입니다.

그래서 손대기 전에 파일을 통째로 복사했습니다. 지금 백업이 8개 쌓여 있고, 파일 이름에 그날 무슨 일이었는지 적어뒀습니다. 되돌릴 수 있다는 걸 알아야 과감하게 지울 수 있습니다.

그리고 지울 때는 「무엇을 왜 지우는지」를 먼저 적었습니다. 휴장일 사고 때는 그날 들어간 항목을 종류별로 세어 목록으로 만든 뒤 지웠고, 지우지 않은 것도 이유를 남겼습니다 — 그날 채점된 값 일부는 며칠 전 데이터의 결과라 정당했습니다.

정리하면

세 사고에 공통점이 있습니다. 전부 「오류 없이 잘못된 결과가 나온」 경우입니다. 프로그램이 멈춘 적은 한 번도 없습니다.

그리고 사고 ①이 특히 그렇습니다. 안전장치가 있었는데 제가 다른 곳을 바꿔서 그 장치의 전제가 무너졌습니다. 장치는 자기 전제가 깨진 걸 모릅니다. 그래서 지금은 무언가를 바꿀 때 「이 값을 믿고 있는 다른 장치가 있나」를 같이 봅니다.

자동화의 어려운 부분은 돌아가게 만드는 것이 아니었습니다. 잘못 돌아갈 때 그게 밖으로 나가지 않게 막는 것이었습니다. 매일 자동으로 나가는 것일수록 그렇습니다 — 제가 보고 있지 않으니까요.

다음 편에서는 이렇게 모은 세 갈래를 한 파일에 합쳐 검색되게 만든 이야기를 적겠습니다.

※ 이 글은 개인의 개발 기록입니다. 브리핑의 내용이나 그것으로 뽑은 결과는 공개하지 않으며, 특정 종목의 매수·매도를 권유하지 않습니다.