sy/dev
Paper Review
15 min read

[논문 리뷰] CliffCompaction — coding agent의 context compaction 비용 줄이기

long-horizon coding agent에서 요약 대신 삭제·절단 기반 compaction으로 비용과 drift를 줄이는 접근을 정리한다.

CliffCompaction: Cost-Efficient Compaction for Long-Horizon Coding Agents

Trang Nguyen, Eulrang Cho, Bingqing Chen, Tim Dettmers (2026)- arXiv

한 줄 요약

CliffCompaction은 long-horizon coding agent의 context가 커질 때 LLM 요약으로 다시 쓰지 않고, 원문에서 덜 중요한 내용을 절단하거나 버리는 방식으로 bounded context를 유지하는 autocompaction 기법이다. 논문 초록과 본문 도입 기준으로, 저자들은 Terminal-Bench와 KernelBench에서 비용을 줄이면서 성능을 유지하거나 개선했다고 주장한다.

내가 보는 핵심은 “context를 똑똑하게 요약하자”가 아니다. 오히려 반대다. coding agent의 장기 세션에서는 요약이 누적될수록 drift가 생기기 쉽다. CliffCompaction은 compaction 결과를 다시 compaction하지 않고, 매번 original content만 대상으로 삼아 정보 손실이 연쇄적으로 증폭되는 경로를 끊는다.

왜 지금 중요한가

Claude Code, Codex, OpenHands류의 coding agent를 긴 repo 작업에 붙이면 context 비용은 금방 실제 병목이 된다.

  • agent가 shell output, test log, file diff, previous attempt를 계속 쌓는다.
  • context window가 차면 sliding window, 요약, 새 세션 handoff 중 하나를 선택해야 한다.
  • test-time scaling으로 여러 rollout을 돌리면 context 비용이 rollout 수만큼 곱해진다.
  • 장기 작업에서는 “정확히 무엇을 잊었는지”보다 “요약이 무엇을 왜곡했는지”가 더 위험할 때가 있다.

논문은 이 문제를 두 층으로 본다.

  1. context management: 세션이 길어졌을 때 어떤 정보를 남길 것인가.
  2. efficiency: 긴 context의 KV-cache 비용과 latency를 어떻게 줄일 것인가.

이 구분이 좋다. 많은 agent memory 글은 retrieval이나 long-context 모델 이야기로 바로 넘어가는데, 실제 운영에서는 “지금 세션의 working context를 얼마나 싸고 안전하게 유지할 것인가”가 먼저 터진다.

기존 선택지의 불편한 점

대표적인 방법은 세 가지다.

1. Sliding window

최근 token만 남긴다. 구현은 쉽고 drop-in으로 쓰기 좋다. 하지만 오래된 결정, 실패 원인, 이미 확인한 제약을 날리기 쉽다. coding agent에서는 이게 꽤 치명적이다. 같은 테스트를 다시 돌리거나, 이미 배제한 접근을 반복하거나, 이전 diff의 의도를 잊는다.

또 하나의 운영상 단점은 prefix cache다. window가 앞으로 밀리면 prefix가 바뀌고, 반복 호출에서 cache hit가 줄어들 수 있다. 논문도 sliding window가 window advance 시 prefix cache를 무효화할 수 있다고 지적한다.

2. LLM summarization

가장 흔한 방법이다. 긴 trace를 요약하고, 다음 세션에 summary를 넣는다. 문제는 요약이 “압축”이 아니라 “재작성”이라는 점이다.

요약은 다음 실패 모드를 만든다.

  • test failure의 작은 조건이 사라진다.
  • 파일 경로·함수명·환경 변수 같은 literal detail이 바뀐다.
  • 불확실했던 내용을 확정적인 문장으로 바꾼다.
  • summary-of-summary가 반복되면서 원문과 멀어진다.

일반 대화형 assistant에서는 어느 정도 참을 수 있지만, coding agent의 실행 trace에서는 작은 왜곡이 바로 잘못된 patch로 이어진다.

3. Memory store + 새 세션

vector DB나 episodic memory에 저장하고 새 세션에서 retrieval한다. 장기 기억에는 필요하지만, 모든 문제를 해결하지는 않는다. retrieval query를 누가 만들지, 어느 시점에 꺼낼지, 현재 작업 상태와 중복되는 내용을 어떻게 제거할지 같은 문제가 남는다.

