AI 코드 리뷰를 한 번 수행하는 것만으로는 부족합니다. 실제로 버그를 잡아내는 루프는 다음과 같습니다.
요약
AI 코드 리뷰를 단 한 번 수행하는 것만으로는 충분하지 않으며, 실제로 버그를 잡아내기 위해서는 여러 단계의 구조화된 검토 루프(loop)가 필요합니다. 이 글은 Anthropic의 Claude-Opus 모델을 사용하여 '행동', '영향', '실패 시나리오', '보안', '관찰 가능성' 등 5가지 명명된 패스(passes)를 거치도록 강제하는 구체적인 Python 하네스를 제시합니다. 핵심은 LLM이 단순히 동의하거나
핵심 포인트
- AI 코드 리뷰는 단일 검토가 아닌, 구조화되고 반복적인 루프여야 한다.
- LLM에게 'LGTM'을 금지하고 비판적 사고를 강제하는 것이 중요하다.
- 다양한 관점(행동, 영향, 실패 시나리오 등)에서 여러 번의 API 호출을 통해 검토해야 한다.
- AI 모델은 신탁이 아니라, 체계적인 체크리스트를 따르는 주니어 엔지니어처럼 사용해야 한다.
AI 리뷰어를 실행했습니다.
"로그/테스트가 충분한가요?" 각 패스(pass)는 새로운 컨텍스트 윈도우 (context window)입니다. 이전 패스에서 "LGTM"이라고 했던 것에 대한 기억이 없습니다. 각 패스는 무언가를 찾아내거나, 명시적으로 "해당 사항 없음"이라고 말하도록 강제됩니다. 오늘 바로 실행해 볼 수 있는 최소한의 하네스 (harness)는 다음과 같습니다:
import anthropic
client = anthropic.Anthropic()
MODEL = "claude-opus-4-7"
PASSES = [
("behavior", "이 diff가 변경하는 내용을 쉬운 영어로 요약하세요."),
("impact", "diff 외부에서 깨질 수 있는 특정 파일이나 함수를 나열하세요."),
("failure", "데이터를 충돌시키거나 손상시킬 수 있는 구체적인 입력값 5개를 제시하세요."),
("security", "새로운 유출 사항을 찾으세요: 인증(auth), 개인정보(PII), 비밀값(secrets), 내부 ID, 스택 트레이스(stack traces)."),
("observability", "만약 이것이 운영 환경(prod)에서 잘못된다면, 어떻게 감지할 수 있습니까? 테스트/로그가 충분한가요?"),
]
def review(diff: str) -> dict[str, str]:
findings = {}
for name, question in PASSES:
msg = client.messages.create(
model=MODEL,
max_tokens=1024,
system="당신은 시니어 엔지니어입니다. 구체적으로 답변하세요. 'LGTM'은 허용되지 않습니다.",
messages=[{
"role": "user",
"content": f"{question}\n\nDIFF:\n{diff}"
}],
)
findings[name] = msg.content[0].text
return findings
그게 전부입니다. 5번의 API 호출. 비용은 몇 센트 정도입니다. 단판 승부형 리뷰어가 그냥 지나쳐버리는 버그들을 잡아냅니다.
명확하지 않은 핵심 부분: "LGTM" 금지
이 프롬프트에서 가장 중요한 한 줄은 "'LGTM'은 허용되지 않습니다"입니다. LLM (Large Language Models)은 눈에 띄는 문제가 없을 때 기본적으로 동의하는 경향이 있습니다. 예의 바른 답변으로 빠져나가는 것을 적극적으로 금지해야 합니다.
더 나은 프롬프트 예시:
- "사소한 것이라도 최소 두 가지 우려 사항을 나열해야 합니다. 변경 사항이 정말로 안전하다면, 단순히 주장하지 말고 그 이유를 설명하세요."
- "심각도를 1-5로 평가하세요. 모든 항목이 1이라면, 파일의 히스토리를 바탕으로 그 이유를 정당화하세요."
- "이 PR(Pull Request)이 배포되어 장애가 발생했다고 가정해 봅시다. 사후 분석(post-mortem)의 헤드라인은 무엇입니까?"
이것들은 단순한 요령이 아닙니다.
이것들은 단순히 "승인"하기 위해 패턴 매칭(pattern-matching)을 하는 대신, 모델이 실제로 업무를 수행하게 만드는 방법입니다. 이것이 여러분의 워크플로우(workflow)에서 해결해 주는 것들: 만약 여러분이 AI의 도움을 받아 코드를 빠르게 배포하는 1인 개발자이거나 소규모 팀이라면, 위의 루프(loop)는 세 가지 역할을 수행합니다:
- 모델이 실패를 상상하도록 강제합니다. 대부분의 단일 패스(one-pass) 리뷰는 암묵적으로 성공을 가정합니다.
- 코드베이스 전체에 주의를 분산시킵니다. 파일 간 버그(cross-file bugs)는 비용 손실이 발생하는 지점입니다.
- 감사 추적(audit trail)을 남깁니다. 다섯 번의 명명된 패스(named passes)는 무언가 잘못되었을 때 지시할 수 있는 근거를 제공하며, 이는 Git 히스토리에 남은 단 하나의 "LGTM"보다 훨씬 낫습니다.
이를 CI(지속적 통합)에서 실행하는 비용은 실제로 존재하지만 적은 수준입니다. Claude를 통해 200줄짜리 PR(Pull Request)을 5번의 패스로 검토하는 비용은 현재 약 0.10달러입니다. 이를 실행하지 않았을 때의 비용은 단 한 번의 잘못된 마이그레이션(migration), 단 하나의 유출된 관리자 엔드포인트(admin endpoint), 혹은 단 하나의 손상된 인보이스(invoice) 배치입니다. 계산해 보십시오.
더 깊은 교훈: AI 코드 리뷰가 잘못된 것이 아닙니다. 대부분의 팀이 이를 사용하는 방식이 잘못된 것입니다. 그들은 모델을 정답을 알고 있는 신탁(oracle)처럼 취급하며 단 한 번만 질문합니다. 모델은 신탁이 아닙니다. 모델은 무한한 체력과 자아(ego)가 없는 주니어 엔지니어입니다. 올바른 멘탈 모델(mental model)은 다음과 같습니다: 코드 리뷰 체크리스트를 실행하듯 AI를 사용하십시오. 즉, 여러 번의 구조화된 패스(structured passes)를 거치고, 매번 다른 부분에 집중하며, 첫 번째 "괜찮아 보입니다"라는 답변에 결코 만족하지 않는 것입니다.
단일 패스는 단순한 무결성 검사(sanity check)일 뿐입니다. 루프(loop)가 되어야 비로소 리뷰입니다. 여러분이 신경 쓰는 대부분의 버그는 이 두 가지 사이의 간극에 존재합니다.
이러한 실용적인 AI 엔지니어링 콘텐츠를 더 보고 싶다면, LayerZero를 팔로우하세요. 우리는 AI 도구를 진지하게 받아들일 때 여러분의 워크플로우에서 실제로 무엇이 변하는지 분석합니다. 과장된 광고가 아니라, 코드를 배포하거나 혹은 망가뜨리는 실제 부분들을 다룹니다.
다음 포스트: 왜 여러분의 CI가 자체 PR에 대해 AI 리뷰어를 실행해야 하는가.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기