도구 출력을 압축하는 것이 코딩 에이전트의 API 비용을 낮출까요?
요약
코딩 에이전트가 매 턴마다 이전 도구 출력을 전체 대화 기록과 함께 모델에 재전송하는 과정에서 발생하는 API 비용 문제를 다룹니다. 이 글은 도구 출력 내용을 압축하거나 요약하여 전송함으로써 비용을 절감할 수 있는 방법을 제시하며, Torana 플러그인 등을 활용한 구현 및 실험 결과를 공유합니다.
핵심 포인트
- 코딩 에이전트는 매 턴마다 전체 대화 기록과 도구 출력을 재전송함.
- 도구 출력 내용을 압축하거나 요약하여 API 비용 절감 가능성을 탐색함.
- Torana의 intent 플러그인은 도구 호출 시 '의도(reason)'를 요청하고 이를 활용해 컨텍스트를 최적화할 수 있음.
코딩 에이전트는 매 턴마다 이전 도구 출력을 재전송하므로, 이를 더 작은 것으로 대체하면 명백한 절약처럼 보입니다. 저는 이것을 Torana 플러그인으로 구현하고, 한 번 망가뜨린 후 다시 구축하여 측정해 보았습니다. DeepSeek V4 Pro의 경우 세션당 약 2%의 절감 효과였는데, 이는 프롬프트 캐싱 덕분에 반복되는 출력이 이미 거의 무료였기 때문에 일반적인 실행 간 변동보다 적은 수치였습니다.
본 글에서는 이 아이디어, 무엇이 고장 났는지, 최종 설계, 실험 설정 및 방법론, 결과, 그리고 다음 계획에 대해 다룹니다.
코딩 에이전트가 도구 출력을 재전송하는 방식
코딩 에이전트의 기반 모델은 파일을 읽거나 명령을 실행할 수 없습니다. 대신 도구 호출(tool call)을 요청하고, 에이전트가 이를 로컬에서 실행하며, 그 결과가 대화에 추가됩니다. 이후 매 턴마다 에이전트는 이전 모든 도구 결과를 포함하여 보이는 전체 대화를 모델로 다시 전송합니다.

각 요청마다 로그가 입력으로 재전송됩니다. 컨텍스트가 채워지고 매 턴마다 출력이 다시 청구됩니다.
이는 보이는 이력(visible history)을 재전송하는 하네스에 적용되며, 일반적으로 Chat Completions 또는 Messages 스타일의 API를 사용합니다. 만약 제공업체가 이력을 소유하는 경우(예: OpenAI Responses의 previous_response_id), Torana는 이전 항목을 다시 작성할 수 없으므로, 네이티브 제공업체 압축 기능은 별도의 메커니즘입니다.
아이디어: 호스팅된 모델을 위한 더 저렴한 어시스턴트
호스팅된 모델이 실제 작업을 수행하는 두뇌라면, 더 저렴한 모델이 그 두뇌가 읽기 전에 도구 출력을 요약할 수 있습니다. 요약은 무엇이 중요한지 알고 있을 때만 유용하기 때문에, Torana의 intent 플러그인은 모델이 보는 도구 정의를 변경하여 모든 도구 호출 시 짧은 이유(reason)를 요청하고, 이후 이 필드를 하네스(harness)가 볼 때 제거합니다. 컴팩터는 포착된 의도(intent)를 사용하여 무엇을 유지할지 결정합니다.

