← 목록으로RETROSPECTIVE

6개월 뒤 열어본 AI 코드 — 코드는 쌓이는데 이해는 안 쌓인다는 인지 부채 이야기

6개월 뒤 열어본 AI 코드 — 코드는 쌓이는데 이해는 안 쌓인다는 인지 부채 이야기

6개월 전에 AI에게 맡긴 파일을 다시 열었습니다. 날짜 포맷 유틸이 세 군데에 있었습니다. 이름이 조금씩 다르고 동작도 미묘하게 달랐습니다. 어느 게 진짜인지 확인하려고 git blame을 돌렸는데 세 개 전부 같은 날짜에 제 이름으로 들어와 있었습니다.

그날 저는 분명히 승인 버튼을 눌렀습니다. 그런데 지금 이 코드에 대해 제가 아는 게 없습니다.

코드는 쌓이는데 이해는 안 쌓인다

기술 부채는 빚인 걸 알고 집니다. 일정 때문에 지금은 대충 하고 나중에 갚겠다고 스스로 결정한 겁니다. 상환 계획이 없어도 최소한 어디에 빚이 있는지는 압니다.

인지 부채는 다릅니다. 빚졌다는 사실 자체를 모릅니다. 코드는 늘어났고 기능은 돌아가고 커밋 로그에 제 이름이 찍혀 있으니 제가 만든 것처럼 보입니다. 그런데 그 코드가 왜 그렇게 생겼는지 설명할 수 없습니다. roboco.io의 표현을 빌리면 “코드는 쌓이는데 이해는 쌓이지 않는” 상태입니다.

이해는 이자가 붙습니다. 6개월 뒤에 그 코드를 고쳐야 할 때 읽는 비용을 한꺼번에 냅니다. 보통 원금보다 비쌉니다.

체감과 실제가 정확히 반대로 간다

이게 감상이 아니라는 증거가 있습니다. 2025년 7월 METR이 발표한 무작위 대조 실험입니다. 숙련 개발자 16명, 246개 과제, 전부 본인이 5년쯤 기여해온 오픈소스 저장소에서 하는 작업이었습니다. 도구는 Cursor Pro와 Claude 3.5/3.7 Sonnet.

수치를 순서대로 보면 이렇습니다.

시점 예측 또는 결과
실험 전 개발자 본인 예측 24% 단축
경제학 전문가 예측 39% 단축
ML 전문가 예측 38% 단축
실제 측정값 19% 증가
실험 후 개발자 본인 체감 20% 단축

마지막 두 줄이 핵심입니다. 실제로 19% 느려진 사람들이, 실험이 끝난 뒤에도 20% 빨라졌다고 느꼈습니다. 느려졌다는 걸 몰랐던 게 아니라 빨라졌다고 확신했습니다.

여기서 무서운 건 숫자의 크기가 아닙니다. 계측기가 고장 났다는 사실입니다. 속도를 잘못 재는 사람은 품질도 잘못 잽니다. 이 실험은 생산성을 잰 것처럼 보이지만 실제로 드러난 건 자기 인식입니다.

그 시간은 어디로 갔나

METR 데이터에서 시간 배분을 보면 답이 나옵니다. AI를 허용한 조건에서 개발자들은 **리뷰와 정리에 전체 시간의 약 9%, 생성 대기에 약 4%**를 썼습니다. 대신 직접 코딩하고 코드를 읽고 검색하는 시간은 줄었습니다.

줄어든 만큼 다른 데서 늘어난 겁니다. 프롬프팅, 대기, 리뷰, 화면 녹화에 아무 동작도 안 잡히는 유휴 시간. 이 새 항목들이 절감분을 전부 먹었습니다.

바꿔 말하면 AI는 코드를 쓰는 일을 코드를 검토하는 일로 바꿔놓습니다. 작업이 사라진 게 아니라 종류가 바뀐 겁니다. 그런데 대부분의 팀은 검토를 작업으로 치지 않습니다. 일정에도 안 잡고 숙련도도 안 봅니다.

리뷰가 형식적 승인으로 바뀌는 지점

생성 속도가 검토 속도보다 빠르면 사람이 병목이 됩니다. 병목은 압력을 받으면 통과율을 올립니다. 열 줄짜리 diff는 읽습니다. 400줄짜리는 스크롤합니다. 그게 하루에 세 번 오면 스크롤도 안 합니다.

앞서 인용한 글의 문장이 정확합니다. 이렇게 통과시킨 코드는 아무도 안 본 코드보다 나쁠 수 있습니다. 안 본 코드는 안 봤다는 걸 최소한 본인은 압니다. 형식적으로 승인한 코드는 “검토 완료”로 기록에 남습니다. 팀 전체가 그 코드를 검증된 것으로 취급하기 시작합니다.

AI 코드의 87.9%는 멀쩡합니다

보안 이야기로 넘어가면 예상과 다른 결과가 나옵니다.

2025년 10월에 나온 대규모 실증 분석이 있습니다. GitHub 공개 저장소에서 AI 생성이라고 명시된 파일 7,703개를 CodeQL로 훑었습니다. 77개 유형에 걸쳐 CWE 4,241건이 나왔습니다. 그런데 같은 논문의 다른 수치가 더 중요합니다.

87.9%는 CWE로 매핑되는 취약점이 없었습니다.

