지난 글에서 AI 코딩 도구를 효과적으로 쓰는 5가지 원칙을 살펴봤다. 이번 주제는 AI 코드 리뷰다. AI가 코드를 생성하는 것을 넘어, 생성된 코드를 다시 AI가 검토하는 파이프라인을 구축하면 팀의 코드 품질을 24/7 자동으로 지키는 시스템이 완성된다.
AI 코드 리뷰가 필요한 이유
전통적인 코드 리뷰의 문제점은 세 가지다.
- 병목: 리뷰어가 바쁘면 PR이 쌓인다
- 일관성 부족: 리뷰어마다 기준이 다르다
- 피로: 반복적인 스타일 지적에 시간을 낭비한다
AI 리뷰는 이 세 문제를 해결한다. 보안 패턴 확인, 코딩 컨벤션 검사, 기본적인 논리 오류는 AI가 즉각적으로, 일관된 기준으로 처리하고, 사람 리뷰어는 비즈니스 로직과 아키텍처에 집중한다.
리뷰 시스템 설계
AI vs 사람 역할 분담
| 검토 항목 | AI | 사람 |
|---|---|---|
| 보안 취약점 패턴 | ✅ | 보완 |
| 코딩 컨벤션 | ✅ | - |
| 기본 에러 처리 | ✅ | - |
| N+1 쿼리 패턴 | ✅ | - |
| 비즈니스 로직 타당성 | ⚠️ 보조 | ✅ |
| 아키텍처 적합성 | ⚠️ 보조 | ✅ |
| 팀 문화·맥락 | ❌ | ✅ |
| 최종 승인 책임 | ❌ | ✅ |
Claude API로 리뷰봇 구축
import anthropic
import subprocess
import sys
client = anthropic.Anthropic()
def get_pr_diff(base_branch: str = "main") -> str:
"""현재 브랜치의 diff 가져오기"""
result = subprocess.run(
["git", "diff", f"{base_branch}...HEAD"],
capture_output=True, text=True
)
return result.stdout
def review_code(diff: str, project_context: str = "") -> str:
"""
Claude로 코드 리뷰 실행
"""
system_prompt = f"""당신은 시니어 소프트웨어 엔지니어입니다.
코드 변경사항을 리뷰하고 다음 형식으로 보고해주세요:
## 요약
변경사항의 간단한 설명
## 이슈
각 이슈를 다음 형식으로:
- 🔴 **Critical**: [파일명:라인] 문제 설명과 수정 방법
- 🟡 **Warning**: [파일명:라인] 문제 설명과 개선 방법
- 🔵 **Info**: [파일명:라인] 개선 제안
## 잘된 점
좋은 코드 패턴이 있다면 언급
{f"## 프로젝트 컨텍스트{chr(10)}{project_context}" if project_context else ""}
"""
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=4096,
system=system_prompt,
messages=[{
"role": "user",
"content": f"다음 diff를 리뷰해주세요:\n\n```diff\n{diff}\n```"
}]
)
return response.content[0].text
def main():
diff = get_pr_diff()
if not diff:
print("변경사항이 없습니다.")
return
# 너무 큰 diff 처리 (4000줄 제한)
lines = diff.split('\n')
if len(lines) > 4000:
diff = '\n'.join(lines[:4000]) + "\n... (이후 생략)"
print(f"⚠️ Diff가 너무 커서 처음 4000줄만 리뷰합니다.")
print("🤖 AI 코드 리뷰를 시작합니다...\n")
review = review_code(diff)
print(review)
# Critical 이슈가 있으면 비정상 종료 (CI 블로킹)
if "🔴" in review:
print("\n❌ Critical 이슈가 발견되었습니다. 수정 후 재시도하세요.")
sys.exit(1)
else:
print("\n✅ Critical 이슈 없음. 리뷰를 완료했습니다.")
if __name__ == "__main__":
main()
GitHub Actions 통합
# .github/workflows/ai-code-review.yml
name: AI Code Review
on:
pull_request:
types: [opened, synchronize]
paths:
- '**.py'
- '**.ts'
- '**.go'
jobs:
ai-review:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: pip install anthropic
- name: Run AI Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: python scripts/ai_review.py
- name: Post Review Comment
if: always()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const review = fs.readFileSync('review_output.txt', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## 🤖 AI 코드 리뷰\n\n${review}\n\n> [AI Generated] This review was automatically generated by Claude.`
});
Claude Code의 /review 슬래시 커맨드
Claude Code를 쓴다면 별도 스크립트 없이도 코드 리뷰가 가능하다.
# 현재 브랜치의 변경사항 리뷰
claude "/review"
# 특정 파일 리뷰
claude "app/services/payment.py를 보안 관점에서 리뷰해줘"
# 마지막 커밋 리뷰
git diff HEAD~1 | claude -p "이 변경사항의 보안·성능 이슈를 분석해줘"
리뷰봇 프롬프트 튜닝
리뷰봇의 품질은 프롬프트 품질에 달려 있다. 팀에 맞게 조정해야 한다.
# 팀 규칙을 시스템 프롬프트에 통합
TEAM_REVIEW_PROMPT = """
당신은 우리 팀의 시니어 개발자입니다. 다음 팀 규칙을 기준으로 리뷰하세요:
## 필수 확인 항목
1. 보안: SQL 인젝션, XSS, CSRF, 인증 누락
2. DB: N+1 쿼리, 인덱스 미사용, 트랜잭션 누락
3. 에러: 예외 처리 누락, 빈 catch 블록
4. 비밀값: 하드코딩된 API 키, 비밀번호
## 팀 컨벤션
- Python: PEP 8 + 타입 힌트 + 한국어 주석
- API: RESTful 설계, 적절한 HTTP 상태 코드
- 테스트: 새 기능에 반드시 테스트 추가
## 금지 패턴
- print() 사용 (logging으로 대체)
- SELECT * 쿼리
- 3단계 이상 중첩 if문
## 리뷰 형식
반드시 다음 형식 사용:
🔴 Critical: [파일명:라인] 설명 — 수정 방법
🟡 Warning: [파일명:라인] 설명 — 개선 방법
🔵 Info: [파일명:라인] 설명 — 제안 이유
"""
리뷰봇 운영 경험
실제 운영 경험에서 나온 팁들이다.
False Positive 관리: AI가 너무 많은 경고를 생성하면 개발자가 무시하게 된다. 처음엔 Critical 항목만 활성화하고 팀 피드백을 받아 점진적으로 확장한다.
파일 크기 제한: diff가 1000줄을 넘으면 리뷰 품질이 떨어진다. 큰 PR을 작게 쪼개도록 유도하거나, 파일별로 나눠서 리뷰한다.
도메인 지식 주입: 비즈니스 규칙을 프롬프트에 추가하면 리뷰 품질이 크게 올라간다. "결제 금액은 항상 양수여야 한다", "관리자만 삭제할 수 있다" 같은 규칙들이다.
비용 관리: GPT-4o 기준으로 1000줄 diff 리뷰에 약 $0.020.05 정도다. 하루 20개 PR이면 월 $1530 수준이다.
# 비용 추적
def estimate_cost(diff: str, model: str = "claude-sonnet-4-6") -> float:
"""리뷰 비용 추정 (USD)"""
# 토큰 수 추정 (rough: 4자 = 1토큰)
input_tokens = len(diff) // 4 + 1000 # 시스템 프롬프트 포함
output_tokens = 2000 # 리뷰 출력 추정
# Claude Sonnet 4.6 가격 (2026년 기준 확인 필요)
input_cost = input_tokens * 3 / 1_000_000 # $3/MTok
output_cost = output_tokens * 15 / 1_000_000 # $15/MTok
return input_cost + output_cost
지난 글: AI 코딩 모범 사례: 생산성과 품질을 동시에 잡는 전략
다음 글: AI 챗봇 설계: 사용자 경험부터 백엔드까지
읽어주셔서 감사합니다. 😊

