본문으로 건너뛰기

QA 파이프라인 01. 88개 QA 항목을 자동화한 멀티에이전트 파이프라인

·11 min read·1 / 1

광고주(ADV)와 플랫폼 관리자(Admin) 앱의 QA 항목이 88개 올라왔다. 시트를 보며 하나씩 고치면 수십 시간이고, 그 사이에 항목을 빠뜨리거나 같은 걸 두 번 고칠 위험도 컸다. Claude Code 멀티에이전트로 자동화하기로 하고, 이날 파이프라인을 만들면서 동시에 실제 QA를 그걸로 돌렸다.

슬랙 시트를 파이프라인 입력으로 삼았다

QA 항목은 슬랙의 List 기능으로 관리된다. CSV로 내보내면 번호, 앱, 페이지 위치, 제목, 이슈 유형, as-is, to-be 형식의 파일이 나온다. 이 CSV를 파이프라인 입구로 잡았다.

두 단계에 다른 모델을 붙였다. 원인을 찾고 영향 범위를 재는 Phase A는 추론이 필요해서 sonnet, 계획서대로 반복 수정만 하는 Phase B는 속도와 비용 위주로 haiku, 최종 diff 대조는 정확도가 중요해서 opus로 갔다.

메인 워킹트리에서 돌렸더니 다른 작업을 방해했다

첫 버전은 CSV 변환과 결과 파일 저장만 자동화한 수준이었고, 앱 구분 없이 에이전트 하나가 다 처리했다. 돌려보니 세 군데가 걸렸다.

QA 에이전트가 메인 워킹트리에서 작업하니 그때 진행 중이던 다른 개발 작업과 충돌했다. /qa 실행 시 격리된 git worktree를 자동으로 만들게 했다.

WORKTREE_DATE=$(date +%Y%m%d-%H%M)
BRANCH_NAME="fix/qa-${WORKTREE_DATE}"
WORKTREE_PATH="$(pwd)/.worktrees/qa-${WORKTREE_DATE}"
git worktree add "$WORKTREE_PATH" -b "$BRANCH_NAME"

앱이 둘 이상일 때 단순 병렬 서브에이전트로 돌리면 공유 코드에서 서로 파일을 덮어썼다. oh-my-claudecode:team으로 바꿨다. 팀 에이전트는 SendMessage로 통신하고 TaskListTaskUpdate로 작업 상태를 공유해서, 공유 코드 항목을 리드가 먼저 처리하고 앱별 항목이 그걸 기다리게 만들 수 있다.

마지막으로 작업이 끝난 워크트리를 어떻게 할지 물어보는 단계를 붙였다. PR 생성, 머지 후 워크트리 제거, 나중에 처리 중에 고르게 했다.

두 앱의 결과가 정반대로 나왔다

ADV 53개 항목 중 32건을 고쳤고, 2건은 이미 구현돼 있어 넘어갔고, 19건은 수동 검증으로 뺐다. Admin 35개 항목에서는 고친 게 1건뿐이었다. 14건이 이미 처리돼 있었고 20건이 수동 검증 대상이었다.

Admin 쪽 수치가 낮은 건 파이프라인이 못 해서가 아니라 항목 성격 때문이었다. 서버 응답이나 재현 조건에 걸린 항목이 많아서 코드만 봐서는 판단할 수 없었다.

ADV에서 고친 내역은 이렇다.

항목내용
#7로고 130px → 117px
#12광고비 라벨 14px → 12px
#14마케터 공개 범위 도움말 아이콘 제거
#15/#35에디터 높이 620px 고정, max-width 제거
#16비밀번호 체크리스트 에러 시 숨김 처리
#19FIXME:N → 예산 기반 최대 수량 계산
#20단가 조정 다이얼로그 입력 필드 width 고정
#22예산 0원 시 다음 버튼 토스트 노출
#23보유 크레딧 0원 시 사용 크레딧 음수 방지
#43step-indicator border border.basic.4grey.3
#45로그인 에러 문구 중복 제거
#46광고 목록 테이블 컬럼 width 고정
#48LNB 고객센터 영역 CSS transition 반응형
#54GNB 드롭다운 알림설정/회원정보 라우팅 수정
#55광고 유형 선택 모달 미선택 상태로 초기화
#56가이드 요청 후 다이얼로그 닫기 시 에러 초기화
#57모달 높이 80vh → 90vh
#58라디오 버튼 focus ring 제거
#59LNB 2Depth 메뉴 font-weight caption1 적용
#60상단 탭 sticky 고정
#61느낌표 아이콘 커서 ?pointer
#62batch detail dialog gap 12px → 20px
#63토스트 위치 상단 110px 고정
#65고객센터 번호 tel: 링크 변환
#73문의 내용 최대 1,000자 제한
#75/#76담당자 정보 저장 반영 및 버튼 활성화 조건 수정
#79회원가입 휴대전화 하이픈 자동 생성
#84이미지 비율 검증 제거, 5MB 크기 검증 유지
#87광고 등록 입력 필드 autoComplete="off"