CliffCompaction은 이 셋 중 “요약을 더 잘하자”가 아니라, bounded context 안에서 원문성을 최대한 보존하는 compaction policy를 잡는다.

핵심 아이디어: 다시 쓰지 말고 버려라

논문 초록에서 가장 중요한 문장은 이 부분이다. CliffCompaction은 compacted information을 faithful하게 유지하기 위해 truncate 또는 drop만 하고, rephrase/rewrite하지 않는다고 설명한다.

이 설계는 단순해 보이지만 coding agent에서는 꽤 강한 선택이다.

  • 원문 token을 유지하면 로그, path, identifier, command output이 바뀌지 않는다.
  • 버린 정보는 명확히 “없다”. 반면 요약은 틀린 정보가 “있는 것처럼” 보일 수 있다.
  • downstream model이 summary 문체를 사실로 과신하는 문제를 줄인다.
  • compaction output을 다시 compaction하지 않으면 drift 누적 경로를 막을 수 있다.

즉 CliffCompaction의 철학은 “모든 것을 조금씩 흐리게 남기기”보다 “남길 것은 원문으로 남기고, 버릴 것은 버리기”에 가깝다. 나는 이쪽이 coding trace에는 더 맞다고 본다. 코드 작업은 추상적 기억보다 정확한 evidence가 더 중요하기 때문이다.

운영 루프로 보면 어떻게 생겼나

논문이 공개한 구현은 scaffold-agnostic API proxy 형태라고 설명된다. Claude Code, Codex 같은 harness 앞단에 proxy를 두고 context가 threshold를 넘으면 compaction을 적용하는 구조로 이해할 수 있다.

실무적으로는 이런 흐름이다.

agent harness
  -> API proxy
    -> context length / cost threshold 확인
    -> original trace 대상으로 compaction
    -> bounded context로 model call
  -> tool 실행 / 파일 수정 / 테스트
  -> trace 누적

여기서 중요한 운영 파라미터는 대략 네 가지다.

  • context threshold: 몇 token부터 compaction할 것인가.
  • drop/truncate policy: 어떤 구간을 버리고 어떤 literal evidence를 남길 것인가.
  • original-only invariant: 이전 compacted output을 다시 압축하지 않을 것인가.
  • eval gate: compaction 적용 전후 성공률·비용·반복 실패를 어떻게 비교할 것인가.

특히 original-only invariant는 제품화할 때 테스트로 강제해야 한다. 구현이 조금만 편해지려고 compacted context 위에 다시 compact를 얹으면, CliffCompaction이 피하려던 summary drift와 비슷한 문제가 돌아온다.

실험 결과를 어떻게 읽을까

논문 초록과 도입부에서 확인되는 주요 claim은 다음과 같다.

  • bounded context에서 비용을 최대 50% 줄이면서 성능을 유지하거나 개선했다고 주장한다.
  • Terminal-Bench에서는 full-context run 두 번보다 낮은 비용으로 10 percentage point 이상을 추가한다고 설명한다.
  • KernelBench에서는 200 step 후 2.23배, 400 step 후 3.58배 CUDA kernel speedup에 도달했다고 보고한다.
  • SWE-bench Verified에서는 GLM-5.1과 Kimi K2.6에 대해 32K 또는 16K threshold에서도 full-context success rate를 보존한다고 설명한다.
  • parallel test-time scaling에서는 Kimi K2.6이 더 낮은 비용으로 일부 frontier coding model과 경쟁하거나 앞선다고 주장한다.

초안 단계에서 내가 조심스럽게 보는 부분은 비교 조건이다. agent benchmark는 model, harness, tool timeout, selection policy, retry budget이 섞이면 숫자가 금방 흔들린다. 따라서 이 논문을 읽을 때도 “CliffCompaction이 모든 coding agent에 50% 절감”이라고 받아들이면 안 된다.

더 현실적인 해석은 이렇다.

장기 coding task에서 요약 기반 compaction이 불안정하다면, drop/truncate 기반의 원문 보존 compaction을 baseline으로 둘 가치가 있다.

이 정도만 해도 충분히 실용적이다.

coding agent 팀이 바로 가져갈 체크리스트

CliffCompaction을 그대로 쓰지 않더라도, 이 논문은 context 운영 기준을 꽤 명확하게 만든다.

1. summary를 기본값으로 두지 말기

