본문 바로가기
강의

에러가 없었다고 성공은 아니다 — 조용한 실패를 막는 법

AI 자동화는 멈추는 것보다 안 된 채 완료된 척하는 조용한 실패가 더 위험하다. 사람 눈에는 멋진 표도 기계가 약속한 형식으로 읽지 못하면 실패다. 출력 계약, 성공 신호가 있어야만 성공으로 치는 방식, 실제 예약 환경에서의 강제 실행까지 비개발자 눈높이로 풀었다.

배달 완료 문자가 왔다고 안심했는데 음식이 다른 집 앞에 놓였다면, 문자가 온 것과 배달이 끝난 것은 같은 일이 아니다.

이 글 3줄 요약

  • AI가 약속한 한 줄 대신 예쁜 표를 내놓자, 사람 눈에는 멀쩡했지만 기계는 읽지 못했다. 그래서 즉시 실패로 처리했다.
  • 에러가 없으면 성공이 아니라, 성공 신호가 있어야만 성공으로 쳐야 한다. 이것이 조용한 실패를 막는 가장 단순한 원칙이다.
  • 내 손으로 한 번 잘된 것으로 끝내지 말고, 실제 예약 실행을 맡은 장치로 강제 1회 돌려봐야 한다.

나는 개발자가 아니라 AI에게 일을 시키며 개발을 배우는 사람이다. 그래서 자동화가 돌아간다는 말만 믿고 손을 떼고 싶은 마음을 잘 안다. 하지만 자동화의 최악은 크게 멈추는 일이 아니다. 안 됐는데도 완료된 척 조용히 지나가는 일이다.

예쁜 표 하나가 첫 사고를 냈다

블로그 글감을 매주 자동으로 모아주는 프로그램을 새 방식으로 바꾸던 날이었다. AI에게 일을 마친 뒤 마지막 줄을 완료 후보=숫자처럼 정해진 한 줄로 쓰라고 했다. 다음 프로그램은 바로 그 한 줄을 찾아 결과를 넘겨받게 되어 있었다.

그런데 AI는 약속한 한 줄 대신 보기 좋은 표를 만들었다. 사람 눈에는 오히려 더 친절하고 완성도 높아 보였다. 하지만 기계는 그 표를 성공 신호로 읽지 못했다. 프로그램은 망설이지 않고 전체 작업을 실패로 기록했다.

여기서 출력을 대충 해석해 성공으로 넘겼다면, 빈 결과가 다음 단계로 흘러갔을 것이다. 대신 지시문 맨 위에 ‘이 형식을 지키지 않으면 전체 실패’라고 박았다. 출력 계약(다음 프로그램이 읽을 결과의 모양을 미리 정한 약속)을 분명히 하자 AI는 약속한 한 줄을 내놓았다.

정상 1건에서만 죽는 버그가 숨어 있었다

한 줄 문제가 해결되자 끝인 줄 알았다. 그런데 이번에는 프로그램 안에 숨어 있던 잠복 버그가 튀어나왔다. 잠복 버그(평소에는 보이지 않다가 특정 조건에서만 나타나는 오류)란 말 그대로 숨어 기다리는 문제다.

이 오류는 결과가 없을 때도, 여러 건일 때도 나타나지 않았다. 하필 정상적으로 딱 1건을 찾았을 때만 프로그램이 죽었다. 가장 평범해 보이는 성공 장면이 유일한 실패 조건이었던 셈이다.

그래도 문제를 바로 발견한 이유는 실패를 조용히 삼키지 않게 만들어두었기 때문이다. 첫 번째 문제를 엄격하게 막자 그 뒤에 숨은 두 번째 문제가 선명하게 드러났다. 실패를 크게 보이게 만드는 장치는 문제를 늘리는 것이 아니라, 원래 있던 문제를 제때 보여준다.

내 손으로 돌릴 때와 예약 실행은 다른 가게다

버그를 고친 뒤 내가 직접 실행했을 때는 잘됐다. 여기서 손을 뗐다면 세 번째 사고는 다음 주까지 숨어 있었을지 모른다. 스케줄러(정해진 시간에 프로그램을 대신 실행하는 장치)가 돌릴 때는 내가 직접 누를 때와 실행 환경이 달라질 수 있기 때문이다.

실행 환경(프로그램이 작동할 때 사용하는 위치·설정·도구의 묶음)이 달라지면 같은 프로그램도 다른 결과를 낸다. 내 컴퓨터 화면에서 성공한 것은 ‘내가 돌린 조건’의 성공일 뿐이다. 그래서 예약 실행을 등록한 직후, 바로 그 스케줄러로 강제 1회 실행했다. 실제로 일을 맡을 주체가 성공 신호를 남기는 것까지 보고서야 작업을 끝냈다.

성공은 느낌이 아니라 신호로 판정한다

