Claude Code 백그라운드 상태 요약이 토큰 16%를 소모한다
Claude Code가 백그라운드 에이전트의 상태 표시줄을 3~5단어로 요약하기 위해 매번 해당 에이전트의 전체 대화록을 모델에 다시 밀어 넣고 있다. 그 요약 호출이 전체 토큰 소비의 15~20%를 차지한다는 측정 결과가 나왔고, 이를 끄는 우회 도구가 MIT 라이선스로 공개됐다.
동작 방식은 이렇다. 약 30초마다, 실행 중인 백그라운드 에이전트마다 전체 트랜스크립트를 그 에이전트가 쓰는 모델(보통 Opus)에 보내고 "가장 최근 행동을 3~5단어로 묘사하라"고 요청한다. 돌아온 응답은 에이전트 패널의 상태줄만 갱신할 뿐, 모델의 추론이나 사용자 대화에는 전혀 반영되지 않는다. 이 기능을 끄는 설정 항목은 없으며, 2.1.232 버전(2026년 8월)부터 기본값으로 켜져 있다.
수치는 Claude Code의 OpenTelemetry 익스포트에서 드러났다. `claude_code.api_request` 이벤트를 `query_source` 기준으로 묶자 `agent_summary`가 16.4%로, 메인 대화(15.7%)보다 큰 비중을 차지했다. 여기서 말하는 비용은 Claude Code 자체의 요청별 추정치이지 실제 청구서가 아니다. 구독제 사용자라면 금액이 아니라 레이트리밋 여유분이 그만큼 사라진다는 뜻이다. 같은 현상을 독립적으로 측정한 사례 네 건이 이슈 #86879에 함께 수집돼 있다.
공개된 `no-agent-summary.js`는 약 80줄짜리 Bun 프리로드다. 바이너리 자체는 손대지 않고 `BUN_OPTIONS=--preload`로 로드된다. Claude Code의 해당 모듈이 미리 컴파일된 Bun 바이트코드 형태로 배포돼 있어 바이너리 안의 JS 텍스트를 고쳐도 효과가 없고, API 클라이언트도 래핑 가능한 `globalThis.fetch`를 거치지 않는다. 대신 `Function.prototype.toString`은 바이트코드에서 실행되는 콜백이라도 소스 문자열을 돌려준다는 점을 이용한다.
그래서 훅은 `setTimeout`과 `setInterval`을 감싸고, 콜백 소스 안에 요약기 표식(예: `[AgentSummary] Timer fired` 로그 문자열)이 들어 있으면 타이머를 실제로 걸지 않고 무력한 핸들을 반환한다. 무력 타이머의 지연값은 2³¹−1ms다. Node와 Bun은 이보다 큰 값을 1ms로 처리하기 때문에 사실상 무한 대기에 해당하는 상한을 쓴 것이다. 나머지 타이머는 그대로 통과시킨다.
설치 후에는 데몬을 반드시 재시작해야 한다. 데몬과 pty 호스트, 미리 예열된 백그라운드 세션은 클라이언트의 환경을 물려받기 때문에, `BUN_OPTIONS`를 설정하기 전에 뜬 데몬은 훅이 없는 세션을 계속 만들어낸다. `claude -p`나 cron, CI, 에디터 통합 같은 헤드리스 실행에도 같은 환경변수가 필요하다. 검증은 OpenTelemetry에서 `query_source=agent_summary`가 0으로 유지되는지 확인하는 것이 가장 확실하며, 원문은 이를 모든 실패 모드를 잡아내는 유일한 검사로 꼽는다. `CC_AGENT_SUMMARY_MODE=pass`로 훅을 로드하되 타이머는 그대로 두는 대조군도 제공된다.
적용 후 달라지는 것은 크지 않다. 서브에이전트, 백그라운드 에이전트, 포크된 스킬, 백그라운드 세션은 정상 동작하고, 에이전트 패널의 상태 갱신이 멈추며 SDK의 `task_progress`에서 요약이 빠진다. 오버헤드는 타이머 콜백 종류당 `Function.prototype.toString` 한 번을 WeakMap에 캐시하는 정도로, `claude --version` 실행 시간이 약 10ms에서 17ms로 늘었다는 측정치가 있다.
주의할 점은 이 방식이 콜백 소스 문자열 매칭에 의존한다는 것이다. Anthropic이 로그 문구나 `query_source` 식별자를 바꾸면 훅은 아무것도 잡지 못하고 요약 호출이 조용히 되살아난다. 콜백이 `fn.bind(...)`로 감싸지거나 문자열이 콜백 밖 공용 상수로 빠지거나 타이머가 `timers/promises` 같은 래핑되지 않은 API로 옮겨가도 마찬가지다. 그래서 업데이트 때마다 재검증이 필요하다. 테스트는 Linux의 Claude Code 2.1.257~2.1.312에서 이뤄졌고 macOS와 Windows는 검증되지 않았다. Windows에서는 `/$bunfs/` 게이트 때문에 훅이 설치되지 않을 가능성이 크다.