Google Cloud Vertex AI で Harper AI エージェントを実行する — 変更は 3 ファイルのみ

Dev.to / 2026/4/15

💬 オピニオンDeveloper Stack & InfrastructureTools & Practical Usage

要点

  • この記事では、Anthropic の直接 API ではなく Vertex AI 経由で Claude 呼び出しをルーティングすることで、同じ Harper の会話型 AI エージェントを Google Cloud 上で実行する方法を説明します。
  • Google Cloud 組織向けの運用上の利点として、請求の一元化、統一された IAM/監査ログ、設定可能なデータの保管場所(データレジデンシ)、クォータ制御、そして Anthropic API キー管理の回避が取り上げられています。
  • 著者は、Anthropic と Vertex の SDK が同じ `messages.create()` インターフェースを共有しているため、エージェントの中核ロジックを書き換える必要はなく、必要な変更は 3 ファイルだけだと報告しています。
  • 実際の手順としては、既存の Anthropic SDK に加えて Vertex SDK(`@anthropic-ai/vertex-sdk`)をインストールし、クライアントの初期化/設定(例:`lib/config.js`)を Vertex 認証とエンドポイントを使用するように更新します。
  • まとめとして、基盤となるモデルの品質や機能は同じままで、違いは主に API アクセスの「入口(フロントドア)」が Vertex か(直接の Anthropic か)である点だと結論づけています。

パート1では、Harper上で会話型AIエージェントを構築しました — セマンティックキャッシュ、ベクターメモリ、ローカル埋め込み、Web検索、チャットUIをすべて1つのプロセス内にまとめました。ClaudeにはAnthropicのダイレクトAPI経由で話しかけていました。

これは、個人開発者やスタートアップにはとてもよく機能します。ですが、組織がGoogle Cloudで運用しているなら、ClaudeはVertex AI経由にしたくなるはずです。請求も同じ、IAMも同じ、そしてGCPプロジェクト内の他のものと同じ監査ログが使えます。

朗報です。エージェントのロジックを作り直すことなく、ファイル変更3回で済みました。

なぜVertex AIなのか?

すでにGCP上にいるなら、Vertex経由でClaudeを動かすことで:

  • 請求の統合 — Claudeのコストが、Compute Engine、BigQuery、Cloud Storageと同じ請求書に表示されます
  • IAMと組織ポリシー — 既に管理しているのと同じロールと権限で、誰がClaudeを呼び出せるかを制御できます
  • データの保管場所(データレジデンシ) — データをどこに置く必要があるかに応じて、リージョナル、マルチリージョン、またはグローバルのエンドポイントを選べます
  • APIキー管理不要 — AnthropicのAPIキーを渡し回るのではなく、GCPのサービスアカウントで認証します
  • クォータ制御 — GCPのクォータシステムを使って、プロジェクト単位・モデル単位でトークン上限を設定できます

ベースとなるモデルは同一です。Claudeも同じで、機能も同じで、応答品質も同じです。違いは入口(フロントドア)だけです。

変更したこと

Anthropic SDKとVertex SDKは、同じmessages.create()インターフェースを共有しています。違いは、クライアントを初期化する方法だけです。

1. Vertex SDKをインストールする

npm install @anthropic-ai/vertex-sdk

新しい依存関係が1つ増えるだけです。@anthropic-ai/sdkと並べて配置されるので、環境変数でプロバイダーを切り替えられるまま両方をインストールした状態にできます。

