본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 18. 07:19

AI 에이전트의 입력 토큰을 71% 절감하면서 품질을 유지했습니다 — 66개 태스크 벤치마크 결과 공개

요약

AI 에이전트의 입력 토큰을 71% 절감하면서도 성능을 유지하는 로컬 리버스 프록시 'tokdiet'를 소개합니다. 66개 태스크 벤치마크를 통해 품질 저하 없이 컨텍스트를 압축할 수 있음을 입증했습니다.

핵심 포인트

  • 입력 토큰을 5.07M에서 1.46M로 약 71% 절감
  • 66개 태스크 중 63개를 해결하며 기존 품질과 유사한 성능 유지
  • Claude Code, Cursor 등 다양한 도구와 API를 지원하는 프록시 방식
  • 중복 제거 및 복구 가능한 방식의 컨텍스트 압축 기술 적용

저는 코딩 에이전트의 입력 토큰을 71% 절감했습니다 — 66개 태스크 실행 과정에서 5.07M에서 1.46M로 줄였으며 — 품질은 모델 노이즈(noise) 범위 내에서 유지되었습니다 (66개 태스크 중 63개 해결 vs 64개 해결).

이 포스트는 벤치마크, 실패 사례, 정직한 주의 사항, 그리고 코드를 담고 있습니다. "혁명적"인 것은 없습니다. 그저 재현 가능한 숫자들뿐입니다.

요약 (TL;DR)

  • 정체: tokdiet — 에이전트 도구(Claude Code, Cursor, Codex, 커스텀 스크립트)와 모델 API(Anthropic, OpenAI, Gemini, MiniMax, OpenAI/Anthropic 호환 방식 모두 포함) 사이에 위치하는 로컬 스트리밍 리버스 프록시 (reverse proxy).
  • 핵심 수치: 입력 토큰 5.07M → 1.46M = -71%; 품질 63/66 vs 64/66 베이스라인 ≈ 동등함. 198회의 쌍을 이룬 실행 결과. LLM-judge는 92%의 유사성을 보고했습니다. 두 번째 모델에서도 -72%로 확인되었습니다.
  • 설치: npx tokdiet start:7787 포트에서 프록시 실행, :7878 포트에서 라이브 대시보드 제공, 루프백(loopback) 전용.
  • 리포지토리 (Repo): https://github.com/agiwhitelist/tokdiet — MIT 라이선스, TypeScript, Node 20+.
  • 정직한 사전 고지: 이것은 무손실(lossless)이 아닙니다. "모델 노이즈 범위 내"에 있는 수준입니다. 중복 제거(dedup) 단계만 무손실이며, 나머지는 삭제되는 것이 아니라 복구 가능한(recoverable) 방식입니다. 또한 비용 절감은 토큰당 과금되는 API 키에 적용됩니다 — 고정 요금제인 Claude 구독의 경우 절감할 토큰당 비용이 없습니다.

GitHub logo
agiwhitelist / tokdiet

품질 저하 없이 비용을 줄이는 ccusage. 토큰을 측정하고, 비대해진 LLM 컨텍스트 (context)를 압축하며, 품질이 떨어지지 않았음을 증명하는 로컬 프록시 (토큰 -72%, 실제 모델 A/B 테스트에서 회귀(regression) 0건).

tokdiet

당신의 AI 에이전트는 동일한 파일 덤프를 다섯 번이나 보내는 비용을 지불하고 있습니다. tokdiet는 에이전트와 모델 API 사이에 위치하여 모든 토큰을 측정하고, 비대해진 컨텍스트를 다이어트(diet) 시키며 — 답변의 질이 나빠지지 않았음을 _증명_하는 로컬 프록시입니다.

품질 저하 없이 비용을 줄이는 ccusage.

tokdiet — −71% tokens, quality = baseline

증명 (이것이 핵심입니다)

모든 '컨텍스트 최적화(context optimizer)'는 토큰을 잘라냅니다. 무서운 질문은 그들이 답할 수 없는 것입니다.

“만약 컨텍스트를 자른다면, 모델의 성능이 떨어질까?”

