본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 06. 14:04

Claude Code를 단 2줄로 커스텀 백엔드로 마이그레이션하기 (그리고 실제로 주의해야 할 점)

요약

Claude Code의 ANTHROPIC_BASE_URL 환경 변수를 활용하여 커스텀 백엔드로 요청을 리다이렉션하는 방법을 소개합니다. 이를 통해 프롬프트 캐싱, 속도 제한 풀링, 멀티 벤더 라우팅, 감사 로깅 및 과금 관리를 구현할 수 있습니다.

핵심 포인트

  • 환경 변수 설정만으로 코드 수정 없이 커스텀 프록시 사용 가능
  • 서버 측 캐시 마커 주입을 통한 비용 60~80% 절감 가능
  • 여러 API 키를 라운드 로빈 방식으로 운영하여 속도 제한 극복
  • 모델별 멀티 벤더 라우팅 및 상세한 사용량 로깅 구현

요약 (TL;DR): Claude Code의 ANTHROPIC_BASE_URL 환경 변수를 사용하면 단 한 줄의 셸 명령어로 모든 요청을 호환 가능한 백엔드로 리다이렉션할 수 있습니다. 거의 아무도 이 방법을 사용하지 않지만, 이를 통해 코드를 전혀 다시 작성하지 않고도 캐싱 (Caching), 속도 제한 풀링 (Rate-limit pooling), 멀티 벤더 라우팅 (Multi-vendor routing), 감사 로깅 (Audit logging) 및 결제 라우팅 (Billing routing)을 구현할 수 있습니다. 여기에는 2줄 설정 방법, 조용히 문제를 일으키는 요소들, 그리고 실제로 운영하기 위한 프로덕션 체크리스트가 포함되어 있습니다.

2줄 설정 방법

export ANTHROPIC_BASE_URL=https://your-proxy.example.com
export ANTHROPIC_API_KEY=your-key
claude

이것이 전부입니다. Claude Code의 기반이 되는 Anthropic SDK는 응답이 Anthropic Messages 형식으로 돌아오기만 한다면 요청을 어디로 보내는지 상관하지 않습니다. SDK는 자동으로 /v1/messages를 붙이고, 모든 anthropic-versionanthropic-beta 헤더를 전달하며, 동일한 방식으로 SSE (Server-Sent Events) 스트리밍을 수행합니다.

동일한 트릭은 Cursor, Cline, Continue 및 Anthropic SDK를 기반으로 구축된 다른 모든 도구에서도 작동합니다.

왜 이렇게 해야 하나요?

저는 커스텀 백엔드를 사용할 가치가 있는 다섯 가지 패턴을 발견했습니다:

1. 캐싱 미들웨어 (Caching middleware)

Anthropic의 프롬프트 캐시 (Prompt cache) 기능은 대부분의 팀이 생략하는 수동 cache_control 마커를 필요로 합니다. 프록시(Proxy)를 사용하면 모든 시스템 메시지에 대해 서버 측에서 이를 주입할 수 있습니다. 2030K 토큰의 시스템 프롬프트와 50회 이상의 대화가 오가는 Claude Code 세션의 경우, 이를 통해 비용을 6080% 절감할 수 있습니다.

2. 속도 제한 풀링 (Rate-limit pooling)

대부분의 팀은 여러 프로젝트에 걸쳐 3~5개의 API 키를 보유하고 있습니다. 프록시가 없다면 각 키는 독립적으로 속도 제한 (Rate-limit)을 받습니다. 즉, 다른 키가 유휴 상태인 동안 특정 키에서 429 오류(Too Many Requests)가 발생할 수 있습니다. 프록시는 키들을 라운드 로빈 (Round-robin) 방식으로 순환시켜, 결합된 속도 제한 예산을 가진 하나의 가상 키를 노출할 수 있습니다.

3. 멀티 벤더 추상화 (Multi-vendor abstraction)

claude-haiku-4-5 호출은 한 제공업체로, claude-opus-4-7 호출은 다른 제공업체로 라우팅하고 싶으신가요 (예를 들어 특정 업체가 Haiku 처리량 할인을 제공하는 경우)? 프록시는 model 필드를 검사하여 그에 따라 라우팅합니다. 여러분의 Claude Code 설정은 변경할 필요가 없습니다.

4. 감사 로깅 (Audit logging)

Claude Code는 매우 많은 요청을 보냅니다. 계측 (Instrumentation) 없이는 각 세션에 비용이 얼마나 들었는지 알 수 없습니다. 프록시 (Proxy)를 사용하면 요청당 메타데이터 (모델, 토큰, 지연 시간 (Latency), 세션 ID)를 데이터 웨어하우스 (Warehouse)에 기록할 수 있습니다.

