Google Cloud Vertex AI menjadi pilihan utama enterprise yang sudah berinvestasi dalam ekosistem GCP. Bukan hanya karena Claude tersedia di sana — tapi karena integrasi native-nya: IAM yang sudah terkonfigurasi, billing yang menyatu dengan GCP invoice, keamanan VPC Service Controls, dan kemampuan menghubungkan Claude langsung ke BigQuery, Cloud Storage, Pub/Sub, dan seluruh ekosistem GCP tanpa friction tambahan.
Yang membedakan Vertex AI dari Bedrock atau langsung ke Anthropic API: authentication berbasis Application Default Credentials (ADC) tanpa perlu mengelola API key model, model ID menggunakan format @ yang berbeda, dan ada peluang unik mengintegrasikan Claude langsung dengan layanan GCP seperti BigQuery dan Vertex AI Search.

Setup: Dari Nol hingga Request Pertama
Langkah Wajib Sebelum Mulai
# Step 1: Install dependencies
pip install 'anthropic[vertex]' # SDK dengan Vertex AI support
pip install google-cloud-aiplatform
# Step 2: Enable API di GCP
gcloud services enable aiplatform.googleapis.com
gcloud config set project YOUR-PROJECT-ID
# Step 3: Enable Claude di Model Garden
# Buka: console.cloud.google.com/vertex-ai/model-garden
# Cari 'Claude' → Pilih model → Klik 'Enable'
# Perlu setujui Terms of Service Anthropic
# Step 4: Setup Authentication
# Development (local machine):
gcloud auth application-default login
# Production (Cloud Run/GCE/GKE):
# Credentials otomatis dari Service Account attached ke resource
Untuk production, buat service account dengan permission minimal:
gcloud iam service-accounts create claude-vertex-sa \
--display-name='Claude Vertex AI Service Account'
gcloud projects add-iam-policy-binding YOUR-PROJECT \
--member='serviceAccount:claude-vertex-sa@YOUR-PROJECT.iam.gserviceaccount.com' \
--role='roles/aiplatform.user'
Test Koneksi Pertama
from anthropic import AnthropicVertex
client = AnthropicVertex(
project_id='YOUR-PROJECT-ID',
region='us-east5' # Region utama Claude: us-east5, us-central1, europe-west1
)
msg = client.messages.create(
model='claude-sonnet-4-6@20250514',
max_tokens=50,
messages=[{'role': 'user', 'content': 'Hello! Koneksi berhasil?'}]
)
print(msg.content[0].text)
Model ID Claude di Vertex AI
| Model ID Vertex | Nama | Use Case |
|---|---|---|
claude-haiku-4-5@20251001 |
Haiku 4.5 | Sub-agents, klasifikasi, high-volume |
claude-sonnet-4-6@20250514 |
Sonnet 4.6 | Production default, coding, agents |
claude-opus-4-6@20250514 |
Opus 4.6 | Complex reasoning, enterprise workflows |
Perhatian penting: Vertex AI menggunakan format @ bukan - untuk versi: claude-sonnet-4-6@20250514 bukan claude-sonnet-4-6-20250514. Ini berbeda dari Bedrock dan Anthropic direct API — error yang sering terjadi saat migrasi.
Bab 1 — AnthropicVertex SDK: Hampir Identik dengan Direct API
Ini keunggulan terbesar Vertex AI dibanding alternatif lain: AnthropicVertex SDK menggunakan interface yang hampir identik dengan Anthropic direct API. Dua perbedaan utama: (1) model ID menggunakan format @, dan (2) credentials dari ADC bukan API key. Semua fitur lainnya — tool use, streaming, prompt caching, extended thinking — bekerja dengan cara yang sama persis.
Request Dasar
import os
from anthropic import AnthropicVertex
client = AnthropicVertex(
project_id=os.environ.get('GOOGLE_CLOUD_PROJECT', 'your-project-id'),
region='us-east5'
)
MODEL = 'claude-sonnet-4-6@20250514'
def ask(prompt: str, max_tokens: int = 1024, temperature: float = 0.7) -> str:
"""Kirim single message ke Claude via Vertex AI."""
msg = client.messages.create(
model=MODEL,
max_tokens=max_tokens,
temperature=temperature,
messages=[{'role': 'user', 'content': prompt}]
)
usage = msg.usage
print(f'Tokens: in={usage.input_tokens}, out={usage.output_tokens}')
return msg.content[0].text
def ask_with_system(user_message: str, system: str, temperature: float = 0.5) -> str:
"""Request dengan system prompt."""
msg = client.messages.create(
model=MODEL,
max_tokens=1024,
temperature=temperature,
system=system,
messages=[{'role': 'user', 'content': user_message}]
)
return msg.content[0].text
# Contoh: GCP Architect assistant
result = ask_with_system(
user_message='Bagaimana cara deploy Claude di Cloud Run dengan best practices?',
system='''Kamu adalah Google Cloud Solutions Architect yang ahli AI/ML.
Berikan jawaban teknikal yang konkret dengan pertimbangan cost dan security.
Sertakan gcloud commands jika relevan.'''
)
Streaming Response
def stream_response(prompt: str, system: str = None) -> str:
"""Stream response token per token — ideal untuk user-facing interfaces."""
kwargs = {
'model': MODEL,
'max_tokens': 2048,
'messages': [{'role': 'user', 'content': prompt}]
}
if system:
kwargs['system'] = system
collected = []
with client.messages.stream(**kwargs) as stream:
for text in stream.text_stream:
print(text, end='', flush=True)
collected.append(text)
final = stream.get_final_message()
print(f'\n\nTokens: in={final.usage.input_tokens}, out={final.usage.output_tokens}')
return ''.join(collected)
Multi-Turn Chatbot
Vertex AI tidak menyimpan state percakapan — seluruh history harus dikirim di setiap request:
from dataclasses import dataclass, field
from typing import List
@dataclass
class VertexChatbot:
"""Production chatbot dengan persistent conversation history."""
system_prompt: str
model: str = MODEL
max_tokens: int = 2048
temperature: float = 0.7
max_history_turns: int = 10
history: List[dict] = field(default_factory=list)
total_input_tokens: int = 0
total_output_tokens: int = 0
def chat(self, user_message: str) -> str:
self.history.append({'role': 'user', 'content': user_message})
# Trim history untuk kontrol context window
if len(self.history) > self.max_history_turns * 2:
self.history = self.history[-(self.max_history_turns * 2):]
msg = client.messages.create(
model=self.model,
max_tokens=self.max_tokens,
temperature=self.temperature,
system=self.system_prompt,
messages=self.history
)
response_text = msg.content[0].text
self.history.append({'role': 'assistant', 'content': response_text})
self.total_input_tokens += msg.usage.input_tokens
self.total_output_tokens += msg.usage.output_tokens
return response_text
@property
def estimated_cost_usd(self) -> float:
return (self.total_input_tokens * 3 + self.total_output_tokens * 15) / 1_000_000
# Demo
bot = VertexChatbot(system_prompt='Kamu adalah GCP expert. Jawab teknikal, ringkas, dengan contoh konkret.')
print(bot.chat('Apa perbedaan Cloud Run vs Cloud Functions?'))
print(bot.chat('Kapan sebaiknya saya pilih Cloud Run?')) # Context terjaga
print(f'Estimasi biaya: ${bot.estimated_cost_usd:.4f}')
Bab 2 — Prompt Engineering dan Evaluasi Sistematis
Empat Teknik yang Bekerja Konsisten
Teknik 1 — Clear and Direct: Gunakan kata kerja aksi, tentukan format output secara eksplisit, dan spesifikkan kriteria yang diharapkan. Alih-alih “Analisis data penjualan kami”, gunakan “Analisis data penjualan dan berikan: Top 5 produk berdasarkan revenue (dengan angka), tren bulanan dalam 3 bulan terakhir, dan dua rekomendasi actionable. Format: tabel markdown untuk data, bullet points untuk rekomendasi.”
Teknik 2 — XML Tags untuk Separasi Konteks:
def analyze_with_xml(document: str, criteria: str) -> str:
"""XML tags membantu model membedakan instruksi dari data."""
prompt = f'''Analisis dokumen berdasarkan kriteria yang diberikan.
<document>
{document}
</document>
<criteria>{criteria}</criteria>
<output_format>
## Temuan Utama
## Analisis Detail
## Rekomendasi
</output_format>
Berikan analisis yang spesifik dan berbasis bukti dari dokumen.'''
return ask(prompt)
Teknik 3 — Few-Shot Examples:
def classify_support_ticket(ticket: str) -> dict:
"""Few-shot examples meningkatkan konsistensi output secara signifikan."""
import json
prompt = f'''Klasifikasikan tiket customer support.
<examples>
Input: 'Paket belum tiba setelah 2 minggu, no tracking sudah tidak update'
Output: {{"type": "pengiriman", "priority": "high", "dept": "logistics"}}
Input: 'Cara ubah metode pembayaran default di akun saya?'
Output: {{"type": "akun", "priority": "low", "dept": "support"}}
Input: 'Aplikasi crash saat buka halaman produk, sudah coba reinstall'
Output: {{"type": "teknis", "priority": "high", "dept": "engineering"}}
</examples>
Klasifikasikan tiket berikut:
<ticket>{ticket}</ticket>
Respons HANYA dengan JSON, tanpa penjelasan.'''
return json.loads(ask(prompt, temperature=0.0))
Teknik 4 — Chain-of-Thought: Tambahkan blok <thinking> sebelum <recommendation> untuk masalah yang butuh reasoning multi-langkah. Ini secara empiris meningkatkan akurasi untuk analisis bisnis dan keputusan teknikal yang kompleks.
Pipeline Evaluasi Sistematis
Jangan mulai dengan menulis prompt — mulai dengan mendefinisikan metrik keberhasilan dan membuat test dataset:
from typing import Callable, List
import json
def generate_test_cases(task: str, n: int = 25) -> List[dict]:
"""Claude menghasilkan test cases yang beragam untuk dirinya sendiri."""
prompt = f'''Buat {n} test cases untuk tugas: {task}
Distribusi: 60% kasus normal, 20% edge cases, 20% ambiguous cases.
Format (JSON array valid):
[{{"input": "...", "expected": "...", "difficulty": "easy|medium|hard"}}]
Respond ONLY dengan JSON array.'''
return json.loads(ask(prompt, temperature=0.4))
def evaluate(
prompt_template: str,
test_cases: List[dict],
grader: Callable,
verbose: bool = True
) -> dict:
results = []
for i, case in enumerate(test_cases):
response = ask(prompt_template.format(input=case['input']), temperature=0.0)
passed = grader(response, case['expected'])
results.append({'case': case, 'response': response, 'passed': passed})
if verbose:
print(f"[{i+1}/{len(test_cases)}] {'✅' if passed else '❌'} {case['input'][:40]}...")
accuracy = sum(r['passed'] for r in results) / len(results)
return {'accuracy': accuracy, 'n': len(results), 'results': results}
# Bandingkan dua versi prompt
cases = generate_test_cases('mengklasifikasikan tiket support', n=30)
v1 = 'Klasifikasikan tiket support ini: {input}. Output: JSON dengan type dan priority.'
v2 = '''Kamu adalah support classifier. Klasifikasikan tiket berikut.
Berikan: type (billing/teknis/pengiriman/akun), priority (low/medium/high), dept.
Tiket: {input}
Output JSON: {{"type":..., "priority":..., "dept":...}}'''
r1 = evaluate(v1, cases, json_grader)
r2 = evaluate(v2, cases, json_grader)
print(f'v1: {r1["accuracy"]:.1%} | v2: {r2["accuracy"]:.1%}')
print(f'Improvement: {(r2["accuracy"]-r1["accuracy"])*100:.1f} percentage points')
Bab 3 — Tool Use dengan Integrasi GCP Native
Ini yang membuat Vertex AI benar-benar unik: Claude bisa langsung mengakses BigQuery, Cloud Storage, dan layanan GCP lainnya menggunakan service account yang sama — tanpa perlu manage API key tambahan.
Mendefinisikan GCP-Native Tools
GCP_TOOLS = [
{
'name': 'query_bigquery',
'description': '''Jalankan SQL query di BigQuery dan kembalikan hasil.
Gunakan untuk analisis data, business intelligence, dan reporting.
Selalu gunakan query yang efisien dengan LIMIT yang tepat.''',
'input_schema': {
'type': 'object',
'properties': {
'sql': {'type': 'string', 'description': 'SQL query yang valid untuk BigQuery'},
'limit': {'type': 'integer', 'description': 'Maksimum baris. Default: 100', 'default': 100}
},
'required': ['sql']
}
},
{
'name': 'read_gcs_file',
'description': 'Baca konten file dari Google Cloud Storage bucket.',
'input_schema': {
'type': 'object',
'properties': {
'bucket': {'type': 'string', 'description': 'Nama GCS bucket'},
'path': {'type': 'string', 'description': 'Path file dalam bucket'}
},
'required': ['bucket', 'path']
}
}
]
Implementasi dengan BigQuery dan GCS
from google.cloud import bigquery, storage
import json
bq_client = bigquery.Client()
gcs_client = storage.Client()
def query_bigquery(sql: str, limit: int = 100) -> str:
"""Jalankan BigQuery SQL dan kembalikan hasil sebagai JSON."""
query = f'{sql} LIMIT {limit}' if 'LIMIT' not in sql.upper() else sql
try:
df = bq_client.query(query).to_dataframe()
return df.to_json(orient='records', force_ascii=False)
except Exception as e:
return json.dumps({'error': str(e)})
def read_gcs_file(bucket: str, path: str) -> str:
"""Baca file dari GCS."""
try:
blob = gcs_client.bucket(bucket).blob(path)
content = blob.download_as_text()
return content[:10000] # Limit 10K chars
except Exception as e:
return json.dumps({'error': str(e)})
TOOL_REGISTRY = {
'query_bigquery': query_bigquery,
'read_gcs_file': read_gcs_file
}
Agentic Loop untuk Data Analysis
def gcp_analyst_agent(user_query: str, max_iter: int = 8) -> str:
"""Agent yang bisa query BigQuery dan baca GCS untuk menjawab pertanyaan data."""
messages = [{'role': 'user', 'content': user_query}]
system = '''Kamu adalah GCP Data Analyst.
Gunakan tools yang tersedia untuk mendapatkan data dari BigQuery dan GCS.
Analisis data secara mendalam dan berikan insight bisnis yang actionable.
Selalu verifikasi data sebelum membuat kesimpulan.'''
for iteration in range(max_iter):
msg = client.messages.create(
model=MODEL,
max_tokens=4096,
system=system,
messages=messages,
tools=GCP_TOOLS
)
messages.append({'role': 'assistant', 'content': msg.content})
# Model selesai
if msg.stop_reason == 'end_turn':
for block in msg.content:
if hasattr(block, 'text'):
return block.text
# Model mau pakai tools
elif msg.stop_reason == 'tool_use':
tool_results = []
for block in msg.content:
if block.type == 'tool_use':
print(f'[Iter {iteration+1}] Calling: {block.name}({block.input})')
try:
result = TOOL_REGISTRY[block.name](**block.input)
except Exception as e:
result = json.dumps({'error': str(e)})
tool_results.append({
'type': 'tool_result',
'tool_use_id': block.id,
'content': result
})
messages.append({'role': 'user', 'content': tool_results})
else:
break
return 'Max iterations reached'
# Contoh penggunaan
result = gcp_analyst_agent(
'Analisis penjualan produk bulan lalu dari BigQuery. '
'Tampilkan top 5 produk dan tren mingguannya.'
)
print(result)
Batch Classification: Satu Request untuk N Items
def batch_classify(items: list, categories: list) -> list:
"""Klasifikasikan beberapa item dalam satu request — lebih hemat dari N calls."""
classify_tool = {
'name': 'classify_item',
'description': f'Klasifikasikan item ke salah satu: {categories}',
'input_schema': {
'type': 'object',
'properties': {
'item_id': {'type': 'integer'},
'classification': {'type': 'string', 'enum': categories},
'confidence': {'type': 'number', 'minimum': 0, 'maximum': 1}
},
'required': ['item_id', 'classification', 'confidence']
}
}
items_text = '\n'.join(f'{i}. {item}' for i, item in enumerate(items, 1))
prompt = f'Klasifikasikan setiap item ke {categories}:\n{items_text}'
msg = client.messages.create(
model=MODEL,
max_tokens=2048,
temperature=0.0,
tools=[classify_tool],
messages=[{'role': 'user', 'content': prompt}]
)
return [b.input for b in msg.content if b.type == 'tool_use']
Bab 4 — RAG Pipeline dengan Vertex AI
Embeddings dengan Vertex AI text-embedding-005
import numpy as np
import vertexai
from vertexai.language_models import TextEmbeddingModel
from typing import List
vertexai.init(project='YOUR-PROJECT-ID', location='us-central1')
embed_model = TextEmbeddingModel.from_pretrained('text-embedding-005')
def get_embedding(text: str) -> list:
"""Generate embedding menggunakan Vertex AI text-embedding-005."""
embeddings = embed_model.get_embeddings([text])
return embeddings[0].values
def get_batch_embeddings(texts: list, batch_size: int = 250) -> list:
"""Batch embedding — Vertex AI support hingga 250 items per call."""
all_embeddings = []
for i in range(0, len(texts), batch_size):
batch = texts[i:i+batch_size]
embs = embed_model.get_embeddings(batch)
all_embeddings.extend([e.values for e in embs])
return all_embeddings
def cosine_similarity(v1: list, v2: list) -> float:
a, b = np.array(v1), np.array(v2)
return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b) + 1e-10))
Hybrid Search: BM25 + Semantic
Pure semantic search tidak baik untuk query spesifik seperti nama produk atau kode error. Hybrid search menggabungkan BM25 (keyword matching) dengan semantic search:
import re
from rank_bm25 import BM25Okapi
class HybridSearch:
def __init__(self, chunks: List[str], alpha: float = 0.6):
"""alpha=0.6: lebih berat ke semantic; alpha=0.0: pure BM25"""
self.chunks, self.alpha = chunks, alpha
self.bm25 = BM25Okapi([re.findall(r'\w+', c.lower()) for c in chunks])
print(f'Building {len(chunks)} embeddings...')
self.embeddings = get_batch_embeddings(chunks)
def search(self, query: str, k: int = 5) -> List[dict]:
tokens = re.findall(r'\w+', query.lower())
bm25_s = self.bm25.get_scores(tokens)
q_emb = get_embedding(query)
sem_s = [cosine_similarity(q_emb, e) for e in self.embeddings]
def norm(arr):
mn, mx = min(arr), max(arr)
return [(x - mn) / (mx - mn + 1e-8) for x in arr]
combined = [(1 - self.alpha) * b + self.alpha * s
for b, s in zip(norm(bm25_s), norm(sem_s))]
top = sorted(range(len(combined)), key=lambda i: combined[i], reverse=True)[:k]
return [{'text': self.chunks[i], 'score': combined[i]} for i in top]
def rag_answer(question: str, search: HybridSearch, k: int = 4) -> str:
chunks = search.search(question, k=k)
context = '\n\n---\n\n'.join(c['text'] for c in chunks)
prompt = f'''Jawab pertanyaan HANYA dari konteks. Jika tidak ada, katakan demikian.
<context>
{context}
</context>
Pertanyaan: {question}'''
return ask_with_system(prompt, 'Kamu adalah asisten berbasis dokumen yang akurat.')
Contextual Retrieval: Tingkatkan Akurasi +20-40%
Teknik ini menambahkan konteks dokumen ke setiap chunk sebelum di-embed — secara signifikan meningkatkan retrieval accuracy:
def contextualize_chunk(chunk: str, doc_summary: str) -> str:
"""Tambahkan konteks dokumen ke chunk."""
prompt = f'''Dokumen ini berisi: {doc_summary}
Berikan konteks singkat (2-3 kalimat) yang menjelaskan bagaimana chunk ini
berhubungan dengan dokumen secara keseluruhan. Fokus pada informasi yang
membantu retrieval, bukan ringkasan ulang.
<chunk>{chunk}</chunk>
Respond hanya dengan teks konteks, tanpa penjelasan tambahan.'''
return ask(prompt, temperature=0.0) + '\n\n' + chunk
def build_contextual_index(documents: dict) -> HybridSearch:
"""Build RAG index dengan contextual enrichment per chunk."""
all_chunks = []
for name, text in documents.items():
summary = ask(f'Ringkas dokumen {name} dalam 2 kalimat: {text[:2000]}')
for chunk in paragraph_chunk(text):
enriched = contextualize_chunk(chunk, f'{name}: {summary}')
all_chunks.append(enriched)
return HybridSearch(all_chunks)
BigQuery RAG: Natural Language ke Data Analysis
def bigquery_rag(question: str, table: str) -> str:
"""Gabungkan BigQuery data dengan Claude untuk data Q&A."""
# 1. Generate SQL dari pertanyaan natural language
sql = ask(f'Buat SQL BigQuery untuk: {question}. Tabel: {table}. Output SQL saja.')
# 2. Eksekusi query
data = query_bigquery(sql)
# 3. Claude analisis hasilnya
analysis_prompt = f'''Analisis data berikut dan jawab: {question}
Data (JSON): {data}
Berikan insight yang konkret dan actionable.'''
return ask(analysis_prompt)
Bab 5 — Fitur Lanjutan: Prompt Caching dan Extended Thinking
Prompt Caching: Kurangi Biaya hingga 90%
Prompt caching menyimpan bagian prompt yang tidak berubah — seperti system prompt panjang atau dokumen referensi — sehingga tidak perlu diproses ulang di setiap request:
def cached_analysis_session(document: str, questions: list) -> list:
"""Analisis dokumen yang sama dengan beberapa pertanyaan — hemat biaya."""
answers = []
for question in questions:
msg = client.messages.create(
model=MODEL,
max_tokens=1024,
system=[{
'type': 'text',
'text': f'''Kamu adalah analis dokumen yang teliti.
Dokumen referensi:
{document}
Jawab semua pertanyaan berdasarkan dokumen di atas. Kutip bagian relevan.''',
'cache_control': {'type': 'ephemeral'} # ← Cache system prompt + dokumen
}],
messages=[{'role': 'user', 'content': question}]
)
# Log untuk verifikasi cache hit
usage = msg.usage
cache_read = getattr(usage, 'cache_read_input_tokens', 0)
cache_write = getattr(usage, 'cache_creation_input_tokens', 0)
print(f'Q: {question[:50]}... | Cache read: {cache_read}, write: {cache_write}')
answers.append(msg.content[0].text)
return answers
# Request pertama: cache MISS (write cache)
# Request berikutnya dengan dokumen yang sama: cache HIT (bayar 10%)
long_doc = "... dokumen panjang ..."
questions = [
'Apa kesimpulan utama dokumen ini?',
'Apa rekomendasi konkretnya?',
'Siapa stakeholder yang terdampak?'
]
answers = cached_analysis_session(long_doc, questions)
Extended Thinking: Reasoning Mendalam
def deep_analysis(problem: str, budget_tokens: int = 10000) -> dict:
"""Analisis kompleks dengan extended thinking."""
msg = client.messages.create(
model=MODEL,
max_tokens=budget_tokens + 4000,
thinking={
'type': 'enabled',
'budget_tokens': budget_tokens
},
messages=[{'role': 'user', 'content': problem}]
)
thinking_text = ''
answer_text = ''
for block in msg.content:
if block.type == 'thinking':
thinking_text = block.thinking
elif block.type == 'text':
answer_text = block.text
return {
'thinking': thinking_text,
'answer': answer_text,
'tokens_used': {'input': msg.usage.input_tokens, 'output': msg.usage.output_tokens}
}
# Cocok untuk:
# - Analisis arsitektur sistem yang kompleks
# - Keputusan strategis bisnis
# - Debugging masalah teknikal yang sulit
# - Review keamanan yang mendalam
result = deep_analysis(
'Evaluasi arsitektur microservices kami dan identifikasi risiko scalability...',
budget_tokens=15000
)
print(result['answer'])
Bedrock vs Vertex AI: Pilih yang Tepat
| Kriteria | AWS Bedrock | Google Cloud Vertex AI |
|---|---|---|
| Authentication | AWS IAM + credentials | GCP ADC + service accounts |
| SDK Interface | boto3 (berbeda dari Anthropic) | AnthropicVertex (identik dengan direct API) |
| Model ID format | anthropic.claude-sonnet-4-6-20250514-v1:0 |
claude-sonnet-4-6@20250514 |
| Native data services | S3, DynamoDB, RDS | BigQuery, GCS, Pub/Sub |
| Compliance | FedRAMP, HIPAA (us-east-1) | FedRAMP High, HIPAA, ISO 27001 |
| Billing | Terpisah dari AWS services | Menyatu dengan GCP invoice |
| Pilih jika | Infrastruktur utama di AWS | Infrastruktur utama di GCP |
Kalau tim sudah menggunakan AWS secara ekstensif, pilih Bedrock. Kalau tim sudah menggunakan BigQuery, Google Kubernetes Engine, atau layanan GCP lainnya, Vertex AI memberikan integrasi yang jauh lebih mulus dan billing yang lebih sederhana.
IAM Best Practices untuk Production
Prinsip least privilege: jangan gunakan credentials dengan permission lebih dari yang dibutuhkan. Untuk production deployment:
# Gunakan IAM Conditions untuk membatasi akses ke model tertentu
# Policy IAM yang disarankan:
policy_document = {
"bindings": [
{
"role": "roles/aiplatform.user",
"members": ["serviceAccount:claude-vertex-sa@PROJECT.iam.gserviceaccount.com"],
"condition": {
"title": "Only Claude models",
"expression": "resource.name.startsWith('projects/PROJECT/locations/us-east5/publishers/anthropic')"
}
}
]
}
# Di Cloud Run: gunakan --service-account flag
# gcloud run deploy my-service --service-account=claude-vertex-sa@PROJECT.iam.gserviceaccount.com
Untuk monitoring cost dan usage, gunakan Cloud Logging dan Cloud Monitoring untuk track token usage per service account:
import logging
from google.cloud import logging as cloud_logging
cloud_logger = cloud_logging.Client()
def log_claude_usage(model: str, input_tokens: int, output_tokens: int, latency_ms: float):
logger = cloud_logger.logger('claude-vertex-usage')
logger.log_struct({
'model': model,
'input_tokens': input_tokens,
'output_tokens': output_tokens,
'latency_ms': latency_ms,
'estimated_cost_usd': (input_tokens * 3 + output_tokens * 15) / 1_000_000
})
Pertanyaan yang Sering Ditanyakan
Apa bedanya Claude di Vertex AI vs langsung ke Anthropic API? Di Vertex AI, tidak perlu mengelola Anthropic API key — authentication menggunakan GCP IAM dan ADC. Billing menyatu dengan GCP invoice, ada compliance certifications seperti FedRAMP High, dan Claude bisa langsung mengakses layanan GCP seperti BigQuery menggunakan service account yang sama. Untuk project yang sudah menggunakan GCP, ini jauh lebih praktis.
Mengapa model ID Vertex AI menggunakan @ bukan -? Ini memang format yang berbeda yang GCP gunakan untuk versioning model. claude-sonnet-4-6@20250514 adalah format Vertex AI, sementara claude-sonnet-4-6-20250514 adalah format Bedrock, dan claude-sonnet-4-6-20250514 di direct API menggunakan format lain. Ini adalah sumber kesalahan yang paling umum saat migrasi — selalu cek dokumentasi model garden untuk format yang tepat.
Apakah AnthropicVertex SDK kompatibel dengan kode yang sudah ada untuk direct Anthropic API? Hampir sepenuhnya. Perbedaannya hanya di cara inisialisasi client (menggunakan AnthropicVertex dengan project_id dan region) dan format model ID. Semua fitur — tool use, streaming, prompt caching, extended thinking — menggunakan interface yang identik.
Bagaimana cara memverifikasi prompt caching bekerja di Vertex AI? Lihat field cache_read_input_tokens dan cache_creation_input_tokens di msg.usage. Jika cache_read_input_tokens > 0, berarti cache hit terjadi dan kamu membayar hanya 10% dari biaya input normal untuk bagian tersebut. Di request pertama, kamu akan melihat cache_creation_input_tokens > 0 yang menandakan cache sedang ditulis.
Apa region terbaik untuk deploy Claude di Vertex AI? us-east5 adalah region utama Claude di Vertex AI dengan model paling lengkap dan latency terendah untuk kebanyakan use case. Untuk data residency di Eropa, gunakan europe-west1. Untuk high availability, gunakan global endpoint (claude-sonnet-4-6 tanpa versi) yang secara otomatis melakukan routing ke region yang tersedia.
Bagaimana cara mengintegrasikan Claude dengan BigQuery tanpa expose data ke luar GCP? Ini justru keunggulan Vertex AI — BigQuery dan Claude keduanya berjalan di dalam GCP, dengan IAM yang sama. Gunakan VPC Service Controls untuk memastikan traffic tidak keluar dari perimeter GCP, dan gunakan Private Service Connect untuk endpoint Vertex AI yang private. Data BigQuery tidak perlu di-export ke mana pun.
Lanjutkan Perjalanan Belajar Claude Anda
Artikel ini adalah bagian dari seri Belajar Claude Gratis — panduan berbahasa Indonesia yang membahas ekosistem Claude untuk berbagai profil pembaca.
Kembali ke peta besar: Belajar Claude Gratis: Panduan Lengkap dari Nol hingga Mahir
Artikel cluster lainnya:
- Claude Code 01: Panduan Lengkap untuk Developer Indonesia
- Claude Code 02: Panduan Pemula untuk Semua Profesi
- Claude 03 Cowork: Panduan Lengkap Otomasi Pekerjaan untuk Profesional
- Claude 04-AI Fluency: Cara Menggunakan Claude AI dengan Benar, Efektif, dan Etis
- Claude 05 API: Panduan Lengkap Membangun Aplikasi AI dengan Python untuk Developer
- Claude 06, Mengenal Model Context Protocol (MCP): Cara Menghubungkan Claude ke Tools dan Data Eksternal
- Claude 7, AI Fluency untuk Pendidik: Panduan Lengkap Menggunakan Claude AI dalam Pengajaran dan Kurikulum
- Claude 08, AI Fluency untuk Mahasiswa: Panduan Lengkap Claude untuk Belajar, Menulis, dan Persiapan Karier
- Claude 09, MCP Advanced Topics: Panduan Teknis Sampling, Notifications, Roots, dan Transport untuk Developer
- Claude 10 Amazon Bedrock: Panduan Lengkap dari Setup hingga Production AI System
- Claude 11 dengan Google Cloud Vertex AI: Panduan Lengkap untuk Developer Indonesia
- Claude 12 Teaching AI Fluency: Panduan Lengkap Mengajarkan dan Menilai Kemampuan AI di Kelas
- Caude 13, AI Fluency untuk Organisasi Nonprofit: Panduan Praktis Menggunakan Claude AI untuk Dampak Misi yang Lebih Besa
- Claude 14 Agent Skills: Panduan Lengkap Membangun dan Mendistribusikan Skills Reusable
- Claude 15, Subagents Claude Code: Panduan Lengkap Mendelegasikan Task dan Mengelola Context Window
- Claude 16, AI Capabilities & Limitations: Model Mental Lengkap untuk Berkolaborasi dengan Claude Secara Cerdas
- Claude 17 Code: Panduan Lengkap Developer Indonesia — Dari Instalasi hingga CI/CD Otomatis
- Claude 18, Belajar Claude API: Panduan Lengkap Membangun Aplikasi AI dengan Python, Dari Hello World hingga Productio
- Claude 19: Cara Pakai Claude dari Nol untuk Semua Profesi — Panduan AI Fluency Lengkap
- Claude 20 untuk Pekerjaan dan Tim: Panduan Lengkap Implementasi Claude di Organisasi Anda