그래서 저희가 측정했습니다. 66개 태스크에 걸쳐 6가지 카테고리에서 실제 모델(MiniMax‑M3)을 사용하여 A/B 벤치마크를 수행했으며, 각 태스크는 두 번씩 실행되었습니다. 비교 대상은 전체 컨텍스트(기준선, baseline)와 tokdiet를 거친 컨텍스트(제어된 방식, governed)였으며, 정답과 비교하여 평가했습니다. 이 과정은 3회 반복되었고 다수결 투표로 모델의 노이즈를 상쇄했습니다:

                       기준선      tokdiet
  입력 토큰          5.07M    →    1.46M       −71%
  품질 (66개 태스크)     64/66        63/66        ≈ 동등(parity) (95–97%)
...

GitHub에서 보기

문제점: 에이전트 루프가 같은 쓰레기를 영원히 재전송한다

긴 에이전트 세션을 지켜본 적이 있다면, 이를 목격했을 것입니다. 모델이 파일을 읽습니다. 3턴 후에 다시 같은 파일을 읽고, 그 이후의 모든 턴마다 전체 내용이 컨텍스트에 실려갑니다. 2단계에서 나온 오래된 도구 출력(tool output)이 40단계에서도 계속 재전송되고 있는 식입니다.

대화 기록(transcript)은 단조 증가합니다. 매 턴마다 전체 이력을 다시 전송하는 데 비용을 지불하게 되며, 그 이력의 대부분은 다시는 아무도 보지 않을 파일 재복사본이나 도구 결과물 같은 불필요한 데이터(dead weight)입니다.

ccusage는 이 현상을 보여주는 데 매우 탁월합니다. 청구 금액이 올라가고 있다는 사실을 알려주죠. 하지만 청구 금액을 줄여주지는 않습니다. 저는 에이전트를 은밀하게 멍청하게 만들지 않으면서도, 비용을 줄여주는 무언가를 원했습니다.

제가 계속해서 되새겼던 프레임워크: 품질 저하 없이 — 청구 금액을 줄여주는 ccusage.

왜 단순히 대화를 요약하지 않았는가

명백한 해결책은 대화 중간 요약(mid-conversation summarization)입니다. 컨텍스트가 커지면 모델에게 이전 턴들을 한 단락으로 압축하도록 요청하고 원본은 버리는 방식이죠.

이것은 모두가 빠지는 무덤입니다. 구조적으로 손실이 발생하는(lossy) 방식이기 때문입니다. 요약 과정에서 정확한 에러 문자열, 정확한 ID, 정확한 줄 번호 등이 누락됩니다. 그러다 세 턴 뒤에 모델이 방금 버린 바로 그 정보가 정확히 필요해지는 상황이 발생하지만, 이미 사라졌기 때문에 다시 가져올 수 없습니다.

따라서 tokdiet에서는 중간 요약(mid-summarize) 기능이 기본적으로 꺼져(OFF) 있습니다. 선택 사항(opt-in)으로 존재하며(추가적인 모델 호출이 발생하므로 비용이 듭니다), 사용자가 요청하지 않는 한 절대 실행되지 않습니다. 기본 설정은 정보를 파괴하지 않는 것을 중심으로 설계되었습니다.

작동 원리

이것은 스트리밍 역방향 프록시(streaming reverse proxy)입니다. SSE(Server-Sent Events) 응답이 점진적으로 프록시되므로, 토큰은 여전히 에이전트로 실시간 스트리밍됩니다. 즉, 버퍼링된 덩어리(blob)를 기다리며 앉아 있을 필요가 없습니다.

요청(request) ─► 인터셉터(interceptor) ─► 미터(meter) ─► 예산(budget) ─► 컴팩터(compactor) ─► 품질 가드(quality guard) ─► 모델 API(model API)
                                                  │
                                                  └─► 저장소(store, SQLite) + 대시보드(dashboard) :7878

이 시스템의 멘탈 모델은 **가상 메모리로서의 컨텍스트(context as virtual memory)**입니다. 핫 콘텐츠(Hot content) — 최근 턴, 고정된 블록, 현재 질문과 관련된 모든 것 — 는 요청 내에 상주(resident)합니다. 콜드 콘텐츠(Cold content) — 오래되고 중복된 도구 출력물 — 는 복구 가능한 스텁(stub) 형태로 로컬 SQLite 저장소로 **페이징 아웃(paged out)**됩니다. 이는 삭제되는 것이 아니라 ID별로 보관됩니다. (필요할 때 다시 페이징 인(paging in)하는 기능은 로드맵에 포함되어 있습니다.)

실질적인 작업을 수행하는 두 가지 전략은 다음과 같으며, 안전한 방법부터 설명합니다:

