우리 팀에 GCP 크레딧이 있었다. Claude Code는 Anthropic 키를 원했다.
Source: Dev.to
배경
저는 이미 Google Cloud 청구를 사용하고 있었고, 또 다른 API 키, 또 다른 할당량 항목, 혹은 코딩‑툴 청구가 다른 곳에 표시되는 이유를 팀에 설명해야 하는 또 다른 장소를 원하지 않았습니다.
Claude Code는 Anthropic의 Messages API와 통신하지만, 제가 사용하려던 예산은 Vertex AI에 있었습니다. Claude Code를 Vertex AI에 직접 연결하면 깔끔하게 맞지 않았습니다.
The Mismatch
Claude Code expects
POST /v1/messages
Anthropic headers
Anthropic content blocks
Anthropic streaming semantics
Vertex AI uses different endpoints
-
Claude models on Vertex:
.../publishers/anthropic/models/claude-sonnet-4-6:rawPredict -
Gemini models on Vertex:
.../publishers/google/models/gemini-2.5-pro:generateContent
So a middle layer was needed to accept Claude Code’s Anthropic‑style requests and translate them to the appropriate Vertex AI endpoint.
Solution: CliGate Local Gateway
저는 CliGate를 사용했습니다. 이 로컬 게이트웨이는 이미 Claude Code, Codex CLI, Gemini CLI 및 여러 업스트림 제공자 사이에 위치합니다. 이 설정에서는 Vertex AI가 동일한 라우팅 레이어 안에서 API‑키‑기반의 또 다른 업스트림에 불과합니다.
Vertex AI Key Configuration
Vertex AI 키는 세 개의 필드를 저장합니다:
| Field | Description |
|---|---|
type | vertex-ai |
projectId | Google Cloud 프로젝트 ID |
location | 지역 (예: us-central1) |
apiKey | 전체 Google 서비스‑계정 JSON 블롭 |
Adding the key via the dashboard
http://localhost:8081
Adding the key via API
curl -X POST http://localhost:8081/api/keys \
-H "Content-Type: application/json" \
-d '{
"type": "vertex-ai",
"name": "vertex-work",
"apiKey": "{\"type\":\"service_account\",\"project_id\":\"my-project\", ... }",
"projectId": "my-project",
"location": "us-central1"
}'
Note:
apiKey값은 전체 서비스‑계정 JSON이며, 단순 문자열이 아닙니다.
Environment Variables for Claude Code
export ANTHROPIC_BASE_URL=http://localhost:8081
export ANTHROPIC_API_KEY=any-key
claude를 실행하면 이제 Claude Code가 로컬 게이트웨이를 가리키게 되며, 이는 여전히 Anthropic‑호환 서버처럼 동작합니다.
Source: …
CliGate가 요청을 라우팅하는 방법
Claude Code는 항상 POST /v1/messages에 Anthropic‑스타일 요청을 보냅니다. CliGate는 모델 이름과 선택된 제공자를 검사한 뒤 두 가지 경로 중 하나를 선택합니다:
-
Vertex에서 Claude
Claude Code → /v1/messages → CliGate → Vertex Claude rawPredict -
Vertex에서 Gemini
Claude Code → /v1/messages → CliGate → Anthropic‑to‑Gemini bridge on Vertex
제공자 구현은 모델 패밀리를 다르게 처리합니다:
claude-*모델은 Vertex에서 Anthropic‑스타일 경로를 유지합니다.gemini-*모델은 Vertex의generateContent호출로 변환됩니다.
중요한 구현 세부 사항: 위치
Vertex AI는 모든 모델 패밀리를 동일하게 취급하지 않습니다. CliGate의 제공자 코드에서는:
- Gemini는 Google 퍼블리셔 엔드포인트를 사용합니다.
- Vertex의 Claude 모델은 여전히 Anthropic 퍼블리셔 경로가 필요합니다.
따라서 저장된 구성에는 projectId와 location 두 가지가 모두 포함되어야 합니다. 이 구분이 “다이어그램에서는 작동한다”와 “오후 11시, CLI가 답변하기만 원할 때 작동한다” 사이의 차이를 만들었습니다.
왜 로컬 게이트웨이가 일회성 래퍼보다 나은가
맞춤형 래퍼를 Claude Code + Vertex AI에 적용하면 오늘의 문제는 해결되지만 내일의 혼란을 만들게 된다. 게이트웨이 접근 방식은 이미 다음을 처리하고 있는 기존 컨트롤 플레인을 재사용한다:
- Claude Code
- Codex CLI
- Gemini CLI
- API‑key 라우팅
- 계정 풀
- 사용량 및 가격 보기
따라서 Claude Code를 GCP 크레딧으로 옮기는 것은 이미 사용하고 있던 시스템 안의 또 다른 라우팅 규칙에 불과했다.
Proxy가 설정된 후 워크플로우
- Claude Code가
http://localhost:8081을 가리킵니다. - Vertex AI가 실제 청구 표면을 담당합니다.
- 대시보드에 요청 로그, 사용량 및 제공자 가시성이 표시됩니다.
- 모델이나 제공자는 CLI를 다시 연결하지 않고도 나중에 교체할 수 있습니다.
핵심 요점: 도구는 게이트웨이가 어디인지 알아야 하며, 돈이 어디서 오는지는 알 필요가 없습니다.
Google Cloud 팀을 위한 요약
이미 Google Cloud에서 팀이 운영 중이라면, Claude Code가 독립형 Anthropic 키 대신 Vertex AI를 사용하도록 하는 것은 대부분 프로토콜 변환 문제입니다. 변환이 localhost에 배치되면 나머지 설정은 최소화됩니다.
저장소
저는 현재 다른 사람들이 이 분할을 어떻게 처리하고 있는지 궁금합니다: Claude Code를 직접 Vertex에 연결하고 있나요, 아니면 공급자 전환을 하나의 로컬 게이트웨이 뒤에 숨기고 있나요?