
Claude가 작성하는 긴 주석은 Claude 자신에게 도움이 되지 않았다
요약
Claude Code 사용 시 발생하는 과도한 주석이 오히려 AI의 컨텍스트를 압박하고 독해를 방해한다는 사실을 발견했습니다. 주석의 길이가 구현의 불확실성을 나타내는 지표가 될 수 있음을 인지하고, 코드에서 복원할 수 없는 정보만 기록하도록 규칙을 정립하는 과정을 다룹니다.
핵심 포인트
- 장황한 주석은 AI의 컨텍스트를 점유하여 코드 구조 파악을 방해함
- 주석의 길이는 모델의 구현 불확실성을 나타내는 지표가 될 수 있음
- 코드에서 복원할 수 없는 정보(사고 과정, 외부 제약 등)만 주석으로 남겨야 함
- 단순 구현 설명 위주의 주석은 정보량이 제로이며 가독성을 저해함
서론
주식회사 Sally 소속 엔지니어인 @wellPicker입니다.
저희 회사는 스마트폰이나 PC로 마다미스(머더 미스터리)를 즐길 수 있는 앱인 Uz, 마다미스 정보·예약 관리 사이트 Madamis.jp, 마다미스 개발 도구 Uz Studio를 개발하고 있습니다.
마다미스에 대해서는 이쪽을 확인해 주세요.
Claude Code에 구현시키다 보면 주석이 지나치게 길어집니다. 궁금해서 본인에게 물어보았더니, 예상과는 다른 답변이 돌아왔습니다. 그로부터 규칙을 정비해 보았지만, 생각만큼 효과가 없었고 원인을 조사해 보니 "줄일 수 없는 이유"가 명확해졌습니다.
그 일련의 기록입니다.
우선 실물
저희 백엔드(Go)의 WebSocket 압축 설정입니다. Claude가 작성했습니다.
// WebSocket 프레임 압축 (RFC 7692 permessage-deflate)을 활성화한다.
// 클라이언트 (Dart graphql v5.2.3 + dart:io WebSocket)는 CompressionOptions.compressionDefault로
// 이미 Sec-WebSocket-Extensions: permessage-deflate를 advertise하고 있으므로,
...
설정 1줄에 대해 주석이 18줄입니다. 게다가 적혀 있는 내용에 거짓은 없습니다. 라이브러리의 사양도, 운영 환경에서 OOMKill이 발생했던 경위도 사실입니다.
이 "거짓이 아니다"라는 점이 나중에 영향을 미칩니다.
본인에게 물어보았다
긴 주석이 AI 자신의 독해를 돕고 있는 것일지도 모른다는 가능성을 생각하여 그대로 물어보았더니, 다음과 같은 답변이 돌아왔습니다.
솔직히 말하면,
도움이 되지 않습니다. 오히려 방해가 되는 경우가 더 많습니다. 제가 파일을 읽을 때 실제로 보고 있는 것은 코드 그 자체입니다.
// 사용자 ID를 가져온다
아래에 final userId = await getUserId();가
있더라도 정보량은 제로이며, 그만큼 화면(컨텍스트, Context)을 점유하여 주변 코드를 보기 어렵게 만듭니다. 긴 파일을 읽을 때는 특히 주석이 많을수록 "실제 로직의 밀도"가 낮아져 전체 구조를 파악하기 어려워집니다.
읽는 사람으로서 이득을 보는 것이 아니라, 컨텍스트를 압박하여 불리하게 만들고 있다는 이야기였습니다. 한정된 컨텍스트에 장황한 행이 섞이면 그만큼 실제 코드가 들어갈 자리가 없어지므로, 듣고 보니 당연한 말이었습니다.
"그럼 왜 쓰는가"에 대한 설명도 이어졌습니다.
이해를 위해서가 아니라, 출력의 습관입니다. 솔직한 내역은 다음과 같습니다:
- 설명적이고 정중한 출력이 선호되도록 훈련되어 있음
- "제대로 생각해서 작성했습니다"를 가시화하는 방향으로 흐르기 쉬움
- 자신 없는 부분일수록 말로 채워서 보강하려고 함 (이것이 가장 좋지 않음. 불확실성이 주석의 분량으로 변질됨)
세 번째가 수확이었습니다. 주석의 분량이 해당 부분의 불확실성을 나타내는 지표가 되고 있다. 본래라면 "이 구현이 맞는지 자신 없다"라고 신고해야 할 상황에서, 대신 긴 설명이 돋아나고 있다는 것입니다. 정중한 설명을 "잘 이해하고 작성된 코드"의 증거로 읽는 것은 오히려 반대였습니다.
어떤 주석이라면 가치가 있는가
같은 답변에서 예외로 언급된 것이 "코드에서 복원할 수 없는 정보"였습니다. 과거의 사고, 외부 제약, 직관에 반하는 동작. 이것들은 코드를 아무리 읽어도 나오지 않습니다.
그래서 이 기준을 프로젝트의 규칙 파일(.claude/rules/coding-principles.md)에 적었습니다.
## 주석의 분량
주석에는 코드에서 복원할 수 없는 정보만 적는다. 구현의 실황(예: `// 사용자 ID를 가져온다` 등)은 정보량이 제로이며 주변 코드의 가독성을 떨어뜨리므로 적지 않는다.
...
이것으로 해결되었다고 생각했습니다.
규칙은 절반만 효과가 있었다
체감이 변하지 않아서 실제로 측정해 보았습니다. 규칙을 추가한 커밋 전후의 일정 기간 동안, 제가 머지(Merge)한 PR 27건의 diff를 집계한 것입니다 (자동 생성 파일은 제외).
| 변경 전 | 변경 후 |
|---|---|
| 추가 코드 | 2,909 행 |
| 추가 주석 | 777 행 |
| 주석 비율 | 21.1% |
| 4행 이상의 연속 주석 블록 | 52 개 |
| 블록의 최대 / 평균 | 17 행 / 7.3 행 |
비율은 절반 이하로 떨어졌지만, 「한 곳에 뭉쳐 있는 긴 블록」은 전혀 줄어들지 않았습니다. 개수는 52개에서 50개로, 최대 길이는 17행에서 18행으로 오히려 늘어났습니다 (서두의 실례가 바로 그 18행입니다).
체감이 변하지 않았던 이유도 이것으로 설명할 수 있습니다. 읽으면서 눈에 띄는 것은 전체 비율이 아니라, 스크롤 중에 나타나는 수십 행의 덩어리이기 때문입니다. 흩어져 있는 1행이 줄어들어도 인상은 변하지 않습니다.
왜 긴 블록만 남았는가
서두의 18행에 규칙을 적용해 보면 이유를 알 수 있습니다.
| 행 | 내용 | 「코드에서 복원할 수 없는 정보」인가 |
|---|---|---|
| 1~4 | 클라이언트 측에서 이미 압축을 advertise 하고 있으므로, 서버는 받아들이기만 하면 된다 | 해당함 (클라이언트 구현을 보지 않으면 알 수 없음) |
| 6~11 | context takeover는 연결마다 고정 메모리를 가진다. 라이브러리의 doc에서도 long-lived 연결에서는 권장하지 않는다 | 해당함 (라이브러리의 내부 사양) |
| 13~18 | 이전에는 gorilla를 사용했으며, 그 구현에서는 context takeover가 비활성화되어 있었다. 이전 시점에 변경했더니 OOMKill이 발생했다 | 해당함 (과거 사고의 경위) |
18행 모두가 「코드에서 복원할 수 없는 정보」에 해당합니다. 즉, 이 규칙으로는 단 한 줄도 깎아낼 수 없습니다.
이것이 「효과가 없었던」 정체였습니다. AI가 쓰는 주석은, 무의미해서 지울 수 있는 것이 아니라, 유용하기 때문에 지울 수 없는 것입니다. 실황 중계처럼 정보량이 제로라면 누구나 지울 수 있겠지만, 사실로서 정확하고 게다가 코드에는 적혀 있지 않은 정보가 18행이나 나열되어 있으면 지울 근거를 만들 수 없는 법입니다.
기준을 「유용함」에서 「위치」로 바꾸었다
그래서 판단 축을 바꾸었습니다. 그 정보가 유용한지 여부가 아니라, 그곳이 그 정보의 적절한 위치인지를 기준으로 자르기로 한 것입니다.
다시 한번 18행을 보면, 후반 6행(13~18행)은 「이전에는 gorilla였다」, 「이전 시점에 변경했더니 망가졌다」라는 변경 이력입니다. 이것은 유용하지만, 위치는 git log와 PR입니다. 반년 뒤에 이 코드를 읽는 사람에게 필요한 것은 「왜 지금 NoContextTakeover인가」이지, 「무엇에서 무엇으로 바뀌었는가」가 아닙니다.
같은 관점에서, (UZU-1234)와 같은 태스크 ID 참조도 제거했습니다. 유용해 보이지만, 링크된 issue가 닫히고 내용이 요약되지 않은 채 식별자만 남게 됩니다. 필요한 내용은 주석에 직접 적어야 합니다.
현재는 이 기준을 프로젝트의 규칙이 아니라 글로벌 ~/.claude/CLAUDE.md에 두고 있습니다.
## 코드 주석
코드 주석에는 비자명한 WHY만 작성한다. 작성하는 것은 숨겨진 제약 사항·workaround를 넣은 이유·읽는 사람이 놀랄만한 동작 등, 코드에서 복원할 수 없는 정보로 한정한다.
...
바꾼 점은 3가지입니다.
- 금지 리스트 형태로 만들었다 — 「작성/미작성」 표는 판단을 맡기는 형식이기에, 표에 없는 항목의 취급이 애매해진다. 금지 대상을 명시하는 편이 AI에게도 인간에게도 해석의 폭이 좁다.
- 실제로 발생한 위반 사항을 그대로 항목으로 추가했다 — 변경 이력과 태스크 ID 참조. 추상적인 원칙을 하나 두는 것보다 구체적인 위반 사례를 나열하는 것이 더 효과적이다 (라는 가설).
- 글로벌로 옮겼다 — 어떤 리포지토리에서도 동일한 것을 요구하기 때문.
이 방식이 효과가 있는지는 아직 판단할 수 없습니다. 옮긴 지 얼마 되지 않았기에, 다음에는 동일한 집계를 돌려 「4행 이상의 블록 수」가 줄어들었는지 확인할 예정입니다. 적어도 체감으로 판단하여 다시 실패하는 일은 피할 수 있습니다.
요약
- AI가 작성하는 긴 주석은 AI 자신의 독해에 도움이 되지 않는다. 오히려 컨텍스트 (Context)를 압박하여 불리하게 작용한다.
- 주석이 길어지는 이유는 이해를 위해서가 아니라 출력의 습성 때문이다. 특히
확신이 없는 부분일수록 말로 채우려 하기 때문에, 주석의 분량은 불확실성의 지표가 된다. - "코드에서 복원할 수 없는 정보만 작성한다"라는 규칙을 도입했더니, 주석 비율이 21.1% → 8.8%로 낮아졌다.
하지만 4행 이상의 긴 블록은 52개 → 50개로 거의 변하지 않았다 - 줄어들지 않은 이유는,
그러한 주석이 무의미해서가 아니라 유용하기 때문이다. 설정 1행에 붙은 18행은 모든 행이 "코드에서 복원할 수 없는 정보"에 해당하여, 이 규칙으로는 단 1행도 줄일 수 없었다. - 판단 기준을 "유용한가"에서 "
그곳이 해당 정보의 위치인가"로 바꾸었다. 변경 이력은 git log, 태스크 ID는 issue에 있으므로 코드에는 작성하지 않는다. - 규칙을 작성한 후에는 출력이 실제로 변했는지를 측정한다. 체감으로는 "효과가 있다/없다"를 착각할 수 있다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기