한 번 읽은 파일이 470턴 동안 다시 청구된다, PR 하나에 41달러 쓴 코딩 에이전트
Sonar가 코딩 에이전트 세션 트레이스를 계측해 공개했습니다. 800줄 PR 한 건에 모델 왕복 512회, 캐시 읽기 1억 5,280만 토큰, 약 41달러였고 새로 읽은 코드는 10만 6천 토큰뿐이었습니다.
- 800줄 PR 한 건에 약 41달러, 새로 읽은 코드는 10만 6천 토큰뿐이었습니다.
- 나머지는 앞서 읽은 파일이 매 턴 다시 청구된 캐시 읽기 1억 5,280만 토큰입니다.
- Sonar 자체 계측이라 재현은 안 되고 같은 방식의 무료 MCP도 있습니다.
정적 분석 도구 SonarQube를 만드는 Sonar가 2026년 9월 1일, 자사 코딩 에이전트 세션의 토큰 청구 내역을 공개했습니다. 800줄을 고친 PR 한 건에서 모델이 512번 왕복했습니다. 컨텍스트 창은 최대 458,700 토큰까지 찼고 세션 하나에 약 41달러가 청구됐습니다.
이 숫자 자체보다 눈에 띄는 것은 41달러의 구성입니다. 에이전트가 새로 읽어들인 코드는 10만 6천 토큰입니다. 캐시 읽기로 다시 청구된 분량은 1억 5,280만 토큰입니다. 약 1,440배 차이입니다. 청구서의 거의 전부가 새 작업이 아니라, 이미 읽어서 대화 기록에 남아 있던 파일이었습니다.
Sonar는 이것을 「컨텍스트 세금(context tax)」이라고 불렀습니다.
왜 이 비용이 청구서에 안 보였나
에이전트가 파일을 한 번 읽으면 그 내용은 대화 기록에 들어갑니다. 그 뒤로 모델이 한 번 응답할 때마다 기록 전체가 다시 모델에 들어갑니다. 사람이 보기에 파일을 읽은 것은 한 번인데 요금은 남은 턴 수만큼 반복해서 매겨집니다.
Sonar가 든 예가 구체적입니다. 618줄짜리 파일을 42번째 턴에서 한 번 열었는데, 정작 필요한 것은 그 안의 함수 하나였습니다. 당장 낭비된 것은 약 5,770 토큰입니다. 그런데 그 읽기가 남은 470턴 동안 대화 기록에 계속 남아 매 턴 캐시 읽기로 다시 청구됐습니다.
Sonar의 원문 표현은 이렇습니다. "512턴 세션의 40번째 턴에서 600줄짜리 파일을 읽으면, 당신이 지불한 것은 600줄이 아닙니다. 600줄 곱하기 남은 470턴입니다."
파일을 잘못 연 대가가 그 순간이 아니라 세션이 끝날 때까지 분할 청구된다는 뜻입니다. 청구서에는 「캐시 읽기」 한 줄로만 찍히기 때문에, 어느 파일 읽기가 얼마를 만들었는지는 트레이스를 직접 열어보기 전까지 보이지 않습니다. 캐시 적중률을 비용 변수로 다룬 Reasonix의 99.82% 프리픽스 캐시 사례는 같은 구조를 반대편, 즉 캐시를 잘 맞혔을 때의 이득에서 본 것입니다.
계측치와 그 한계
Sonar는 단일 세션 외에 비슷한 규모의 PR 18건 평균도 함께 냈습니다.
| 항목 | 단일 PR (800줄 변경) | PR 18건 평균 |
|---|---|---|
| 모델 왕복 횟수 | 512회 | 약 700회 |
| 컨텍스트 토큰 총량 | 1억 5,280만 (캐시 읽기) | 평균 약 2억 3,400만, 중앙값 1억 7,800만 |
| 컨텍스트 창 최대치 | 458,700 토큰 | 45만에서 97만 5천 토큰 |
| 세션 비용 | 약 41달러 | 평균 약 65달러, 중앙값 약 52달러 |