세 번의 사고를 관통한 원칙은 하나다. 에러가 없었으니 성공했겠지라고 넘기지 않는 것이다. 성공 신호가 있어야만 성공으로 치는 방식(fail-closed)으로 문을 잠가야 한다.

반대는 실패 신호만 없으면 성공으로 넘기는 방식(fail-open)이다. 사람 눈에는 편해 보이지만 자동화에서는 위험하다. 예약 발송, 매출 보고서, 자료 백업처럼 사람이 매번 지켜보지 않는 일은 한 번의 애매한 통과가 계속 반복될 수 있다. 빨간 에러보다 초록색 완료 표시를 잘못 믿는 일이 더 비싼 이유다.

자동화를 맡기기 전, 이 세 문장만 박아라

  1. ‘마지막 성공 신호는 이 형식 한 줄로 남겨라.’ — 출력 계약을 정한다.
  2. ‘그 신호가 없거나 형식이 다르면 성공으로 넘기지 마라.’ — 성공 신호가 있어야만 성공으로 친다.
  3. ‘등록 직후 실제 예약 실행 주체로 한 번 강제 실행하고 결과를 보여라.’ — 진짜 환경을 확인한다.

자동화는 사람이 안 보려고 만드는 장치다. 그렇기 때문에 사람이 안 보는 동안에도 성공과 실패를 더 엄격하게 가려야 한다. ‘문제가 없었다’가 아니라 ‘성공했다는 증거가 있다’를 완료 기준으로 삼자. 조용한 실패는 눈치로 잡는 것이 아니라, 처음부터 조용히 지나갈 수 없게 설계하는 것이다.

자주 묻는 질문

조용한 실패란 무엇인가요?

프로그램이 할 일을 제대로 못 했는데도 멈추거나 알리지 않고 완료된 것처럼 넘어가는 상황입니다. 눈에 띄는 에러가 없어서 사람은 성공했다고 착각합니다. 예를 들어 예약 발송이 한 건도 안 됐는데 화면에는 완료라고만 남는 경우입니다. 이런 실패는 발견이 늦어져 누락이 계속 쌓일 수 있습니다. 그래서 에러가 없다는 사실보다 성공했다는 증거를 확인해야 합니다.

AI가 보기 좋은 표로 답했는데 왜 실패로 처리해야 하나요?

사람에게 좋은 답과 다음 프로그램이 읽을 수 있는 답은 다를 수 있기 때문입니다. 자동화에서는 다음 단계가 찾기로 한 한 줄 형식이 일종의 바통입니다. AI가 내용을 맞게 써도 바통 모양이 다르면 다음 주자가 받을 수 없습니다. 이때 어림짐작으로 성공 처리하면 잘못된 결과가 뒤 단계까지 흘러갑니다. 약속한 형식이 아니면 즉시 실패로 멈추게 하는 편이 안전합니다.

출력 계약은 AI에게 어떻게 적어야 하나요?

해야 할 일과 함께 마지막 성공 신호의 모양을 정확히 적으면 됩니다. 예를 들어 ‘마지막 줄은 완료 후보=숫자 형식으로만 작성’처럼 글자와 순서를 정합니다. 이어서 ‘이 형식을 지키지 않으면 전체 작업은 실패로 처리’라고 판정 기준도 붙이세요. 가능하면 올바른 예시 한 줄도 함께 보여주는 것이 좋습니다. 핵심은 사람이 알아보는 설명이 아니라 기계가 틀리지 않고 확인할 신호를 받는 것입니다.

성공 신호가 없으면 무조건 실패로 치는 건 너무 엄격하지 않나요?

자동으로 반복되는 일에서는 그 엄격함이 오히려 비용을 줄입니다. 애매한 결과를 성공으로 넘기면 예약 발송, 보고서, 백업 같은 누락이 한참 뒤에 발견될 수 있습니다. 실패로 멈추면 그 자리에서 확인하고 다시 실행할 수 있습니다. 즉 결과를 버리자는 뜻이 아니라 사람이 확인할 기회를 확보하자는 뜻입니다. 중요한 업무일수록 성공의 증거가 있을 때만 다음 단계로 보내는 편이 안전합니다.

수동 실행이 성공했는데도 예약 실행을 따로 시험해야 하나요?

따로 시험해야 합니다. 내가 직접 누를 때와 정해진 시간에 프로그램이 대신 돌릴 때는 사용 가능한 설정과 실행 위치가 다를 수 있습니다. 그래서 같은 프로그램도 수동으로는 되고 예약 실행에서는 다른 결과를 낼 수 있습니다. 자동화를 등록한 직후 예약 실행 주체로 한 번 강제로 돌려보세요. 그 결과와 성공 신호까지 확인해야 실제 운영 준비가 끝난 것입니다.

관련 글