AI 코딩 도구가 생산성을 높여준다는 건 이제 논쟁거리가 아니다. 진짜 논쟁은 다른 곳에 있다. AI가 생성한 코드를 팀이 얼마나 믿을 수 있는가, 그리고 그 신뢰를 '느낌'이 아닌 '설계'로 확보할 수 있는가.
최근 세 가지 사례가 동시에 같은 지점을 가리킨다. 하나씩 뜯어보자.
첫 번째: AI는 2019년 이전의 취약점을 재현한다
dev.to에 올라온 한 분석 글은 Cursor와 Claude Code가 공통적으로 생성하는 JavaScript deepMerge 함수를 해부했다. 코드는 읽기 좋고 구조도 깔끔하다. 문제는 for...in 루프를 쓴다는 것. 이건 CWE-1321, 즉 프로토타입 오염(Prototype Pollution) 취약점이다. 공격자가 __proto__ 키를 JSON 바디에 심으면 Node 프로세스 전체의 Object.prototype이 오염된다. {}.isAdmin이 true가 되는 순간 인증 미들웨어가 무력화된다.
왜 AI는 계속 이 패턴을 뱉는가. 이유는 단순하다. LLM 학습 데이터의 핵심인 2013~2019년 StackOverflow 답변들이 for...in 머지를 정답으로 가르쳤다. Object.hasOwn()은 더 최근 컨벤션이고, 주로 보안 중심 아티클에만 등장한다. 모델은 통계적으로 가장 빈번한 답을 선택하고, 그 답이 취약한 것이다. Cursor만의 문제가 아니다. GitHub Copilot도 마찬가지고, 2020년 이전 JavaScript 튜토리얼로 학습한 모델은 모두 동일한 패턴을 재현한다.
수정은 한 줄이면 된다—!Object.hasOwn(source, key) 가드를 추가하거나 아예 Object.keys()로 전환하면 상속된 키 순회 자체가 사라진다. 하지만 AI는 당신이 명시적으로 요청하지 않으면 그 한 줄을 추가하지 않는다. 이게 핵심이다. AI는 보안 컨텍스트가 없으면 보안을 고려하지 않는다.
두 번째: $500K를 절감한 건 AI가 아니라 테스트 스위트였다
최근 커뮤니티에서 화제가 된 Reco의 사례를 보자. 이 회사는 AI를 활용해 JavaScript JSONata 구현체를 Go로 재작성하며 연간 50만 달러를 절감했다. 많은 사람들이 'AI가 레거시 코드를 마이그레이션했다'는 헤드라인만 공유했지만, 실제로 성공을 만든 건 다른 데 있었다.
Reco가 먼저 한 일은 jsonata-js 공식 테스트 스위트 1,778개를 Go로 포팅해 사양서로 삼은 것이다. AI는 코드를 번역했지만, 무엇이 맞는지는 테스트가 판단했다. AI는 타이피스트였고, 테스트 스위트가 아키텍트였다. 이 테스트 스위트가 없었다면? 50만 달러 절감 스토리가 아니라 50만 달러짜리 수습 스토리가 됐을 것이다.
이 사례의 진짜 교훈은 냉정하다. AI로 코드베이스를 안전하게 다루려면, AI가 들어오기 전에 이미 기계가 읽을 수 있는 정답이 존재해야 한다. 테스트는 AI 시대를 위해 작성된 게 아니었다. 탄탄한 엔지니어링의 부산물이었고, AI가 그 가치를 증폭시켰을 뿐이다. AI는 제로에 곱하면 여전히 제로다.
세 번째: 멀티 에이전트는 경계가 무너지면 즉시 샌다
한 인디 개발자가 Claude Code 4개 인스턴스를 병렬로 돌리며 Flutter Web + Supabase 앱을 만드는 워크플로우를 공유했다. VSCode 인스턴스, Windows Desktop 인스턴스, PowerShell 인스턴스, Web 인스턴스—각자 담당 파일 영역을 갖고 동시에 작업하는 구조다. 그가 Web 인스턴스를 종료한 이유는 세 가지 장애가 한 세션에서 동시에 터졌기 때문이다. GitHub MCP 연결이 세 번 끊겼고, 스트림 타임아웃으로 응답이 중간에 잘렸고, MCP 호출 실패로 인해 다른 인스턴스 소유 파일을 새로 만들려는 시도가 발생했다.
마지막 케이스가 핵심이다. 에이전트는 자신이 어떤 파일을 건드리면 안 되는지 '느낌'으로 알지 못한다. 명시적 소유권 경계가 문서화되어 있지 않으면, 장애 상황에서 에이전트는 엉뚱한 파일을 생성하거나 덮어쓴다. 이 개발자가 복구를 빠르게 할 수 있었던 이유는 각 인스턴스의 쓰기 권한 범위가 이미 문서로 정의되어 있었기 때문이다. 경계가 설계되어 있으면 장애를 수습할 수 있고, 없으면 장애가 조용히 퍼진다.
세 사례가 합쳐서 말하는 것
취약점, 테스트, 멀티 에이전트 장애—표면적으로는 다른 주제처럼 보이지만 실은 같은 질문이다. AI 생성 코드의 신뢰성은 AI 도구 자체에서 오지 않는다. 그 코드를 둘러싼 검증 파이프라인에서 온다.
팀 차원에서 내일 당장 설계에 반영할 수 있는 세 가지 레이어가 있다.
1. 정적 분석 레이어: AI가 생성한 코드를 커밋하기 전에 semgrep 같은 도구로 알려진 취약 패턴을 스캔한다. for (const key in처럼 AI가 반복적으로 뱉는 위험 패턴은 규칙으로 만들어 pre-commit 훅에 걸면 된다. 이건 AI가 2019년 이전 답변을 재현하는 문제를 시스템 레벨에서 막는 가장 저렴한 방법이다.
2. 테스트 커버리지 레이어: Reco 사례가 증명했듯, AI에게 코드를 위임하려면 먼저 그 코드가 무엇을 해야 하는지 기계가 읽을 수 있는 형태로 정의되어 있어야 한다. 테스트 없이 AI에게 리팩터링이나 마이그레이션을 맡기는 건 지도 없이 길을 찾으라고 하는 것과 같다.
3. 에이전트 권한 경계 레이어: 멀티 에이전트를 운영한다면 각 에이전트의 파일 소유권과 쓰기 범위를 코드베이스 안에 명시적으로 문서화해야 한다. 장애는 반드시 온다. 경계가 설계되어 있으면 수습이 빠르고, 없으면 조용한 오염이 퍼진다.
그래서 팀이 먼저 만들어야 할 것
'AI 코드를 믿을 수 있는가'라는 질문의 답은 AI 모델의 성능표에 없다. 팀이 그 코드를 검증하는 구조를 먼저 갖고 있는가에 있다. AI 도구 도입 전에 물어야 할 진짜 질문은 이것이다: 지금 우리 팀에 정적 분석 훅이 있는가, 테스트 스위트가 있는가, 에이전트 권한 문서가 있는가.
없다면 AI 도입은 생산성 향상이 아니라 부채 가속이 될 가능성이 높다. 검증 파이프라인은 AI가 들어온 이후에 만드는 게 아니다. AI에게 진짜 일을 맡기기 전에 완성되어 있어야 한다.