CLI 워크플로에서 에이전트 토큰 비용 줄이는 방법
출력 압축, 명령어 위생, 컨텍스트 규율을 활용해 CLI 워크플로에서 에이전트 토큰 비용을 줄이는 실용적인 가이드.
저는 Dora입니다. 지난달 Claude Code를 통해 npm test 하나를 실행했을 때, 에이전트가 한 마디도 하기 전에 세션이 약 12,000개의 입력 토큰을 소모하는 것을 지켜봤습니다. 테스트 출력은 400줄이었습니다. 그 중 의미 있는 건 30줄 정도였습니다. 나머지 — 지원 중단 경고, 의존성 노이즈, Jest의 진행 상태 점들 — 모두 모델의 컨텍스트로 곧장 들어갔습니다. 저는 모든 바이트에 비용을 지불했습니다.
그때부터 토큰을 “모델이 알아서 처리하는 것”으로 여기지 않고, 제가 능동적으로 낭비하고 있는 예산으로 취급하기 시작했습니다. Claude Code, Gemini CLI, 또는 이와 유사한 에이전트 CLI 워크플로우를 운영하고 있다면, 이것이 아마도 가장 큰 비용 항목일 것입니다 — 그리고 해결책은 더 나은 모델이 아니라, 더 나은 습관입니다. Anthropic의 비용 관리 문서는 명확하게 설명합니다: 토큰 비용은 컨텍스트 크기에 따라 확장되며, 대부분의 최적화는 모델이 데이터를 보기 전에 이루어진다고. 이 글은 필요한 디버깅 신호를 잃지 않으면서 CLI 워크플로우에서 에이전트 토큰 비용을 줄이는 방법에 관한 것입니다.
CLI 워크플로우가 토큰을 낭비하는 곳
무언가를 고치기 전에, 어디서 누수가 발생하는지 파악해야 했습니다. 두 가지 패턴이 두드러졌으며, 제가 감사한 거의 모든 CLI 워크플로우에서 나타납니다.
장황한 명령어와 불필요한 출력
터미널 명령어는 화면을 훑어보는 사람을 위해 설계되었지, 바이트 단위로 읽는 LLM을 위해 설계된 것이 아닙니다. git status는 모델이 필요로 하지 않는 ANSI 코드를 출력합니다. npm install은 모델이 이미 알고 있는 의존성 트리를 수천 줄씩 쏟아냅니다. next build는 15초 동안 자신의 진행 상황을 반향합니다. 이 중 어느 것도 컨텍스트 창에서 제 몫을 하지 못합니다.
숫자는 겉으로 보이는 것보다 더 나쁩니다. 중간 규모 Rust 프로젝트에서 단 한 번의 cargo test 실행이 8,000~15,000개의 토큰 출력을 만들 수 있습니다. 대부분은 컴파일 노이즈입니다. 에이전트가 하나의 실패한 단언문을 찾기 위해 전부 읽을 때, 당신은 빌드 로그를 스트리밍하는 특권을 위해 Opus 요금을 지불한 것입니다.
이것이 rtk와 tokf 같은 커뮤니티 프로젝트가 존재하는 이유이기도 합니다 — 이들은 셸과 에이전트 사이에 위치하여, 보일러플레이트가 컨텍스트에 들어오기 전에 걸러내고, 일반적인 명령어에서 70~90%의 절감 효과를 보고합니다. 래퍼를 사용하든 안 하든, 원칙은 동일합니다: 원시 터미널 출력은 LLM에 적합한 데이터가 아닙니다.
컨텍스트 누적과 반복 읽기
두 번째 누수는 더 미묘합니다. 에이전트가 수행하는 각 도구 호출 — 파일 읽기, grep, bash 명령어 — 은 대화 기록에 남습니다. 10번째 턴이 되면, 모델은 모든 요청에서 9번의 오래된 출력을 재처리하고 있습니다. Anthropic의 4월 사후 분석은 Claude Code 품질 문제에 대해 정확히 이 역학을 설명합니다: 캐싱 버그로 인해 생각 기록이 턴을 거듭하며 누적되었고, 누군가 알아채기 전에 토큰 사용량이 10~20배 증가했습니다. 버그가 없어도 이것이 기본 동작입니다. 긴 세션은 비싼 세션입니다.
제 일주일 된 세션 하나를 확인해봤습니다. 에이전트가 동일한 package.json을 네 번 읽었습니다. 그 재독 중 어느 것도 정보를 추가하지 않았습니다 — 파일은 변경되지 않았습니다. 단지 에이전트가 이미 알고 있는 것을 모른다는 아티팩트였습니다.
1단계: 노이즈가 많은 출력 압축하기
가장 저렴한 수정 방법은, 압도적으로, 쓰레기가 처음부터 컨텍스트에 들어오는 것을 막는 것입니다. 세 가지 규칙을, 이 순서로:
필터링은 사후가 아닌 소스에서. npm test 대신, 에이전트는 npm test —silent 2>&1 | grep -E “(FAIL|PASS|Error)“를 실행합니다. git status 대신, git status —short를 실행합니다. cargo build 대신, cargo build —quiet 2>&1 | tail -20을 실행합니다. 이 중 어느 것도 영리한 것이 아닙니다. 그냥 규율입니다. 에이전트는 실패한 테스트, 수정된 파일, 실제 오류를 얻습니다 — 그 외엔 아무것도 없습니다.
하네스 수준에서 도구 출력을 제한하세요. Claude Code에서는 최대 도구 출력 크기를 설정할 수 있습니다. 저는 호출당 8,000자로 낮췄습니다. 명령어가 이를 초과하면, 에이전트는 잘림 알림을 받고 쿼리를 정제할지 결정합니다. 이 단일 설정만으로 다른 모든 변경을 합친 것보다 더 많은 토큰을 절약했습니다.
업스트림 도구가 침묵하지 않을 때는 CLI 프록시를 사용하세요. 일부 명령어에는 쓸 만한 quiet 플래그가 없습니다 — next build, webpack, Java 기반의 모든 것. 이를 위해, 알려진 보일러플레이트를 제거하는 래퍼는 설정 시간을 들일 가치가 있습니다. rtk/tokf 계열의 도구들은 이것을 일반적으로 처리합니다; 가장 귀찮은 세 가지 명령어를 위한 30줄짜리 bash 함수를 직접 작성할 수도 있습니다.
여기에는 실제 트레이드오프가 있습니다. 공격적인 압축은 디버깅 신호를 숨길 수 있습니다. 빌드가 필터가 제거하는 이유로 실패할 때 — 오류로 변한 지원 중단 경고, 847번째 줄에 묻힌 모호한 설정 문제 — 에이전트는 더 짧고, 덜 유용한 그림을 얻습니다. 저는 두 번 겪었습니다. 두 번 모두 수정은 전략을 포기하는 것이 아니라 하나의 필터 규칙을 완화하는 것이었습니다.
2단계: 모델에 도달하기 전에 컨텍스트 제한하기
출력 필터링은 각 턴에 들어오는 새 토큰을 처리합니다. 컨텍스트 규율은 세션 내부에 이미 있는 누적된 토큰을 처리합니다. 서로 다른 문제입니다.
중요한 두 명령어는, Anthropic의 Claude Code 모범 사례에서 직접 가져온 것으로, /clear와 /compact입니다. /clear는 세션을 완전히 초기화합니다 — 관련 없는 작업으로 전환할 때 유용합니다. /compact는 핵심 결정과 현재 상태를 보존하면서 이전 기록을 요약합니다 — 작업은 계속되지만 초기 탐색이 더 이상 중요하지 않을 때 유용합니다. Claude Code는 컨텍스트 한도에 가까워지면 자동으로 압축하지만, 그 트리거를 기다리는 것은 보통 너무 늦습니다. 그때쯤이면 이미 몇 번의 턴에 대해 부풀려진 요금을 지불한 것입니다.
제 현재 습관: 모든 자연스러운 작업 경계에서 /compact focus on the failing test and the recent file edits처럼 지시와 함께 /compact를 실행합니다. 지시가 중요합니다. 없으면, 압축은 모든 것을 대략적으로 요약합니다. 있으면, 에이전트는 다음 단계에 중요한 부분을 유지합니다.
API 기반 에이전트(CLI 구독이 아닌)의 경우, Anthropic의 컨텍스트 편집 문서는 더 엄격한 메커니즘을 설명합니다: clear_tool_uses_20250919는 컨텍스트가 임계값을 넘어 증가하면 자동으로 이전 도구 결과를 지웁니다. 에이전트는 대화를 유지하지만 이미 처리한 원시 출력은 잃습니다. 장기 에이전트 작업에는 이것이 올바른 기본값입니다.
한 가지 언급할 사항: 부풀려진 CLAUDE.md는 영구적인 세금입니다. 매 턴, 매 세션마다 로드됩니다, 영원히. 저는 제 것을 ~280줄에서 ~90줄로 줄였습니다. 턴당 토큰 수가 눈에 띄게 감소했고 에이전트의 행동은 측정할 수 있는 방식으로는 변하지 않았습니다.
3단계: 낮은 낭비를 위한 에이전트 도구 재설계
처음 두 단계는 전술적입니다. 이것은 구조적이며, 지속적인 절감이 이루어지는 곳입니다.
LLM 친화적인 출력을 내보내는 도구를 설계하세요. 커뮤니티 주도 CLI Spec은 이 논점을 저보다 잘 설명합니다: 에이전트를 위한 명령어는 —output 플래그를 지원하고, 데이터(stdout)와 진단(stderr)을 분리하며, 무제한 JSON을 덤프하는 대신 페이지네이션을 제공해야 합니다. 에이전트가 호출할 내부 CLI를 만들고 있다면 해당 사양을 따르세요. 그렇지 않은 외부 CLI를 사용하고 있다면 래핑하세요.
넓은 도구보다 좁은 도구를 선호하세요. 세 개의 구조화된 필드를 반환하는 git_status_summary 함수는 에이전트가 원시 git status를 실행하고 출력을 파싱하도록 하는 것보다 낫습니다. 모델이 수행해야 하는 파싱의 모든 계층은 추론이 아닌 번역에 토큰이 소모되는 계층입니다. 가장 많이 사용하는 명령어 네 개를 JSON을 반환하는 얇은 Python 래퍼로 변환했습니다. 해당 작업의 왕복 토큰 사용량이 약 60% 감소했습니다.
읽기 집약적인 작업에는 서브에이전트를 사용하세요. Claude Code의 서브에이전트 기능은 “저장소를 스캔하고 인증 흐름을 요약하라”와 같은 작업을 위한 별도의 컨텍스트를 실행합니다. 결과는 간결한 요약으로 돌아옵니다 — 서브에이전트가 실제로 읽은 40개의 파일이 아닌. 메인 대화는 원시 데이터를 절대 보지 못합니다. 탐색 집약적인 작업에 이것은 가장 큰 구조적 이점입니다.
모델을 작업에 맞추세요. Opus 4.7은 인상적이고 비쌉니다. 대부분의 CLI 작업 — 파일 편집, 테스트 수정, 일상적인 리팩토링 — 은 Opus의 토큰당 비용의 약 40%인 Sonnet에서도 잘 실행됩니다. 알아둘 가치가 있는 것: Opus 4.7의 새 토크나이저는 동일한 텍스트에 대해 이전 모델보다 최대 35% 더 많은 토큰을 생성할 수 있으며, 이는 비용 차이를 더 크게 만듭니다.
솔직한 주의사항: 최적화하기 전에 측정하고, 그 후에도 측정하세요. 무언가를 변경하기 전에 일주일 동안 /cost(API) 또는 /usage(구독)로 기준선을 설정하고, 각 변경 후 다시 측정했습니다. 제 “최적화” 중 두 개는 측정 가능한 효과가 없는 것으로 판명되었습니다. 기준선 없이는 추측하는 것입니다.
자주 묻는 질문
터미널 워크플로우가 왜 그렇게 많은 토큰을 소비하나요?
터미널 출력이 사람을 위해 설계되었고, 에이전트는 바이트 단위로 비용을 지불하기 때문입니다. 일반적인 빌드 명령어는 모델이 필요로 하지 않는 수천 줄의 진행 상황, 경고, 보일러플레이트를 내보냅니다. 그것을 절대 초기화되지 않는 대화 기록, 턴을 거쳐 누적되는 도구 결과와 결합하면, 실제 작업이 시작되기 전에 컨텍스트 예산을 다 써버리는 세션이 됩니다.
출력 압축은 얼마나 도움이 될 수 있나요?
제 측정에서, 명령어 수준 필터링과 출력 제한은 테스트 실행, 빌드, git 작업에서 턴당 입력 토큰을 4060% 줄였습니다. rtk 같은 커뮤니티 래퍼는 특정 명령어에서 8090% 감소를 보고하지만, 그 수치는 최악의 경우 장황한 출력을 가정합니다. 현실적인 이득은 에이전트가 가장 많이 실행하는 명령어에 따라 다릅니다. 상위 다섯 개를 감사하고, 그것들을 수정하면, 대부분의 절감이 즉시 나타납니다.
팀은 무엇을 먼저 최적화해야 하나요?
이 순서로: 도구 출력 제한, /clear와 /compact 규율, 모델 선택. 출력 제한은 지속적인 비용이 없는 일회성 구성 변경입니다. 세션 위생은 습관이지만, 일단 익히면 무료입니다. 모델 선택은 가장 간과하기 쉬운 이득입니다 — 대부분의 작업이 Sonnet에서도 잘 실행되는데 모든 것을 Opus에서 실행하는 것은 조용하고 큰 누수입니다.
토큰 최적화가 디버깅 품질을 해치는 경우는 언제인가요?
에이전트가 무엇이 잘못되었는지 볼 수 없을 정도로 압축할 때입니다. 잘린 스택 트레이스, 필터링된 지원 중단 경고, 실제 오류를 숨기는 —quiet 플래그 — 이 모든 것이 저에게 실제 시간을 낭비하게 했습니다. 제가 따르는 패턴: 일상적인 명령어(git status, npm install, 성공적인 테스트 실행)에서는 공격적으로 압축하고, 알려진 실패 또는 낯선 작업에는 장황한 출력을 유지합니다. 디버깅을 위해 필터 없이 명령어를 다시 실행하고 있다면, 필터가 잘못된 것이지 전략이 잘못된 것이 아닙니다.
결론
CLI 워크플로우의 토큰 비용은 모델 문제가 아닙니다. 배관 문제입니다. 대부분의 지출은 터미널 명령어가 내보내는 것과 모델이 추론하기 위해 실제로 필요한 것 사이의 간극으로 사라집니다 — 그리고 그 간극은 출력 필터링, 컨텍스트 규율, 그리고 반대편의 에이전트를 존중하는 도구로 수정할 수 있습니다.
약 6주 동안 위의 설정을 운영해왔습니다. Claude Code의 일일 토큰 소비량이 약 55% 감소했고, 에이전트 지연 시간은 더 작은 컨텍스트의 부작용으로 개선되었으며, 워크플로우가 디버깅하기에 덜 노이즈가 많아진 느낌입니다. 그 숫자들 중 어느 것도 보편적이지 않습니다 — 당신의 기준선과 상위 다섯 가지 명령어는 다르게 보일 것입니다. 하지만 패턴은 유지됩니다: 컨텍스트에 들어오는 것을 제어하고, 컨텍스트에 머무는 것을 제어하며, 모델이 빌드 로그를 읽는 대신 추론에 예산을 쓰도록 하세요.
여기서 제 데이터는 끝납니다. 압축 레이어는 계속 진화하고 있으며, Anthropic의 토크나이저 변경은 이 숫자들이 유효 기간이 있다는 것을 의미합니다. 분기마다 기준선을 다시 측정하는 것이 좋습니다.
이전 게시물:



