레슨 4: 컴팩션과 노트: 긴 작업을 위한 컨텍스트 관리
학습 목표:
- 컴팩션이 무엇이고 어떻게 구현되는지 말하기: 대화가 컨텍스트 윈도의 한계에 가까워지면 메시지 히스토리를 모델에 넘겨 요약하게 하고, 그 요약본에서 새 윈도를 다시 시작한다
- '이미 내린 아키텍처 결정과 아직 풀리지 않은 버그는 남기고, 중복된 도구 출력은 버린다'는 규칙에 따라 한 번의 컴팩션을 위한 요약 지시문과 keep/drop 목록을 쓰기
- 컴팩션과 구조화된 노트의 역할을 구분하고, 긴 작업을 도는 에이전트를 위해 쓰면서 남기는 노트 방식을 설계하기
전제: 이 코스의 레슨 1부터 3까지를 마쳤고, 이 시리즈의 코스 7 '에이전트 하네스 기초: 루프와 통제'의 하네스 루프를 손으로 직접 쓸 수 있을 것 | 이전: 레슨 3 << | 다음: 레슨 5 >>
하나의 윈도로는 담을 수 없는 작업
머지않아 마주칠 장면에서 시작해 봅시다. 이 시리즈의 코스 7 '에이전트 하네스 기초: 루프와 통제'에서 손으로 직접 쓴 하네스를 디버깅 작업에 겨눕니다. 동시 실행일 때만 드러나는 경쟁 상태를 고치는 일입니다. 에이전트는 파일을 읽고, 테스트를 돌리고, 코드를 고치고, 다시 테스트를 돌립니다 — 마흔 턴 남짓 지났는데도 작업은 아직 끝나지 않았고, 메시지 히스토리는 10만 토큰을 넘겨 부풀었으며 윈도는 곧 가득 찰 참입니다.
코스 7의 네 가지 제어 밸브(최대 턴 수, 예산, 공회전 감지, 승인 밸브)는 여기서 아무 도움이 되지 않습니다. 그것들이 다스리는 것은 '루프가 폭주하지 않게 하라'인데, 루프의 동작 자체는 멀쩡합니다 — 작업 자체가 그저 긴 것뿐입니다. 이것은 사고가 아니라 루프의 본성입니다. "An agent running in a loop generates more and more data that could be relevant for the next turn of inference"1 — 도구 출력, 중간 결론, 실패한 시도가 모두 메시지 히스토리에 쌓입니다.
그리고 윈도는 공짜가 아닙니다. 방대한 양의 컨텍스트를 해석하는 모델은 "attention budget"에서 끌어다 쓰며, "Every new token introduced depletes this budget by some amount."1 토큰이 쌓일수록 모델이 정확히 떠올리는 능력은 나빠집니다. "as the number of tokens in the context window increases, the model's ability to accurately recall information from that context decreases"1 — 절벽이라기보다 완만한 내리막이지만, 내리막인 것에는 변함이 없습니다. 그래서 "context, therefore, must be treated as a finite resource with diminishing marginal returns."1 Claude Code 베스트 프랙티스 문서는 더 직설적입니다. "Claude's context window fills up fast, and performance degrades as it fills", 그리고 "The context window is the most important resource to manage."2
작업이 너무 길어 하나의 윈도로 담을 수 없을 때, 무기는 두 가지입니다. 컴팩션과 구조화된 노트. 이번 레슨은 둘을 모두 관통합니다.
컴팩션: 요약한 다음, 새 윈도를 연다
컴팩션은 이름 그대로입니다. "taking a conversation nearing the context window limit, summarizing its contents, and reinitiating a new context window."1 마지막 부분에 주목하세요 — 요약본을 옛 대화에 도로 밀어 넣고 계속 욱여넣는 것이 아니라, 다시 시작하는 것입니다. 옛 윈도는 통째로 버려지고, 새 윈도는 시스템 프롬프트와 요약본만 챙긴 채 가볍게 출발합니다.
구현은 들리는 것보다 소박합니다. "passing the message history to the model to summarize and compress the most critical details."1 곧 컴팩션 자체가 모델 호출 한 번이라는 뜻입니다. 코드로 보면 대략 이렇습니다(formatHistory는 메시지 배열을 읽을 수 있는 평문으로 이어 붙이기만 합니다. 구현은 생략).
이것을 코스 7의 그 루프에 이어 붙이는 데는 발상 하나만 더 있으면 됩니다. 각 턴의 첫머리에서 메시지 히스토리의 토큰 사용량을 확인하고, 한계에 가까워지면 compact()를 호출해 messages 배열 전체를 반환값으로 갈아 끼우는 것입니다. 실제로 이것을 하네스에 짜 넣는 일 — 발동 임계값을 어떻게 정할지, 컴팩션이 실패하면 어떻게 할지 — 은 레슨 6의 실습 재료입니다. 지금은 메커니즘만 똑바로 잡아 두면 됩니다.
컴팩션의 기술: 무엇을 남기고 무엇을 버릴 것인가
컴팩션에서 어려운 부분은 '어떻게 요약할까'가 아니라 '무엇을 남기고 무엇을 버릴까'입니다. 방향 자체는 사실 분명합니다. "preserves architectural decisions, unresolved bugs, and implementation details while discarding redundant tool outputs."1
왜 그런 맞바꿈일까요. 에이전트가 새 윈도에서 '깨어나는' 장면을 상상해 보세요. 그 요약본이 에이전트가 가진 기억의 전부입니다. 압축의 방향을 잘못 잡았을 때의 대가는 구체적입니다. 요약 지시문에 그저 '대화 내용을 간략히 요약하라'라고만 썼다고 해 봅시다. 모델은 'orders/service.js에 아직 끝내지 못한 경쟁 상태가 있다'를 무심코 떨어뜨립니다 — 에이전트는 '완료'라고 표시된 기록만 보며 깨어나서, 일이 끝났다고 선언하거나 이미 고쳐 놓은 것들을 다시 헤집습니다. 컴팩션 한 번에 마흔 턴어치 작업이 그대로 궤도를 벗어난 것입니다.
거꾸로 보면, 중복된 도구 출력이야말로 가장 살진 표적입니다. grep 한 번이 200줄의 매치를 돌려주지만, 쓸모 있는 신호는 이미 다음 단계의 결론인 'updateStatus 함수로 범위를 좁혔다'에 담겨 있습니다. 날것의 200줄이 계속 남아 있어 봐야 주의 예산만 태울 뿐, 다음 수의 판단 가치는 거의 더해 주지 않습니다.1
실무적인 자가 점검이 하나 있습니다. 요약 지시문을 다 썼으면, 실제로 긴 대화 하나를 가져와 한 번 컴팩션해 보고, 요약본만 보고 세 가지 질문에 답해 보세요 — '다음에 무엇을 해야 하는가', '어떤 결정이 확정되어 있는가', '어떤 구멍이 아직 메워지지 않았는가'. 셋 다 깔끔하게 나오면 그 지시문의 keep/drop 규칙은 합격입니다. 하나라도 백지가 되면, 그 keep 규칙을 기워 넣으러 돌아가세요.
실전의 컴팩션: 자동 컴팩션과 /clear
매일 쓰는 도구에 이미 만들어진 참조 구현이 있습니다. Claude Code는 "automatically compacts conversation history when you approach context limits, which preserves important code and decisions while freeing space"2 — 위에서 손으로 쓴 compact()와 같은 메커니즘이고, 발동 조건과 keep/drop 규칙을 제품 쪽이 대신 마련해 준 것뿐입니다.
하지만 컴팩션만이 선택지는 아닙니다. 무관한 새 작업으로 옮겨 간다면, 옛 컨텍스트는 쓸모없는 정도가 아니라 해롭습니다 — "Long sessions with irrelevant context can reduce performance."2 그럴 때 문서는 이렇게 말합니다. "Run /clear between unrelated tasks to reset the context window entirely"2 — 요약도 없고 보존도 없이, 그냥 전면 초기화입니다. 이유는 단순합니다. 컴팩션은 모델 호출을 한 번 쓰고 keep/drop 판단을 그르칠 위험을 안습니다. 무관한 작업이라면 아예 비워 버리는 쪽이 더 싸고 깔끔합니다. 컴팩션이 맡는 것은 '같은 작업이 아직 안 끝났다'이고, /clear가 맡는 것은 '이제 다른 일을 한다'입니다.
그 문서에는 손 닿는 곳에 둘 만한 문장이 하나 더 있습니다. "A clean session with a better prompt almost always outperforms a long session with accumulated corrections."2 옮기자면, 세션의 히스토리가 주로 '아니, 다시 해'와 '아직도 틀렸어'로 채워져 있을 때 그 히스토리가 다음 수에 주는 가치는 아마 음수라는 것입니다 — 세션을 새로 열고 배운 것을 새 프롬프트에 곧바로 새겨 넣는 편이, 그 짐을 전부 끌고 가는 것보다 나은 경우가 많습니다.
구조화된 노트: 핵심 상태를 윈도 바깥에 쓴다
컴팩션에는 타고난 약점이 하나 있습니다. 수동적이라는 것입니다. 윈도가 거의 찰 때까지 기다렸다가 뒤돌아보며 요약하므로, 무엇이 살아남는지는 전적으로 그 순간의 판단에 달려 있습니다 — 그리고 판단은 실패할 수 있습니다. 정보가 신선할 때 미리 남겨 두는 방법은 없을까요.
있습니다. 게다가 단순합니다. "the agent regularly writes notes persisted to memory outside of the context window."1 "Like Claude Code creating a to-do list, or your custom agent maintaining a NOTES.md file."1 첫머리의 그 경쟁 상태 작업을 다시 가져오면, 합격점을 받을 노트는 대략 이런 모습입니다.
배선하는 법은 코스 7에서 배운 그대로입니다. 에이전트에게 파일 쓰기 도구를 주고, 시스템 프롬프트에 요구사항을 하나 더합니다 — "중요한 결정을 내렸을 때, 새 문제를 발견했을 때, 한 단계를 마쳤을 때는 먼저 NOTES.md를 갱신하고 나서 계속하라". 이때부터 윈도 안의 핵심 상태는 윈도 바깥에 사본을 하나 갖습니다. 윈도가 어떻게 컴팩션되든 다시 시작되든 노트는 디스크에 남아 있고, 새 윈도가 가장 먼저 하는 일은 그것을 읽어 들이는 것입니다.
이 요령은 코딩 작업에만 국한되지 않습니다. "Claude playing Pokémon demonstrates how memory transforms agent capabilities in non-coding domains."1 Anthropic의 멀티 에이전트 리서치 시스템도 긴 작업에서 같은 일을 합니다. "agents summarize completed work phases and store essential information in external memory."3
분업: 컴팩션은 최후의 보루, 노트는 일상
두 무기를 나란히 놓으면 분업이 또렷해집니다. 컴팩션은 수동적입니다. 윈도가 한계에 가까워질 때 발동하므로 시점을 고를 수 없고, 손실을 동반하며, 무엇이 살아남는지는 그 순간의 keep/drop 판단에 달려 있습니다. 노트는 능동적입니다. 핵심 상태가 태어나는 순간에 쓰므로 내용에 손실이 없고, 비용은 매번 몇 줄의 파일 쓰기뿐입니다. 한 문장으로 하면, 노트는 일상이고 컴팩션은 최후의 보루입니다.
둘은 충돌하지 않고 서로를 떠받칩니다. 노트가 부지런할수록 컴팩션이 무언가를 떨어뜨렸을 때의 대가가 가벼워집니다 — 요약본이 세부를 놓쳐도 노트에는 남아 있습니다. 반대 방향으로도, 컴팩션이 최후의 보루로 있다는 것은 노트가 빠짐없을 필요는 없고 '에이전트가 깨어났을 때 반드시 알아야 하는' 몇 가지 부류면 된다는 뜻입니다.
분량 감각도 중요합니다. 모든 작업이 이 장치를 누릴 자격이 있는 것은 아닙니다. Anthropic의 지침은 이렇습니다. "you should consider adding complexity only when it demonstrably improves outcomes."4 동사에 주목하세요 — consider, 곧 검토입니다. 금지가 아니라 저울질하는 자세입니다. 열 턴이면 끝나는 작업에서 컴팩션도 노트도 여분의 부품입니다. 가장 단순한 루프에서 시작하고, 실제로 천장에 부딪혔을 때 더하세요.
마지막으로 경계 두 가지를 그어 둡니다. 이번 레슨이 다루지 않는 답을 찾느라 시간을 쓰지 않도록.
- 노트 파일의 세션을 넘나드는 영속화 — 어떻게 정리할지, 새 세션에서 어떻게 복원할지, 장기적으로 어떻게 유지할지 — 는 이 시리즈의 코스 5 '에이전트 메모리와 상태'의 주제입니다. 이번 레슨이 신경 쓰는 것은 하나의 긴 작업 안에서 노트가 윈도의 부하를 어떻게 덜어 주는가뿐입니다.
- 긴 시간 지평의 작업을 다루는 수는 사실 세 가지입니다. "compaction, structured note-taking, and multi-agent architectures,"1 모두 에이전트가 "maintain coherence, context, and goal-directed behavior over sequences of actions"1 하게 만드는 것을 겨눕니다. 앞의 둘은 끝냈고, 세 번째 — 깨끗한 윈도를 든 서브에이전트들에게 작업을 쪼개어 맡기는 것 — 은 레슨 5입니다.
정리
- 컴팩션 = 대화가 윈도 한계에 가까워졌을 때 "passing the message history to the model to summarize and compress the most critical details,"1 그런 다음 그 요약본에서 "reinitiating a new context window"1 하는 것 — 다시 시작하는 것이지, 옛 대화에 도로 이어 붙이는 것이 아니다
- 컴팩션의 기술은 남기고 버리는 선택에 있다. "preserves architectural decisions, unresolved bugs, and implementation details while discarding redundant tool outputs";1 압축의 방향을 잘못 잡으면 에이전트는 자기가 무엇을 하고 있었는지 잊은 채 깨어난다
- Claude Code는 "automatically compacts conversation history when you approach context limits, which preserves important code and decisions"2 한다. 무관한 작업 사이에서는
/clear로 전면 초기화하라 — "A clean session with a better prompt almost always outperforms a long session with accumulated corrections"2 - 구조화된 노트: "the agent regularly writes notes persisted to memory outside of the context window"(할 일 목록,
NOTES.md).1 컴팩션은 수동적인 최후의 보루이고 손실을 동반하며, 노트는 능동적인 외부화이고 쓰면서 남기는 것이다 - 긴 시간 지평의 작업을 다루는 세 가지 수는 "compaction, structured note-taking, and multi-agent architectures".1 앞의 둘은 손에 넣었고, 세 번째는 레슨 5다. 노트의 세션을 넘나드는 영속화는 이 시리즈의 코스 5 '에이전트 메모리와 상태'의 주제다
Footnotes
-
Effective context engineering for AI agents — Anthropic Engineering — https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17 ↩18
-
Best practices for Claude Code — Claude Code Docs — https://code.claude.com/docs/en/best-practices ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7
-
How we built our multi-agent research system — Anthropic Engineering — https://www.anthropic.com/engineering/multi-agent-research-system ↩
-
Building Effective AI Agents — Anthropic Engineering — https://www.anthropic.com/engineering/building-effective-agents ↩
연습
누군가 하네스에 이런 '컴팩션' 함수를 써 넣고, 윈도가 거의 찼을 때 호출하게 했습니다.
레벨 2: '컴팩션 이후의 기억상실' 진단하기연결한 뒤 에이전트는 45턴째에 컴팩션을 발동했습니다. 그러고 나서 두 가지 증상을 관찰했습니다. 첫째, 47턴째에 '테스트 프레임워크를 node:test로 할지 vitest로 할지'를 다시 논쟁하기 시작했습니다. 3턴째에 vitest로 이미 결정된 문제인데도 말입니다. 둘째, 5턴째에 기록된 미해결 경쟁 버그를 한 번도 언급하지 않았고, 몇 턴 뒤에는 작업이 끝났다고 선언했습니다. 두 증상의 원인을 설명하고, 두 겹의 수정을 제시하세요.