콘텐츠로 이동

클로드 코드는 왜 쓸수록 느려지는가 — 하네스 부채

AI 코딩 에이전트를 오래 쓴 사람이라면 익숙한 감각이 있습니다. 새로 깔았을 땐 날아다니는데, 몇 달을 쓰다 보면 어느새 굼떠집니다. 파일 하나 고치는데 뜸을 들이고, 방금 알려준 걸 또 잊고, 세션은 자꾸 스스로를 요약하느라 멈칫합니다. “도구가 예전 같지 않다”는 막연한 의심 — 그런데 그게 도구 탓이 아니라면? 이 글은 반년간 쌓인 hook·규칙·방법론을 전수 감사해 “느린 것 같다”를 숫자로 바꾸고, 다시 가볍게 만든 기록입니다.

결론부터 말하면, 느려짐의 원인은 대부분 모델이 아니라 제가 모델 주위에 쌓아 올린 것들이었습니다. 사고가 날 때마다 규칙 하나, 스크립트 하나, 훅(hook) 하나를 더했고 — 폐기한 적은 한 번도 없었습니다. 그렇게 반년치 “안전장치”가 지층처럼 퇴적됐습니다.

전수 감사에서 나온 대표 실측치는 이렇습니다.

실측치의미
~40%작업을 시작하기도 전에 이미 소진된 컨텍스트 (자동 로드 문서 과다)
4.4초파일 저장 1회마다 붙던 검증 훅의 소요 시간 — 그런데 결과는 크래시
10 / 43줄바꿈(CRLF) 오염으로 조용히 죽어 있던 훅 스크립트 수
~27초편집이 많은 턴 1회당 순수 “훅 세금” (기능값은 0에 가까움)

특정 프로젝트의 실측 예시입니다. 절대값보다 구조를 봐야 합니다 — 어느 환경에서든 같은 함정이 생깁니다.

“처음엔 빠르다”가 핵심 단서입니다. 세션 초반엔 컨텍스트 창에 여유가 있어 정말 빠릅니다. 그런데 파일 몇 개만 읽어도 창이 차오르고, 그 순간부터 도구가 스스로를 요약(compact)하기 시작합니다. 요약은 분 단위로 걸리고, 캐시를 통째로 무효화합니다. 그래서 “빠름 → 급격한 둔화”가 반복됩니다. 이건 기분이 아니라 메커니즘입니다.

다른 컴퓨터에선 같은 프로젝트가 멀쩡히 빠른데 이 컴퓨터만 느린 경우도 있었습니다. 이 대비가 결정적 힌트였습니다 — git으로 동기화되는 코드는 두 컴퓨터가 동일하니, 차이는 전부 로컬 상태에서 온다는 뜻입니다.

원인을 이해하려면 “어떻게 여기까지 왔나”부터 봐야 합니다. 패턴은 단순했습니다. 사고 1건 → 규칙 1개 추가. AI가 거짓으로 “완료”를 보고했다? 완료 검증 훅을 추가합니다. 거대 파일이 또 생겼다? 파일 크기 게이트를 추가합니다. 배포했는데 화면이 깨졌다? 배포 후 검증 규칙을 추가합니다.

규칙 하나하나는 정당했습니다. 전부 실제 사고의 재발 방지책이었습니다. 문제는 대응 수단이 “추가”뿐이었다는 것 — 기존 규칙과 통합하거나 오래된 규칙을 폐기한 적이 한 번도 없었습니다. 그렇게 방법론이 겹겹이 쌓였습니다.

층 (위 = 최근 추가)무엇이 쌓였나추가한 이유덜어냈나
표층지식 인프라 · 메모리 누적세션마다폐기 없음
유틸리티 스킬 벨트 (수십 종)편할 것 같아서폐기 없음
에이전트 파이프라인자동화 기대사실상 사용 중단
하네스 (훅 · 스크립트)사고 대응검증 없음
심층개발 방법론 (TDD · 검증 게이트)모범 사례통합 없음
골격코드 구조 · 커밋 게이트 · 도메인 불변식건강 — 유지

뼈대(맨 아래)는 튼튼합니다. 문제는 그 위에 얹힌 다섯 겹입니다. 각 층은 개별적으론 업계 모범을 따랐지만, 서로 맞물리는지 아무도 검증하지 않았습니다. 남의 방법론을 통째로 들여올 때 충돌 규칙을 솎아내야 하는 이유는 〈방법론 이식〉에 적었습니다.

원인 A — 조용히 고장 난 로컬 인프라

섹션 제목: “원인 A — 조용히 고장 난 로컬 인프라”

