
Claude Code의 '낭비'를 시각화하는 도구 cclens를 만들었습니다
요약
Claude Code 사용 시 발생하는 설정의 비효율성과 토큰/시간 낭비를 시각화하는 도구인 cclens를 소개합니다. 별도의 추가 실행 없이 기존 로그를 분석하여 사용되지 않는 설정이나 비용 낭비 요소를 찾아냅니다.
핵심 포인트
- Claude Code의 비결정성으로 인한 설정 효과 검증 난제 해결
- 추가 비용 없이 기존 세션 로그를 분석하여 낭비 요소 측정
- 미사용 설정, 고비용 저효율 설정, 반복 실패 도구 등을 리스트업
- 로컬 환경에서 데이터 전송 없이 안전하게 분석 수행
의사로부터 알코올을 자제하라는 말을 들어 논알코올 맥주를 마셔보았지만, 그리 취향은 아니었던 16세(진수 불명), ありすえ(아리스에)입니다.
갑작스럽지만, 여러분은 자신의 Claude Code가 얼마나 낭비적인 일을 하고 있는지 파악하고 계신가요?
설정의 효과 검증은 어렵다
AI는 비결정적 (Non-deterministic)인 도구죠. 그래서 설정의 효과 검증이 굉장히 어렵습니다.
어떤 목적을 위해 규칙이나 스킬을 작성했다고 쳤을 때, 그것이 정말 효과가 있는지? 효과가 있다면 제대로 효과적으로 작동하고 있는지? 이를 정량적으로 측정하는 것은 참으로 난제입니다. 결국 "일단, 당분간 써보면서 지켜보자"로 결론이 나곤 하지만, 그 "당분간 써보는" 단계가 제대로 오는 경우는 드물며, 정신을 차려보면 사용되지 않는 설정들만 조용히 쌓여가는 느낌입니다.
그럼 재고 조사를 할까 생각해도, 이번에는 그 비결정성이 오히려 걸림돌이 됩니다. "혹시 내가 모르는 곳에서 효과를 내고 있는지도 몰라"라고 생각하면 갑자기 삭제할 수 없게 됩니다. 재고 조사 그 자체에 은근한 심리적 장벽이 있는 셈입니다.
이거, 성능 검증과 똑같지 않나요?
이 구도가 왠지 낯익다고 생각하셨다면, 바로 성능 튜닝 (Performance Tuning) 그 자체였습니다.
"여기에 인덱스를 걸면 빨라질 거야", "이 로직을 바꾸면 빨라질 거야"라고 짐작하며 변경을 가하고, "빨라져라~"라고 기도합니다. 게다가 "당분간 지켜보자"라고 결정한 날에는, 그 변경 사항을 제거한다는 판단은 훨씬 더 어려워집니다. ……완전히 동일한 구조입니다.
그리고 성능 튜닝의 세계에는 이 병에 잘 듣는 유명한 처방전이 있죠. 바로 "추측하지 말고, 측정하라" 입니다.
그래서, 측정하는 메커니즘을 만들었습니다
물론 시간과 비용을 들인다면 측정 자체는 가능합니다. 설정 전후로 특정 태스크의 소요 시간이나 결과의 좋고 나쁨에 변화가 있었는지 몇 번 측정해 보면, 그 설정에 의미가 있었는지는 알 수 있습니다. 이른바 A/B 테스트죠.
하지만 AI는 하루가 다르게 발전하고 있지 않나요? 모델의 똑똑함도 변하고, 프롬프트 (Prompt) 해석 방식도 변하고, 도구의 동작도 변합니다. 그런 상황에서 "이 설정 변경이 효과적인가?"를 비용을 들여 조사해도, 내일이면 그 설정의 의미가 없어질지도 모릅니다. 게다가 그 조사는 시간도 토큰 (Token)도 꽤 잡아먹습니다. ……솔직히 바보 같은 짓이죠 🙃
그래서 cclens는 측정을 위해 무언가를 굳이 실행하는 것이 아니라, 평소 사용하는 로그를 그대로 분석하도록 만들었습니다. "측정을 위해 별도의 비용을 지불하는" 일은 하지 않습니다 (물론 분석 자체의 비용은 발생하지만요).
이것이 은근히 효과적입니다. 아무 신경 쓰지 않고 적당히 설정을 막 추가해 나가다가, 마음 내킬 때 cclens로 재고 조사를 합니다. 그런 거친 운용이 가능해지는 것입니다. "효과 검증을 위해 신중하게 설정을 추가하는" 것이 아니라, "일단 추가해 두고 나중에 한꺼번에 정답을 맞히는" 방식으로 가도 됩니다.
이 "거친 재고 조사"를 가능하게 하는 것이 cclens입니다. 평소의 세션 기록을 분석하여, 시간·토큰·노력이 어디에서 낭비되고 있는지를 측정 및 시각화합니다 (어떻게 측정하는지는 후반부의 기술 상세에서 설명하겠습니다). 모든 과정은 로컬에서 완결되며, 데이터는 어디로도 전송하지 않습니다.
할 수 있는 일 · 사용법
cclens로 할 수 있는 일은 크게 두 가지로 나뉩니다.
- 낭비스러운 부분을 리스트업하기: "넣어두었지만 한 번도 호출되지 않은 설정", "비용은 높은데 가끔밖에 사용하지 않는 설정", "매번 같은 이유로 실패하는 도구", "Claude가 몇 번이고 다시 편집하며 막혀 있는 파일" 등을 비용과 함께 랭킹으로 표시합니다.
- 상세 정보를 AI에게 전달하여 최적화를 도움받기: 리스트업된 findings (발견 사항)와 이를 뒷받침하는 상세 데이터를 AI (Claude Code 자신)에게 전달하여, 근본 원인 조사부터 구체적인 설정 수정 제안까지 수행하게 합니다.
요컨대, "어디가 수상한지 찾는 것"부터 "그럼 어떻게 고칠 것인가"까지를 챙겨주는 것이 cclens입니다. 이하, 구체적인 명령어를 순서대로 살펴보겠습니다.
설치
macOS / Linux (Intel · ARM64 모두 대응)에서 동작합니다. Windows는 번거로워서 대응하지 않았습니다. 원리적으로는 지원하지 못할 이유가 없으므로, 원하는 분이 있다면 PR이나 issue를 주세요.
# Homebrew
brew install lambdalisue/cclens/cclens
# Nix (툴체인 불필요, 설치 없이 즉시 실행 가능)
...
Rust 툴체인 (Toolchain)이 있다면 cargo build --release를 사용하세요.
하지만 일반적인 방법으로도 빌드할 수 있습니다.
doctor
부터
명령어는 다양하지만, 무엇을 할지 모르겠다면 doctor부터 시작하세요. 전체적인 건강 상태를 한 화면에 보여주는 종합 건강검진 결과 페이지로, "글로벌(~/.claude)에서 수정해야 할 사항"과 "프로젝트별로 수정해야 할 사항"을 나누어 보여줍니다.
cclens doctor # 전체 원스크린 건강검진 (최초 실행 시 자동으로 analyze도 실행됨)
cclens doctor --scope global # 글로벌 설정 레이어만 확인
cclens doctor --scope project:<slug> # 특정 프로젝트만 확인
읽기 전용 명령어는 리포트를 생성하기 전에 자동으로 스토어 (Store)를 최신화합니다 (변경 사항이 없는 트랜스크립트 (Transcript)는 스킵되므로 빠릅니다). 업데이트를 원하지 않을 때는 --frozen을 붙이면 현재 있는 스토어를 그대로 읽습니다.
다양한 각도에서 낭비 살펴보기 (Views)
doctor로 대략적인 위치를 파악했다면, 관심 있는 관점을 개별 명령어로 심층 분석합니다. 모든 명령어는 단순한 집계가 아니라 분류, 순위 매기기, 그리고 "이렇게 수정하면 좋다"라는 제안까지 포함된 관점을 제공합니다.
cclens waste # 최적화 여지를 랭킹으로 표시. 삭제/슬림화/트림 권장 액션 포함
cclens inventory # 모든 설정 서피스 (Scope 포함) × 실제 사용 현황
cclens overhead # 세션별 상시 활성화된 컨텍스트 (Context) 양을 설정과 대조하여 표시
...
예를 들어 failures를 보면 "와, 이 도구가 매번 이 이유로 실패하고 있었구나"라는 것을 깨달을 수 있습니다. 규칙이나 프롬프트 (Prompt)를 한 줄 추가하는 것만으로 사라질 낭비가 의외로 곳곳에 널려 있습니다. stuck은 Claude가 제자리걸음을 하고 있는 파일, 즉 지시나 설계가 미흡하다는 신호를 알려줍니다.
그리고 서두에서 언급한 "보이지 않는 고정비"에 가장 효과적인 것이 overhead입니다. 이는 아직 아무 작업도 하지 않았음에도 매 세션 반드시 지불하고 있는 컨텍스트 양(= 상시 활성화된 바닥값)을 보여줍니다. 게다가 그 내역을 다음과 같이 분해해 줍니다.
- 자신의 설정 파일 유래 (
CLAUDE.md+ 상시 활성화된 규칙) = 줄일 수 있는 부분 - 나머지 (시스템 프롬프트 · 내장 도구 · MCP 스키마) = 파일로는 줄일 수 없는 부분
이를 통해 "비대해진 원인이 내 설정 때문인지, 아니면 애초에 깔려 있는 기본값 때문인지"를 한눈에 알 수 있습니다. 또한 프로젝트별 바닥값도 나오기 때문에, 특정 MCP 서버를 활성화한 프로젝트와 활성화하지 않은 프로젝트의 바닥값을 비교하면, 해당 MCP 서버가 실제로 얼마만큼의 토큰을 소비하는지 역산할 수 있습니다. "왠지 무거운 MCP"를 숫자로 추적할 수 있게 되는 것입니다.
--scope 옵션은 doctor / waste / inventory / failures (및 후술할 optimize)에서 작동합니다. "불필요하거나 무거운 설정"은 해당 파일이 위치한 곳으로, "반복되는 실패"는 그 실패의 대부분을 차지하는 프로젝트로 각각 분류됩니다 (어느 프로젝트에도 속하지 않는 실패는 횡단적인 습관으로서 글로벌로 취급됩니다).
생 SQL로 자유롭게 탐색하기
준비된 View로 부족하다면 스토어에 직접 쿼리를 던질 수 있습니다. 스토어는 읽기 전용으로 열리므로 쿼리로 데이터를 망가뜨릴 걱정은 없습니다.
# 실패 카테고리별 발생 도구는?
cclens sql "SELECT category, tool, COUNT(*) n FROM tool_errors GROUP BY 1,2 ORDER BY n DESC"
# 스키마 들여다보기
...
출력 형식
표를 출력하는 View 계열 명령어는 --format markdown (PR이나 메모에 바로 붙여넣기 가능)을 지원하며, --format json (기계 판독 가능)은 거의 모든 명령어에서 사용할 수 있습니다 (doctor...
요약이므로 Markdown 형식은 없으며, 대신 JSON을 출력할 수 있습니다). JSON 모드일 때는 stdout에 JSON 이외의 내용은 일절 출력하지 않으며, 최신성(freshness) 등의 노이즈는 stderr로 보냅니다. 사람을 위한 출력은 터미널에서는 색상이 적용되지만, 파이프(pipe) 연결 시나 NO_COLOR 환경 변수 설정 시 자동으로 꺼집니다.
그대로 수정하기 · Claude Code 플러그인으로 사용하기
발견된 낭비를 그대로 수정하러 가는 것이 optimize입니다. 주요(headline) findings를 최적화 어드바이저용 프롬프트와 함께 대화형 Claude 세션 (interactive claude session) 으로 전달합니다. findings는 임시 파일을 통해 전달되며, 커맨드라인 인자(command line argument)에는 포함되지 않습니다.
cclens optimize --scope global
이 부분은 제가 조금 공을 들인 포인트입니다. 하루가 다르게 발전하는 AI를 상대한다면, 최적화 그 자체는 AI 스스로 하게 하는 것이 좋다는 생각입니다. cclens는 어디까지나 "측정하여 확실한 데이터를 제공하는 것"에 집중합니다. 그 데이터를 어떻게 요리하고 어떤 설정으로 고칠지는, 그 시점에서 가장 똑똑한 AI 스스로 결정하게 합니다. 그래서 cclens는 "이것을 지워라"라고 단정 짓지 않고, 재료만 준비해서 AI에게 넘겨주는 방식으로 설계되었습니다.
이것을 실제로 해보면 정말 흥미로운데, 스스로도 깨닫지 못했던 해결책까지 대화형으로 제안해 줍니다. 제가 테스트했을 때는 다음과 같은 제안이 돌아왔습니다.
cd를 불필요하게 너무 많이 입력하는 문제: "worktree로 작업하라"는 스킬을 넣어두었음에도, 해당 스킬이 cwd(current working directory)를 변경하지 않았기 때문에 Claude가 매 명령마다cd를 불필요하게 입력하고 있었습니다. cclens는 이를 감지한 후, "Claude Code 내장 worktree 명령어(cwd를 함께 전환하는 것)로 스킬을 수정하면 매번cd를 입력할 필요가 없어진다"라고 제안해 주었습니다.awk/sed금지 규칙의 과도함:awk나sed를 금지하는 규칙은 제대로 작동하고 있었지만, 실제 용도는 대부분 "파일의 부분 읽기"였습니다. 그래서 "perl을 안내하기보다 내장된 부분 읽기 기능을 안내하는 것이 더 타당하다"라며 규칙을 어떻게 다시 작성해야 하는지까지 깊이 있게 제안해 주었습니다.
둘 다 "듣고 보니 정말 그렇네" 싶은 내용이지만, 스스로 데이터를 살펴보고 있을 때는 놓치기 쉬운 것들입니다. 측정 데이터를 AI에게 전달하면 이와 같은 한 단계 더 깊은 최적화 (one step deeper optimization) 를 끌어낼 수 있습니다. 이 부분이 optimize의 가장 큰 묘미라고 생각합니다.
참고로 cclens 자체도 Claude Code의 플러그인 마켓플레이스(plugin marketplace)에 등록되어 있어, 세션 안에서 바로 호출할 수 있습니다.
/plugin marketplace add lambdalisue/cclens
/plugin install cclens@cclens
설치하면 /cclens:doctor (세션 내 건강 진단), /cclens:optimize (현재 세션에서 근본 원인을 조사하여 구체적인 수정 제안), /cclens:query (읽기 전용 SQL로 애드혹(ad-hoc) 질문에 답변)를 사용할 수 있습니다. "Claude Code에게 자신의 낭비를 진단받는다"라는, 약간 메타(meta)한 경험을 할 수 있습니다.
기술 상세
여기서부터는 완전히 내부 구현 이야기이므로, 관심이 없다면 건너뛰셔도 괜찮습니다. cclens는 Rust로 제작되었으며, 설계 사상은 docs/specs/에 명시되어 있습니다.
왜 2단계 + SQLite인가
cclens는 "분석(analyze)"과 "리포트(각 View / sql)"의 2단계로 나뉘어 있으며, 두 단계는 SQLite 스토어(store)를 통해서만 느슨하게 결합(loosely coupled) 되어 있습니다.
이렇게 설계한 이유는 단순합니다. 입력 데이터를 다시 파싱(re-parsing)하는 비용이 너무 높기 때문입니다. 트랜스크립트(transcript)는 수백 MB에 달할 수 있지만, 분석은 여러 번 반복해서 수행하는 작업입니다. 따라서 "무거운 원본 입력은 한 번만 읽어 컴팩트한 스토어에 저장하고, 이후의 리포트는 스토어만 읽는다"라는 방식을 택했습니다. analyze는 증분(incremental) 방식으로 동작하므로, 두 번째 실행부터는 차이점(diff)만 처리합니다.
커맨드 이름을 build가 아닌 analyze로 정한 것도 의도가 있습니다. "결과물을 빌드한다"는 느낌보다는 "원본 입력을 사실(fact)로 분석한다"는 뉘앙스를 담았습니다.
중심에 있는 모델: catalog × usage
이 도구의 해답은 '집계'가 아니라 'join'입니다.
surface: 설정 가능한 것 1개 (스킬, 규칙, MCP 서버…). 설정 파일을 읽어 측정된 정적 비용 (static cost) (정의된 토큰 무게)을 가짐. -
event: 타임스탬프가 포함된 사건 1개. 토큰, 컨텍스트 증가, 실행 시간과 같은 **런타임 비용 (runtime cost)**을 가짐. 스킬 호출은 event의 일종일 뿐임.
surface에 대응하는 event가 없으면 '미사용', 정적 비용은 높은데 event가 적으면 '가지치기 후보'. 이 곱(join)이야말로 최적화의 쐐기(wedge)가 됩니다.
레이어 분리: 포맷 변화를 한 곳에 가두기
Claude Code의 입력 포맷(트랜스크립트 JSONL, 각종 설정 파일)은 릴리스마다 변경될 수 있습니다. 그래서 analyze의 내부를 상류의 포맷 변경이 단 하나의 레이어에만 파급되도록 계층화했습니다.
| 레이어 | 담당 | 몰라야 할 것 |
|---|---|---|
| adapter | 두 가지 입력 포맷의 원시 형태를 내부 도메인 모델로 매핑 | SQLite 스키마, 비용 계산 방법 |
| core | 이벤트 추출 · 정적 비용 측정 · catalog × usage의 join · 집계. 모두 순수 함수 (pure function) | Claude Code의 필드명이나 설정 경로, SQL |
| store | sessions / surfaces / events를 SQLite로 영속화 및 쿼리 | 원시 입력의 형태 |
| report | 쿼리 결과를 표 / Markdown으로 정형화하여 쐐기를 랭킹화 | 원시 입력의 형태, store API 이상의 SQL |
adapter와 그 외의 계약은 '내부 도메인 모델(Claude Code의 릴리스를 넘나들며 안정적인, 도구 중심의 명명)'입니다. 상류의 필드명이 바뀌더라도 바뀌는 것은 adapter의 매핑뿐입니다. 이 경계는 .claude/rules/format-isolation.md에 명문화되어 있으며, 포맷 변경의 차분이 adapter 외부로 새어 나간다면 그것은 경계 버그(boundary bug)로 간주하는 운영 방식을 따릅니다.
core를 순수 함수로 유지하는 것 또한 정책입니다. 이 도구의 가치는 바로 분석 로직(이벤트 경계, compaction에 강한 컨텍스트 측정, 서브 에이전트의 귀속, catalog × usage의 join)에 있습니다. 이 부분은 버그가 숨어들기 쉬워 테스트로 묶어두고 싶으므로, I/O · 시계 · SQL을 배제하고 작은 합성 피스처(composite fixture)를 통해 각 규칙을 단위 테스트(unit test)할 수 있도록 했습니다. '현재 시각'이나 튜닝 상수와 같은 비결정성(non-determinism)은 주입(injection)합니다.
하위 호환성과 데이터 처리
adapter는 방어적으로 역직렬화(deserialize)합니다. 필요한 필드만 읽고, 알 수 없는 필드는 무시하며, 임의 필드의 누락도 허용합니다. 새로운 Claude Code의 필드나 설정 키가 늘어나더라도 analyze를 망가뜨리지 않는다는 방침입니다.
그리고 데이터에 대하여. cclens는 원시 트랜스크립트나 설정을 리포지토리나 스토어에 복사하지 않습니다 (.claude/rules/session-data-privacy.md). Claude Code가 놓아둔 장소를 읽기 전용으로 읽을 뿐입니다. 스토어는 어디까지나 재생성 가능한 캐시이며, 스키마가 변경된 경우에는 오래된 파일의 이용을 거부하고 힌트를 제공하므로, cclens.db를 삭제하면 다음 로드 시 다시 생성됩니다.
참고로 구현상의 이유로 rusqlite는 0.32로 고정(pin)해 두었습니다 (새로운 libsqlite3-sys가 아직 unstable한 cfg_select를 사용하여 stable Rust로 빌드할 수 없기 때문입니다). 이러한 생생한 판단 근거는 Cargo.toml의 주석으로 남겨두었습니다.
마치며
cclens는 자신의 Claude Code 사용법을 객관적으로 점검하기 위한 도구입니다. 쌓인 낭비를 깎아내어 시간 · 토큰 · 노력의 로스를 줄이는 것. 그것뿐입니다. AI 주도 개발(AI-driven development)은 방치하면 설정이 점점 비대해지기 때문에, 정기적인 건강검진은 생각보다 큰 효과가 있습니다.
모든 과정이 로컬에서 완결되므로, 우선 가볍게 실행해 보세요.
cclens doctor
부터 시작해 보세요. 자신의 설정이 얼마나 비대해져 있었는지 분명 놀라게 될 것입니다.
버그 보고, 요청, 스타(Star)는 이쪽으로 부탁드립니다.
스폰서
GitHub Sponsors도 운영하고 있습니다. 후원을 해주신다고 해서 특별한 혜택이 있는 것은 아니지만, 저의 승인 욕구가 충족되어 이런 도구를 만드는 의욕이 엄청나게 상승합니다.
그리고 서두에서도 썼듯이, 저는 지금 논알코올 맥주 난민입니다. 크래프트 맥주를 좋아하는 분들 중 맛있는 논알코올 맥주를 알고 계신다면, 꼭 알려주세요.
Discussion

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