Claude Code의 압축(Compaction) 과정에서 살아남는 것과 규칙을 유지하는 방법
요약
Claude Code의 컨텍스트 압축(Compaction) 과정에서 발생하는 정보 손실 문제를 분석하고, 규칙과 지침을 유지하는 방법을 설명합니다. SessionStart 훅과 matcher: compact 설정을 활용하여 중요한 컨텍스트를 효율적으로 재주입하는 전략을 제안합니다.
핵심 포인트
- 압축 과정에서 범위 지정 규칙과 세션 중간 지침이 유실될 수 있음
- SessionStart 훅을 사용하여 압축 직후 필요한 컨텍스트를 재주입 가능
- 토큰 효율성을 위해 전체 내용 대신 인덱스나 포인터 방식으로 재주입 권장
- 불변량(invariants)과 현재 작업 상태를 요약하여 전달하는 것이 핵심
긴 Claude Code 세션은 결국 컨텍스트 윈도우(context window)의 한계에 도달합니다. 이 경우 Claude Code는 _압축(compaction)_을 실행합니다. 즉, 지금까지의 대화를 요약하고 해당 요약을 시드로 사용하여 새로운 윈도우를 시작합니다. 작업은 계속되지만, 처음에 로드했던 모든 내용이 그대로 유지되지는 않습니다.
에이전트가 한 시간 동안 따르고 있던 규칙을 갑자기 잊어버리는 것을 본 적이 있다면, 대개 이것이 그 이유입니다. 여기서는 실제로 압축 과정에서 무엇이 살아남는지, 무엇이 조용히 사라지는지, 그리고 중요한 부분을 계속 유지할 수 있는 해결책은 무엇인지 설명합니다.
압축(Compaction)이 실제로 하는 일
압축은 절단(truncation)이 아닙니다. Claude Code는 단순히 오래된 메시지를 버리는 것이 아니라, 결정된 사항, 수정된 파일, 현재 작업 상태 등 세션의 요약본을 작성하고, 이 요약본과 항상 로드되는 소수의 자료를 결합하여 컨텍스트를 재구축합니다.
이러한 차이는 중요합니다. 왜냐하면 요약은 설계상 손실이 발생하는(lossy by design) 방식이기 때문입니다. 요약은 작업의 형태(
- Scoped rules (범위 지정 규칙): 일치하는 파일을 작업 중이었기 때문에 불러왔던 규칙들입니다. 압축(Compaction)이 이루어지면, 무언가가 이를 다시 트리거하기 전까지는 사라집니다. 만약 에이전트의 다음 행동이 해당 범위(scope)와 일치하지 않는다면, 에이전트는 방금까지 따르고 있던 규칙 없이 행동하게 됩니다.
- Mid-session instructions (세션 중간 지침): 두 시간 전에 입력했던 지침들입니다. 이들은 요약본에 남겨진 내용으로서만 존재하게 됩니다.
- Injected context (주입된 컨텍스트): 이전 훅(hook) 실행이나 도구 출력(tool output)으로부터 주입된 컨텍스트입니다. 원문(raw text)은 사라지고, 요약본의 의역된 내용만 남게 됩니다.
범위 지정 규칙(scoped-rules)의 사례는 매우 교묘합니다. 범위 지정의 핵심 목적은 항상 로드되는 세트의 크기를 작게 유지하는 것이지만, 이는 동시에 가장 구체적이고 가장 정성스럽게 작성된 규칙들이 가장 짧은 수명을 갖게 된다는 것을 의미합니다.
해결책: matcher: compact를 사용한 SessionStart
Claude Code의 SessionStart 훅은 완전히 새로운 세션뿐만 아니라, 매처(matcher)가 compact로 설정된 압축 직후에도 실행됩니다:
{
"hooks": {
"SessionStart": [
...
해당 명령어가 표준 출력(stdout)으로 출력하는 모든 내용은 새로운 윈도우(window)에 주입됩니다. 윈도우가 교체되는 현상은 더 이상 눈에 보이지 않는 이벤트가 아니라, 여러분이 제어할 수 있는 훅이 됩니다. 즉, 불변량(invariants)을 다시 기술하고, 작업 노트(working notes)를 다시 로드하며, 누락되어서는 안 될 규칙을 다시 확언할 수 있게 됩니다.
재주입되는 페이로드(payload)를 작게 유지하세요
모든 것을 다시 주입하고 싶은 유혹이 생길 수 있습니다. 압축이 일어날 때마다 전체 규칙 파일을 다시 붙여넣는 식입니다. 하지만 이를 참아야 합니다. 압축은 단지 토큰을 확보한 것뿐입니다. 동일한 대량의 자료로 윈도우를 다시 채우는 것은 토큰을 즉시 다시 소모하는 것이며, 결국 더 빨리 한계치(ceiling)에 도달하게 만듭니다.
더 효과적인 방법은 상태(state) 자체를 주입하는 것이 아니라, _인덱스(index)_를 재주입하는 것입니다:
- 반드시 유지되어야 하는 불변량당 한 줄씩 작성 (예: "모든 커밋 전에는 테스트가 통과해야 함")
- 상세 내용이 있는 위치를 가리키는 포인터 (예: "전체 DB 마이그레이션 규칙:
.claude/rules/db.md") - 현재 작업 상태를 두세 줄 내외로 요약
에이전트는 세부 정보가 필요할 때 포인터(pointer)를 따라갈 수 있습니다. 15줄 정도의 재주입(reinject) 파일은 압축(compaction) 시 비용이 거의 들지 않지만, 400줄짜리 파일은 압축을 통해 확보한 여유 공간(headroom)을 모두 소모해 버립니다.
실무 체크리스트
- 규칙을 수명(lifespan)에 따라 분류하세요. 세션 전체 동안 유지되어야 하는 모든 것은 범위가 지정된 규칙(scoped rule)이 아니라 루트
CLAUDE.md에 있어야 합니다. - 범위 지정 규칙(scoped rules)을 휘발성(ephemeral)으로 취급하세요. 이 규칙들은 에이전트가 다시 발견할 여유가 있는 파일별 세부 정보를 위한 것이지, 불변량(invariants)을 위한 것이 아닙니다.
matcher: compact를 포함한SessionStart훅(hook)을 추가하여 재주입 인덱스(reinject index)를 출력하도록 하세요.- 인덱스를 약 20줄 이내로 유지하세요. 페이로드(payload)보다는 포인터(pointer)를 활용해야 합니다.
- 의도적으로 테스트하세요: 세션 중간에 수동으로
/compact를 실행하고, 에이전트가 당신이 중요하게 생각하는 규칙을 여전히 준수하는지 확인하세요. 만약 준수하지 않는다면, 해당 규칙은 컨텍스트 창(window)에서 살아남지 못하는 부분에 위치했던 것입니다.
압축(Compaction)은 좋은 거래입니다. 이것 없이는 긴 세션이 불가능할 것입니다. 실패 모드는 각 규칙이 어디에 위치해야 하는지, 그리고 컨텍스트 창이 넘어갈 때 무엇이 재주입(re-injected)되어야 하는지를 의도적으로 결정하지 않았을 때만 조용히 발생합니다. 한 번 결정하고, 훅(hook)을 연결해 두면 에이전트는 더 이상 잊어버리지 않습니다.
저는 Claude Code, Cursor, Codex를 위한 규칙/기술 팩 세트인 Rulestack을 운영하고 있습니다. 여기에는 이와 같은 훅 레시피(hook recipes)가 포함되어 있습니다.
_Bluesky에서 매일 AI 코딩 에이전트 팁을 확인하세요: @ai-shop.bsky.social — 또는 그곳의
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기