2. 設定を更新する(lib/config.js

変更前 — Anthropicのみ:

export const config = {
  anthropic: {
    apiKey: () => required('ANTHROPIC_API_KEY'),
    model: () => optional('CLAUDE_MODEL', 'claude-sonnet-4-5-20250929'),
  },
}

変更後 — プロバイダー対応:

export const config = {
  provider: () => optional('LLM_PROVIDER', 'anthropic'),
  anthropic: {
    apiKey: () => required('ANTHROPIC_API_KEY'),
    model: () => optional('CLAUDE_MODEL', 'claude-sonnet-4-5-20250929'),
  },
  vertex: {
    projectId: () => required('VERTEX_PROJECT_ID'),
    region: () => optional('VERTEX_REGION', 'global'),
    model: () => optional('VERTEX_MODEL', 'claude-sonnet-4-6'),
  },
}

LLM_PROVIDERは、エージェントがどの経路を取るかを制御します。デフォルトはanthropicなので、既存のデプロイが壊れません。

3. エージェントを更新する(resources/Agent.js

クライアントの初期化は、1行の記述から条件分岐に変わります:

import Anthropic from '@anthropic-ai/sdk'
import { AnthropicVertex } from '@anthropic-ai/vertex-sdk'
let _client
const getClient = () => {
  if (_client) return _client
  if (config.provider() === 'vertex') {
    _client = new AnthropicVertex({
      projectId: config.vertex.projectId(),
      region: config.vertex.region(),
    })
  } else {
    _client = new Anthropic({ apiKey: config.anthropic.apiKey() })
  }
  return _client
}

後続の呼び出し — getClient().messages.create(...) — はまったく同じままです。Vertex SDK は Anthropic SDK と API互換です。同じ messages、同じ tools、同じ system、同じ max_tokens。リファクタリング不要です。

唯一の機能上の違い:Anthropic のサーバーサイド Web 検索ツールは、デフォルトでは Vertex では利用できません(GCP 組織ポリシーの変更が必要なため)ので、スキップします:

const tools = isVertex() ? [] : [WEB_SEARCH_TOOL]

let apiResponse = await getClient().messages.create({
  model: getModel(),
  max_tokens: 1024,
  ...(tools.length && { tools }),
  system: SYSTEM_PROMPT,
  messages,
})

以上です。意味キャッシュ(semantic cache)、ベクトルコンテキスト(vector context)、ローカル埋め込み(local embeddings)、コスト計測(cost tracking)、チャットUI — すべてそのまま、変更なしです。

GCPセットアップ(5分)

まだ GCP プロジェクトがない場合は、console.cloud.google.com で作成してください。次に:

1. Vertex AI API を有効化:

https://console.developers.google.com/apis/api/aiplatform.googleapis.com/overview?project=YOUR_PROJECT_ID

2. Model Garden で Claude を有効化:

Vertex AI Model Garden に移動し、「Claude」を検索します。有効化したいモデル(例:Claude Sonnet 4.6)を選んで有効化してください。ここで Anthropic の利用規約に同意します。

3. クォータの申請:

新しいプロジェクトは、パートナーモデルで tokens/min が 0 から始まります。IAM & Admin → Quotas に移動し、Claude のモデルでフィルタして、増加を申請してください。テストなら 100K tokens/min でも十分です。

4. サービスアカウントを作成:

IAM → Service Accounts → Create を開きます。Vertex AI User のロールを付与してください。JSON キーをダウンロードします。

5. .env を設定:

LLM_PROVIDER=vertex
VERTEX_PROJECT_ID=my-gcp-project
VERTEX_REGION=us-east5
GOOGLE_APPLICATION_CREDENTIALS=./my-service-account-key.json

6. エージェントを起動:

npm run dev

http://localhost:9926/Chat を開いてチャットを開始します。エージェントは現在、あなたの GCP プロジェクト経由で Claude を実行しています。

元に戻す

Anthropic の直接 API に戻したいですか? 1 行だけ変更してください:

LLM_PROVIDER=anthropic

再起動してください。完了です。Web 検索が自動的に復帰します。

変わらなかったこと

ここが強調する価値のある部分です。Vertex AI への切り替えでは、次の変更はゼロでした:

  • 意味キャッシュ(semantic cache) — Harper の HNSW ベクトル検索は、LLM レスポンスがどこから来たか気にしません
  • ローカル埋め込み(local embeddings)bge-small-en-v1.5 は、LLM プロバイダに関わらずプロセス内で動作します
  • スキーマ — 同じ 3 つのテーブル、同じベクトルインデックス、同じ TTL
  • チャット UI — 同じ HTML、同じ WebSocket なしのポーリング、同じサイドバーの統計情報
  • コスト計測 — トークン数は、両方の SDK から同じ形式で返ってきます
  • デプロイharperdb deploy . は同じやり方で動きます

Harper が LLM 呼び出しより下のすべてを処理します。LLM 呼び出し自体は、バックエンドが 2 つあるだけの単一の関数です。バックエンドの入れ替えは書き換えではなく、設定変更です。

全体像

.env: LLM_PROVIDER=vertex
         │
         ▼
┌─────────────────────────┐
│      resources/Agent.js │
│                         │
│  getClient() ─────────► AnthropicVertex (GCP 認証情報)
│  getModel()  ─────────► claude-sonnet-4-6
│                         │
│  その他すべて:        │
│  same cache, same       │
│  embeddings, same       │
│  vector search, same    │
│  cost tracking          │
└────────┬────────────────┘
         │
         ▼
┌─────────────────────────┐
│         Harper          │
│  DB + ベクトル + キャッシュ +  │
│  API + 埋め込み       │
│  (変更なし)           │
└─────────────────────────┘

まず試してみる

返却形式: {"translated": "翻訳されたHTML"}

リポジトリはgithub.com/stephengoldberg/agent-example-harperにあります。これをクローンし、プロバイダーを選択して、npm run dev を実行してください。

すでに第1部の内容でエージェントを実行している場合、差分は小さいです:

npm install @anthropic-ai/vertex-sdk
# .env を GCP の設定で更新
npm run dev

変更されたファイルは3つです。エージェントのロジックは一切書き換えていません。Claudeはそのまま、エンタープライズ向けのGCP統合です。