본문 바로가기

실전 원칙

자동화가 사람 개입 후 멈추는 문제: 중복 없이 다시 태우는 재개 경로 설계법

문제 제기: 사람이 고쳐도 자동화로 돌아갈 길이 없다

여러 단계를 이어 붙인 자동화(글 생성 → 품질 검사 → 이미지 생성 → 발행 대기)를 운영하다 보면, 중간 단계에서 멈추는 작업이 생길 수 있습니다. 품질 검사에 걸린 글이 대표적입니다. 이때 사람이 문장을 손봐서 검사를 통과시키는 것까지는 어렵지 않습니다. 진짜 문제는 그다음입니다.
실제 개발 기록에서 확인한 상황은 이랬습니다. 검사에 걸리면 자동으로 이어지는 작업 흐름은 돈이 드는 이미지 생성 단계를 건너뜁니다. 그런데 사람이 원고를 고쳐 검사를 통과시켜도, 한 번 건너뛴 그 단계가 저절로 되살아나지 않았습니다. 결국 사람이 이미지를 손으로 만들어 다시 올렸고, 그 재업로드 과정에서 블로그에 중복 초안이 실제로 생겼습니다.
핵심 원인은 기능 부족이 아니라 경로 부족입니다. '사람이 개입한 뒤 다시 정상 자동 경로로 합류하는 길'이 아예 없었던 것이죠. 이 글은 그 다리를 놓는 방법 — 부분 재실행(resume) 명령을 중복 없이 안전하게 설계하는 절차를 정리합니다.


왜 위험한가: 개입 지점이 곧 사고 지점이다

자동화의 각 단계는 앞 단계가 끝나야 다음으로 넘어가도록 이어져 있습니다. 사람이 중간에 끼어들어 한 단계를 수동으로 통과시키면, 그 뒤 단계를 자동으로 다시 시작할 방법이 사라집니다. 이때 갈라지는 위험은 세 가지입니다.

  • 중복 초안(실제로 발생함): 손으로 재업로드하면 이미 존재하는 초안과 겹칩니다. 어느 쪽이 최신인지 알 수 없게 됩니다. 원문 기록에서 실제로 이 문제가 발생했습니다.
  • 중복 과금(위험/방지 대상): 이미지처럼 돈이 드는 작업을 통째로 다시 돌리면, 이미 만들어 둔 것에도 다시 비용이 나갈 수 있습니다. 원문에서는 이것을 실제 발생한 사고라기보다 '없는 것만 만들도록' 막아야 할 대상으로 다뤘습니다.
  • 검수 신뢰도 저하(일반적 위험): 사람이 '고쳤다'는 말만 믿고 뒷단계를 진행하면, 실제로는 조건을 못 채운 글이 나갈 수 있습니다. 이는 재개를 설계할 때 경계해야 할 일반적 위험입니다.

세 번째와 관련해 원문 기록에는 명확한 판단 기준이 있었습니다. 사람이 '고쳤다'고 말했다는 이유만으로 뒷단계를 진행하지 않는다는 원칙입니다. 자동으로 이어지는 작업 흐름의 내부 규칙(원문에서는 '계약 5항')은 사람이 개입해도 그대로 적용됩니다. 그래서 재개할 때도 사람 말만 믿지 않고 검사를 다시 돌리도록 설계했습니다.


확인 절차: 재개 명령이 밟아야 하는 순서

재개 로직은 원문 기준으로 app/resume.py에 담겼고, 다음 한 줄로 실행합니다.

python -m app.resume <slug>

여기서 slug는 글을 가리키는 주소용 이름입니다. 이 명령이 밟는 순서는 이 자동으로 이어지는 작업 흐름에서 구현한 재개 설계의 한 사례이며, 재개 경로를 설계할 때 확인할 원칙으로 참고할 수 있습니다.

  1. 다시 검사한다. 사람이 고친 원고(draft.json)를 원문과 대조해 품질 검사를 다시 돌립니다. 통과하지 못하면 아무것도 바꾸지 않고 새 판정 결과만 남깁니다. 이 지점이 '사람 말을 믿지 않는' 방어선입니다.
  2. 빠진 것만 채운다. 통과하면 없는 이미지만 생성합니다. 원문에서는 이미 있는 장(章)에 다시 비용을 쓰지 않도록 generate_images(only_indices=...) 옵션을 새로 넣었습니다. 전체를 다시 만드는 대신 인덱스로 대상만 지정하는 방식입니다.
  3. 정상 경로로 되돌린다. 산출물을 갱신하고 대기열 상태를 '발행 대기'로 바꿉니다. 그러면 원래의 자동 발행 경로가 그 글을 자연스럽게 다시 집어갑니다. 사람이 손으로 올릴 필요가 없어집니다.