// 1. 중복 제거 (Dedup) — 손실 없음 (LOSS-FREE)
// 다시 붙여넣은 블록: 가장 최신 복사본을 그대로 유지하고,
// 이전 복사본들을 마커(marker)로 대체합니다. 이를 통해
...

중복 제거 (Dedup)는 공짜 점심과 같습니다. 만약 동일한 파일이 컨텍스트 (context) 내에 다섯 번 포함되어 있다면, 네 개의 복사본은 순수한 낭비이며 이를 제거해도 결과에는 아무런 영향을 주지 않습니다. 절약의 대부분은 생략 (Elision)에서 발생하며, 이 부분은 반드시 측정되어야 합니다. 왜냐하면 "핵심적인 줄(salient lines)을 유지하라"는 것은 판단 (judgment call)이 필요한 영역이기 때문입니다.

벤치마크 (The benchmark)

단순히 느낌(vibes)에 의존한 주장을 하고 싶지 않았기에, A/B 테스트 하네스 (harness)를 구축했습니다.

방법론 (Methodology):

  • 6개 카테고리에 걸친 **66개 태스크 (tasks)**를 실제 모델 (MiniMax-M3)로 수행했습니다.
  • 각 태스크는 두 번 실행됩니다: 한 번은 전체 컨텍스트 (full context)를 사용한 경우 (기준점, baseline), 다른 한 번은 tokdiet를 거친 경우 (제어됨, governed)입니다.
  • 두 실행 모두 **알려진 정답 (known correct answer)**을 기준으로 채점됩니다.
  • 모델의 비결정성 (nondeterminism)을 상쇄하기 위해 모든 태스크를 **3회 반복하여 다수결 (majority-voted)**로 결정합니다.
  • 총 **198회의 쌍을 이룬 실행 (paired runs)**이 이루어집니다.
  • 별도의 **LLM 판사 (LLM judge)**가 기준점과 제어된 결과 사이의 출력 유사도를 점수화합니다.
  • 그 후, 특정 모델의 산물(artifact)이 아닌지 확인하기 위해 **두 번째 모델 (MiniMax-M2.5)**에서 다시 실행합니다.

결과 (Results):

지표 (Metric)기준점 (전체 컨텍스트)제어됨 (tokdiet)차이 (Delta)
입력 토큰 (Input tokens)5.07M1.46M-71%
...

직접 재현해 보세요:

node bench/run.mjs   # 환경 변수에 API 키가 필요합니다

1개 태스크의 차이에 대하여 — 솔직하게 말씀드립니다

기준점은 64개를 해결했고, 제어된 방식은 63개를 해결했습니다. 저는 이것을 "품질 손실 제로"라고 부르지 않을 것입니다. 데이터가 그렇게 말하고 있지 않으며, 과장하는 것이 신뢰를 잃는 지름길이기 때문입니다.

실제 차이는 다음과 같습니다. 3회 다수결을 적용한 198회의 실행 전체를 살펴보면, 그 차이는 모델의 비결정성 (nondeterminism) 범위 내에 있습니다. 즉, 동일한 프롬프트 (prompt)가 항상 동일한 점수를 생성하지는 않는다는 것입니다. 또한 차이의 일부는 모델이 비밀 값 (secret value)을 다시 출력하기를 거부한 것 때문이었는데, 이는 컨텍스트 손실 버그가 아니라 행동의 변화 (behavior change)입니다.

제가 가장 신경 썼던 부분, 즉 필요한 단 하나의 사실이 쓸모없는 출력물 더미 속에 숨겨져 있는 가장 까다로운 "쓰레기 속에 파묻힌 바늘 (needle buried in junk)" 형태의 적대적 사례(adversarial cases)들에서, 이 방식은 통과(pass)했습니다. 이는 생략(elision) 과정에서 중요한 정보를 버리는 실수를 잡아낼 수 있는 테스트였으며, 결과는 성공적이었습니다.

즉: 모델 노이즈 범위 내에서. ≈ 동등한 수준. 품질 유지. 완벽한 무손실(lossless)은 아닙니다.

품질 보장 메커니즘 (The quality-guarantee mechanism)