가장 먼저, 그리고 가장 의외였던 발견입니다. 방법론이 “나쁜” 게 아니라, 실행 인프라가 고장 나서 비용만 내고 기능은 죽어 있었습니다. 특히 Windows에서 쓰는 사람이라면 거의 다 겪는 함정들입니다.

1순위 — 줄바꿈(CRLF) 오염이 훅을 죽인다

섹션 제목: “1순위 — 줄바꿈(CRLF) 오염이 훅을 죽인다”

Git이 core.autocrlf=true로 셸 스크립트(.sh)를 CRLF 줄바꿈으로 체크아웃하면, Bash가 스크립트를 읽다가 $'\r' 오류로 죽습니다. 그런데 죽기 전까지 시간은 다 씁니다. 저장 1회마다 4.4초를 소모하고 크래시 — 즉 검증 효과는 0인데 지연만 붙습니다. “다른 컴퓨터는 빠른데 이 컴퓨터만 느린” 미스터리의 정체가 바로 이것이었습니다. 체크아웃 시점과 로컬 설정이 달라서, 한쪽만 훅이 CRLF로 오염돼 있었습니다.

2순위 — compact 임계값을 낮췄더니 요약 루프

섹션 제목: “2순위 — compact 임계값을 낮췄더니 요약 루프”

예전 모델 시절 “컨텍스트를 아끼자”며 자동 compact 임계값을 기본보다 낮게 오버라이드해 뒀습니다. 대형 컨텍스트 모델로 세대가 바뀌자 이 설정은 정반대로 작동했습니다 — 실작업 창이 전체의 ~25%로 쪼그라들어, 파일 몇 개만 읽어도 compact가 발동하고, 재요약·재적재가 끝없이 반복됐습니다.

  • 상태줄이 렌더마다 프로세스를 스폰 — 화면 하단 상태줄(statusline)을 커스텀하면서 렌더 때마다 셸+파이썬 여러 개를 스폰하게 만들어 뒀습니다. 회당 ~0.75초, 그런데 이게 상시 돕니다. 있는 줄도 몰랐던 상시 부하였습니다.
  • 백신 실시간 검사에 작업 폴더가 무방비 — Windows Defender 제외 경로가 비어 있었습니다. bash·node·python 프로세스 스폰과 대량 파일 IO가 전부 실시간 스캔 대상이 됐고, 콜드 스폰 4.5초의 배경이 이것이었습니다.
  • 저장소 비대 — git이 문서 창고가 됐다 — 빌드 산출물, 압축 파일, 각종 바이너리가 git 트리에 쌓여 작업 폴더가 몇 GB로 불었습니다. 검색·심볼 인덱싱·백신 스캔·백업이 전부 이 무게를 짊어졌습니다. 정작 코드 자체는 정상 규모였는데 말입니다.

원인 B — 컨텍스트 경제의 붕괴

섹션 제목: “원인 B — 컨텍스트 경제의 붕괴”

체감상 가장 큰 주범은 이것이었습니다. 세션을 시작하기도 전에 컨텍스트의 ~40%가 이미 사라져 있었습니다. 프로젝트 지침, 지식 문서, 규칙 파일, 메모리 인덱스 — “매번 자동으로 읽히면 좋겠다” 싶은 걸 다 자동 로드로 걸어 뒀더니, 한국어라 토큰 밀도까지 높아서 시작부터 무거웠습니다.

여기에 앞서 말한 낮은 compact 임계값이 곱해졌습니다. 시작 40% 선점 + 낮은 상한 = 실작업 창 ~25%. 그러니 “처음엔 빠른데 금방 느려진다”가 정확히 재현된 것입니다. 컨텍스트는 예산입니다. 시작하자마자 절반 가까이 써버리면, 남은 예산으로 할 수 있는 게 없습니다.

진단의 원칙: 추측하지 말고 측정하라

섹션 제목: “진단의 원칙: 추측하지 말고 측정하라”

이 감사에서 가장 값진 교훈은 방법론 하나하나가 아니라 태도였습니다. “느린 것 같다”를 “무엇이 몇 초”로 바꿨습니다.

  • 훅마다 실제 소요 시간을 측정했습니다 — 어떤 게 0.2초고 어떤 게 4.4초인지.
  • 스크립트가 정말 작동하는지 하나씩 실행해 봤습니다 — “있음”과 “동작함”은 다릅니다.
  • CRLF로 오염된 파일 개수를 세었고, 저장소를 폴더별로 재봤습니다.
  • 게이트가 통과/차단을 실제로 하는지 확인했습니다 — 상당수가 || true로 무력화돼 있었습니다.