Reason 필드: 외부로 나가는 도구 스키마에 추가되고, 돌아오는 도구 호출에서는 제거됩니다. 에이전트는 절대 이를 볼 수 없습니다.
시도 1: 모든 대용량 출력 요약하기
첫 번째 컴팩터는 2,000자 이상의 모든 도구 출력을 요약했습니다. 이는 코딩 에이전트를 즉시 오작동하게 만들었습니다(issue #166). 코딩 에이전트는 정확한 검색 및 대체(search and replace)로 파일을 편집합니다. 파일 읽기 결과가 자연어 요약으로 돌아오자, 수정 사항들이 더 이상 일치하지 않았습니다. 에이전트는 파일을 다시 읽으려 했고, 또 실패했으며, 토큰을 절약하기는커녕 소모하며 루프에 빠졌습니다.
시도 2: 기본적으로 정확하게 유지하고, 오래된 출력만 압축하기
두 번째 설계는 모든 것을 기본적으로 정확하게 유지합니다. 정책은 우선순위가 정해져 있으며, 첫 일치(first-match) 및 대소문자 구분 없음(case-insensitive)을 따릅니다. 매칭되지 않은 도구는 절대 변경되지 않습니다:
- exact: 변경되지 않은 원본(never altered)을 유지합니다. Mutation tools, diffs, 실패한 명령어, 오류, 스택 추적(stack traces), 그리고 0이 아닌 종료 코드(non-zero exits)는 더 광범위한 규칙과 일치하더라도 정확하게 유지됩니다.
- deterministic: 경계가 지정된 헤드 및 테일 증거(bounded head and tail evidence)와 크기, SHA-256, 생략된 바이트 수(omitted-byte count), 그리고 재실행 지침(rerun instruction)을 유지합니다.
first_pass를 사용하면 모델이 출력을 처음 보는 순간부터 적용되므로 프롬프트에 나중에 다시 작성할 필요가 없습니다. - keyword (
keyword_compactor): 최소한 한 번의 정확한 노출(exact exposure) 이후에만 의도 일치 라인(intent-matching lines)을 유지합니다. - model (
compactor): 최소한 한 번의 정확한 노출 이후, 그리고 경제적 게이트(economic gate)가 순이익 절감(net saving)을 예측할 때만 의도 기반 요약(intent-guided summary)을 제공합니다. - source (파일 읽기): 구성에서 허용되지만 exact처럼 작동합니다 (참조: what broke).
Keyword/model: 첫 노출 시 exact로 처리되며, 게이트가 허용하는 경우 다음 요청부터 압축 대상이 될 수 있습니다. first_pass를 사용하면 처음 노출되는 순간부터 압축되어 나중에 접두사(prefix)를 다시 작성할 필요가 없습니다. 캐시된 압축 버전은 이후 요청에서도 동일한 바이트를 유지합니다.
오래된 메시지를 재작성하면 그 시점부터 프롬프트의 접두사가 변경됩니다. 따라서 모델 게이트 컴팩터는 두 가지 경제적 게이트를 실행합니다: 요약 비용을 지불하기 전에 최상의 경우 감소만으로 캐시 재작성을 상환할 수 있는지 확인하는 사전 비행(preflight) 검사, 그리고 실제 후보들에 대한 최종 검사입니다. 추정된 순이익 절감이 양수일 때만 배치(batch)를 적용합니다.
실험 설정 및 방법론
환경
- 날짜: 2026년 7월 21일.
- Harness: OMP 16.2.9 (코딩 에이전트).
- 대상 모델:
https://api.deepseek.com/beta를 통한 DeepSeek V4 Pro (OpenAI 호환 형식). - 요약기 (model-gated arm): 동일한 엔드포인트의 DeepSeek V4 Flash.
- Torana: PR #179의 커밋 e09d225에서 가져옴. 해당 PR은 실험 브랜치였으며, 플러그인은 나중에 torana-plugins으로 이동했고 현재 릴리스는 다름. 이는 과거 실행에 사용된 구현이며, 아래의 미공개 작업 프롬프트와 실행 아티팩트만으로는 이 기사만으로 정확한 재현이 불가능함.
사용된 가격 (2026년 7월, 백만 토큰당)
현재 가격이 아닌 과거 테스트 입력값. V4 Pro의 캐시 히트 가격은 캐시 미스 가격의 0.83%임.
| 모델 | 입력 (캐시 미스) | 캐시 히트 | 출력 |
|---|---|---|---|
| DeepSeek V4 Pro | $0.435 | $0.003625 | $0.87 |
| DeepSeek V4 Flash | $0.14 | $0.0028 | $0.28 |
Arm (구현 방식)
- Control (대조군): 압축 플러그인이 없는 요청 경로의 Torana.
- Deterministic (결정론적):
schema_translator → intent → keyword_compactor, 요약기 비활성화. 이는 커밋된config.dogfood.json임. 실제 실행은 대상 모델에 대해https://api.deepseek.com/beta엔드포인트를 사용함.
결정론적 arm 구성 (JSON)
{
DeepSeek은 별도의 캐시 쓰기 비용이 없으므로, 캐시 쓰기 비율은 입력 비율과 동일하게 설정됩니다: 재작성된 스팬(span)은 캐시 미스(cache misses)로 청구됩니다.
### 프로토콜
- **태스크:** OMP를 사용하여 다섯 개의 레포지토리 태스크가 실행되었습니다: 아키텍처, 경제학, 회귀 검토, 안전성 (변이, 패치, 오류 및 0이 아닌 종료점 운동), 그리고 스트레스 태스크.
- **설계:** 5회 반복 × 3개 팔(arms) = 총 75 세션입니다. 각 쌍으로 이루어진 블록(태스크 × 반복) 내에서 3개 팔의 순서는 무작위화되었습니다.
가드, 비용 회계, 통계 및 공개되지 않은 내용
- **가드:** 요청 수 25회 초과 시, 진행 없이 150초 경과 후, 동일한 의미론적 도구 의도(semantic tool intent) 세 번 발생 시, 또는 총 지출액 $15 상한선에 도달하면 중단됩니다. 총 지출: $1.90.
- **비용:** 위에서 언급된 가격으로 제공업체 보고 캐시 미스(cache-miss), 캐시 히트(cache-hit) 및 출력 토큰을 계산하며, 요약기 사용량도 포함됩니다. DeepSeek은 캐시 히트를 `prompt_cache_hit_tokens`로 보고합니다.
- **통계:** 쌍별 절감액(paired saving) = 모든 25쌍에 걸쳐 동일한 태스크와 반복에 대한 통제 비용 − 처리 비용입니다. 95% 구간은 고정된 시드 166을 사용한 10,000개의 부트스트랩 리샘플링의 백분위수 구간입니다.
- **품질:** 분류를 위한 키워드 휴리스틱(keyword heuristic)과 모든 15개 안전성 태스크 답변에 대한 수동 검토가 이루어졌습니다.
- **공개되지 않은 내용:** 개인 정보 보호 검토를 기다리느라 보류된 정확한 태스크 프롬프트와 세션별 원시 전사 기록(raw per-session transcripts)입니다. 집계 결과는 [DEEPSEEK_RESULTS.md](https://github.com/torana-edge/torana-plugins/blob/main/plugins/compactor/DEEPSEEK%5FRESULTS.md)에서 확인할 수 있습니다.
## 결과
_팔당 25회 실행에 대한 세션별 중앙값._
## 결정론적(Deterministic) arm:
25개 중 15개의 테스트 실행에서 무언가가 변환되었으며, 총 399개의 애플리케이션(새로운 변환 34개, 캐시 재사용 365개)을 통해 4,809,164바이트가 제거되었습니다. 중앙값 쌍별 절감액은 **$0.000524 (~2.1%)**이며, 95% 구간은 −$0.003714에서 +$0.003725입니다. 평균 절감액은 −$0.0000559로, 25개 쌍 중 13개에서 더 저렴했습니다. 중앙값 쌍별 입력 토큰 절감액은 29,117(구간 −57,989에서 +60,161)입니다. 변환만 발생한 실행의 경우 중앙값 변화는 −$0.000262로, 약간 증가했습니다.
**Model-gated arm:** 출력은 네 번만 변환되었으며, 모두 결정론적 규칙을 통해 이루어졌습니다(변환 6개, 재사용 79개). 중앙값 쌍별 절감액은 $0.000478 (~1.9%)이며, 구간은 −$0.000998에서 +$0.004973입니다. 평균은 $0.001569로, 25개 쌍 중 15개에서 더 저렴했습니다. 사전 검사(preflight)는 **Flash** 호출을 전혀 하지 않았습니다. DeepSeek의 캐시 적중가 기준으로 예상되는 6개의 애플리케이션으로는 재작성된 접두사가 캐시 미스를 상쇄할 수 없었습니다. 이는 모델이 작성한 요약본이 아닌 게이트를 측정합니다.
루프 중단(요청 제한 종료)은 control arm과 변환이 없는 테스트 실행에서 발생했으므로, 압축보다는 에이전트의 분산을 반영합니다.
**작업별 중앙값 비용**
_작업당 중앙값 비용. 도구 호출 및 답변 길이의 차이가 제거된 캐시 토큰의 가치보다 더 컸습니다._
| Task | Control | Deterministic | Model-gated |
| --- | --- | --- | :--- |
| Architecture | $0.026040 | $0.022984 | $0.025993 |
| ... |
## 비용 효율적이지 않은 이유: 프롬프트-캐시 경제학 (prompt-cache economics)
입력 토큰의 약 92%가 모든 arm에서 캐시 적중(cache hit)이었고, V4 Pro에서의 캐시 적중은 미스(miss) 대비 0.83%에 불과했습니다. 즉, 약 120배 더 저렴했던 것입니다. 제거되는 반복적인 도구 출력은 이미 거의 무료였습니다. 재작성은 그 시점부터 프롬프트를 변경하므로, 캐시가 다시 구축될 때까지 그 이후의 모든 것이 새로운 입력으로 청구됩니다.
[](https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiz3asaf2vkepsbrpi18l.png)
요소를 제거하는 것이 이득이 되려면, 나중에 발생하는 턴(turn)에서 절약되는 비용이 제거로 인해 발생하는 누락(misses)보다 커야 합니다. 캐시 적중률(cache hits)이 92%이고 가격 차이가 120배에 달했기 때문에, 제거된 요소들은 거의 가치가 없었습니다.
이는 DeepSeek의 가격 정책에서 나타나는 특성입니다. 캐시된 입력에 대해 더 많은 비용을 청구하거나 아예 프롬프트 캐시(prompt cache)가 없는 제공업체(provider)라면 결과가 달라질 수 있습니다. 이는 다음 실험([issue #193](https://github.com/torana-edge/torana-edge/issues/193))에서 다루어집니다.
### 손익분기점 조건 (The break-even condition)
`N`을 미래 턴 수, `R`을 재작성된 캐시 스팬(rewritten cached span)으로, `W`를 제공업체의 쓰기/입력 비율(write/input rate), `C`를 캐시 읽기 비율(cache-read rate), `D`를 미래 턴당 제거되는 토큰 수, 그리고 `S`를 요약기 비용(summariser cost)이라고 합시다. 압축이 필요하려면 다음 조건이 충족되어야 합니다:
N > (R × max(0, W − C) + S) / (D × C)
이 단순화된 모델은 양수 `D × C`와 일치하는 단위를 가정하며, `S`가 달러($) 단위일 때 비율은 토큰당 비용입니다. 이 모델은 모든 제공업체의 캐싱 규칙이나 에이전트 행동의 변화를 반영하지는 않습니다. 경제적 입력값이 누락되었거나 예상 순이익(net)이 양수가 아닐 경우, 게이트는 아무것도 하지 않는데, 이는 올바른 결과입니다.
## 과정에서 문제가 된 부분 (What broke along the way)
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기