제가 당당하게 "품질이 유지되었다"라고 말할 수 있는 이유는, 반대의 상황을 감시하고 스스로 제동을 걸 수 있는 장치가 있기 때문입니다.

  • Shadow-eval — 압축된 요청 중 샘플링된 일부(기본값 5%)를 압축되지 않은 베이스라인(baseline)과 대조하여 다시 실행하고, 그 차이를 0(동일함)에서 100(관련 없음) 사이의 척도로 점수화합니다. 이는 추측이 아닌 측정값입니다.
  • 품질 예산 (Quality budget) — 측정된 품질 저하에 대한 엄격한 상한선(기본값 2%)입니다. 저하 수치가 상한선에 도달하면, 압축기(compactor)는 가장 안전한 전략만을 사용하도록 스스로를 제한합니다.
  • 안전 모드 (Safe-mode) — 누적되는 품질 저하가 예산을 초과하면, 문제가 되는 전략을 전략별로 비활성화합니다.

품질이 떨어지기 전에 절감이 중단됩니다.

이것이 전체 설계 철학을 한 줄로 요약한 것입니다. Shadow-eval은 비용이 발생하기 때문에(재실행이 필요하므로) 샘플링 방식을 사용합니다. 이는 공짜 기능이 아니라 실제적인 트레이드오프(tradeoff)입니다.

Claude Code 사용자들을 위한 특별 참고 사항

이 부분은 매우 중요하며, 많은 분이 실수하는 것을 보았습니다.

토큰을 절약해 주는 것은 바로 **프록시 (proxy)**입니다. 에이전트가 프록시를 가리키도록 설정해야 합니다:

npx tokdiet start
export ANTHROPIC_BASE_URL=http://localhost:7787
export OPENAI_BASE_URL=http://localhost:7787/v1

Claude Code 플러그인(/plugin marketplace add agiwhitelist/tokdiet 실행 후 /plugin install tokdiet)도 존재하지만, 이 플러그인은 측정용 훅(metering hook)일 뿐입니다. 플러그인은 Claude Code 프로세스에 대한 ANTHROPIC_BASE_URL을 설정할 수 없으므로, 플러그인 설치만으로는 토큰을 절약할 수 없습니다. 플러그인은 측정 기능과 대시보드를 제공할 뿐입니다. 토큰 절약을 원한다면 반드시 프록시를 통해 라우팅하십시오. 플러그인을 설치해 놓고 왜 아무것도 줄어들지 않는지 의아해하기 전에 미리 말씀드리고 싶었습니다.

프록시는 캐시 인지적 (cache-aware) 이며 ( cache_control 접두사를 절대 다시 쓰지 않으므로 프롬프트 캐시 (prompt cache)를 깨뜨리지 않습니다), 사고 안전적 (thinking-safe) 입니다 (서명된/사고 블록 (signed/thinking blocks)을 절대 변형하지 않으므로 400 에러를 유발하지 않습니다). 두 기능 모두 회귀 테스트 (regression-tested)를 거쳤습니다.

적용 가치가 있는 경우와 없는 경우

  • 토큰당 과금 방식의 키 (Pay-per-token keys) (MiniMax, Anthropic API, OpenAI): -71%는 실제 비용 절감으로 이어집니다.
  • Claude 정액제 구독: 줄일 수 있는 토큰당 요금이 없으므로, 가치는 청구서가 아니라 사용량 측정 (metering), 예산 관리, 그리고 대시보드에 있습니다.
  • **키 (Keys)**는 전달만 됩니다. SQLite나 그 어떤 로그에도 절대 기록되지 않습니다. 루프백 바인드 (Loopback bind)만 허용됩니다. 페일 오픈 (Fail-open): 프록시에 문제가 생겨도 요청은 그대로 전달됩니다.
  • 알려진 제한 사항: 기본 판정기 (judge)는 휴리스틱 (heuristic) 방식입니다 (LLM 판정기는 선택 사항입니다). 섀도우 평가 (shadow-eval)는 비용이 발생하며 샘플링 방식으로 이루어집니다. 세션 추론 (session inference)은 휴리스틱 방식이며, 스트리밍 (streaming) 시 페이지 폴트 복구 (page-fault recovery)는 제한적입니다. 비용 수치는 추정치입니다.

60초 만에 시도하기

npx tokdiet start
# 프록시는 :7787에서, 대시보드는 :7878에서 실행됩니다 (루프백 전용)

...

평소처럼 에이전트를 실행한 다음, http://localhost:7878을 열어 토큰과 USD가 올라가는 것을 확인하세요. 중복 제거 (deduped)된 것과 페이지 아웃 (paged out)된 것을 포함하여 확인할 수 있습니다.

마음껏 망가뜨려 주세요

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0