LLM 지원 배포: 타이핑 시간은 줄어들지만, 사고 과정은 줄어들지 않는다
요약
LLM을 활용한 배포 스크립트 작성 시, 코드 작성 시간은 단축하되 핵심 로직과 결정권은 개발자가 유지해야 함을 강조합니다. 무조건적인 자동화 대신 명시적인 제어 지점과 검증 단계를 설계하는 반자동화 접근법을 제안합니다.
핵심 포인트
- LLM은 타이핑 시간을 줄여주지만 사고 과정은 대체할 수 없음
- 리스크가 큰 결정과 로직 확인은 반드시 수동으로 유지해야 함
- 배포 프로세스에 텍스트 기반 캡차 등 의도적인 제어 지점 도입 권장
- 사전 운영 환경(preprod)과 운영 환경(production)의 명확한 분리 필요
요약 (TL;DR)
LLM의 도움을 받아 약 한 시간 만에 배포(deploy) 프로세스를 구성할 수 있었지만, 이는 제가 배포 자체를 LLM에 통째로 맡기지 않았기 때문에 가능했습니다.
발생한 상황
저는 배포 스크립트(deploy scripts)를 작성하는 방법을 알고 있습니다. 이론적인 내용이 아니라, 실제로 여러 번 해보았으며 보통은 그냥 앉아서 바로 작성하곤 합니다.
이번에 문제는 작성하는 '방법'이 아니었습니다. 문제는 '시간'이었습니다. 그리고 저는 그 과정에서 무엇인가를 망가뜨리고 싶은 마음이 전혀 없었습니다.
그래서 저는 "LLM이 이것을 깔끔하게 정리해 줄 거야"라는 식의 게임을 하지 않았습니다. 반자동 배포(semi-automated deployment)에서 그런 방식은 유난히 좋지 않은 생각입니다. 아름다운 결과물 대신, 바닥에 굴러다니는 아름답게 망가진 사이트를 얻게 될 뿐입니다.
저는 다른 방식을 택했습니다.
이전 경험을 바탕으로 스크립트 구조를 직접 정의했습니다. 배포가 정확히 무엇을 해야 하는지, 경계(boundaries)는 어디인지, 어떤 제어 지점(control points)이 존재하는지, 무엇이 성공으로 간주되는지, 그리고 무엇이 진행을 중단해야 하는 이유인지 상세히 설명했습니다. 그런 다음 그 텍스트를 LLM에 입력하여 bash 스크립트를 작성하게 했습니다.
다시 말해, 모델은 오류의 비용이 상대적으로 저렴한 부분, 즉 코드를 타이핑하는 부분을 도와주었습니다.
실제로 비용(리스크)이 발생하는 모든 부분은 수동으로 유지했습니다. 결정, 검토, 로직 확인, 그리고 안전한 환경에서의 실행이 그러합니다.
결과적으로 저는 두 개의 스크립트를 얻었습니다: deploy-preprod.sh와 deploy-production.sh.
저에게는 이러한 분리가 중요했습니다. 프로덕션(Production)은 그냥 바로 "가버려"해서는 안 됩니다. 먼저 프리프로드(preprod) 관문을 거친 다음, 프로덕션으로 가야 합니다. 또한 저는 프로덕션 배포 확인을 위한 저만의 표준적인 트릭을 유지했습니다. 일종의 텍스트 기반 캡차(captcha)입니다. 스크립트가 콘솔에 무작위 코드를 출력하면, 사용자가 이를 직접 손으로 입력할 때까지 아무것도 진행되지 않습니다. 이것은 악의적인 해커를 막기 위한 것이 아닙니다. 너무 쉽고 너무 기계적인 "좋아, 그냥 배포해 버리자"라는 식의 태도로부터 스스로를 보호하기 위한 것입니다.
총 4번의 반복(iterations)이 필요했습니다. 솔직히 말해서, 이것은 접근 방식이 나빴다는 신호가 아닙니다. 오히려 그 반대입니다.
그 과정들을 거치면서, 배포를 위험하게 만드는 전형적인 쓰레기들이 정확히 나타났습니다. 오타, 잘못된 변수, 형편없는 로그 파싱 같은 것들 말이죠. 개념적으로 흥미로운 것은 아무것도 없었습니다. 코드 자체는 꽤 경쾌해 보였습니다. 아이러니하게도 그 코드는 LLM이 작성했다는 점입니다. 아마 LLM도 서두르고 있었고, 세계 정복에 집중하느라 주의가 분산되는 것을 원치 않았던 모양입니다.
제 검증 방식 또한 "음, 꽤 합리적으로 보이네" 같은 식의 유형도 아니었습니다. 컨테이너가 시작된 후 더 신뢰할 수 있는 접근 방식은 docker-compose 로그를 자동으로 스캔하여 명백한 에러 징후를 찾는 것입니다. 그다음 수동 스모크 테스트 (smoke check) — 즉, 로그인하여 주요 흐름을 따라가며 확인하는 과정을 거칩니다. e2e (end-to-end) 테스트도 생각했지만, 이 작업에는 과하다고 판단했습니다. 제가 그 순간 필요했던 것은 완벽한 자동화 윤곽이 아니라, 명시적인 제어 지점과 예측 가능한 실패 동작을 갖춘 재현 가능한 배포였습니다.
이것을 실제 스크립트에 적용해 보면, "가속화"와 "제어권 양도" 사이의 경계가 꽤 명확해집니다:
- preprod (사전 운영 환경)는 배포 자체를 수행하기 전 운영 사이트의 정확한 복사본을 재현합니다. 사이트 규모가 작기 때문에 가능한 일입니다.
- production (운영 환경)은
latest태그를 사용하여 실행하는 것을 거부합니다. - production은 동일한 태그에 대해 아무 작업도 수행하지 않는 no-op 배포를 거부합니다.
- production 단계 이전에 preprod 게이트가 실행되며, preprod에서 조금이라도 문제가 발생하면 실패합니다.
- Postgres가 올라오지 않으면 명시적인 실패가 발생합니다.
error,exception,traceback,panic,fatal에 대한 로그 체크가 수행됩니다.- production 단계 이전에 수동 확인 절차가 있습니다.
따라서 LLM이 "배포를 수행한" 것이 아닙니다. LLM은 제가 이미 정의해 둔 구조와 일련의 제약 조건 주위에 코드를 조립하도록 도와준 것입니다.
결과적으로, 약 한 시간 정도가 소요되었습니다.
시사점 (Takeaways)
LLM은 시간을 절약해 주었지만, 많은 사람이 꿈꾸는 방식으로는 아니었습니다. 책임(responsibility)에 대해서는 아닙니다. 엔지니어링 결정(engineering decision)에 대해서도 아닙니다. 검증(verification)에 대해서도 아닙니다. LLM은 초안 단계, 즉 키보드를 두드리는 시간을 압축해 주었습니다. 모든 결정적인 부분은 여전히 수동 엔지니어링 작업이었습니다.
이러한 작업의 경우, 제정신인 LLM 지원 (LLM-assisted) 모드는 다음과 같은 모습이어야 합니다. 모델에 리스크를 위임하지 마십시오. 대신 기계적인 부분을 제거하는 데 모델을 사용하여, 아키텍처 (architecture)와 실수가 실제로 큰 비용을 초래하는 제어 지점 (control points)에 더 많은 주의를 기울일 수 있도록 하십시오.
1분의 사고가 1시간의 가동 시간 (uptime)을 늘려줍니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기