PR 한 건에 중앙값 52달러입니다. 10명이 하루에 PR을 하나씩 올리는 팀이면 월 1만 달러 규모가 됩니다. 편차도 큽니다. 위 그래프에서 가장 작은 PR은 1,300만 토큰으로 끝났습니다. 가장 큰 PR은 7억 6천만 토큰 가까이 썼습니다.
다만 이 수치는 전부 Sonar가 자사 코드베이스에서 뽑은 자체 보고값입니다. Sonar는 "SemSitter를 코딩 에이전트로 만들면서 전체 트레이스를 보관했기 때문에 정확히 계측할 수 있다"고만 밝혔습니다. 어떤 에이전트와 어떤 모델을 썼는지는 공개하지 않았습니다. 대상 저장소도 "우리 코드베이스", "SemSitter 저장소"로만 적혀 있습니다. 제3자가 같은 조건으로 재현할 방법은 없습니다.
토큰 단가가 계속 내려가고 있다는 점도 같이 봐야 합니다. Claude Fable 5.1은 캐시 읽기 단가를 100만 토큰당 0.25달러로 내렸습니다. 같은 1억 5,280만 토큰이라도 어느 모델의 어느 가격표로 계산하느냐에 따라 41달러라는 숫자는 크게 달라집니다.
원인으로 지목된 것: grep식 탐색
Sonar가 지목한 원인은 에이전트가 코드를 찾는 방식입니다. 지금 대부분의 코딩 에이전트는 파일 이름과 텍스트를 검색해서(grep, ripgrep 등) 후보 파일을 찾은 다음 그 파일을 통째로 읽습니다.
Sonar가 정리한 텍스트 검색의 한계는 네 가지입니다.
- 여러 백엔드의 결과를 한꺼번에 반환해서 무엇이 관련 있는지 구분하지 못합니다.
- 어떤 호출이 어떤 정의에 연결되는지 알 수 없습니다. 이름이 같은 함수가 셋이면 셋 다 후보입니다.
- 함수 경계를 모르기 때문에 함수 하나가 필요해도 파일 전체를 열게 됩니다.
- 간접 호출자, 별칭, 다른 언어로 된 같은 구현을 놓칩니다.
대안으로 Sonar가 내놓은 것이 SemSitter라는 코드 색인 엔진입니다. 저장소의 함수, 메서드, 클래스, 필드, 파라미터를 하나씩 노드로 만듭니다. 그리고 그 사이의 관계, 즉 호출·참조·반환·파라미터 보유·타입·포함·상속을 종류가 구분된 연결선으로 이어 그래프를 만듭니다. Sonar는 이 그래프를 UDG(Unified Dependency Graph)라고 부릅니다. 저장소가 바뀌면 즉시 갱신됩니다.
질문하는 방식이 달라집니다.
“어느 파일이 resolve_return_type을 언급하나?”
결과: 후보 파일 여러 개. 각각을 통째로 열어서 확인해야 합니다.
“이 호출이 연결되는 resolve_return_type의 정의, 그것을 소유한 타입, 반환 타입, 호출자를 달라.”
결과: 해당 노드와 연결선만. 주변 파일도, 여섯 갈래 검색도, 범위를 넓힐 일도 없습니다.
효과는 Sonar가 6월 30일 공개한 A/B 실험에 나옵니다. Claude Opus 4.8을 high effort로 쓰고 서브에이전트를 켠 상태에서, 오픈소스 프로젝트의 실제 머지 커밋 6건을 조건당 10회씩 재현했습니다. 모든 실행이 컴파일되고 대상 테스트를 통과해야 집계에 넣었습니다.
| 과제 | 언어 | 입력 토큰 | 비용 (중앙값) |
|---|---|---|---|
| BloomFilter self-typing | Java | -31% | -34% |
| SQLAlchemy compiler kwargs | Python | -24% | -29% |
| BloomFilter 패키지 이름 변경 | Java | -11% | -25% |
| QuartzNET 반환 타입 | C# | -25% | -20% |
| AssertJ 인자 순서 변경 | Java | -18% | -15% |
| TanStack mutation context | TypeScript | -21% | -6% |

