Claude Code를 몇 달 쓰다 보면 이런 순간이 옵니다. "아까도 말했잖아." 어제 고쳐 준 실수를 오늘 또 하고, 다른 프로젝트에서 또 합니다.
제 첫 대응은 다들 하는 그것이었습니다. CLAUDE.md에 규칙을 한 줄 더 적었죠. "테스트 결과는 직접 확인하고 말할 것." "절대 상대 경로를 쓰지 말 것." 그렇게 규칙이 59개까지 늘었는데, 실수는 줄지 않았습니다. 오히려 규칙끼리 비슷한 말을 다른 단어로 반복하고 있었습니다.
두 달 동안 실수를 하나하나 기록해 보고 알게 된 건, 이게 기억력 문제가 아니라 분류 문제라는 점이었습니다.
먼저 결론부터 정리하면 이렇습니다.
실수마다 가야 할 곳이 다릅니다. 아무 데도 안 적기 / 그 레포 문서 / 매번 읽히는 규칙 파일 / 실행 전에 막는 훅.
어디로 보낼지는 질문 세 개로 정합니다. 피해가 남는가, 두 번 이상 일어났나, 다른 곳에서도 통하나.
매번 읽히는 규칙 파일은 24줄로 묶고, 넘치면 훅이 저장을 막습니다.
규칙으로 적었는데도 또 어기면, 그때 훅으로 올립니다.
CLAUDE.md 같은 파일은 요청할 때마다 통째로 다시 읽힙니다. 대화가 길어질수록 그 크기만큼 매번 비용을 냅니다. 더 큰 문제는 주의력입니다. 다시 읽어 보니 여러 규칙이 사실은 "직접 확인하고 말해"라는 같은 얘기를, 각자 겪은 사고의 단어로 하고 있었습니다. 따로 있으면 아무도 안 읽는 목록이고, 하나로 합치면 머리에 들어가는 규칙입니다.
그래서 규칙 파일에 상한을 걸었습니다. 8000바이트, 규칙 24개. 이 숫자를 넘기는 저장은 훅(habits-budget-guard.sh)이 거부합니다. 줄이는 저장은 언제나 통과하고요. 새 규칙을 넣고 싶으면 비슷한 규칙과 합치거나, 하나를 은퇴시켜야 합니다. 은퇴한 규칙은 지우지 않고 보관 파일로 옮깁니다.
사고 경위 같은 긴 배경은 규칙 옆에 두지 않습니다. 규칙에는 [C27] 같은 번호만 달고, 경위는 매번 읽지 않는 사례 파일에 둡니다. 규칙만으로 판단이 안 설 때만 꺼내 봅니다.
질문 | "아니오"면 어디로 |
|---|---|
이 실수가 또 나면 피해가 남는가? (운영 데이터, 외부 게시, 비밀값, 파괴 명령) | 규칙 등급만 바뀝니다. 남으면 "절대 금지", 아니면 "권장 습관" |
두 번 이상 일어났나? | 아무 데도 안 적습니다. 그 세션이 배운 걸로 끝 |
이 도구·이 레포 밖에서도 통하나? | 그 레포의 CLAUDE.md나 도구 위키로 |
세 번째 질문이 제일 많이 걸러냅니다. 예를 들어 이런 일이 있었습니다. 파일을 읽기만 하는 grep 명령이었는데, 검색어 안에 git reset --hard라는 글자가 들어 있다는 이유로 안전 훅이 멈춰 세웠습니다. 짜증 나는 일이었지만, 이건 "그 훅의 특성"에 대한 지식이지 습관이 아닙니다. 이름을 지우면 남는 말이 없으니까요. 그래서 규칙 파일이 아니라 위키로 갔습니다.
반대로 세 질문을 다 통과한 예도 있습니다. 병렬로 실행한 명령 하나가 cd로 폴더를 옮기는 바람에, 다른 명령의 상대 경로가 엉뚱한 곳을 가리켰습니다. 상태를 감시하던 스크립트는 다른 작업 폴더를 조용히 지켜보고 있었고요. 비슷한 사고는 다른 날 다른 프로젝트에서도 났습니다. 그때는 테스트 명령이 엉뚱한 폴더에서 다섯 번 돌았고, 다섯 번 다 초록불이었습니다. 이건 도구 이름을 지워도 남습니다. "경로는 전부 절대 경로로 쓴다." 규칙 파일에 들어갈 자격이 있습니다.
규칙으로 적어도 안 지켜지는 실수가 있습니다. 제 경우 대표가 이겁니다.
xcodebuild ... -destination '...' build 2>&1 | tail -15
# → "exited with code 0"빌드는 한 번도 돌지 않았습니다. 따옴표 때문에 인자가 먹혀서 xcodebuild는 목록만 출력하고 실패했는데, 마지막에 받은 0은 tail의 종료 코드였습니다. 같은 시간에 다른 스크립트도 | tail -2 뒤에서 실패를 숨겼습니다. 이걸 규칙으로 적어 뒀는데, 적은 뒤에도 한 세션에서 세 번 어겼습니다.
그래서 훅으로 올렸습니다. 종료 코드가 판정 결과인 명령(작업 완료 대기, 상태 확인 같은 것)을 파이프로 감싸면 실행 전에 막습니다. 그런데 일부러 모든 | tail을 막지는 않았습니다. 평범한 ls | head까지 막는 훅은 하루 만에 꺼집니다. 그래서 훅이 못 보는 나머지는 여전히 규칙으로 남아 있습니다.
여기서 기준이 하나 더 생깁니다.
훅으로 올릴 조건: 피해가 남고, 반복되고, 명령 글자만 보고 기계적으로 잡을 수 있을 때.
판단이 필요한 건 훅이 못 합니다. 그건 규칙의 몫입니다.
훅이 꼭 필요한 이유를 가장 아프게 배운 건 이 사고였습니다. 커밋 안 한 작업이 있는 폴더에 읽기 전용 점검을 하는 에이전트를 붙였습니다. 초기화하라는 지시는 어디에도 없었습니다. 그런데 에이전트가 작업 폴더를 되돌려 버렸습니다.
프롬프트는 부탁이고, 훅은 문입니다. 지금은 git reset --hard, git checkout -- ., git restore . 같은 명령이 실행되기 전에 훅이 확인을 요구합니다. 확인 프롬프트를 다 끄는 --dangerously-skip-permissions 모드에서도 훅은 그대로 돕니다. 그리고 규칙 파일에는 사람 쪽 습관을 하나 남겼습니다. "커밋 안 한 작업이 있으면, 에이전트에게 넘기기 전에 git diff부터 떠 둔다."
숫자로 보면 이렇습니다. 사용자가 "아니야", "다시 해"처럼 교정하는 듯한 말을 하면 훅이 기록하는데, 10월 3일부터 3주 동안만 839번 잡혔습니다. 물론 단어만 보고 잡은 거라 진짜 교정이 아닌 것도 섞여 있습니다. 그중 경위를 남긴 사례가 42건, 매번 읽히는 규칙은 24줄입니다.
처음엔 이게 아까웠습니다. 실수에서 배운 게 다 어디 갔지? 그런데 생각해 보면 대부분의 실수는 그 세션 안에서 고쳐지고 끝나는 게 맞습니다. 모든 걸 기억하려는 파일은 아무것도 못 가르칩니다. 실제로 저는 습관을 38KB나 모아 놓고, 그 파일이 한 번도 읽힌 적이 없었다는 걸 나중에야 알았습니다.
AI가 같은 실수를 반복할 때, 규칙을 하나 더 적기 전에 세 가지만 물어보세요.
또 나면 피해가 남나? → 남으면 "금지", 아니면 "습관"
두 번 이상이었나? → 아니면 적지 않는다
이 도구·이 레포 밖에서도 통하나? → 아니면 그 레포 문서로
그리고 규칙 파일에는 상한을 거세요. 상한이 있어야 합치고, 합쳐야 지켜집니다. 적었는데도 또 어기는 실수는, 글자로 잡을 수 있다면 훅으로 올리면 됩니다.
이 방식은 제가 쓰는 Claude Code 플러그인 묶음 groundwork에 들어 있습니다. 질문 세 개와 24줄 상한은 memory-loop가, 실행 전 차단은 guardrails가 맡습니다.
/plugin marketplace add choiyounggi/groundwork
/plugin install memory-loop@groundwork
/plugin install guardrails@groundwork👉 저장소: github.com/choiyounggi/groundwork (MIT)
플러그인 없이도 CLAUDE.md 하나로 똑같이 해 볼 수 있습니다. 규칙 수를 정해 두고, 경위는 다른 파일로 빼고, 규칙마다 번호를 다는 것만으로도 꽤 달라집니다. 써 보시고 막히는 점은 이슈로 남겨 주세요.
관련 글:
이 글은 제 벨로그에 먼저 올린 글입니다. 원문: AI가 같은 실수를 반복하는 건 기억력 문제가 아니었다