AI가 코드를 짤 때, 품질 방어선은 어디에 세워야 하나

AI가 코드를 짤 때, 품질 방어선은 어디에 세워야 하나

생성 속도가 검증 속도를 앞지르는 지금, 코드 품질과 보안의 방어선은 린터·SAST·LLM 리뷰 세 레이어의 조합으로만 완성된다

AI 코드 리뷰 SAST 코드 품질 자동화 pre-commit hook 보안 취약점 claude code review 린터 AI 생성 코드 보안
광고

AI 코딩 어시스턴트가 팀에 자리를 잡으면서 역설적인 문제가 생겼다. 코드는 더 빨리 나오는데, 그 코드를 믿어도 되는지 확인하는 속도는 그대로다. 빠르게 생성된 코드가 리뷰 없이 main 브랜치에 쌓이기 시작하면, 품질 부채는 그냥 쌓이는 게 아니라 가속도를 붙여 쌓인다. 이 문제를 진지하게 다룬 세 가지 사례를 보면, 방어선을 어디에 세워야 할지 윤곽이 잡힌다.

문제 1: LLM 코드 리뷰는 일관성이 없다

dev.to에 공개된 brooks-lint 실험은 불편한 사실 하나를 수치로 보여준다. 동일한 코드를 Claude에게 두 번 리뷰시켰더니 첫 번째는 SQL 인젝션을 잡고 관심사 분리를 언급했고, 두 번째는 네이밍 컨벤션에 집중하다 인젝션을 통째로 놓쳤다. 같은 모델, 같은 코드, 완전히 다른 결과다.

이걸 해결하기 위해 만들어진 도구가 brooks-lint다. Brooks, Fowler, Martin, McConnell, Evans, Ousterhout 등 소프트웨어 공학 고전 12권을 Claude Code 스킬로 인코딩해서, 매번 동일한 6가지 코드 부패 리스크(인지 과부하, 변경 전파, 지식 중복, 우발적 복잡성, 의존성 혼란, 도메인 모델 왜곡)를 진단하게 만든 것이다. 결과는 명확했다. Plain Claude의 전체 통과율이 16%인 데 반해, brooks-lint는 94%였다. 구조화된 발견 사항, 책 인용, 심각도 레이블, 구체적 처방 — 네 항목 모두 100% 일관성을 달성했다.

이 실험이 말하는 건 단순하다. LLM 코드 리뷰의 문제는 모델 능력이 아니라 일관성이다. Claude가 뭘 찾아낼 수 있느냐가 아니라, 매번 빠짐없이 찾아내느냐가 팀 운영 기준으로서 의미가 있다. 컨텍스트를 구조화하지 않은 LLM 리뷰는 동료 리뷰어가 그날 컨디션에 따라 다른 기준을 적용하는 것과 다를 바 없다.

문제 2: AI 생성 코드에는 보안 취약점이 숨어 있다

AI 생성 코드 보안 가이드가 짚는 문제는 두 방향이다. 첫째, AI 모델은 수백만 줄의 공개 코드로 학습했는데 그 공개 코드 안에는 취약한 패턴이 무수히 많다. SQL 인젝션, 하드코딩된 자격증명, 인증 로직 오류, 안전하지 않은 역직렬화 — 이것들은 구문 검사를 통과하고, 단위 테스트를 통과하고, 심지어 수동 코드 리뷰도 통과하는 경우가 많다. 코드가 '올바르게 실행되는 것'과 '적대적 조건에서 안전한 것'은 다른 문제인데, AI 모델에겐 적대적 의도라는 개념이 없다.

둘째, 그리고 대부분의 팀이 간과하는 방향이 있다. 개발자가 AI 도구에 코드를 붙여넣는 순간 그 코드가 환경 밖으로 나간다. 실제 Stripe API 키가 포함된 파일을 Cursor나 Copilot에 통째로 붙여넣는 일이 지금 이 순간 수많은 팀에서 조용히 벌어지고 있다. 고객 PII, DB 자격증명, 내부 인프라 정보, 독점 비즈니스 로직 — 전통적인 SAST 도구는 코드 저장소를 스캔하지, 개발자와 AI API 사이를 오가는 데이터를 보지 않는다.

