매일 아침 한국 주식 시장 브리핑(환율·지수·공시·뉴스)을 만들어 카카오톡으로 보내주는 예약 작업을 AI에게 맡겨 뒀어요. 제가 지침을 짜서 세팅해두면 정해진 시각에 알아서 도는 구조죠. 그런데 어느 날, 그 요약에 꼭 필요한 핵심 데이터 도구가 아예 안 불려왔습니다. 보통 이러면 작업이 통째로 실패하죠. 그런데 이날은 달랐어요 — 제가 맡겨둔 AI 루틴이 스스로 다른 길로 우회해서 결과물을 끝까지 완성했고, 대신 “이건 정확한 값이 아니라 대체 정보”라고 정직하게 밝혔습니다. 이 글은 그 과정을 지켜본 설계자로서 “필수 데이터가 죽어도 자동화를 완결시키는 법”에 대해 배운 기록입니다.
미리 밝혀둘게요. 이 편엔 제가 AI에게 실시간으로 뭘 물어본 장면이 없어요. 루틴은 저 없이 혼자 돌았고, 저는 나중에 로그를 보고 “왜 이렇게 됐지?”를 되짚은 거니까요. 그러니 이건 주고받은 대화 기록이 아니라 설계자가 자기 자동화를 사후에 뜯어본 리뷰에 가깝습니다.
핵심 도구가 통째로 안 불려왔다
상황부터요. 이 예약 작업은 여러 소스에서 데이터를 모아 요약을 만들어 메신저로 보내는 흐름이에요. 그중 가장 핵심인 실시간 데이터 도구가 이날따라 로드(도구를 불러와 쓸 수 있게 준비하는 것)에 실패했어요. 그 도구가 없으니, 요약의 핵심 숫자들을 정확하게 가져올 수가 없었죠.
여기서 자동화가 취할 수 있는 길은 보통 둘이에요. 하나는 “핵심 데이터가 없으니 그냥 실패” — 아무것도 안 보내고 끝. 다른 하나는 이날 실제로 일어난 길 — 있는 걸로라도 완성하는 것입니다.
통째 실패 대신 — 다른 소스로 우회(폴백)
이날 자동화는 핵심 도구가 안 되자, 곧바로 일반 웹 검색과 뉴스로 방향을 틀었어요. 정확한 실시간 수치는 못 가져와도, 뉴스에는 “오늘 시장 분위기가 어떤지”에 대한 정성적인(숫자가 아니라 서술로 된) 정보가 있거든요. 그걸 읽어서 요약을 만들고, 메신저 전송까지 끝까지 완결했습니다.