5. 과금 라우팅 (Billing routing)

팀원마다 서로 다른 비용 센터 (Cost center)를 사용하나요? 프록시는 API 키를 과금 태그 (Billing tags)에 매핑하고 사용량을 재무 부서로 전달할 수 있습니다.

무엇이 고장 나는가 (그리고 주의해야 할 점)

2줄 설정은 이상적인 경로 (Happy path)에서는 잘 작동합니다. 하지만 실제로는 다음과 같은 문제들이 발생합니다.

스트리밍 동작 (Streaming behavior)

Anthropic은 stream: true 설정 시 청크 단위의 SSE (Server-Sent Events)를 반환합니다. 만약 프록시가 응답을 버퍼링 (Buffering)하거나 각 청크를 즉시 플러시 (Flush)하지 않으면, 체감 지연 시간이 엄청나게 길어집니다. 즉, Claude Code가 전체 응답을 기다리느라 계속 회전하게 됩니다.

해결책: 버퍼링 없이 SSE 청크를 그대로 통과(Pass-through)시키세요. Caddy에서는 flush_interval -1을 의미합니다. Cloudflare Workers에서는 각 청크마다 명시적인 .write()를 사용하는 TransformStream을 사용하세요. Node.js에서는 응답 소켓에 noDelay: true를 설정하세요.

헤더 전달 (Header forwarding)

Anthropic의 SDK는 다음과 같은 헤더를 보냅니다:

  • anthropic-version
  • anthropic-beta (프롬프트 캐시 (Prompt cache), 배치 (Batches) 등을 위해)
  • x-api-key (인증 (Auth))
  • x-stainless-* (SDK 텔레메트리 (Telemetry))

만약 프록시가 실제 업스트림 (Upstream)으로 전달하기 전에 이 중 하나라도 제거하면, 특정 기능들이 조용히 고장 납니다:

  • anthropic-version 제거 → SDK가 기대치와 일치하지 않을 수 있는 기본 버전 응답을 받게 됨
  • anthropic-beta 제거 → 프롬프트 캐시 헤더가 무시되어, 왜 캐싱이 작동하지 않는지 의문을 갖게 됨
  • x-stainless-* 제거 → 무해함

경험 법칙 (Rule of thumb): hostauthorization (이들은 재작성해야 하므로)을 제외한 모든 것을 전달하세요.

도구 사용 반복 루프 (Tool use iteration loops)

Claude Code는 도구 호출 (Tool calling)을 매우 빈번하게 사용합니다. 일반적인 세션은 30~50회의 도구 호출 라운드를 거치며, 각 라운드는 전체 대화 기록을 포함한 별도의 API 호출입니다.

만약 프록시가 소스 IP당 분당 60회 (60 RPM)로 속도 제한 (Rate-limited)이 걸려 있다면, 단 하나의 Claude Code 세션이 30초 만에 제한을 다 써버릴 수 있습니다.

해결책: 소스 IP(Source IP)가 아닌 API 키(API key)별로 속도 제한(Rate-limit)을 설정하세요. 그리고 높은 버스트 속도(Heavy tool-call 세션 중 200+ RPM)를 위한 예산을 확보하세요.

요청 본문 검사 (Request body inspection)

cache_control을 주입하거나 요청 본문(Request bodies)을 재작성하려면 JSON을 파싱(Parse)하고, 수정하고, 다시 직렬화(Re-serialize)해야 합니다. 주의할 점은, 대규모 요청(JSON으로 인코딩된 문자열 형태의 50K+ 토큰 컨텍스트)은 파싱하는 데 눈에 띄는 CPU 시간이 소요된다는 것입니다.

Node에서의 최소한의 주입 방식:

const body = JSON.parse(rawBody);

// 첫 번째 시스템 메시지에 cache_control 주입
...

Claude Code의 일반적인 트래픽의 경우, 이는 요청당 5ms 미만의 시간을 추가합니다. 매우 큰 워크로드의 경우, 스트림 파싱(Stream-parsing)을 고려하십시오.

스트리밍 에러 처리 (Streaming error handling)

Anthropic은 무언가 실패했을 때(속도 제한, 콘텐츠 필터 등) 스트림 중간에 error SSE 이벤트를 보냅니다. 대부분의 단순한 프록시(Proxy)는 본문을 불투명한 바이트(Opaque bytes)로 전달하며, 이는 정상적으로 작동합니다. 만약 프록시가 "스마트"하게 동작하려고 SSE를 파싱하려 한다면, 연결을 끊지 않고 에러 이벤트를 처리해야 합니다.

안전한 방법: 반드시 필요한 경우가 아니라면 프록시에서 SSE를 파싱하지 마세요.

최소한의 프로덕션 체크리스트 (A minimal production checklist)

