Skip to content
isdnetworks
Go back

AI 에이전트 세션을 기능이 아니라 배포 경계로 나눠 넘겨받은 시스템을 운영했다

넘겨받은 커머스는 GitHub 조직에 fork 가 아닌 활성 저장소만 146개였다. 사람 한 명이 이 전부를 직접 손대기는 어렵다. 그래서 처음부터 AI 코딩 에이전트 세션 여러 개를 띄워 영역을 나눠 맡기고, 사람은 결정과 승인을 맡는 구조로 운영했다. 문제는 나누는 기준이었다. 처음 기준이 틀렸고, 그것을 드러낸 것은 하마터면 충돌할 뻔한 수정 한 건이었다.

Table of contents

Open Table of contents

배경 — 기능별 분할과 한 파일의 두 수정

처음에는 과업 번호, 즉 기능을 기준으로 세션을 나눴다. 그랬더니 같은 저장소를 여러 세션이 만졌다. 하루는 백오피스 JavaScript 파일 하나를 한 세션은 택배사 처리 788행 때문에, 다른 세션은 가드 10곳 때문에 각자 고쳤다. 둘이 충돌하지 않은 것은 우연이었다.

원인은 기능이 시스템 경계와 맞지 않는다는 데 있었다. 기능 하나는 여러 시스템에 걸치는데, 시스템마다 배포 수단이 완전히 달랐다.

PHP 백오피스 세 벌은 VM 에서 sudo 로 파일을 직접 바꿔 끼우고 git 으로 관리되지 않는다. 고객·주문 백오피스는 GKE 클러스터에 Docker 이미지를 빌드해 rollout 하고, iOS·Android 앱은 App Store 와 Play 의 심사를 거친다. 공장·출고 서버는 Firebase Functions 로 배포하고, 메일 서비스는 Amazon SES 위에 새로 짓는 중이었다. 한 기능을 끝까지 맡은 세션은 이 다섯 가지 배포 절차를 모두 오가야 했다.

판단 — 배포 경계라는 축의 기준

나누는 기준은 두 가지가 있었다.

  1. 기능(과업)별로 세션을 나눈다. 기능 하나를 처음부터 끝까지 한 세션이 맡는다
  2. 시스템(배포 경계)별로 세션을 나눈다. 그 시스템의 저장소·배포 권한·환경을 한 세션이 소유한다

1번 대신 2번을 고른 이유는 충돌과 사고가 생기는 자리가 배포 경계이기 때문이다. 같은 저장소를 두 세션이 고치면 서로의 변경을 모르고, 배포 수단이 다른 시스템을 한 세션이 오가면 배포 절차를 틀리기 쉽다. 반면 기능 하나가 여러 시스템에 걸치면 누군가 그것을 쪼개 배정하고 결과를 모아야 한다. 그 역할은 메인 세션이 맡는다. 세션은 시스템 소유자이고, 메인은 기능 조율자다. 대가는 기능 하나에 세션 사이 전달이 여러 번 생긴다는 점이다.

이 기준으로 다시 그린 축은 일곱 개다.

app 은 iOS·Android 앱과 인증서 저장소를 갖고 App Store·Play 로 내보낸다. shop 은 고객 웹·선물 웹·결제 화면을, core 는 API 모노레포와 결제 게이트웨이와 문자 API 를 갖는데, 두 축의 배포 수단은 아직 확인 중이었다(core 는 Jenkins 로 추정). backoffice 는 PHP 백오피스 세 벌과 CRM 을 VM 에서 직접 교체하고, 주문 백오피스 축은 고객·주문 관리와 공장 서버를 GKE 와 Firebase Functions 로 배포한다. platform 은 Terraform·GCP·Firebase·Jenkins·GitHub 조직 설정·자격증명 같은 인프라 전체를 맡고, transition 은 새로 짓는 메일 서비스와 저장소가 없는 계약·양수도 업무를 맡는다.

세션 이름은 한 단어 소문자로 짓고 저장소 접두사와 맞췄다. 메시지를 주고받을 때 주소로 쓰이므로 짧아야 하고, 저장소 이름에서 바로 떠올릴 수 있어야 기억 비용이 준다. 재편은 개명 3, 신설 3, 유지 1이었다. 개명은 같은 세션이라 맥락이 깨지지 않지만, 신설 세 개는 인계가 필요했다. 셋 다 하나의 기존 세션에서 나왔는데, 그 세션이 세 축 분량을 들고 있어 조사는 끝냈는데 실행이 승인 대기로 막혀 있었다.

해결 — 맥락 이관 규약

새 세션에 일을 넘길 때는 아래 다섯 규칙을 따른다. 앞서 한 축에서 다른 축으로 푸시 발송 업무를 넘길 때 실제로 통한 방식을 그대로 규약으로 굳혔다.

  1. 인계 문서는 하나로 만들고, 받는 쪽이 그 문서 하나만 읽으면 바로 착수할 수 있게 쓴다
  2. 미결은 무엇이 누구의 결정을 기다리는지까지 이름을 붙여 명시한다
  3. 조사에서 드러난 한계와 함정을 담아 받는 쪽이 같은 함정을 다시 밟지 않게 한다
  4. 넘긴 뒤에는 그 일을 거론하지 않고, 진행을 추적하는 것도 받는 쪽 몫으로 둔다
  5. 실측값은 다시 타이핑하지 않고, 파일 경로를 주어 받는 쪽이 그 파일을 직접 읽게 한다

다섯 번째가 가장 중요했다. 값을 옮겨 적으면 옮기는 순간 원본과 갈라질 수 있다. 같은 이유로 각 세션의 부팅 문서에도 공통 규약을 복사하지 않고 정본 경로만 적었다. 규약이 개정되면 복사본이 조용히 갈라지기 때문이다.

영향 범위 — 부하 대신 축을 따르는 배분

배분 원칙도 함께 정했다. 일은 축이 맞는 세션에만 준다. 한가하다는 이유로 다른 축의 일을 넘기면, 세션 이름이 단순한 식별자가 되고 받는 쪽은 맥락이 없어 처음부터 조사해야 한다. 그 편이 오히려 느리다. 축 하나가 과부하면 부하를 옮기지 않고 축을 쪼갠다. 이번 재편이 바로 그 원칙의 첫 적용이었다. 어느 축에도 속하지 않는 데이터·공통 저장소 60개는 지금 업무에 나오지 않아 비워 두고, 필요해지면 platform 이 받거나 새 축을 세운다.

결과 — 배포 경계로 나눈 세션의 운영

정리


Share this post on:

Previous Post
브라우저 코드에 박힌 Slack 토큰은 바꿔 끼우지 않고 경유지를 세워 없애기로 했다
Next Post
넘겨받을 시스템의 범위를 정책을 기다리는 과업과 기다리지 않는 과업으로 갈랐다