추가 안전장치도 두었습니다. 이미 임시저장된 글은 기본적으로 재개를 거부해 중복 초안을 막았고, --force를 붙였을 때만 산출물을 수정하도록 했습니다. 마지막으로 사람에게 보내는 텔레그램 알림에 재개 명령을 함께 넣어, 멈춘 글마다 '다음에 무엇을 실행하면 되는지'를 바로 알 수 있게 했습니다.


전후 비교: 재개 경로 유무가 만드는 차이

사람이 고친 뒤돌아갈 길 없음명령 한 줄로 다시 태움
이미지 채우기사람이 손으로 생성빠진 것만 자동 생성
과금통째 재실행 시 중복 과금 위험없는 것만 만들어 중복 과금 방지
중복 초안수동 재업로드 과정에서 실제 발생임시저장 글 기본 거부로 방지
재검사 후 뒷단계 연결연결 경로 없음재개 시 자동 재검사 후 연결
정상 경로 합류이어지는 자동 경로 없음발행 대기로 되돌려 자동 합류

표에서 반복되는 핵심은 하나입니다. 재개 경로의 가치는 '자동화를 다시 돌린다'가 아니라 '사람 개입 지점을 자동으로 이어지는 작업 흐름에 다시 봉합한다'는 데 있습니다.


체크리스트: 부분 재실행을 만들 때 확인할 것

  • 사람이 '고쳤다'고 말한 뒤에도 자동 재검사를 거치도록 했는가?
  • 재개가 빠진 것만 처리하는가, 아니면 통째로 다시 도는가? (비용이 드는 단계일수록 중요)
  • 이미 임시저장된 글은 기본 거부하고, 강제 실행(--force)은 명시적으로만 허용하는가?
  • 재검사에 실패하면 아무것도 바꾸지 않고 판정만 기록하는가? (되돌릴 방법 확보)
  • 산출물을 만들 때 근거로 삼는 것이 '이번에 만든 것'이 아니라 '지금 있는 것 전부'인가?
  • 멈춘 작업마다 다음 실행 명령을 알림에 함께 남기는가?

잘못하면 어떻게 되나: 재개 기능이 새 버그를 만들 뻔한 사례

재개 기능을 만드는 과정에서 원래 없던 버그를 하나 더 만들 뻔했습니다. 산출물을 정리하는 write_outputs에 '이번에 새로 만든 이미지'만 넘기면, 재개된 글의 검수 노트가 실제보다 적은 이미지 수를 표시할 수 있는 문제였습니다. 이미 있던 이미지가 집계에서 빠지는 것이죠. 실제 사고로 이어지지는 않았습니다.

여기서 얻은 원칙은 재실행 설계 전반에 적용됩니다. 부분 재실행은 전체 실행과 다르다. 전체 실행에서는 '이번에 만든 것 = 전부'라서 문제가 없지만, 부분 재실행에서는 이 등식이 깨집니다. 산출물을 만들 때 근거로 삼아야 하는 것은 '이번에 만든 것'이 아니라 '지금 있는 것 전부'여야 합니다.
또 하나의 함정은 메타데이터 손실이었습니다. 이미지의 이름표(label)와 배치 위치(placement)가 어디에도 저장돼 있지 않아, 재개할 때 원고에서 되살려야 했습니다. 중간 산출물의 부가 정보를 남겨두지 않으면, 나중에 부분 재개할 때 그것을 원고에서 복원하는 비용을 치르게 됩니다. 재실행 기능을 설계한다면, 각 단계 산출물에 '무엇을·어디에·어떤 이름으로 만들었는지'를 함께 저장해 두는 편이 뒤탈이 적습니다.


한계와 주의사항

이 재개 경로는 특정 자동으로 이어지는 작업 흐름 구조에서 나온 것이므로 그대로 복사할 수 없습니다. 함수 이름(generate_images, write_outputs), 파일 이름(app/resume.py, draft.json), 명령 형태는 각자 환경에 맞게 바꿔야 합니다. 여기서 가져갈 것은 코드가 아니라 순서와 원칙입니다.

또한 원문 기록의 수치(테스트 15건 추가, 45건 통과)나 내부 규칙 번호는 개발 시점 기준이며, 여러분의 환경 성과를 보장하지 않습니다. 재개 기능이 있다고 해서 사람 검토가 불필요해지는 것도 아닙니다. 오히려 이 설계의 전제는 '사람 개입은 계속되지만, 그 뒤를 자동으로 다시 이어 붙인다'입니다. 마지막으로, 강제 실행 옵션(--force)을 붙였을 때만 산출물을 수정하도록 분리해 두면, 평소에는 기본 거부가 그대로 지켜집니다.

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

반응형