자동화의 핵심 데이터 소스가 죽었을 때 — 통째로 실패하지 않고 ‘정직한 폴백’으로 완결하기

매일 아침 한국 주식 시장 브리핑(환율·지수·공시·뉴스)을 만들어 카카오톡으로 보내주는 예약 작업을 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 있는 걸로 완결🟢 폴백: 대체 소스로 우회해 완결
폴백으로 만든 결과물정확도가 원본보다 낮음🔴 지금: “대체 데이터”라고 명시
폴백을 자주 쓰게 됨임시방편이 상습화됨🟡 백로그: 폴백을 상시 경로로 격상
핵심 소스가 하나뿐그게 죽으면 매번 위태로움🟡 백로그: 데이터 소스 이중화

한마디로, 자동화는 “핵심 부품이 죽었을 때 어떻게 되는가”로 진짜 실력이 갈려요. 이날 제가 미리 넣어둔 지침은 “데이터 실패 시 ‘데이터 없음’ 표기 후 진행” 한 줄뿐이었고, 대체 소스로 우회한 건 루틴이 그 안에서 스스로 찾은 길이었어요. 지켜보면서 제가 챙긴 교훈은 따로 있습니다. 자동화를 만들 때부터 “핵심이 죽는 날”을 설계에 넣어둬야 한다는 것. 툭 죽는 대신 덜 좋은 결과로라도 완결하게 하고, 그게 대체품이라는 걸 정직하게 밝히게 하고, 근본적으로는 하나의 소스에만 목매지 않게 이중화하는 것 — 이 결정들은 결국 루틴이 아니라 그걸 설계하는 사람의 몫이더라고요.


댓글 남기기