같은 질문 하나를 처리하는 데 올라간 토큰이 grep 방식 6,472개, 그래프 조회 700개였습니다. 약 9분의 1입니다. 앞의 618줄 사례에 대입하면 grep 방식이 470턴 동안 만든 재청구가 약 270만 토큰인 데 비해, 그래프 조회는 약 33만 토큰이었습니다.
가장 큰 절감 사례는 기준선 중앙값 14.29달러가 9.38달러로 내려간 것입니다. 반대편 끝은 TanStack 과제의 6%입니다. Sonar 자신이 조건을 밝혔습니다. 절감은 "코드를 찾고 이해하는 일이 실제 작업일 때" 나타납니다. 널리 구현된 추상을 손보는 리팩터링처럼 텍스트 검색이 대상 위치를 깔끔하게 열거하지 못하는 과제에서 특히 큽니다. 파일 두세 개만 건드리면 되는 작업에서는 그래프를 연결해도 별 차이가 없습니다.
지금 쓸 수 있나
SemSitter는 단독 제품이 아니라 Sonar Vortex 안에 들어 있습니다. Sonar Vortex는 2026년 6월 30일 정식 출시(GA)됐습니다. 기존 베타 제품이던 Sonar Context Augmentation과 SonarQube Agentic Analysis를 합친 제품입니다. 유료 기업 요금제 전용이라는 점이 이 도구의 가장 큰 진입 장벽입니다.
| 항목 | 조건 |
|---|---|
| 필요 요금제 | SonarQube Cloud의 Team(연간 결제) 또는 Enterprise |
| 추가 구매 | Sonar Agent Essentials 별도 구독. 가격 미공개, 영업 문의 |
| 무료 티어 | 50k LOC까지 무료이지만 Vortex는 포함되지 않습니다 |
| Team 요금제 | 10만 LOC 기준 월 34달러부터, 14일 무료 체험 |
| 한국 사용 가능 여부 | 지역 차단은 없습니다. 다만 리전 선택지가 EU와 US 두 곳뿐이라 아시아 리전이 없습니다 |
| 필요 조건 | Docker Desktop·Podman·Nerdctl 중 하나 실행, SonarQube CLI 1.3.0 이상, 대상 프로젝트가 main 같은 장기 브랜치에서 사전 분석 완료 |
| 지원 에이전트 | Claude Code, Cursor, GitHub Copilot, Windsurf, Google Gemini CLI, OpenAI Codex CLI, 그 밖의 MCP 호환 에이전트 |
| 시맨틱 탐색 지원 언어 | Java, C#, JavaScript, TypeScript, Python, Rust |
Claude Code에 연결하는 절차는 문서에 공개돼 있습니다. /plugin으로 SonarQube 플러그인을 설치한 뒤 프로젝트 폴더에서 /sonarqube:sonar-integrate를 실행하면 됩니다. 그러면 .mcp.json에 MCP 서버가 등록되고 .claude/settings.json에 훅 3종이 생성됩니다. 파일 읽기 시 시크릿 탐지, 프롬프트 제출 시 자격증명 스캔, 편집 시 분석입니다. 다만 컨텍스트 증강은 자동이 아니라 작업마다 /sonar-context-augmentation을 직접 불러야 합니다.
돈을 쓰지 않고 탐색 방식만 바꿔보고 싶다면 오픈소스 쪽에도 같은 발상의 도구가 있습니다. Serena는 언어 서버(LSP)를 이용해 기호 단위로 정의와 참조를 조회하는 MCP 서버입니다. mcpls는 언어 서버 기능을 MCP 도구로 노출하는 범용 브리지입니다. 둘 다 로컬에서 무료로 돌아갑니다. Sonar가 함께 파는 품질·보안 규칙 주입이나 실시간 검증은 없습니다. 겹치는 것은 탐색을 텍스트 검색에서 기호 질의로 바꾸는 부분뿐입니다.
Sonar의 41달러가 자기 팀에도 해당하는 숫자인지는 남의 계측을 믿을 게 아니라 직접 재보는 편이 빠릅니다. 대형 저장소에서 에이전트를 돌리고 있다면, 이번 주 세션 하나의 사용량 로그를 열어 캐시 읽기 토큰과 신규 입력 토큰의 비율부터 확인해 보세요. 그 비율이 Sonar가 본 1,440배 근처라면 그래프 탐색 도구를 도입할 이유가 생긴 것입니다. 두 자릿수에 그친다면 도입해도 절감 폭은 TanStack 과제의 6% 쪽에 가깝습니다.