Claude Code의 압축(Compaction)을 손실 없이 처리하여 52초를 0.26초로 단축
요약
Claude Code 사용 시 발생하는 긴 대화 세션의 압축(compaction) 지연 문제를 해결하기 위해 'lossless-compaction' 플러그인이 개발되었습니다. 이 플러그인은 모델이 요약하는 대신, 정보를 로컬에 보관하여 속도를 획기적으로 개선했습니다. 그 결과, 기존 대비 압축 시간이 수십 초에서 0.26초로 단축되었으며, 이후의 컨텍스트 유지력과 성능도 향상되었습니다.
핵심 포인트
- 내장 compaction은 요약(summary)을 생성하여 정보 손실 위험이 있습니다.
- lossless-compaction은 정보를 로컬에 보관하며, 속도를 52초에서 0.26초로 단축했습니다.
- 정보를 단순히 압축하는 것이 아니라, 컨텍스트 유지력과 성능 향상에 초점을 맞췄습니다.
- 플러그인 사용법을 안내하며, 사용자에게 즉시 적용할 수 있는 방법을 제시합니다.
Claude Code의 compaction, 기다리기 지겹지 않으신가요?
긴 세션에서 compaction이 실행되면 수십 초 동안 기다려야 할 때가 있습니다. 제 환경에서 약 576,000 토큰의 대화를 Sonnet 5.5로 측정했을 때, 내장된 /compact에는 51.8초가 걸렸습니다. 게다가 내장 compaction은 대화를 모델이 요약하도록 하는 방식이기 때문에, summary에 들어가지 않은 정보는 다음 context에 남아있지 않습니다.
이 두 가지 점이 싫어서, Claude Code용 플러그인 lossless-compaction을 만들었습니다. 모델에게 summary를 작성하게 하지 않고, 큰 정보를 로컬로 보관했다가 필요할 때 원래 내용을 그대로 되돌릴 수 있습니다. 같은 대화에서는 0.26초 만에 compaction이 끝났습니다.
바로 시도하고 싶다면, Claude Code 2.1.287 이후 세션에서 다음 한 줄을 입력하세요. 설정은 필요 없습니다.
/plugin install lossless-compaction --marketplace yottayoshida/lossless-compaction
| lossless-compaction | 내장(built-in) | |
|---|---|---|
/compact | 0.26초 | 51.8초 |
| 다음 요청 (next request) | 272,163 토큰 | 9,669 토큰 |
| 연속으로 11문제 정답 | 11 | 6 |
/compact + 11문제 | $2.05 | $1.58 |
압축된 토큰 양만 보면 상당히 불리해 보입니다. 내장 기능이 9,669 토큰까지 줄인 것에 비해, lossless-compaction은 272,163 토큰을 남기고 있습니다.
하지만 그 후에 같은 세션에서 11문제를 연속으로 질문했을 때, 정답률은 11문제 대 6문제였습니다. 총 비용은 $2.05 대 $1.58로, 약 28배 큰 context를 유지하고 있음에도 차이는 그렇게 크지 않습니다.
즉, 단순히 '압축률을 희생해서 200배 빠르게 만들었다'는 이야기도 아닙니다. compaction에 52초를 기다릴 것인가, 아니면 더 큰 context를 이후에도 가질 것인가. 실제 비용은 prompt cache나 그 후에 어떤 정보를 재활용하느냐에 따라서도 달라집니다.
TL;DR (요약)
- 내장 compaction은 모델이 대화를 summary로 변환합니다. lossless-compaction은 summary를 만들지 않고, 큰 정보를 로컬로 보관합니다.
- 약 576,000 토큰의 대화에서, 내장 기능은 51.8초, lossless-compaction은 0.26초였습니다. 이어서 질문한 11문제 정답률은 11대 6이었습니다.
- 성격이 다른 6가지 종류의 대화를 각각 두 번씩 측정했을 때, lossless-compaction은 12번 모두 summary 없이 압축했으며, 108문제 정답률은 106대 96이었습니다.
- 압축된 context는 내장 기능보다 큽니다. 첫 번째 측정에서는 6가지 종류 중 5가지에서 lossless-compaction이 더 저렴했고, window를 채우는 한 종류에서는 비쌌습니다.
- 보관한 정보에는 복구 지점(return point)을 남겨두어 필요할 때
recall로 원래 내용을 가져올 수 있습니다. - '나중에 필요한 정보'를 예측하는 방식도 시도했지만 포기했습니다. 예측 정확도를 높이는 것보다, 예측에 실패해도 정보가 사라지지 않는 구조로 만들었습니다. - 현재 과제는 압축률입니다. compaction의 비용을 없애기보다는, 어디서 부담할지 변화시키고 있습니다.
왜 만들었나
이전에는 auto compaction이 다가오면 작업 흐름상 적절한 지점에서 제가 직접 /compact를 입력하는 경우가 있었습니다. 중간에 summary로 변환되는 것보다, 제가 타이밍을 선택하는 것이 낫다고 생각했기 때문입니다.
하지만 이것은 하드웨어의 연속성을 사람이 일부러 끊고 있는 것에 불과합니다. Claude Code가 그냥 작업을 계속하도록 해야 하는데, context window의 사정 때문에 사람이 감시하고 적절한 지점을 찾아 compaction을 끼워 넣는 것입니다. auto compaction의 타이밍만 조절할 뿐, 대화를 summary로 대체하는 메커니즘 자체는 아무것도 변하지 않았습니다.
그렇다면, 타이밍이 아니라 compaction 그 자체를 바꾸는 것이 낫습니다. 기다리는 시간을 줄이고 싶었던 것도 있지만, compaction을 '여기서 한 번 대화를 요약하여 재시작하는 이벤트'로 만들고 싶지 않았습니다.
또 다른 OSS는 지금까지 만들어 온 것들이 직전의 sideeye처럼 모두에게 적합하지 않은 경우가 많았다. sideeye는 stateful software의 프로세스를 잘못된 타이밍에 멈추고, 영속화된 state에 문제가 없는지 검증하는 도구인데, 나로서는 흥미롭지만 사용하는 사람은 상당히 제한적이다. 이번에는 조금 더 폭넓게 사용될 수 있는 것을 만들어보려고 했고, 이미 GitHub에서 사람들이 모여 있는데도 issue나 PR을 보면 아직 해결되지 못한 영역을 찾아냈다. 그중 하나가 Claude Code의 compaction이었다.
기존 방식
조사해 보니, compaction에는 여러 가지 방법이 있었다. Claude Code처럼 전체 대화를 summary로 변환하는 것, 오래된 tool result를 잘라내는 것, 시작과 끝만 남기는 것, heuristic이나 작은 모델로 중요도를 매기는 것 등 다양했다. fast-jev-compaction은 Jev를 사용해 tool call이나 result를 평가하는 방식이었다.
구현은 달라도, 내가 조사한 범위에서는 대부분 '무엇을 남기고 무엇을 버릴지'를 결정하려 하고 있었다. 나도 처음에는 같은 방향으로, Jev에게 '이 정보가 나중에 필요할까?'를 판정하게 하려고 했지만, 실제로 시도해 보니 기대만큼 쓸모가 없었다.
생각해보면 당연하다. compaction 시점의 context만 보고 30턴 후에 필요할 정보를 예측하려는 것이다. 모델을 아무리 똑똑하게 해도, 미래의 작업 내용까지 입력에 들어가는 것은 아니다. 이런 종류의 'LLM에게 중요한 것을 선택하게 하려다 결국 그 부분이 가장 불안정해지는' 경우는 LLM을 사용한 시스템을 만들 때 흔히 발생한다.
그래서 무엇을 남길지 예측하는 정확도를 높이는 대신, 예측이 빗나가도 문제가 없는 방식으로 바꿨다.
버리지 않고 외부에 저장하기
lossless-compaction은 큰 정보를 context에서 빼내지만 삭제하지는 않는다. 로컬에 저장하고, 대화에는 원래 정보로 돌아가기 위한 티켓(ticket)을 남긴다.
[moved out] Read result, 18204 bytes; recall with mcp__lossless-compaction__recall id 3f9a…
Claude가 그 정보를 필요로 하면, 티켓에 있는 id로 recall을 한다. 저장된 내용은 SHA-256으로 식별하고, 디스크에 기록한 후 다시 읽어와 일치 여부를 확인한다. 저장에 실패한 정보는 context에서 빼내지 않는다.
지금은 tool result뿐만 아니라, 긴 Write, Edit, Bash 등의 input, 오래된 작은 tool call, 긴 메시지의 중간 부분까지 단계적으로 context 밖으로 빼낸다. 그래도 대화가 너무 크다면, 오래된 메시지 그룹을 parts로 저장하고, context에는 돌아갈 위치를 남긴다. plugin 측에서 compaction이 가능하다면 summary를 만들 필요도 없고, compaction을 위한 모델 호출도 하지 않는다.
내장(組み込み) 방식이 '긴 대화를 읽고 짧은 대화를 다시 쓰는' 것에 비한다면, lossless-compaction은 '큰 정보를 대화 밖으로 옮기고, 필요하면 돌아올 수 있게 하는 것'이다. 이 차이점 덕분에 무엇을 빼낼지 판단을 잘못해도 원래 정보가 사라지지 않는다. selection의 정확도는 정보를 잃는지 여부가 아니라, 나중에 불필요한 recall이 몇 번 발생할지의 문제다.
Jev는 compaction에서 제외했지만, 퇴비된(退避した) 정보를 자연어로 찾는 optional한 find에서는 사용하고 있다. 이 기능은 선택을 잘못해도 정보 자체를 지우지 않기 때문에, 모델에 의한 모호한 판정을 사용하는 곳과 궁합이 좋다.
복원 경로
Sonnet 5.5나 Opus 5.5로 벤치마크하면서 흥미로웠던 점은, 내장 summary에서 정보가 누락되어도, 모델이 Claude Code의 session record를 스스로 찾아가서 요약 전 기록을 발견하고 답변하는 경우가 있었다는 것이다.
이렇게만 보면 굳이 lossless일 필요가 없어 보일 수도 있다. 하지만 나는 이 동작을 compaction의 복원 수단으로는 그다지 신뢰하지 않는다.
모델이 먼저 'summary만으로는 정보가 부족하다'고 판단하고, Claude Code의 session record를 찾아보는 것을 떠올리게 되며, 올바른 이력까지 도달할 필요가 있다. 현재 Sonnet이나 Opus로는 상당히 잘 작동하지만, 이는 compaction 메커니즘으로 보장된 복원 경로가 아니라 모델의 행동에 의존하는 것이다. 모델이나 하네스 측의 동작이 바뀌면, 똑같이 찾아가지 않을 수도 있다.
실제로 약 576,000 토큰의 대화에서 11문제를 연속으로 질문했을 때, 내장(built-in) 기능의 정답률은 6문제에 그쳤다. 6종류의 대화 108문제에서도, 정답률은 lossless-compaction이 106문제였고, 내장 기능이 96문제였다.
애초에 summary로 잘라낸 정보가 나중에 필요해져서 session record를 다시 읽어와야 한다면, 그 내용은 다시 context에 들어오게 된다. 압축할 때는 작아질 수 있지만, 필요한 정보까지 지워버리면, 나중에 그 토큰을 또다시 비용으로 지불해야 하는 상황이 생긴다.
lossless-compaction은 복원 경로의 발견을 모델에게만 맡기지 않는다. 외부로 내보낸 정보에 대해 '여기에 원본 데이터가 있다', '이 ID로 되돌릴 수 있다'고 context에 남겨둔다. 필요하면 recall를 하고, 필요하지 않으면 읽지 않는다.
둘 다 궁극적으로 필요한 정보를 context에 넣는다. 다만, 내장 기능은 'summary로 충분한지', '충분하지 않다면 과거를 찾아볼지'까지 모델에게 위임한다. lossless-compaction에서는 격리(퇴비)와 복원의 경로 자체를 하네스 측에 가지고 있다.
비용 (Cost)
이 차이점을 고려하면, compaction의 비용은 단순한 압축률만으로는 비교하기 어렵다.
내장 기능은 compaction 시 대화 전체를 모델에게 전달하여 summary를 만든다. 이 처리에 시간과 토큰을 사용하는 대신, 그 이후의 context는 상당히 작아진다. 하지만 summary에서 빠진 정보가 다시 필요해지면, session record 등에서 다시 읽어와서 그 분량만큼의 토큰을 또 context에 넣어야 한다.
lossless-compaction은 summary를 만들지 않기 때문에, compaction 자체의 모델 비용과 대기 시간은 거의 없다. 대신, 내장 기능의 summary보다 더 많은 정보를 context에 남기므로, 이후 요청(request)은 무거워진다. 외부로 내보낸 것이 필요해지면 recall을 한다.
벤치마크는 두 가지가 있다. 성격이 다른 6종류의 대화(큰 tool result가 많은 것, Write가 많은 것, 긴 문서가 많은 것, 짧은 tool call이 많은 것 등)를 수동으로 /compact를 친 후에 9문제를 연속으로 질문하는 방식으로 두 번씩 측정했다. 또 하나는 100만 토큰의 window에서 약 576,000 토큰까지 키운 대화이다. 둘 다 Sonnet 5.5로 측정했다.
| lossless-compaction | built-in | |
|---|---|---|
| 6종류 × 2회, 연속으로 9문제 질문 | ||
/compact 후 summary 작성됨 | 0 / 12 | 12 / 12 |
/compact 시간 | 0.07~0.35초 | 15~27초 |
| 다음 요청 (Next request) 토큰 수 | 12,283~83,475 tokens | 9,044~30,735 tokens |
| 108문제 정답률 | 106 | 96 |
| 1차 비용 합계 (Cost total) | $2.82 | $2.17 |
약 576,000 토큰, 연속으로 11문제 질문 | | |
| /compact 시간 | 0.26초 | 51.8초 |
| 다음 요청 (Next request) 토큰 수 | 272,163 tokens | 9,669 tokens |
| 11문제 정답률 | 11 | 6 |
| /compact + 11문제 비용 합계 (Cost total) | $2.05 | $1.58 |
1차 측정에서는 6종류 중 5종류에서 lossless-compaction이 더 저렴했다. 비쌌던 것은 window를 채우는 한 종류였는데, 9문제 중 4문제에서 Claude Code가 약 79,500 토큰을 prompt cache에 다시 기록했기 때문이다.
반대로, 작업 사이에 공백이 생겨 prompt cache가 만료되면, lossless-compaction은 다음 문제에서 남긴 27만 토큰을 캐시에 다시 기록해야 한다. 보존하는 양이 많기 때문에, 캐시가 만료될 때의 부담은 내장 기능보다 무겁다.
물론 이것만으로 경제성을 일반화하려는 의도는 아닙니다. prompt cache의 효율성이나, 그 이후 작업에서 과거 정보를 얼마나 활용하는지에 따라 결과는 달라질 수 있습니다.
하지만 적어도 '272,163 토큰이 남아있으니 실용적이지 않다'와 같이 단순하지는 않았습니다. 압축률에 28배 가까운 차이가 있어도, 계속해서 작업을 진행하는 한, 이후 작업까지 포함한 실제 측정 비용은 같은 자릿수에 머물러 있습니다.
임베딩(embedding)은 압축 시의 대기 시간과 요약(summary) 생성에 비용을 할당합니다. lossless-compaction은 큰 컨텍스트를 유지함으로써 비용을 지불합니다. 요약에서 떨어진 정보를 나중에 다시 읽어오면, 임베딩 측에도 추가적인 비용이 발생합니다.
현재로서는 문제는 '압축 비용을 없앨 수 있느냐'가 아니라, '어디서, 어떤 형태로 지불하는 것이 사용하기 편리한가'라고 생각하고 있습니다.
사용해 보니
제 환경에서는 평소 사용하는 repository의 거의 전부에서 lossless-compaction을 구동하고 있습니다. 1분 가까이 걸리던 compaction이 수백 ms로 끝나면서, /compact를 입력하여 다른 작업을 하거나 auto compaction이 근접했는지 신경 쓸 필요가 없어졌습니다.
이전에 하던, auto compaction보다 먼저 적절한 시점에서 수동으로 compact하는 운영도 중단했습니다. 번거로움이 하나 줄었다기보다는, 컨텍스트 윈도우의 사정상 Claude Code의 작업을 저희 쪽에서 끊어낼 필요가 없어졌다는 점이 더 큽니다.
남아있는 과제는 압축률입니다. 계속 사용한다고 해서 총비용이 크게 악화되는 것은 아니지만, 유지하는 토큰을 더 줄일 수 있다면 속도를 유지한 채 더욱 편리해질 것입니다. 어느 부분까지를 컨텍스트에 남기고 어디부터를 외부로 빼내는 것이 좋을지는 아직 개선할 여지가 있다고 생각합니다.
다만, 미래에 필요한 정보를 더 정확하게 예측하여 제거하는 방향으로는 현재 돌아갈 생각이 없습니다. 그 부분을 고정밀도로 맞추기보다는, 제외해도 문제가 없는 구조로 만드는 편이 낫다고 생각합니다.
주의점
제 사용 방식에서는 상당히 안정화되었지만, 혼자만 사용한다면 당연히 편향성이 있습니다. 예상하지 못한 tool 조합이나 잘 작아지지 않는 conversation도 있을 것입니다.
우선은 compaction이 수백 ms로 끝나는 느낌을 경험해 보시길 바랍니다. 이상한 동작이 있다면 issue를 주시면 감사하겠습니다.
Discussion

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