이 프록시를 직접 구축하고 있다면:

  • TLS 종료 (TLS termination) (Let's Encrypt 또는 Cloudflare 프론트)
  • SSE 스트리밍 통과 (Pass-through SSE streaming) (버퍼링 없음)
  • 키별 속도 제한 (Per-key rate limiting) (IP별이 아님)
  • host/authorization을 제외한 모든 헤더 전달
  • JSON 요청 본문 수정을 유연하게 처리
  • 메시지 본문을 저장하지 않고 요청별 메타데이터 로깅 (개인정보 보호)
  • 업스트림(Upstream) 5xx 에러 발생 시 지수 백오프(Exponential backoff)를 적용한 재시도
  • 프록시를 거치지 않는 상태 확인(Health check) 엔드포인트
  • 업스트림 다운 시 우아한 성능 저하 (Graceful degradation) (빠르게 502를 반환하고 대기하지 말 것)
  • 브라우저 클라이언트(TypingMind 등)가 직접 호출하기를 원한다면 CORS 헤더 설정

이것은 더 이상 "2줄"이 아닙니다. 2줄인 부분은 SDK 설정이며, 이 체크리스트가 프로덕션에서 실제로 운영하는 데 드는 비용입니다.

아무도 말하지 않는 부수적 이점

Claude Code 앞에 프록시를 두면, 관측성(Observability)을 공짜로 얻게 됩니다. 다음과 같은 것들을 볼 수 있습니다:

  • 모든 요청 및 토큰 수 (token count)
  • 어떤 세션이 비용이 많이 드는지
  • 어떤 프롬프트가 반복되는지 (캐시 후보)
  • 도구 호출 (Tool-call) 패턴
  • 모델별 지연 시간 (Latency) 분포
  • 시간대별 지출 곡선

Anthropic의 대시보드는 청구 금액을 알려주지만, 여러분의 프록시(Proxy)는 그 '이유'를 알려줍니다. Claude Code를 대규모로 운영하는 팀에게는 이것이 비용 최적화 그 자체보다 더 가치 있는 경우가 많습니다.

이 작업을 하지 말아야 할 때

커스텀 백엔드(Custom backend)를 구축하는 것이 오히려 손해인 몇 가지 경우입니다:

  • 하루에 한 번 claude를 실행하는 단일 개발자 — 직접 API를 사용하는 것으로 충분합니다.
  • 사용 패턴이 단순한 5명 미만의 팀
  • 프록시를 유지 관리할 엔지니어링 대역폭(Bandwidth)이 없는 경우
  • 프록시 체인에서 작동이 중단될 수 있는 Anthropic 전용 베타 기능을 사용하는 경우

손익분기점은 대략 다음과 같습니다:

  • 관리해야 할 API 키가 3개 이상이거나,
  • 월간 Claude 청구 금액이 $500를 초과하거나,
  • 팀 간 사용 분석(Usage analytics)이 필요하거나,
  • 여러 LLM 벤더와 통합해야 하는 경우

이 기준보다 낮다면, 그냥 실제 Anthropic API를 사용하고 엔지니어링 시간을 아끼세요.

직접 구축하고 싶지 않다면

제가 MidRelay를 만든 이유는 바로 이 체크리스트를 제대로 완성하는 데 6주가 걸렸고, 다른 팀들은 이 과정을 반복하지 않기를 바랐기 때문입니다. Anthropic과 OpenAI 인터페이스를 모두 지원하는 호스팅된 프록시이며, 프롬프트 캐시 주입(Prompt cache injection)이 기본적으로 활성화되어 있고, 키별 사용 로그 및 브라우저 클라이언트를 위한 CORS가 활성화되어 있습니다.

Claude Code를 여기에 연결하는 방법은 이 포스트 상단에 있는 2줄 설정법과 같습니다.

하지만 솔직히 말씀드리면: 여기서 설명한 기술들은 MidRelay를 사용하든, 직접 구축하든, 혹은 다른 게이트웨이를 선택하든 상관없이 모두 작동합니다. 흥미로운 점은 Anthropic이 이를 명시적으로 문서화했음에도 불구하고, Claude Code를 커스텀 백엔드로 연결할 수 있다는 사실을 아는 사람이 거의 없다는 것입니다. 만약 이 포스트가 여러분에게 그러한 기능이 존재한다는 사실을 깨닫게 해주는 것만으로도, 충분히 읽을 가치가 있습니다.

비슷한 것을 구축해 보셨다면, 운영 환경(Production)에서 어떤 문제가 발생했는지 댓글로 남겨주세요. 멀티 벤더 LLM 라우팅(Multi-vendor LLM routing)에 관한 후속 포스트를 위해 패턴을 수집하고 있습니다.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0