
OptScale Kompressor는 코딩 에이전트가 반복해서 보내는 작업 기록을 결정론적으로 압축하는 Rust 프로그램이다. Hystax는 Terminal-Bench 2.1의 87개 과제에서 기본 설정의 Headroom보다 비용을 15.8% 줄였다고 보고했다. 다만 Kompressor의 과제 해결률은 Headroom 기본 설정보다 0.5%포인트 낮았다.
코딩 에이전트는 매 단계마다 이전 작업 기록을 모델에 다시 보낸다. 긴 작업에서는 apt-get 로그와 컴파일러 경고, 진행 상황 표시를 여러 번 전송하므로 같은 내용을 반복해서 처리하는 비용이 생긴다. Hystax는 여러 팀과 에이전트가 함께 쓸 수 있도록 Kompressor를 만들었다. 입력이 같으면 매번 바이트 단위로 같은 결과를 내 프롬프트 캐시가 유지되도록 하고, 제거한 세부 정보는 검색으로 다시 가져올 수 있게 한다.
벤치마크 결과
Hystax는 모든 비용 수치를 프롬프트 캐시 할인을 반영한 실제 제공업체 청구액의 차이로 계산했다. 제거한 토큰을 캐시되지 않은 정가로 계산하는 자체 보고식 절감액은 사용하지 않았다고 밝혔다. 전체 과제별 부록이 포함된 설명은 Twice the Savings of Headroom on Coding-Agent Traffic에 있다.
Terminal-Bench 2.1에서 Codex CLI와 GPT-5.5를 사용해 89개 과제를 실행했다. Harbor에서 세 번의 동시 실행을 진행했고, 비교군은 압축 없음, 기본 설정의 Headroom 0.40(ML 모델 사용), Headroom의 가장 공격적인 설정, OptScale AI를 통한 OptScale Kompressor였다. 표의 수치는 모든 비교군이 완료한 87개 과제에 대한 전체 실행 결과다. 에이전트 설정이 외부 요인으로 실패한 실행은 제외했다. 비용과 토큰 절감 차이는 통계적으로 유의했지만, 과제 해결률 차이는 유의하지 않았다.
GPT-5.5 토큰 가격은 캐시되지 않은 입력 토큰 100만 개당 5.00달러, 캐시 입력 토큰 100만 개당 0.50달러, 출력 토큰 100만 개당 30.00달러다.
| 전체 실행 기준 | 압축 없음 | Headroom 기본 | Kompressor |
|---|---|---|---|
| 비용 | $107.89 | $99.04 | $83.40 |
| 입력 토큰 | 96.1M | 95.5M | 72.2M |
| 캐시되지 않은 입력 토큰 | 6.68M | 5.16M | 4.46M |
| 해결한 과제 | 82.2% | 81.6% | 81.1% |
| 실행 시간 중앙값 | 4.8분 | 5.3분 | 4.5분 |
Headroom의 가장 공격적인 설정은 검색을 끄고, 크기 하한을 120토큰으로 두며, 배열 항목을 최대 8개로 제한했다. 이 설정은 같은 기준선보다 비용을 11.6% 줄였다.
| 압축 없음 대비 | 비용 변화 | 해결 과제 비율 |
|---|---|---|
| Kompressor | −22.7% | 81.1% |
| Headroom 가장 공격적인 설정 | −11.6% | 85.1% |
| Headroom 기본 설정 | −8.2% | 81.6% |
Hystax의 계산에서 Kompressor의 절감액은 Headroom의 가장 공격적인 설정보다 2.0배, 기본 설정보다 2.8배 컸다. 기본 설정과 직접 비교하면 Kompressor는 비용이 15.8% 낮고 입력 토큰을 24.4%, 캐시되지 않은 입력 토큰을 13.6% 덜 보냈다. 대신 해결 과제 비율은 81.1%로 Headroom의 81.6%보다 0.5%포인트 낮았다. Kompressor는 87개 과제 중 54개에서 비용이 더 적게 들었다.
차이는 로그가 많은 장시간 작업에서 두드러졌다. 예를 들면 ML 학습, 크로스 컴파일, 통계 모델링이다. 짧은 과제에서는 두 도구 모두 제거할 내용이 많지 않았다.
과제 유형별로 보면 ML 학습, 소스 빌드, 데이터 파이프라인이 전체 절감액의 83%를 차지했다. ‘제거’는 512자 이상인 대상 도구 출력 가운데 압축으로 없앤 비율이다. 출력이 작거나 접어서는 안 되는 산문인 경우 압축 효과가 낮았다.
| 과제 유형 | 과제당 도구 출력 | 제거 비율 | 압축 없음 대비 청구액 변화 |
|---|---|---|---|
| ML 학습·샘플링·평가 (17개 과제) | 598K자 | 81% | −26% |
| 역공학·보안 (12개) | 310K자 | 69% | −5% |
| 소스에서 소프트웨어 빌드 (10개) | 1,178K자 | 64% | −28% |
| 서비스 설정·git (10개) | 262K자 | 58% | −14% |
| 데이터 파이프라인·미디어 (9개) | 288K자 | 55% | −37% |
| 텍스트·문서·시퀀스 (7개) | 120K자 | 51% | −23% |
| 알고리즘·수학·퍼즐 (22개) | 99K자 | 48% | −8% |
캐시된 토큰도 전송되며 컨텍스트 창을 차지한다. 바이트 크기는 압축하지 않은 실행에서 토큰당 요청 JSON 4.35바이트로 측정해 추정했다.
| 요청 크기 | 압축 없음 | Headroom | Kompressor |
|---|---|---|---|
| 실행당 전송한 프롬프트 | 96.1M 토큰 · 약 418MB | 95.5M · 약 415MB | 72.2M · 약 314MB |
| 요청 크기 90백분위 | 106.9K 토큰 · 약 465KB | 110.5K · 약 481KB | 66.5K · 약 289KB |
| 100K 토큰 초과 요청 | 11.2% | 12.0% | 3.2% |
| 200K 토큰 초과 요청 | 1.9% | 0.6% | 0.13% |
압축하지 않은 경우 GPT-5.5의 258K 컨텍스트 창 가운데 200K를 넘긴 요청이 1.9%였고, 두 번의 실행에서 컨텍스트 압축이 일어났다. Kompressor를 썼을 때는 해당 요청이 0.13%, 컨텍스트 압축이 일어난 실행은 한 번이었다. 무거운 과제인 mcmc-sampling-stan의 최고 요청 크기는 165K에서 60K 토큰으로, caffe-cifar-10은 152K에서 68K로 줄었다. 제공업체가 캐시를 지원하지 않는 환경에서는 프롬프트 전송량 25% 감소가 그대로 청구액 감소로 이어진다.
Hystax는 동일한 도구 출력 6,255개(총 34.2M자)를 세 엔진에 재생해 비교했다. 설정은 optscale-kompressor 0.13 기본값, ML 모델을 끈 Headroom 0.40, Magika 감지와 ModernBERT 모델을 켠 Headroom 0.40이다.
| 콘텐츠 유형 | 전체 비중 | Kompressor | Headroom ML 사용 | Headroom ML 미사용 |
|---|---|---|---|---|
| 목록·덤프 | 27.8% | 81.8% | 22.6% | 7.0% |
| 일반 텍스트 | 25.3% | 41.0% | 20.6% | 5.2% |
| 빌드 출력·로그 | 19.3% | 75.4% | 17.1% | 4.2% |
| 소스 코드 | 13.8% | 35.0% | 31.9% | 0.0% |
| 검색 결과 | 11.1% | 82.7% | 25.5% | 25.4% |
| diff·설정·HTML·JSON | 2.7% | 40.9% | 19.8% | 12.5% |
| 압축 대상 도구 출력 전체 | 100% | 62.8% | 22.6% | 7.3% |
| KB당 처리 시간 | 0.2ms | 87ms | 1.5ms |
이 재생 결과에서 Kompressor는 ML 모델을 켠 Headroom보다 2.8배, 끈 경우보다 8.6배 많은 내용을 제거했다. 모델을 사용하는 데 걸리는 시간의 약 1/440에 해당하는 시간으로 처리했다고 Hystax는 설명한다. 제거한 내용은 모두 검색으로 되찾을 수 있다고 밝혔다.
설치와 사용
Linux(x86_64, arm64)와 macOS(arm64, x86_64)용 사전 빌드 바이너리와 체크섬은 Releases 페이지에서 받을 수 있다. Cargo로 설치하려면 Rust 1.90 이상이 필요하다.
cargo install --locked --git https://github.com/hystax/optscale-kompressor kompressor-cli
소스에서 빌드하는 방법은 다음과 같다.
git clone https://github.com/hystax/optscale-kompressor
cd optscale-kompressor
make release
./target/release/kompressor version
make deb, make rpm, make static(musl), make docker, make macos-pkg-docker로 패키지를 만들 수 있다. 필요한 도구가 없으면 각 명령이 요구 사항을 알려준다. 서비스로 실행하는 방법은 docs/QUICKSTART.md, macOS 관련 방법은 docs/MACOS.md에 있다.
Codex에서 지원되는 실행 방식은 다음과 같다.
kompressor wrap codex
Kompressor는 프록시를 시작하고 Codex가 프록시를 사용하도록 설정한 뒤 Codex를 실행하며, 종료할 때 정리한다. 세션이 끝나면 처리 결과를 출력한다.
kompressor: 26 request(s), 126 message(s) compressed, ~2029706 tokens saved (2015180 net of retrieval)
Codex는 OPENAI_BASE_URL을 무시한다는 점을 0.155.1에서 측정했다. 이에 wrap은 시작할 때 ~/.codex/config.toml에 표식으로 둘러싼 설정 블록을 추가하고 종료할 때 제거한다. 파일의 나머지 부분은 바이트 단위로 그대로 둔다. Codex의 auth.json을 읽고 로그인 방식, API 키, ChatGPT 플랜에 맞는 블록을 쓴다. 세션이 강제로 종료되면 kompressor unwrap codex로 남은 블록을 제거할 수 있다. 자세한 내용은 docs/CODEX.md에 있다.
구독 세션은 WebSocket을 열며, 프록시는 이를 중계하고 압축한다. 이 기능은 0.14.0부터 기본으로 켜져 있다. 중계된 턴은 제공업체 사용량을 보고하지 않아 절감 효과는 실제로 발생하지만 측정되지는 않는다. KOMPRESSOR__PROXY__WEBSOCKET_RELAY=false로 설정하면 이 범위를 포기하고 수치를 측정할 수 있다.
다른 에이전트와 실행 인자를 지정하는 방법은 다음과 같다.
kompressor wrap --list # the agents wrap knows
kompressor wrap aider -- --model sonnet # your own arguments go after --
kompressor wrap --env NAME=root|v1 -- your-agent
wrap은 codex, claude, opencode, aider, cursor, cursor-agent를 알고 있다. Cursor에서는 설정할 기본 URL을 출력하며, 사용자가 직접 OpenAI 키를 쓸 때만 적용된다. cursor-agent는 프록시가 읽을 수 없는 protobuf 기반 Connect RPC를 사용하므로 실행을 거부하고 이유를 설명한다.
Claude Code는 래핑할 수 있지만 요청을 압축하지 않고 그대로 전달한다.
kompressor wrap claude
Claude Code는 마지막 메시지를 프롬프트 캐시 경계로 표시해 대화 전체를 고정한다. 그 안의 바이트를 바꾸면 새 입력 비용의 약 10분의 1로 청구되는 캐시가 무효화된다. 따라서 압축하지 않는 것은 아직 채우지 않은 기능이 아니라 의도된 동작이라고 Hystax는 설명한다.
대신 wrap claude는 Claude Code가 직접 실행하는 MCP 서버로 검색 도구를 제공한다. ref:k_… 핸들은 프록시를 통과하는 요청에서만이 아니라 세션 어디서나 해석할 수 있다. ~/.claude.json이나 ~/.claude/settings.json 같은 지속 파일은 쓰지 않으므로 unwrap 단계도 필요 없다.
제공업체가 아직 캐시하지 않은 부분만 압축하는 초기 경로는 proxy.frozen_prefix = "first_seen" 설정 뒤에 있지만, 미해결 이슈가 있어 기본적으로 꺼져 있다. 측정과 설명은 docs/CLAUDE-CODE.md에 있다.
프록시를 통해 다른 클라이언트도 연결할 수 있다.
kompressor serve # every surface on 127.0.0.1:8817
export OPENAI_BASE_URL=http://127.0.0.1:8817/v1 # OpenAI Chat Completions or Responses
export ANTHROPIC_BASE_URL=http://127.0.0.1:8817 # Anthropic Messages: the root, no /v1
파일 하나를 설명과 함께 압축하려면 다음 명령을 쓴다.
kompressor compress build.log --explain
기본값은 별도 설정 파일이 필요 없는 단일 테넌트 구성이다. 조각과 통계는 ./data 아래 SQLite에 저장하고, 인증은 사용하지 않으며, recoverable 모드로 동작한다. 설정 파일은 $KOMPRESSOR_CONFIG, ./kompressor.toml, $XDG_CONFIG_HOME/kompressor/config.toml 순으로 찾는다. kompressor check-config는 비밀 값을 제거한 유효 설정을 출력한다.
설계와 압축 모드
엔진 크레이트에는 입출력, 시계, 난수가 없다. 출력에 영향을 줄 수 있는 순회는 순서가 정해진 자료구조를 사용한다. 핸들은 콘텐츠 주소 지정 방식으로 만들며, k_와 잘린 BLAKE2b 다이제스트로 구성한다. 따라서 같은 조각은 어떤 컴퓨터, 어떤 이후 실행에서도 같은 핸들을 얻는다. 압축기는 대화의 앞뒤 맥락을 살펴보지 않는다. 질문과 도구 결과를 비교해 순위를 매기면 더 강하게 압축할 수 있지만, 다음 턴에도 남아 있는 입력을 매번 다르게 압축하게 되기 때문이다. 기록된 274개 테스트 벡터가 세 모드에서 어떤 입력이 어떻게 압축되는지 고정한다.
모든 입력에 네 가지 불변 조건을 적용하고 전체 코퍼스에서 확인한다.
- 결과가 원문보다 커지면 압축하지 않고 원문을 반환한다.
- 줄어든 출력에는 생략 표식이 있거나, 레이아웃만 바꿨음이 증명되거나, 되돌릴 수 있는 봉투 형식임을 밝혀야 한다. 그렇지 않으면 결과를 거부하고 원문을 반환한다.
- 같은 입력은 매번 같은 바이트를 낸다.
- 오류, 패닉, 시간 초과, 저장소 장애가 발생하면 원문 전달로 대체한다. 압축은 토큰을 줄일 뿐 서비스 가용성을 낮추지 않는다.
기본 recoverable 모드에서는 생략한 내용을 SQLite 저장소의 핸들 뒤에 두거나, 화면에 남아 있는 텍스트를 가리키도록 한다. 프록시는 모델에 검색 도구를 제공하고 직접 실행하므로 OptScale Kompressor를 모르는 클라이언트도 복원할 수 있다.
모델을 사용하거나 내려받지 않는다. 처음 1MB를 대상으로 순서가 정해진 규칙 15개로 콘텐츠를 감지한다. 소스 코드는 바이너리에 컴파일된 tree-sitter 문법 9개로 처리한다. 실행 중 내려받는 항목은 없으며 컴퓨터에 따라 결과가 달라지지 않는다. 라이브러리, CLI, HTTP API, MCP 서버, LLM 프록시는 하나의 알고리즘을 공유하는 단일 바이너리다.
| 모드 | 보장 |
|---|---|
aggressive | 손실 압축이다. 모든 생략에 표식을 붙이고 내용을 보관하지 않는다. |
lossless | 되돌릴 수 있는 변환만 한다. 내용을 버리지 않는다. |
recoverable(기본값) | 공격적 압축 엔진을 쓰되 생략한 내용을 모델이 가져올 수 있는 핸들 뒤에 보관하거나, 컨텍스트에 남은 텍스트를 가리킨다. |
모드는 요청별로 API·MCP의 options.mode 또는 프록시의 X-Kompressor-Mode 헤더에서 정하거나, 설정에서 테넌트별 또는 전역으로 지정할 수 있다. 헤더와 테넌트 설정에서는 통계를 계속 기록하는 통과 모드 off도 사용할 수 있다. 호출 측에서 검색할 수 없다면 기본 API에서 aggressive를 쓰도록 안내한다.
압축 처리 흐름은 다음과 같다.
payload -> gutter lift -> redraw fold -> size gate -> detect -+-> segmenter (structured spans in mixed content) +-> whole-payload compressor -> arbitrate -> accounted guard -> output + handles nothing claimed it? clip any opaque over-long line behind a handle then, across messages: fold runs an earlier message already showed into a pointer
감지는 순서가 정해진 규칙 15개를 차례로 적용한다. 느슨한 규칙이 먼저 입력을 가져가 잘못 압축하는 사례를 막기 위해 규칙의 순서가 중요하다. 압축기는 JSON(배열 샘플링, 키 묶기, 중첩 경로 처리), 로그(템플릿 묶기와 점수화한 항목 선택), grep 결과, diff, 표, 목록, 소스 코드, 설정 파일을 다룬다. 혼합 콘텐츠에서는 구조화된 구간만 압축하고 산문은 바이트 단위로 그대로 두는 분할기도 있다.
메시지 사이 중복 제거는 이전 메시지에 이미 나온 줄이 이어지는 부분을 포인터로 접는다. 이전 메시지만 읽으므로 턴을 추가해도 앞선 메시지를 다시 쓰지 않는다. 가리키는 텍스트가 화면에 남아 있어 핸들도 필요하지 않다. 여러 압축기가 같은 입력을 다르게 해석하면 중재 단계에서 더 짧은 결과를 보내고, 선택되지 않은 결과가 보관한 조각은 되돌린다. 설계·구현 사양은 docs/DESIGN.md, 다이어그램은 docs/charts/에 있다.
제공 인터페이스와 측정
| 인터페이스 | 사용 방법 |
|---|---|
| 에이전트 래퍼 | kompressor wrap <agent> |
| LLM 프록시 | kompressor serve --proxy: OpenAI Chat Completions, OpenAI Responses, Anthropic Messages, WebSocket 중계 |
| HTTP API | POST /v1/compress, /v1/compress/raw, /v1/retrieve, /v1/detect; GET /v1/stats/*, /healthz, /readyz, /metrics |
| MCP 서버 | kompressor serve --mcp(streamable HTTP): optscale_kompressor_retrieve, optscale_kompressor_compress, optscale_kompressor_compress_raw, optscale_kompressor_stats |
| CLI | kompressor compress, retrieve, detect, stats, bench, check-config |
| 라이브러리 | kompressor-engine 크레이트: 입출력 없이 문자열이나 대화를 압축 |
옵션 없이 kompressor serve를 실행하면 모든 인터페이스가 하나의 리스너에서 동작한다.
saved_gross는 압축으로 제거한 양이다. recoverable 모드에서는 검색할 때마다 조각을 프롬프트에 다시 넣고 모델이 해당 토큰 비용을 다시 청구하므로, 중요한 값은 saved_net = saved_gross - retrieved tokens이며 음수가 될 수도 있다. 에이전트 트래픽에서는 매 턴 커지는 기록을 다시 압축하면서 같은 바이트를 반복해 절감액으로 계산하므로, 일정 기간의 총 절감액을 더하면 실제보다 커질 수 있다.
kompressor stats summary는 두 값을 모두 보고한다. 수치를 인용하기 전에 /metrics의 kompressor_stats_dropped_total이 0인지 확인해야 한다. 그렇지 않으면 모든 보고가 실제보다 낮게 집계된다. 실제 에이전트 기준으로 측정하는 방법은 docs/BENCHMARK.md에 설명돼 있다.
아직 구현하지 않은 기능과 개발
- Claude Code 요청 압축은 아직 구현되지 않았다. 기본 동작은 Claude Code 설명에 따라 요청을 그대로 전달하는 것이다.
- 압축 뒤에도 에이전트가 나중에 사용한 정보를 보존했는지 재는 Needle retention은 아직 없다. 압축률이 모두 좋아져도 실패할 수 있는 유일한 품질 지표라고 프로젝트는 설명한다.
- 여러 프록시를 하나의 로드 밸런서 뒤에서 운영할 때 필요한 Redis 조각 저장소는 아직 없다. SQLite와 메모리 저장소는 구현돼 있다.
replay와extract를 넘어서는bench하위 명령(sample,needles, `calibrate-tokens)은 아직 없다.- 단계별 추적과
/metrics의 프록시 지표는 아직 없다. 상태 코드, fail-open 단계, 검색 반복 횟수는 현재stats.db에 기록된다. - WebSocket 중계에서 검색을 반복하는 루프는 아직 없다. 중계된 턴은 압축되지만 해당 전송에서는 도구를 제공할 수 없어 다음 프레임에 내용을 함께 실어 돌려보낸다.
- 스트리밍 응답은 헤더가 반복 처리 전에 전송되므로
X-Kompressor-Retrieve-Rounds가 항상 0이다. 실제 횟수는stats.db에 기록된다. - 생략할 내용이
max_ref_bytes(기본값 1MiB)보다 크면recoverable모드에서 압축을 포기하고 전체 입력을 전달한다.
good first issue 라벨이 붙은 항목은 첫 기여 과제로 제안돼 있다. make만 실행하면 모든 대상 명령을 볼 수 있다.
make check
what CI gates on: lint, tests, the corpus replay against its recorded baseline, the docs check
make bench
replay the committed corpus, compare against fixtures/baseline.json, verify determinism
make smoke
start every surface in a scratch directory, exercise it end to end, stop it
make e2e
the hermetic suite: three containers, all modes, refs and the retrieve loop
make harbor-gates
every live-agent benchmark gate, with no provider spend
cargo test --workspace는 10개 크레이트에서 1,157개 테스트를 실행한다. clippy와 rustfmt는 깨끗한 상태라고 프로젝트는 보고한다. make bench-save와 make golden은 테스트의 비교 기준을 바꾸므로 실행 전에 확인을 요청한다. make e2e는 all good을 출력하거나 실패 항목을 표시한다. 총 검사 수를 출력하지 않으므로 검사 개수는 제시하지 않았다고 설명한다.
기여 요청과 풀 리퀘스트를 받는다. CONTRIBUTING.md를 참고하면 된다. 커밋에는 DCO 서명이 필요하며 git commit -s를 사용한다. 보안 문제는 공개 이슈가 아니라 SECURITY.md에 안내된 방식으로 비공개 신고해야 한다. 참여자는 행동 강령을 따라야 한다.
Hystax는 Headroom(Apache-2.0)에서 페이로드 종류에 맞는 압축기로 보내는 방식, 압축 후 검색하는 패턴, 요청을 압축하지 않은 이유의 분류 체계, 코드 본문 예산 아이디어를 가져왔다고 밝혔다. Headroom은 wrap claude가 처리하는 Claude Code의 두 가지 기본 URL 부작용도 발견했다. 이 저장소의 구현은 자체적으로 작성했다고 설명한다.
OptScale Kompressor는 Hystax가 개발하며 OptScale AI의 압축 엔진으로도 쓰인다. OptScale AI는 조직 단위로 엔진을 운영하고 공유 절감 대시보드, 팀별 정책, 거버넌스를 제공한다. 엔진과 저장소의 모든 내용은 MIT 라이선스를 유지한다. 자세한 내용은 LICENSE에 있다.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요