기존 SAST 도구(SonarQube, Semgrep, Snyk)의 한계도 명확하다. AI 모델이 생성하는 코드 구조는 인간이 작성하는 패턴과 미묘하게 달라서 기존 룰셋이 잡아내지 못하고, 10~35%에 달하는 오탐률은 개발자들이 경고 자체를 무시하도록 훈련시킨다. 2026년 CASTLE 벤치마크 기준으로 CodeQL의 정밀도가 48%, Semgrep이 34%, SonarQube가 24%인 반면, AI 네이티브 스캐너는 98%에 도달하고 있다. 오탐이 절반을 넘는 도구는 진짜 위협도 노이즈로 묻어버린다.

문제 3: 규칙은 문서가 아니라 훅에 있어야 한다

린터와 pre-commit 훅 기반 실전 구축기는 가장 현실적인 통찰을 준다. 개발 가이드라인 파일은 대부분 읽히지 않는다. 문서는 주의를 두고 경쟁해야 하지만, 훅은 그냥 실행된다. Anthropic 내부 툴링에서도 같은 패턴이 확인됐다 — 규칙을 문서에서 강제 실행 훅으로 옮겼다.

구체적으로, Ruff 23개 룰 프리픽스를 사용하면 SQL 인젝션 패턴(f-string으로 SQL 문자열 조립하는 패턴), 비동기 순차 실행 함정(await를 루프 안에서 직렬로 쓰는 패턴), McCabe 복잡도 10 초과 함수, 타임존 없는 datetime.now() 호출을 커밋 전에 차단할 수 있다. 핵심은 경고가 아니라 차단이라는 점이다. 코드가 기준을 통과하지 못하면 저장소에 들어오지 않는다.

방어선은 세 레이어의 조합이다

이 세 사례가 수렴하는 지점을 정리하면 이렇다.

레이어 1 — pre-commit 린터: 포맷, 복잡도, 보안 안티패턴, 타임존 오류처럼 구조적으로 감지 가능한 문제의 80%를 커밋 전에 기계적으로 차단한다. AI가 생성한 코드든 인간이 작성한 코드든 동일하게 적용된다.

레이어 2 — AI 네이티브 SAST: 패턴 매칭이 아니라 코드 의미론을 이해하는 스캐너로 AI 생성 코드에 숨어있는 취약점을 잡는다. 정밀도가 낮은 도구는 오히려 경보 피로를 만들어 실제 위협을 놓치게 한다.

레이어 3 — 구조화된 LLM 리뷰: 아키텍처 드리프트, 도메인 모델 왜곡, 기술 부채처럼 기계적 검사가 닿지 않는 영역을 다룬다. 단, 컨텍스트 없이 맨 프롬프트로 돌리면 일관성이 보장되지 않는다. brooks-lint처럼 판단 기준을 구조화해서 매 실행마다 동일한 프레임으로 진단하게 만들어야 한다.

지금 팀에 없다면, 만들어야 한다

솔직히 말하면, 이 레이어들은 숙련된 개발자라면 수년간의 사고 경험으로 본능적으로 세팅하게 되는 것들이다. 파라미터화된 쿼리가 중요한 이유를 인젝션 사고를 겪고 나서야 알게 되고, 복잡도 제한이 필요한 이유를 300줄짜리 함수를 유지보수해보고 나서야 깨닫는 것들.

AI 도구가 빠를수록 이 학습 곡선을 건너뛰고 코드를 프로덕션에 밀어 넣는 속도도 빨라진다. 경험에서 나온 '흉터 조직'이 없는 개발자가 강력한 생성 도구를 쓸 때, 가드레일 없이 달리는 속도는 위협이 도달하는 속도이기도 하다. AI-First 팀을 리빌딩한다는 건 생성 도구를 도입하는 것만이 아니라, 이 세 레이어의 방어선을 함께 세우는 것이다. 그 방어선이 없는 AI-First는 그냥 빠르게 망가지는 팀이다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요