메인 컨텍스트를 저장하여 품질을 높이고 비용을 절감하는 방법: Context Drop 구축기
요약
본 글은 대화 기록이 길어지면서 발생하는 '컨텍스트 비대화(context bloat)' 문제를 해결하는 방법을 제시합니다. Context Drop이라는 데스크톱 도구는 원시 컨텍스트를 메인 대화에 쏟아붓는 대신, 격리된 서브 에이전트가 처리하여 핵심 결과물만 전달함으로써 메인 컨텍스트의 안정성과 효율성을 높입니다.
핵심 포인트
- Context Bloat: 대화가 길어지면 비용 증가와 응답 불안정성이 발생합니다.
- Context Drop: 원시 데이터를 격리된 서브 에이전트에서 처리하고 결과만 요약합니다.
- ultracode 이해: Claude Code의 옵트인 기능으로, 대규모 다중 에이전트 워크플로우를 생성합니다.
1. 도입부 + 핵심 주장
어느 순간, Claude Code가 저에게 '작동하지 않는' 경험을 했습니다.
정확히 말하자면, 고장 난 것은 Claude Code 자체가 아니었습니다. 문제가 된 것은 제가 그것을 사용하는 방식이었습니다. 수십 개의 에이전트를 한 번에 가동하고, 거대한 로그와 스크린샷을 대화창에 그대로 붙여넣고, /compact로 이들을 연결하며 긴 세션을 유지하는 것 — 이는 Claude Code의 ultracode 옵트인 기능이 자연스럽게 만들어내는 무겁고 분산된(fan-out) 스타일입니다. 이런 방식을 계속하면, 어느 날쯤 도구 호출(tool calls)이 원시 텍스트로 대화에 새어 나오거나, 모델이 생각만 하고 아무런 답변을 하지 않는 상황이 발생합니다.
제가 가장 일관되게 발견한 요인 하나를 꼽자면, 그것은 바로 **컨텍스트 비대화(context bloat)**입니다. 대화가 커질수록, 매 턴마다 재전송하는 비용이 증가하고, 오염을 유발하는 조건에 점점 가까워지며, 응답의 안정성이 떨어집니다.
Context Drop은 이 근본적인 습관 하나를 끊기 위해 제가 만든 작은 데스크톱 도구입니다: 원시 컨텍스트를 메인 대화에 직접 쏟아붓는 행위입니다. 스크린샷, 로그, JSON과 같은 자료들이 메인 대화에 남는 대신, 격리된 서브 에이전트(isolated subagent) (메인 것과는 별개로 자체적인 대화 기록을 가지고 작동하는 워커 AI)가 읽고, 돌아오는 것은 간결한 결과물뿐입니다. 덕분에 메인 컨텍스트는 가볍게 유지됩니다.
본 게시물은 먼저 기초를 다집니다 — 왜 무거운 사용 방식이 문제를 일으키는지와 모델, 노력, ultracode 중 무엇을 선택해야 하는지에 대한 내용이며 — 이어서 Context Drop이 무엇인지, 어떻게 사용하는지, 그리고 단계별 설치 방법까지 설명합니다.
2. 배경 지식 1 — 왜 문제가 되었나 (ultracode와 컨텍스트 비대화)
'ultracode'가 실제로 무엇인가
우선 용어를 명확히 하겠습니다. ultracode는 Claude Code의 옵트인 기능입니다. 프롬프트에 키워드 ultracode를 넣거나 세션 전체에서 이 기능을 켜서 사용할 수 있습니다. 이 기능이 활성화된 동안, 모델은 모든 실질적인 작업에 대해 다중 에이전트 워크플로우(multi-agent Workflows)를 오케스트레이션하며, 토큰 비용을 제약 조건으로 간주하지 않습니다(토큰은 AI가 입력과 출력을 계산하는 단위이며, 사용자가 청구되는 기준입니다).
두 번째 부분이 중요합니다. 비용에 상관없다고 알려진 모델은 상당히 합리적으로 광범위하게 전개됩니다: 작업을 여러 에이전트에게 분산시키고, 그 결과들을 검증하고 반박하기 위해 더 많은 에이전트를 추가하는 식입니다. 저희 내부 기록에는 좋은 예가 있습니다: 한 릴리즈에서 **77개의 에이전트로 구성된 적대적 리뷰(adversarial review)**였는데, 이 기록에 따르면 이는 어떤 규칙에 의해 의무화된 것이 아니라 저자의 재량으로 — 즉 ultracode를 켜서 — 실행되었습니다.
따라서 ultracode는 저희 내부 설계 기록에 정의된 항상 켜져 있는 모드는 아닙니다. 이것은 Claude Code의 스위치이며, 설계상 엄청난 규모의 확산(fan-outs)을 생성하고 — 그와 함께 엄청난 양의 컨텍스트와 토큰을 만들어냅니다. 이렇게 축적된 컨텍스트는 아래 실패 사례들의 공통 요인이었습니다 (이는 나중에 제가 언급할 상관관계입니다).
증상 1 — 도구 호출이 'count / court' 등으로 변질되는 현상
가장 심각했던 것은 Opus 4.8에서 발생한 도구 호출 손상(tool-call corruption) 문제였습니다. 구조화된 tool_use가 되어야 할 도구 호출이 순수 텍스트로 대화에 누출됩니다. 내부 제어 태그가 count / court / call 같은 실제 영어 단어로 변질되고, 파서(parser)는
하지만 일단 기록이 깨지면 스스로 강화된다. 아마도 모델은 손상된 출력을 모방하는 것이리라 추정되며, 어느 쪽이든 같은 세션에서 재시도할 경우 그 현상을 더욱 강화할 뿐이다. 우리 사례에서는 자체적으로 복구되지 않았다. 해결책은 "앞으로 진행하기"(--continue)가 아니라 "뒤로 돌아가기"이다: /rewind를 실행한 다음, /compact를 수행하고, 궁극적으로는 /clear를 해야 한다.
증거에 대해 솔직히 말하자면, "컨텍스트 부풀림 → 손상(corruption)"이라는 연결고리는 인과관계로 증명된 것이 아니라 상관관계 수준에서 기록된 것이며, 후크(특정 시점에 자동으로 실행되는 핸들러)가 자동으로 /compact를 수행할 수는 없다. 하지만 이 상관관계는 내가 작업하는 방식을 바꿀 만큼 충분히 강력했다.
증상 2 — compact 직후의 재팽창, 마라톤 세션 이후의 침묵
/compact는 대화를 압축하여 가볍게 만드는 기능이다. 그러나 우리는 세션 시작 시에 19–32 KB 크기의 다이제스트(digest)를 주입하는 메커니즘을 가지고 있었고, 이 메커니즘은 /compact 직후에도 발동되었다. 그 결과: 대화가 압축 직후 원래 크기로 되돌아가는 현상이 발생하여 축소 효과를 상쇄하고 위에서 언급된 트리거 조건을 재창조했다.
또 다른 측면은 긴("마라톤") 세션 이후의 완전한 침묵이다. 마라톤 세션을 거치면 모델이 완전히 조용해질 수 있다. 동일한 요청을 신규 세션에 던지면 즉시 답변하지만, 유일한 차이점은 이전 세션에 쌓여 있던 컨텍스트라는 점이다.
"모든 것을 최고 설정으로 실행"해도 소용없었다
이 시점에서 당신은 생각할지도 모른다: 만약 어렵다면, 왜 Claude Code를 최고 설정으로 사용하지 않는가? 더 큰 모델, 더 많은 노력, 그리고 ultracode를 통한 더 많은 에이전트들이 이를 더 똑똑하게 만든다면, 돈 문제가 아니라면 처음부터 가장 스마트한 설정으로 모든 것을 실행할 수 있을 것이다.
실제로 우리는 그와 비슷한 것을 실행해 보았습니다. 그리고 바로 거기서 문제가 발생했습니다. 위에서 언급된 오류(breakage)의 트리거 조건을 다시 살펴보세요. 최고 사양인 Opus 모델, 긴 1M 컨텍스트, 다중 에이전트 분산 처리(multi-agent fan-out). 이 모든 것이 '최대 설정'입니다. 우리가 최대치로 실행할수록 대화는 부풀어 올랐고, 그 부푼 대화 속에서 도구 호출(tool calls)은 오류가 발생하고 응답은 멈췄습니다.
그래서 이것은 비용 문제가 아니라 품질 문제였습니다. 인과관계의 증거는 상관관계를 넘어설 수 없지만, 우리의 판단은 컨텍스트를 쌓아 올리는 데 돈을 쓰는 것 자체가 품질을 떨어뜨렸다는 것입니다. 우리는 돈으로 품질을 구매한다고 생각했지만, 실제로는 돈을 써서 품질을 떨어뜨리고 있었습니다. 해결책은 '더 높은 설정을 사용하라'가 아니라 '메인 대화에서 무엇을 제외할지 결정하라'였습니다.
무거운 컨텍스트가 비용을 소모하는 이유
단순히 데이터 손상(corruption)만의 문제는 아닙니다. 컨텍스트 팽창(Context bloat)은 비용에도 영향을 미칩니다. Claude Code는 매 턴마다 지금까지의 전체 대화와 모든 도구 결과를 재전송하고 재청구합니다. 기록된 추정치에 따르면, 20k 토큰 로그를 한 번 읽는 것은 다음 30턴 동안 약 85k 토큰을 지불하는 것을 의미합니다. 반면, 200토큰 요약본(digest)은 같은 기간 동안 약 0.9k에 불과하며, 이는 대략 100배의 차이입니다. 그리고 큰 읽기 작업은 더 빨리 압축(compaction)을 유발하여 위에서 언급된 손상 위험으로 다시 돌아가게 만듭니다.
극단적인 예로: 전체 무거운 게이트 분산 처리(full heavy-gate fan-out)를 거친 하나의 블로그 기사는 하위 에이전트 포함 약 800k 토큰을 소비했으며, 이 중 부모 컨텍스트에만 289k가 포함되었습니다.
핵심 — '위임(delegation) ≠ 절약'
여기 반드시 알아야 할 역설적인 사실이 하나 있습니다.
그렇다면 위임(delegation)의 가치는 무엇일까요? 바로 부모 대화(parent conversation)를 오염시키지 않는 것입니다. 원본 대용량 데이터(raw bulk data)가 부모 컨텍스트에 포함되지 않도록 격리하면, 부모 컨텍스트는 가볍게 유지되고, 손상 유발 조건에서 멀어질 수 있으며, 이후 모든 턴(turn)의 재전송 비용을 증가시키지 않습니다. '부모를 보호하기 위해 격리한다'는 이 아이디어가 Context Drop의 설계 철학이 되었습니다.
3. 배경 2 — 모델, 노력, 그리고 ultracode: 무엇을 위해, 언제 어떤 것을 사용할 것인가, 어떻게 전환할 것인가
손상과 비대화(bloat)에 대한 대응책은 두 가지 레버로 요약됩니다: 컨텍스트 다이어트(context diet) (지나치게 많이 읽거나 붙여넣지 않기)와 모델 계층 라우팅(model-tier routing) — 각 작업에 얼마나 많은 모델 자원을 할당할지 선택하는 것입니다. Context Drop은 전자에 대한 도구이지만, 후자를 아는 것은 운영을 안정화시키므로 여기에 설명하겠습니다.
한 줄 요약
노력(Effort)은 '에이전트가 얼마나 깊게 생각하는가'입니다. ultracode는 '얼마나 많은 에이전트가 작업을 분할하고 검증하는가'입니다. 이 둘은 독립적이며, 각각을 개별적으로 높이거나 낮출 수 있습니다.
세 가지 노브(knobs)
| knob | 결정하는 것 | 값 | 현재 설정 |
|---|---|---|---|
| model | 모델의 지능 수준 상한선 | Opus / Sonnet / Haiku / Fable | opus[1m] |
| ... |
각 노력 수준이 의미하는 바
제가 생각하는 각 수준에 대한 대략적인 감(문서화된 동작은 아니며, 경험적 추정치)입니다:
| effort | 사고 방식 (제 경험적 추정치) | 적합한 경우 (제 경험적 추정치) |
|---|---|---|
low | 가장 얕은 추론 | 문구 수정, grep 결과 요약, 기계적인 대체 작업 |
| ... | ||
| 주의할 점: 노력이 높을수록 답변 속도는 느려지고 사용 토큰이 더 많이 소모됩니다. 그리고 이는 생각(thinking)으로 해결될 수 있는 문제에 대해서만 정확도를 향상시킵니다. 만약 실제 원인이 _누락된 정보_라면, 노력을 높여도 해결되지 않으며 — 이때 도움이 되는 것은 조사 범위를 넓히는 것(이것이 바로 폭(breadth), 즉 ultracode가 필요한 부분입니다). |
조합 패턴
| 패턴 | 노력(effort) | ultracode | 사용 시점 |
|---|---|---|---|
| A. Everyday | medium | off | 일반적인 구현, 질문, 작은 수정 사항 |
| ... | |||
| A note on E. Workflow 스크립트 내부에서는 각 에이전트가 노력(effort)을 재정의할 수 있습니다: |
agent(prompt, { effort: "low" }) // 'low' | 'medium' | 'high' | 'xhigh' | 'max'
따라서 효율적인 분리는 다음과 같습니다. 단순한 항목이 많은 단계는 얕게 실행하고; 중요한 판단을 내리는 소수의 단계는 깊게 실행합니다. ultracode가 활성화되면, 이것이 제가 워크플로우를 구축할 때 원하는 분리입니다. 또한 이는 §2의 문제에 대한 가장 저렴한 제동 장치이기도 합니다. ultracode 자체만으로는 엄청나게 확장되기 때문입니다.
어떤 모델을 사용할 것인가 — 티어 규칙
모델 노브(Model knob)는 자체적인 결정 규칙을 가지고 있습니다. 내부 운영 규칙을 요약하면 다음과 같습니다:
| 티어 | 모델 | 적합한 작업 |
|---|---|---|
| light | Haiku | 기계적 작업 (대량 교체, 이름 변경, 인덱스 업데이트, 작은 문서) |
| ... | ||
| 그리고 망설이지 않고 하나를 선택하기 위한 규칙: |
- 위험 최소화(Risk floor): 청구, 인증, 프로덕션 또는 되돌릴 수 없는 어떤 것이 관련되면, 최상위 티어를 사용하고 인간의 확인을 거쳐야 합니다.
- 크기(Size): 작고 기계적인 작업 → light; 여러 파일 또는 새로운 디자인 → 골격 구조에 대해 top tier를 사용합니다.
- 작업 유형(Task type): 구현, 버그 수정, 테스트 → mid; 검토, 적대적 검증(adversarial verification), 디자인 → top.
- 의심스러울 때는 더 높은 것을 선택: 품질 사고로 인한 손실이 토큰 절감액보다 큽니다.
모델 티어와 노력(effort)은 두 가지 다른 축입니다. 티어가 상한선을 설정하고, 노력이 응답당 얼마나 많이 사용할지를 결정합니다. 경계 변경(청구/인증)은 보통 top tier 및 high effort를 정당화하며; 대량 이름 변경은 어느 쪽도 필요하지 않습니다.
전환 방법
노력(Effort)
- 실행 시:
claude --effort high— 현재 세션의 노력 수준("Effort level for the current session")을 지정합니다 (확인된 정보 출처:claude --help; 사용 가능한 값은low/medium/high/xhigh/max). - 세션 중:
/effort를 실행하여 원하는 수준을 설정할 수 있습니다. 이 프로젝트에서 확인한 바에 따르면,medium으로 설정된 기록에는 "Set effort level to medium (saved as your default for new sessions)"라는 메시지가 출력되었습니다. 참고로, 이는 새로운 세션을 위한 기본값으로도 해당 수준을 저장합니다. - 기본값 설정:
~/.claude/settings.json파일에서"effortLevel": "medium"부분을 변경합니다. - 워크플로우 내부: 위와 같이
agent(prompt, {effort: ...})를 사용하여 에이전트별로 재정의할 수 있습니다.
모델 (Model)
- 실행 시:
claude --model …(사용 가능한 목록은claude --help에 기재되어 있습니다). - 세션 중:
/model. - 기본값 설정:
~/.claude/settings.json파일의model필드입니다 (예:opus[1m]= 1M 토큰 컨텍스트 창을 가진 Opus 모델). - 속도:
/fast는 Opus fast 모드를 전환합니다. 이는 더 작은 모델로 성능이 저하되는 것이 아니라, 동일한 Opus 모델에서 더 빠른 출력을 제공합니다.
ultracode: 필요한 턴(turn)에 프롬프트에 키워드 ultracode를 넣거나 세션 전체에 대해 이 기능을 활성화할 수 있습니다.
참고:
/effort,--effort,effortLevel,/model,opus[1m],/fast, 그리고 ultracode는 Claude Code harness의 기능이며, 여기에 인용된 내부 설계 기록이 발명한 것이 아닙니다. 해당 기록들이 정의하는 것은 "어떤 수준을, 언제 사용할지"에 대한 의사결정 규칙입니다.
명칭 함정 (A naming trap)
/code-review high에서 사용되는 high는 **세션의 추론 노력(reasoning effort)**이 아닙니다. 이는 검토가 얼마나 광범위하게 발견 사항을 포착할지를 제어합니다. 이름은 비슷해 보이지만, 서로 다른 개념입니다. 마찬가지로, /code-review ultra는 사용자가 트리거 할 때 클라우드에서 실행되는 **유료의 심층 다중 에이전트 검토(paid, deep multi-agent review)**이며, ultracode와는 별개의 메커니즘입니다.
권장 작동 방식 (Recommended operation)
기본값은 **A (medium / ultracode 비활성화)**로 유지하고 의도적으로 전환하는 것을 권장합니다:
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기