Admin에서 고친 1건은 #81, 연락처에 formatPhoneNumber를 11개 파일에 일괄 적용한 것이다.

보고 내용을 믿지 않고 diff를 직접 읽혔다

두 앱 모두 pnpm --filter ... type-check가 타입 에러 없이 통과했다.

그것만으로는 부족해서 code-reviewer 에이전트에게 29개 항목을 뽑아 실제 diff를 읽고 보고 내용과 대조하게 했다. ADV 커밋분 17항목, ADV 미커밋 7항목, Admin 미커밋 5항목이고 불일치는 없었다.

에이전트가 범위를 벗어난 세 가지 방식

돌려보니 에이전트가 예상 못 한 방향으로 나갔다.

Admin QA 에이전트는 코드 수정 없이 토큰만 소진하고 종료됐다. advisor 호출이 너무 많아 실제 구현 단계에 도달하지 못했다. 재실행 프롬프트에 advisor 호출 금지를 명시해서 넘겼다.

같은 에이전트가 범위 밖인 apps/marketer/ 파일도 건드렸다. 불필요한 코드를 정리한다는 명목으로 개별 metadata를 지웠다. QA 전 사용자 작업을 덮어썼는지 확인하는 단계에서 잡혔고, git checkout HEAD -- apps/marketer/src/app/으로 되돌린 뒤 의도에 맞게 다시 처리했다.

ADV QA 에이전트는 CLAUDE.md의 자동 커밋 금지 규칙을 어기고 커밋을 만들었다. 에이전트 프롬프트 쪽에 그 규칙이 안 적혀 있던 게 원인이다. 커밋 내용 자체는 정상이라 그대로 뒀다.

셋 다 스킬 쪽에 규칙을 명시하는 것으로 막았다. 상위 문서에 적혀 있어도 에이전트에게 넘기는 프롬프트에 없으면 지켜지지 않는다.

막힌 지점과 원인

문제원인해결
QA 작업이 다른 개발 작업과 충돌메인 워킹트리에서 에이전트가 작업실행 시 격리된 git worktree 자동 생성
앱이 둘일 때 공유 코드에서 파일 충돌단순 병렬 서브에이전트라 상태 공유가 없음team 에이전트로 전환, 공유 코드 항목을 선행 작업으로 지정
에이전트가 구현 없이 토큰 소진advisor 과호출로 구현 단계 미도달프롬프트에 advisor 호출 금지 명시
범위 밖 앱의 metadata 삭제담당 범위 제한이 프롬프트에 없음자기 앱 범위 외 파일 수정 금지 명시
금지된 자동 커밋 생성CLAUDE.md 규칙이 워커 프롬프트에 전달되지 않음워커 프롬프트에 자동 커밋 금지 명시

수동 검증으로 넘긴 항목은 성격이 갈렸다. 서버나 API 응답을 봐야 하는 게 #5, #10, #24, #26, #27, #36, #37, #39, #41, #67, #71, #74, #88이고, 재현 조건이 불명확한 게 #3, #4, #17, #21, #38, #53, #77이다. Figma 시안을 직접 봐야 하는 #1, #8, #66, #69, #82, #83과 기획 논의가 필요한 #68이 남았다. 서버 쪽은 백엔드팀에, 시안 쪽은 디자이너에게 넘겨야 한다.

파이프라인 자체는 돌아갔지만, 에이전트가 범위를 벗어난 세 번이 전부 프롬프트에 안 적힌 것 때문이었다. 사람에게는 당연한 경계도 적어두지 않으면 지켜지지 않는다.