n8n과 Claude로 구축하는 프론트엔드 팀의 'AI 코드 리뷰어'
안녕하세요, 프론트엔드 개발팀입니다. 프로젝트 규모가 커지고 MR(Merge Request)이 쏟아지면서, 저희는 "어떻게 하면 비즈니스 로직에 더 집중하면서도 사내 코딩 컨벤션을 완벽하게 지킬 수 있을까?"라는 고민에 빠졌습니다. 이를 해결하기 위해 도입한 n8n 기반의 'AI 코드 리뷰어' 구축기를 공유합니다.
n8n: 자동화 워크플로우 tool 의 선택
가장 먼저 해결해야 할 과제는 다양한 도구(GitLab, Slack, LLM)를 하나로 묶어줄 '자동화 툴'을 선택하는 것이었습니다. 저희는 n8n을 선택했습니다.
n8n은 다른 자동화 도구와 차별화되는 강력한 통합 환경을 제공합니다.
방대한 연결성: 2025년 5월 기준으로 약 1,000개가 넘는 서비스와 즉시 연동됩니다. 슬랙, 구글 시트, 지라(Jira) 등 일상적인 협업 도구는 물론, 최신 AI 서비스들까지 폭넓게 지원합니다.
AI 에코시스템 구축: ChatGPT, Claude, Gemini와 같은 LLM들을 워크플로우 내부에 'AI 에이전트' 형태로 쉽게 통합할 수 있어, 단순히 데이터를 옮기는 것을 넘어 '판단'이 가능한 워크플로우를 만들 수 있습니다.
시각적 워크플로우: 백엔드 작업 없이도 노드를 연결하여 서비스 간 연관성을 한눈에 파악하고 제어할 수 있습니다.
n8n 설치 및 초기 세팅
저희는 보안과 관리 편의성을 위해 Docker를 사용하여 n8n을 구축했습니다.
Docker 설치: 복잡한 설정 없이 명령어 몇 줄로 서버를 바로 시작할 수 있습니다. 특히 데이터 보존을 위해 볼륨 설정을 추가했습니다.
Bash# n8n 실행 예시 docker volume create n8n_data docker run -it --rm --name n8n -p 5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n계정 생성: 설치 후 브라우저에서
http://localhost:5678에 접속하면 소유자 계정(Owner Account) 설정 화면이 나타나며, 이를 통해 보안이 강화된 독립적인 자동화 환경을 시작할 수 있습니다.
실전 인프라: AWS 사설망과 Docker 환경 구축 전략
코드 리뷰 자동화 시스템은 단순히 코드를 짜는 것보다 "어디서, 어떻게 안정적으로 돌릴 것인가"가 더 중요합니다. 저희 팀이 t3.medium 사양의 EC2 하나로 5일째 무중단 운영 중인 인프라 일부의 명세와 튜닝 기록을 공개합니다.
① 인프라 구성 명세 (Overview)
보안과 성능을 모두 잡기 위해 서울 리전 내에 독립된 VPC 환경을 구성했습니다.
항목 | 내용 |
인프라 | AWS EC2 (ap-northeast-2, 서울 리전) |
인스턴스 | t3.medium (vCPU 2, RAM 4GB) |
n8n 버전 | n8nio/n8n:2.17.5 (stable) |
런타임 | Node.js 24.14.1 (Alpine 3.22 기반) |
GitLab 통신 단절과 사설망 라우팅을 위한 인프라 보완 작업
n8n 서버에서 사내 GitLab으로 API 연동 시 타임아웃이 발생했습니다. 분석 결과, 트래픽이 외부망(WAF)을 거치려다 보안 정책에 의해 드랍(Drop)되는 것이 원인이었습니다.
해결책: VPC 아키텍처 재설계 및 Docker 매핑
Docker
extra_hosts활용: 내부 DNS 서버 없이도 GitLab 사설 IP를 직접 인식하도록docker-compose.yml에 도메인 맵핑을 추가했습니다.
# docker-compose.yml 핵심 설정
services:
n8n:
restart: always
extra_hosts:
- "gitlab.XXXX" # 내부 GitLab 도메인 직접 매핑
volumes:
- XXX # 워크플로우 데이터 영속성 보장504 Gateway Timeout: AI의 침묵
AI 리뷰는 코드 분석 양에 따라 응답 시간이 수십 초에서 분 단위까지 길어집니다. 초기 설정에서는 Nginx나 n8n 내부 타임아웃으로 인해 504 Gateway Timeout이 빈번하게 발생했습니다.
해결책: 5분(300,000ms)의 여유, 타임아웃 튜닝 AI가 충분히 고민할 시간을 벌어주기 위해 n8n 환경 변수를 다음과 같이 최적화했습니다.
# n8n 환경 변수 설정 (타임아웃 및 보안)
N8N_PAYLOAD_SIZE_MAX=100 # 워크플로우 저장을 위한 용량 확보
N8N_EXTERNAL_FRONTEND_TIMEOUT=300000 # UI↔서버 타임아웃 5분 연장
N8N_BLOCK_TIMEOUT=300000 # 내부 작업 타임아웃 5분 연장워크플로우 일부 들여다보기: 지능형 루프와 폴백 시스템
기획한 n8n 워크플로우는 AI 에이전트의 결과를 단순한 직선형 구조로 처리하지 않고 리뷰 항목을 반복 처리(Loop)하며 각 단계마다 정밀한 판단을 수행합니다.
리뷰 항목 반복 처리 (Loop): 여러 파일의 변경 사항을 하나씩 순회하며 개별 코멘트를 생성합니다.
지능형 분기 (If Node): 이슈 존재 여부와 인라인 코멘트 가능 여부를 판단하여, 가장 적절한 피드백 채널을 선택합니다.
자가 치유 폴백 (Fallback): GitLab의 API 특성상 특정 라인의 SHA 값이 일치하지 않아 인라인 등록에 실패할 경우, '에러 알림' 노드를 거쳐 '일반 코멘트'로 재시도하여 리뷰 유실을 원천 차단합니다.
토큰 관리 전략: "무엇을 버릴 것인가"
AI 리뷰 시스템의 핵심은 비용 효율성과 정확도입니다. 전체 Diff를 그대로 전달하면 토큰 낭비가 심하므로, n8n의 Custom JS Code 노드를 통해 데이터를 최적화했습니다.
노이즈 제거:
package-lock.json, 이미지, SVG 등 리뷰가 불필요한 파일을 필터링하는 전략을 추구하였습니다.코드 압축: 삭제된 라인이 길 경우
[Deleted]표시로 압축하여 컨텍스트 공간을 확보합니다.거대 MR 대응: 2,000줄 이상의 변경 사항은 하단부를 잘라내고 시스템 메시지를 통해 AI가 '거대 변경'임을 인지하게 하여 인풋 토큰을 60% 이상 절감했습니다.
사내 가이드를 읽는 AI: 프롬프트 엔지니어링
AI가 단순한 텍스트 생성을 넘어, 우리 팀의 코드 품질을 책임지는 '리뷰어'로 작동하게 하려면 정교한 시스템 프롬프트 설계가 필수적입니다. 저희는 n8n 내에서 Claude의 System Prompt와 User Message 형식을 구조화했습니다.
① 페르소나와 리뷰 철학의 정의
단순히 "리뷰해줘"가 아닙니다. AI에게 '10년 차 이상의 한국인 시니어 프론트엔드 개발자'라는 구체적인 페르소나를 부여했습니다.
실용적 리뷰: 사소한 취향(Style) 지적은 배제하고, 실제 버그, 보안 취약점, 성능 저하, 사내 가이드 위반을 최우선으로 탐지하도록 철학을 주입했습니다.
근거 중심: 추측성 리뷰를 금지하고, 반드시 diff 내에 존재하는 명확한 근거가 있을 때만 지적하게 하여 신뢰도를 높였습니다.
② 다이내믹 가이드라인 주입 (Dynamic Injection)
우리 팀의 규칙은 살아 움직입니다. 프롬프트 내에 고정된 규칙 대신, 프로젝트 저장소의 가이드라인 파일을 실시간으로 읽어와 주입하는 로직을 구현했습니다.
실시간 업데이트:
project-guide.md가 수정되면 AI의 리뷰 기준도 즉시 바뀝니다.폴백(Fallback) 메커니즘: 가이드 파일 조회 실패 시를 대비해, 네이밍 컨벤션(
list접미어,is/has접두어), 객체 구조 분해 할당 권장 등 핵심 FE 규칙을 기본값으로 내장하여 안정성을 확보했습니다.
③ 엄격한 출력 스키마와 자동화 호환성
n8n의 다음 노드(GitLab API 호출, Slack 전송)가 에러 없이 작동하려면 AI의 응답 형식이 100% 일관되어야 합니다. 이를 위해 'Strict JSON Schema' 전략을 사용합니다.
Zero-Tolerance Formatting: 마크다운 코드 펜스(```)나 서술형 문구를 일체 금지하고, 오직 순수한 JSON 객체만 반환하도록 강제했습니다.
판단 지표의 정형화: * Severity: 🔴수정 필요, 🟣기존 코드 이슈, 🟡가벼운 의견으로 분류.
RiskLevel: 지적 사항의 개수와 중요도에 따라 High/Medium/Low를 자동 판정.
Traceability: 문제가 된 파일 경로와 정확한 라인 번호(
file_line_path)를 명시.
④ 컨텍스트 최적화 (Context Mapping)
AI가 MR의 전체 맥락을 파악할 수 있도록 단순 코드가 아닌 '메타 데이터'를 함께 전달합니다.
MR 컨텍스트: Base/Head SHA 정보, 전체 파일 수, 리뷰에서 제외된 파일 리스트 등을 요약하여 제공합니다.
Diff 구조화: 각 변경 사항을
[FILE_PATH],[CHANGE_TYPE],[DIFF_CONTENT]등의 태그로 래핑하여 AI가 구조적으로 코드를 읽을 수 있게 맵핑했습니다.
[참고] 실제 시스템 프롬프트 일부 구성 (Schema)
저희 시스템이 Claude에게 요구하는 응답 스키마는 다음과 같습니다. 이 규격을 통해 모든 리뷰 결과가 데이터화됩니다.
JSON
{
"RiskLevel": "High" | "Medium" | "Low",
"Summary": "한 줄 요약",
"Issues":
[{
"PotentialIssue": "이슈 설명 (가이드 위반 시 프리픽스 포함)", "Severity": "🔴 수정 필요" | "🟡 가벼운 의견" | "🟣 기존 코드 이슈", "file_path": "파일 경로","file_line_path": 123
}]
}4. 지속 가능한 운영 및 유지보수
시스템을 안정적으로 운영하기 위해 다음과 같은 장치를 마련했습니다.
Google Sheets 기록: 사용 모델, 소요 시간, 토큰 사용량을 기록하여 비용을 모니터링하고 Risk Level 통계를 통해 팀의 코드 품질 추이를 확인합니다.
에러 폴백(Fallback): GitLab 인라인 코멘트 등록 실패 시, 일반 코멘트로 자동 전환하여 AI의 리뷰 의견이 유실되지 않도록 이중화했습니다.
슬랙 스레드 연동: 리뷰 시작 시 "리뷰 중..." 메시지를 남기고, 완료 시 스레드 답글로 요약을 전송하여 개발자가 작업 흐름을 끊지 않고도 심각도를 인지할 수 있게 했습니다.
실전 사례: 복잡한 예외 상황과 런타임 에러 추적
단순히 "코드가 깔끔한가?"를 넘어, AI 리뷰어가 실제 프로젝트의 비즈니스 흐름을 이해하고 잠재적인 서비스 장애 요인을 잡아낸 구체적인 사례를 소개합니다.
Case A: 런타임 에러 방어 (Critical)
상황: 상품 관련 로직 추가 중
productList[0]에 직접 접근.AI의 지적: "productList가 빈 배열로 들어올 경우
Cannot read properties of undefined에러가 발생하여 결제/신청 단계에서 앱이 뻗을 수 있습니다."가치: 타입 정의만으로는 잡기 힘든 실질적인 런타임 안정성을 확보했습니다.
Case B: 비즈니스 로직의 불일치 (UX/Policy)
상황: '바로 신청하기'에는 로그인 체크 로직이 추가되었으나, '장바구니 담기' 버튼에는 누락됨.
AI의 지적: "동일한 진입점인데 버튼에 따라 로그인 정책이 다른 것은 사용자 경험의 일관성을 해칩니다."
가치: 단순 코드 리뷰를 넘어 서비스 기획 의도와 정책의 일관성을 재점검하게 합니다.
Case C: 불필요한 설정 및 중복 (Maintenance)
지적 내용: 실제 사용되지 않는
eslint-disable주석 제거 및 모달/바텀시트 간의 중복된 신청 로직 통합 제안.가치: 기술 부채를 쌓지 않고 팀의 전체적인 코드 품질 유지보수 공수를 줄여줍니다.
마치며: 개발자는 더 중요한 것에 집중합니다
이 시스템 도입 이후, 프론트엔드 팀은 단순 컨벤션 지적에서 조금씩 자유로워지고 있습니다. 대신 아키텍처 설계와 비즈니스 로직에 대해 더 깊이 있는 대화를 나누기 시작했습니다.
자동화는 단순히 손을 편하게 하는 것이 아니라, 팀의 에너지를 어디에 집중할지 결정하는 전략입니다. n8n과 AI의 결합은 그 전략을 실현하는 좋은 방법 중 하나이며 우리 팀은 그 부분을 채택하였습니다.