폴백(fallback): 원래 쓰려던 방법이 안 될 때를 대비해 마련해 둔 대체 경로예요. 엘리베이터가 고장 나면 계단으로 가는 것과 같죠. 자동화에서 폴백이 있으면, 한 부품이 고장 나도 전체가 멈추지 않고 “덜 좋지만 작동하는” 상태로 굴러갈 수 있어요. 이걸 우아한 성능 저하(graceful degradation)라고도 불러요 — 툭 죽는 대신, 품질을 낮춰서라도 살아남는 거죠.
핵심은 이거예요. 핵심 데이터가 없다고 결과물이 0이 되진 않았다는 것. 정확도는 낮아졌지만, 사용자(저)는 그날 아침에도 “오늘 시장이 대충 어떤 분위기인지”를 받아볼 수 있었어요. 아무것도 못 받는 것보다 훨씬 낫죠.
가장 중요한 부분 — 대체한 걸 ‘정직하게’ 밝혔다
그런데 폴백에는 함정이 하나 있어요. 대체 데이터는 원본만큼 정확하지 않잖아요. 이걸 원래 데이터인 척 그냥 내보내면, 사용자는 부정확한 값을 정확한 값으로 착각하게 됩니다. 그게 더 위험해요.
그래서 이날 자동화가 잘한 게 바로 이 지점이에요. 결과물에 “이 수치는 정확한 실시간 값이 아니라 뉴스 서술에 기반한 것”이라고 명시했습니다. 즉 폴백을 했다는 사실 자체를 숨기지 않고 드러낸 거죠.
폴백은 반드시 “티가 나게” 해야 해요. 대체 경로로 갔다는 걸 숨기면, 사용자는 낮은 품질의 결과를 높은 품질로 오해합니다. “지금 평소와 다른 방식으로 만들어졌다”는 표시가 있어야, 받는 사람이 그만큼 걸러 들을 수 있어요. 조용한 폴백은 조용한 거짓말이 될 수 있습니다.
예약해 둔 AI 작업이 끝나기 직전에 멈췄더니, 결과가 통째로 사라졌다
이 폴백이 왜 값졌는지는 며칠 전 실행과 나란히 놓아야 보여요. 그날도 같은 루틴이 돌았고, 시세·공시·뉴스 호출까지는 다 나갔어요. 그런데 요약을 조립해 보내는 마지막 구간에서 실행이 끊겼고, 메신저 전송까지 가지 못했습니다. 손에 남은 결과물은 없었어요.
왜 통째로 사라졌나 — ‘무상태 단발’ 설계
먼저 이 설계를 변호부터 할게요. 그래야 반전이 살거든요.
제 예약 루틴은 매 실행이 이전 대화의 기억 없이, 그날 지침만으로 처음부터 끝까지 완결되도록 짜여 있었어요. 이걸 어려운 말로 무상태(stateless, 이전 상태를 기억하지 않음) 단발 실행이라고 해요. 이게 왜 합리적이냐면, 기억을 안 가지니까 매번 똑같이 재현되고(어제 실행이 오늘에 영향을 안 줌), 중간에 꼬인 상태가 다음 실행으로 새지 않아요. 자동화에서 이건 꽤 큰 장점입니다.
무상태(stateless): 매 실행이 과거를 기억하지 않고 백지에서 시작하는 방식이에요. 장점은 예측 가능성(늘 같은 입력이면 같은 동작)과 깔끔함(오염된 상태가 안 쌓임). 학생마다 새 시험지로 채점하는 것과 비슷하죠 — 앞 학생 답이 다음 채점에 안 섞이니까요.
그런데 이 장점의 정확히 뒷면이 이번 사고였어요. 기억을 안 가진다는 건, 실행이 중간에 끊기면 그때까지 받아둔 데이터도 어디에도 안 남는다는 뜻이거든요. 백지에서 시작해 한 번에 완결하는 구조라, 완결에 도달하지 못하면 손에 쥔 게 통째로 날아갑니다. 그러니 이건 코드가 틀려서 난 버그가 아니라, 무상태 단발이라는 선택이 치르는 대가예요. 편리함과 맞바꾼 트레이드오프인 거죠.
진짜 축 — “데이터 없음” 지침이 못 막은 이유
사실 제 지침에는 안전장치가 있었어요. 데이터가 실패하면 ‘데이터 없음’이라고 표기하고 계속 진행하라 — 이런 규칙이요. 그래서 저는 당연히 이번에도 “데이터 없음”이라도 찍힌 브리핑이 올 줄 알았죠.
그런데 안 왔어요. 왜일까요? 그 지침이 대비한 상황과 실제로 벌어진 상황이 달랐기 때문이에요. 이게 이 글에서 제일 중요한 대목입니다.
- 지침이 대비한 것: 도구가 응답은 했는데 그 내용이 비었을 때 → “데이터 없음”으로 표기하고 진행.
- 실제로 벌어진 것: 실행 자체가 중간에 끊겼을 때 → 표기고 진행이고 할 코드에 도달조차 못 함.
즉 “데이터 없음” 규칙은 빈 응답을 대비했지, 실행의 중단을 대비하지 못했어요. 안전장치가 지키는 자리와 사고가 난 자리가 어긋나 있었던 거죠. 안전장치가 있다고 다 막히는 게 아니라, 그 장치가 정확히 어떤 상황을 막도록 설계됐는지를 봐야 한다는 걸 이 사고로 배웠어요.
그럼에도 남는 근본 리스크 — 한 소스에 매달리면
이날은 폴백 덕에 넘어갔지만, 진짜 문제는 따로 있어요. 핵심 데이터를 단 하나의 소스에만 의존하고 있었다는 것. 그 소스가 죽으면 매번 이렇게 아슬아슬하게 폴백으로 때워야 하죠.
이 루틴의 실행 기록을 날짜별로 펼쳐 보면, 시세 도구가 흔들린 날이 한 번이 아니었어요. 매번 같은 방식으로 고장 난 것도 아니었고요.
| 실행일 | 시세 도구 | 루틴이 한 일 | 메신저 전송 |
|---|---|---|---|
| 7/31 | 정상 | 세션 한도로 한 번 끊겼다가 재개. 지침만으로 처음부터 다시 돌아 끝냄 | 완료 |
| 8/3 | 정상 | 지침대로 수집·요약 | 완료 |
| 8/6 | 정상 | 지침대로 수집·요약 | 완료 |
| 8/8 기록 | 호출 도중 끊김 | 재시도 뒤 기록이 끝남. 받아 둔 데이터도 남지 않음 | 못 함 |
| 8/11 | 불러오기 실패 | 웹 검색·뉴스로 우회. «뉴스 서술 기반»이라고 밝힘 | 완료 |
| 8/13 | 쓸 수 없음. 직접 조회도 네트워크에서 막힘 | 종목별 뉴스 검색으로 시세를 복원. 출처를 세 단계로 밝힘 | 완료 |
| 8/14 | 정상 복귀 | 개장 전 실행이라 등락률이 비어 전일 종가로 표기 | 완료 |
| 9/2 기록(첫 실행) | 응답은 왔지만 지수·환율 현재가가 빔 | 보완용 과거 시세 조회에서 멈춤. 사용자가 중단 | 못 함 |
| 9/2 재실행 | 같음 | 과거 시세 응답이 15분 넘게 늦게 와서 끝냄 | 완료 |
그래서 방향은 두 가지예요. 하나는 폴백 경로를 임시가 아니라 상시 경로로 격상하는 것 — 어차피 자주 쓸 거면 처음부터 정식 대안으로 두는 거죠. 다른 하나는 데이터 소스를 이중화하는 것 — 한 곳이 죽어도 다른 곳에서 같은 값을 가져오게요. 어느 쪽이든 핵심은 “하나가 죽어도 전체가 안 죽게” 만드는 거예요.
| 상황 | 어떻게 판단할까 | 액션 |
|---|---|---|
| 핵심 데이터 도구가 안 됨 | 통째 실패 vs 있는 걸로 완결 | 🟢 폴백: 대체 소스로 우회해 완결 |
| 폴백으로 만든 결과물 | 정확도가 원본보다 낮음 | 🔴 지금: “대체 데이터”라고 명시 |
| 폴백을 자주 쓰게 됨 | 임시방편이 상습화됨 | 🟡 백로그: 폴백을 상시 경로로 격상 |
| 핵심 소스가 하나뿐 | 그게 죽으면 매번 위태로움 | 🟡 백로그: 데이터 소스 이중화 |
한마디로, 자동화는 “핵심 부품이 죽었을 때 어떻게 되는가”로 진짜 실력이 갈려요. 이날 제가 미리 넣어둔 지침은 “데이터 실패 시 ‘데이터 없음’ 표기 후 진행” 한 줄뿐이었고, 대체 소스로 우회한 건 루틴이 그 안에서 스스로 찾은 길이었어요. 지켜보면서 제가 챙긴 교훈은 따로 있습니다. 자동화를 만들 때부터 “핵심이 죽는 날”을 설계에 넣어둬야 한다는 것. 툭 죽는 대신 덜 좋은 결과로라도 완결하게 하고, 그게 대체품이라는 걸 정직하게 밝히게 하고, 근본적으로는 하나의 소스에만 목매지 않게 이중화하는 것 — 이 결정들은 결국 루틴이 아니라 그걸 설계하는 사람의 몫이더라고요.