측정 없이 손대면 멀쩡한 걸 지우거나 진짜 병목을 놔둡니다. 병목은 대개 당신이 의심하는 곳에 없습니다. 제 경우 “코드가 커서 느리다”는 가설은 측정 후 곧바로 기각됐습니다.

처방 — 다시 가볍게 만드는 여섯 원칙

섹션 제목: “처방 — 다시 가볍게 만드는 여섯 원칙”

“다 버려라”가 아닙니다. 실제로 값을 한 코어는 유지하고, 나머지를 옮기거나 합치거나 지웁니다.

원칙내용
1. 검증은 커밋 한 곳에편집 중 실시간 차단은 최소로. 타입 체크·린트·크기 검사는 커밋 시점 하나로 모은다. “왼쪽으로 옮길수록 좋다”가 아니라, 그 비용이 값어치보다 작을 때만
2. 상시 컨텍스트는 슬림하게자동 로드는 “정본 하나”만. 배포 절차·상세 설정은 필요할 때 읽는 런북으로 뺀다. 시작 소진을 40%에서 15% 이하로
3. 추가에는 폐기가 따른다새 규칙 1개를 넣으면 기존 규칙 1개의 통합·폐기를 검토한다(one-in-one-out). 그러지 않으면 반드시 다시 퇴적된다
4. 분기마다 하네스 감사죽은 게이트·CRLF 오염·부풀어 오른 메모리를 분기 1회 실측으로 잡아낸다. 감사 없이는 고장을 아무도 모른다
5. 환경을 표준화·동기화.gitattributes로 셸 스크립트를 eol=lf 고정, 백신 제외 경로 등록, “컴퓨터 간 같아야 할 설정” 체크리스트. “이 컴퓨터만 느림” 재발 방지
6. 안전은 훅이 아니라 코드로도메인의 진짜 불변식은 훅으로 매번 검사하지 말고 함수·상태전이·DB 제약으로 강제한다. 비용 0, 우회 불가

오늘 바로 할 일 — 코드 수정 없이 설정만으로

섹션 제목: “오늘 바로 할 일 — 코드 수정 없이 설정만으로”

이 다섯 개만 해도 체감 속도가 돌아옵니다.

  1. [CRLF] .gitattributes*.sh text eol=lf 추가 → git add --renormalize . → 재체크아웃. 죽은 훅이 되살아납니다.
  2. [컨텍스트] 자동 compact 임계값 오버라이드를 삭제하고 기본값으로 원복. compact 루프가 해소됩니다.
  3. [컨텍스트] 자동 로드 문서를 “정본 1개 + 짧은 메모리”로 줄이고, 나머지는 필요 시 읽기로 전환.
  4. [상시 부하] 커스텀 상태줄을 경량화하거나 기본값으로 복귀. 매 렌더 프로세스 스폰 제거.
  5. [백신] 백신에 작업 폴더·git·node·런타임 경로를 제외 등록. 콜드 스폰이 초 단위에서 수백 ms로 줄어듭니다.

그다음 주엔 하네스 다이어트(죽은 게이트 제거·문서 통폐합), 그다음엔 재비대 방지 거버넌스로 넘어갑니다. 순서가 중요합니다 — 응급처치 먼저.

하네스 부채 — AI 시대의 새 기술부채

섹션 제목: “하네스 부채 — AI 시대의 새 기술부채”

AI 코딩 에이전트 시대의 새 기술부채는 “하네스 부채”입니다. 모델은 강력해졌지만, 우리가 모델을 감싸느라 만든 훅·규칙·스킬·방법론도 결국 코드입니다 — 관리하지 않으면 썩습니다. 그리고 이 부채의 무서운 점은, 대부분 코드 밖(설정·훅·문서)에 쌓여서 눈에 안 띈다는 것입니다.

다행인 것도 그것입니다. 비대해진 곳이 코드 밖이라, 덜어내는 수술의 위험이 낮습니다. 의심이 든다면 방법은 하나입니다 — 추측하지 말고, 측정하고, 코어만 남기십시오. 도구가 예전 같지 않게 느껴진다면, 아마 도구가 아니라 그 주위에 쌓인 지방층 때문일 것입니다.


이 글은 SL.AIMS를 만들며 AI와 협업한 기록 중 하나입니다. 하네스가 무엇이고 왜 모델보다 중요한지는 〈하네스를 초기에 적용하지 못한 것〉에, 하네스가 품질 하한선을 지키는 법은 〈루프를 닫다〉에 있습니다.