요약은 편하지만 trace fidelity가 낮다. 특히 다음 정보는 재작성하면 안 된다.

  • command와 exit code
  • failing test name과 stack trace
  • file path, symbol name, config key
  • 사용자가 준 hard constraint
  • 이미 시도했고 실패한 patch의 이유

이런 정보는 요약보다 원문 snippet으로 남기는 편이 낫다.

2. compaction output의 lineage를 남기기

어떤 content가 원문이고, 어떤 content가 compacted artifact인지 구분해야 한다. 나중에 agent가 이상한 결정을 했을 때 “원문에 없던 말이 summary에서 생겼는지”를 추적할 수 있어야 한다.

간단한 schema는 이 정도면 된다.

{
  "segment_id": "trace-042",
  "source": "original",
  "kept": true,
  "reason": "failing test output"
}

3. 비용 metric을 token 수 하나로 보지 말기

context token이 줄어도 prefix cache가 깨지면 실제 비용·latency가 기대만큼 줄지 않을 수 있다. 반대로 원문 prefix를 안정적으로 유지하면 token 수 이상의 효과가 날 수 있다.

봐야 할 metric은 최소한 이 정도다.

  • input token cost per step
  • wall-clock latency
  • prefix cache hit ratio
  • task success rate
  • repeated-failure rate
  • human handoff 시 trace 이해 가능성

4. compaction regression test 만들기

context policy는 prompt만큼 regression이 잘 생긴다. compaction을 바꿨다면 작은 benchmark라도 돌려야 한다.

예를 들면 다음 task를 고정해둘 수 있다.

  • 한 번 실패한 test를 기억하고 같은 실수를 반복하지 않는가.
  • repo 규칙을 초반에 읽고 후반 patch에도 지키는가.
  • 오래된 stack trace의 핵심 symbol을 나중에 다시 참조하는가.
  • irrelevant log를 버려도 current failing path는 보존하는가.

내 의견: agent memory보다 먼저 agent context hygiene

요즘 agent memory 이야기는 대개 장기 기억, vector DB, user profile, knowledge graph로 간다. 다 필요하다. 하지만 coding agent에서는 그 전에 context hygiene가 있어야 한다.

CliffCompaction이 좋은 이유는 거창한 memory architecture를 제안해서가 아니다. 장기 세션의 가장 지저분한 부분, 즉 “이미 너무 길어진 실행 trace를 어떻게 덜 망치면서 줄일 것인가”를 정면으로 다룬다.

내 기준으로 이 논문이 주는 실무 메시지는 세 가지다.

  1. coding trace에서는 사실성이 압축률보다 중요하다.
  2. 요약은 정보 손실보다 정보 변형 때문에 위험하다.
  3. test-time scaling은 rollout 수만 늘리는 문제가 아니라 rollout당 context 비용을 낮추는 문제다.

다만 이 접근도 만능은 아니다. drop/truncate는 결국 정보를 버린다. task가 초반 설계 결정을 후반에 강하게 참조하는 유형이라면, 잘못 버린 정보 때문에 실패할 수 있다. 그래서 compaction policy는 반드시 task family별 eval과 같이 가야 한다.

어디에 쓰면 좋은가

바로 적용 가치가 큰 곳은 다음이다.

  • repo-scale coding agent가 30분 이상 같은 task를 수행하는 환경
  • Terminal-Bench류 long-horizon shell task
  • KernelBench처럼 반복 개선이 필요한 optimization loop
  • 여러 rollout을 병렬로 돌리는 test-time scaling setup
  • Claude Code/Codex/OpenHands 앞단에 proxy를 붙일 수 있는 팀 내부 harness

반대로 짧은 one-shot 코드 생성이나 단순 Q&A에는 과하다. context가 아직 짧다면 compaction policy보다 task prompt와 verifier를 먼저 고치는 편이 낫다.

정리

CliffCompaction은 “더 긴 context window가 나오면 해결될 문제”라는 낙관을 잘 끊어준다. context window가 커져도 장기 coding agent는 비용, latency, cache, trace fidelity 문제를 계속 만난다.

좋은 compaction은 단순히 token을 줄이는 기술이 아니다. agent가 나중에 자기 trace를 믿고 행동해도 되는지 결정하는 runtime contract다. CliffCompaction의 drop/truncate 중심 설계는 그 contract를 꽤 보수적으로 잡는다. 나는 coding agent 운영에서는 이 보수성이 장점이라고 본다.

참고 자료

Comments