언어별로도 갈립니다. Python이 16.1818.50%로 가장 높고, JavaScript가 8.668.99%, TypeScript는 2.50~7.14%입니다. Copilot이 만든 Python은 1,739줄당 CWE 1건 꼴이었습니다.

“AI가 취약한 코드를 쏟아낸다”는 서사는 이 데이터로 지탱되지 않습니다. 대부분은 괜찮습니다.

그래서 더 위험합니다. 아홉 번 멀쩡하면 열 번째도 안 읽게 됩니다. 매번 문제가 터지는 도구는 사람을 긴장시키지만 열 번에 한 번 터지는 도구는 사람을 방심하게 만듭니다. 1,739줄을 읽고 한 건을 잡는 작업은 사람이 오래 못 합니다.

그리고 하필 그 한 건이 인증이나 결제나 외부 입력 파싱에 있으면 나머지 1,738줄이 멀쩡했다는 사실은 아무 위로가 안 됩니다.

유지보수가 무너지고 있다는 징후

다음 중 두 개 이상이면 이미 인지 부채가 쌓여 있습니다.

  • 같은 일을 하는 유틸 함수가 두 개 이상 있다
  • 에러 처리 방식이 파일마다 다르다 (throw, return null, 조용히 삼키기가 섞여 있다)
  • 분기는 있는데 그 분기를 타는 테스트가 없다
  • 지워도 되는지 아무도 모르는 코드가 있다
  • “이 함수 왜 있어요?“에 대한 답이 “지웠더니 깨져서요”다

마지막 항목이 가장 명확한 신호입니다. 그건 코드를 이해하는 게 아니라 관찰하고 있다는 뜻입니다. 블랙박스를 다룰 때 쓰는 방식을 자기 코드에 쓰고 있는 겁니다.

제 저장소를 세어봤습니다

지금 이 블로그도 AI로 만들었습니다. 2026년 8월 20일에 시작했고 원격 브랜치가 27개 쌓여 있습니다. 글을 올린 브랜치 14개를 빼면 코드를 건드린 브랜치가 13개입니다.

그중 5개가 fix/로 시작합니다.

fix/astro-731
fix/cloudflare-adapter-astro-pin
fix/figma-websocket-path
fix/post-table-styles
fix/untrack-wrangler

코드 변경 13건 중 5건이 앞선 변경을 수리한 작업입니다. 38%입니다.

이 중 fix/cloudflare-adapter-astro-pin은 기억에 남습니다. Cloudflare 빌더가 Astro 어댑터를 알아서 주입하는데 제가 버전을 고정해두지 않아서 어느 날 배포가 통째로 깨졌습니다. 설정 파일은 AI가 짜줬고 저는 배포가 되는 걸 확인하고 넘어갔습니다. 그 파일을 한 번이라도 읽었으면 고정 안 된 의존성이 보였을 겁니다.

읽는 데 3분 걸렸을 일을, 몇 주 뒤에 30분짜리 장애로 냈습니다. 이자가 이런 식으로 붙습니다.

금지가 아니라 경계선

그렇다고 AI를 끄자는 얘기는 아닙니다. 위 저장소는 AI 없이는 애초에 안 만들어졌습니다. 필요한 건 선입니다.

1. 설명 못 하면 머지 금지. 이 변경이 왜 이렇게 생겼는지 한 문단으로 못 쓰면 아직 내 코드가 아닙니다. AI에게 설명을 시키지 말고 본인이 씁니다. 설명을 AI가 대신 쓰는 순간 검증 장치는 사라지고 부채만 하나 더 늘어납니다.

2. 변경 단위를 리뷰 가능한 크기로. 400줄을 대충 보는 것보다 40줄을 제대로 보는 게 낫습니다. 큰 작업은 프롬프트 단계에서 쪼갭니다. 프롬프트를 스펙처럼 쓰는 방법을 따로 정리해뒀습니다.

3. 테스트는 사람이 먼저. AI에게 코드와 테스트를 같이 시키면 테스트는 코드의 현재 동작을 그대로 박제합니다. 버그까지 같이 고정됩니다. 기대 동작을 사람이 먼저 적고 구현을 시키면 검증이 됩니다.

4. 경계 코드는 직접 씁니다. 인증, 결제, 권한 체크, 외부 입력 파싱. 87.9%가 안전하다는 통계는 여기서 의미가 없습니다. 이 네 곳은 한 건이 전부입니다.

5. 검증을 의지가 아니라 환경에 맡깁니다. 위 네 가지는 전부 사람의 규율에 기대는 방법이라 바쁘면 제일 먼저 무너집니다. CI, 린트 규칙, 훅처럼 검증을 환경에 박아두는 쪽이 오래갑니다.

바이브 코딩의 원래 정의는 “코드가 존재한다는 사실 자체를 잊는다”였습니다. 카파시는 그걸 주말 프로젝트에 쓴다고 했지 프로덕션에 쓰라고 하지 않았습니다.

그러니까 질문은 “바이브 코딩을 할 것이냐”가 아닙니다. 어디까지 안 읽어도 되는지 선을 어디에 그을 것이냐입니다. 그 선을 안 그으면 6개월 뒤에 코드가 대신 그어줍니다. 보통 제일 불편한 자리에 그어집니다.

참고