baseURL 한 줄로 끝내는 LLM 비용 추적과 Spanlens의 핵심 기능

월말에 날아온 OpenAI 청구서의 총액을 보고 당황하는 일은 흔하다. 어느 기능에서 비용이 샜는지, 어떤 모델이 토큰을 과하게 썼는지 알 수 없어 매번 코드에 로그를 남기고 CSV 파일로 내려받아 엑셀에서 합산하며 추정치를 계산해야 했다. Spanlens는 이런 번거로움을 baseURL 한 줄 수정으로 해결한다. baseURL은 프로그램이 AI 서버에 접속하는 주소다. OpenAI, Anthropic, Gemini SDK의 주소를 `https://api.spanlens.io/proxy/openai/v1` 형태로 바꾸면 모든 호출 기록과 비용이 자동으로 추적된다. 요청을 그대로 전달하는 passthrough 방식을 써서 스트리밍이나 tool calling, JSON mode 같은 기존 기능들을 제약 없이 그대로 사용할 수 있다.

비용만큼 골치 아픈 것이 에이전트의 실행 경로를 디버깅하는 일이다. 여러 모델이 섞인 작업 하나가 30초 넘게 걸릴 때, 어느 단계에서 시간이 지체됐는지 로그 파일만으로는 파악하기 어렵다. Spanlens는 LangGraph의 토폴로지 뷰를 통해 이 과정을 시각화한다. 토폴로지 뷰는 AI가 거치는 단계인 노드와 그 연결선인 엣지를 지도로 그려낸 것이다. 개발자는 화면에서 어떤 노드의 지연 시간이 가장 긴지, 어떤 경로를 가장 자주 지나가는지 한눈에 확인하며 실행 흐름을 추적한다.

여기서 더 나아가 지연 시간을 가장 많이 잡아먹은 호출 체인을 찾아내는 Critical Path 분석 기능을 제공한다. 전체 실행 과정 중 가장 병목이 심한 구간을 자동으로 표시해 주기 때문에, 개발자가 수천 줄의 로그를 일일이 대조하며 원인을 찾는 수고를 덜어준다. 시각화된 맵에서 병목 구간을 즉시 확인해 튜닝 시간을 단축하는 방식이다.

프롬프트를 수정했을 때의 효과를 객관적으로 검증하는 통계 도구도 갖췄다. 두 버전의 프롬프트를 두고 비용과 토큰, 지연 시간을 비교하는데, 단순 평균값이 아니라 Welch t-test를 적용한다. 이는 표본의 분산까지 고려해 두 결과의 차이가 우연히 발생한 것인지 아니면 통계적으로 유의미한 변화인지를 판별하는 방법이다. 이 모든 기능은 MIT 라이선스 기반의 오픈소스로 공개되었으며, GitHub에서 코드를 확인하거나 Docker 이미지를 통해 자체 서버에 설치해 운영할 수 있다.

Hono와 ClickHouse로 구현한 고성능 트레이싱 아키텍처

Spanlens는 비용 누수를 방지하기 위해 Hono(경량 웹 프레임워크)를 사용해 프록시 서버를 구축했다. 사용자가 보낸 요청은 여기서 먼저 처리되며, 보안이 중요한 API 키는 AES-256-GCM 암호화 방식으로 복호화한다. 암호화된 키는 호출 직전 메모리에서만 잠시 풀렸다가 사라지므로 외부 유출 위험을 최소화했다. 요청과 응답 사이에 위치한 이 프록시 계층이 모든 데이터의 출입구를 통제하며 비용 추적의 기초 데이터를 수집한다.

기록을 위해 데이터를 분석하는 시간이 추가되면 서비스 응답 속도가 느려질 수 있다. 이를 해결하려고 `body.tee()` 기능을 도입해 들어오는 데이터 흐름을 두 갈래로 쪼갰다. 원본 스트림은 분석 과정을 거치지 않고 사용자에게 즉시 전달하고, 복사본만 백그라운드에서 따로 떼어 파서가 토큰 수와 비용을 계산한다. 데이터 분석이 실제 응답 속도에 영향을 주지 않도록 완전히 분리한 설계다.

방대한 로그 데이터를 효율적으로 쌓기 위해 ClickHouse(대용량 분석용 데이터베이스)를 선택했다. 로그를 비동기로 적재하며, 적재 과정에서 오류가 나면 Supabase(백엔드 서비스 플랫폼)의 폴백 큐에 임시로 보관한다. 이후 cron이 주기적으로 확인해 실패한 로그를 다시 밀어 넣는다. 데이터 유실을 방지해 청구서 금액과 실제 로그가 일치하도록 만들었다.

모델별 가격 정보는 데이터베이스에 저장하고 5분 단위의 TTL(데이터 유효 기간) 캐싱을 적용했다. stale-while-revalidate(낡은 데이터를 먼저 보여주고 백그라운드에서 갱신하는 방식) 기법을 써서 가격 조회 때문에 응답이 지연되는 일을 막았다. 혹시 모를 시스템 장애에 대비해 기본 가격망을 구축한 폴백 시스템도 갖췄다. 전체 시스템은 Next.js 14, Hono, Supabase Postgres, ClickHouse를 기반으로 하며 TypeScript pnpm monorepo 구조로 관리된다. 구체적인 구축 방법은 셀프호스팅 가이드에서 확인할 수 있다.

Spanlens는 baseURL 수정만으로 LLM 비용 추적과 실행 경로 시각화를 가능하게 한다. 개발자는 이제 수천 줄의 로그를 분석하는 대신 시각화된 맵을 통해 병목 구간을 찾아 LLM 성능을 최적화할 수 있다.