Google CloudのClaude 4 Sonnet APIを叩いてみた【GAS】
2025年に入ってからのGeminiの進化がだいぶ良くなってきたということもあって、ずっとGemini APIでの開発をしていましたが、そう言えば以前使ったAnthropicのClaudeはどうなったのだろうか?だいぶ感じが違ってるのかな?とも思い、今回はClaude公式サイトではなく、Google Cloud上のVertex AI APIのModel Gardenで使えるClaude 4 Sonnet APIをGoogle Apps Scriptから叩いてみました。
Opusも公開されていますがとってもお高いので、Sonnetでテストです。
目次
今回利用する素材
- Claude4Sonnet - Google Spreadsheet
- Claude 4 API Reference
以前から、日本語周りの扱いがChatGPTやGeminiより全然良くて個人的には優秀だなぁと思ってるClaude。一時期、Geminiが盛り上がった時に離れてその性能が下がったみたいなことを言われてはいたものの、その後もMCPといった新技術を出してきたりと、なんだかんだ言っても生成AI界隈では、GoogleやOpenAIと違って技術道を進んでる印象です。
Geminiを使っていて、なかなかプロンプトの指示どおり動かない部分も多く、ちょっと疲れてしまったので、再度、Claude 4 Sonnetでどれくらい快適に答えが得られるのか?試してみたいと思います。
以前GASから叩いた時のClaude3 Sonnetのケースでのエントリーは以下の内容を参照してみてください。
Claude 4 Sonnetとは?
特徴
ChatGPTやGeminiを使っていて最近は慣れたとは言え、結構気になる点は多いです。前から気になってる点は日本語に対する扱いが、Geminiはやはり劣ってる。Claudeは以前より日本語に対する処理能力は評価が高く、指示する側からするとプロンプトの投げ方に変な気を使う頻度は少ないのが特徴。
また、Claude CodeやMCPといった新技術の開発でもリードしており、ありがちなベンチマークに偏ってイケイケというよりは、技術に重きを置き質実剛健というスタンスです。似ているようでかなり違いがあるため、特に昨今のChatGPTやGeminiの「思い込み・頑固・猪突猛進」といった行動からすると、安心感があります。Canvasの元になってるArtifactsも元々、Claudeが始めた機能で後追い気味のGoogleやOpenAIとはこういった点で違いが見られます。
プログラミングのコード生成では定評があり、以前よりも出力トークンが圧倒的に増えたことで実用的になりました。
注目はハイブリッド推論。日常な簡単なタスク内容に対しては標準モードで速度重視、数学的な高度な内容は拡張モードでじっくり思考という切り替えを内部的に行ってくれるようです。拡張思考モードの場合、Web検索併用で回答精度の向上も図られており、従来の生成AIの弱点である「リアルタイム性」の確保にチャレンジしています。
故に生成AIを使い倒してる人ほど、GeminiやChatGPTよりもClaudeを選ぶという傾向があるのではないかと思います。海外調べの企業LLM API利用シェア率では32%、コーディングに絞ると42%にもなり断然トップとのこと。支持されてますね。
図:Geminiは情報が古いケースが多い
図:Claudeは正確性や事実に重きを置く
利用料金
今回は価格が比較的に安いClaude 4 Sonnetを使っています。今回のコードでダミーデータ生成で十数回ほど叩いてデータ生成した結果が、50円程度なので100件ほど生成していたらだいたい500円くらいの感じかなと。Geminiと比較するとおおよそ2倍近い価格ではあるのですが、Geminiと比較して日本語に対しての柔軟性等を考えたら「アリ」ではないかと思います。
コスト表は以下の通り。単位MTok = 100万トークンとなっています。以下はAPI利用時の料金になります。こちらがGoogle Cloud上のコスト表になります。Claude 3.5時代からお値段据え置きという形になってるみたいです。
モデル | 入力 | 出力 |
Sonnet | $3 / MTok | $15 / MTok |
ただ、Geminiと大きく異なる点が、1回で扱える入出力のトークン量。
Claudeは最大入力トークンが200,000と昔とあまり変わっていない。出力トークンが64,000とGeminiとほぼ同じ。Geminiの入力トークンが1,000,000と大きいのですが、この差は特に一度に処理させる時に堪える可能性がある。ただ、自分のような開発者の場合には、この入力トークンは十分な量とも言える。
図:そこまで極端に高くはない
Google Cloudで使う利点
Google CloudのモデルガーデンでClaude 4のAPIが使える利点は大きいです。
- 請求書や管理をGoogle Cloudに1本化することが出来る
- GASやGWSからみたら内部であるので、シームレスに運用することが出来る(認証周りは特に)
- Claudeを別途契約してるわけではないので、契約の手間が省けるため内部稟請の障壁が無い
- 従量制であるため月額の固定の費用の支出がない
Gemini API同様に、Google CloudのAPIの1つとして扱える為、他社サービスであるということで起きる様々な問題がクリア出来るというのは大きい。技術的な問題というよりも社内調整上これは本当に楽。シームレスである点も良く、Gemini APIがいまいちというケースに於いて、アプリケーション側でスパっと切り替えて使えるようにロジックを組めば良いだけなので、エンジン挿げ替えも楽ちん
事前準備
APIを有効化する
Claude4を使えるようにする
Google提供のモデルではなく、Google Cloudでパートナーモデルとして提供してるので別途有効化が必要です。有効化手順内に課金と同意についてがあるため、同意するとGoogle Cloud側から請求という形になるので注意が必要です。
Google Workspace利用企業は別途Anthropicと契約する必要も無いのと、Google Cloud上で使えるためGASなどからシームレスで使える為、こちらの手法がオススメ。
- Google Cloud Consleを開き、右上のプロジェクトが課金対象のプロジェクトに変更する
- Modelガーデンを開く
- 検索窓から、Claude Sonnet 4を検索する
- 有効にするをクリック
- 利用目的やウェブサイトなどの情報入力フォームが出るので入力して次に進む。
- 課金に関する同意が出るので、オッケーなら同意する
これで有効化されて使えるようになります。解約というものが無いのですが、これはプロジェクト単位で有効化するだけというもので、料金は、従量制ゆえに月額基本料金等はありません。使った分だけ払うという意味では、Gemini APIと変わらないです。
図:Claude4 Sonnet 4を有効化しておく
図:料金の課金について
GCPのAPIを有効にする
Google Cloud側で今回利用するAPIを有効化する必要性があります。
- Google Cloudを開き、サイドバーからAPIとサービスを開きます。
- 上部にある「APIとサービスの有効化」をクリック
- 検索窓で「vertex」で検索し、Vertex AI APIをクリックします。
- 有効化をクリックします。
図:今回はこのAPIを有効化する
GAS側の準備
Google Cloud側プロジェクトと連結
図:プロジェクト変更画面
appsscript.jsonを書き換える
スクリプトエディタの左サイドバーから「プロジェクト設定」を開き、「appsscript.json」マニフェスト ファイルをエディタで表示するにチェックを入れて、appsscript.jsonを表示する。
その後そのファイルを開き、以下のように記述を行います。必須の作業です。これをしてしまうと、今後メソッドを追加したときに追加の認証は手動で、Scopeを入れてあげないと認証されないので要注意。
"oauthScopes": [ "https://www.googleapis.com/auth/script.external_request", "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/spreadsheets.currentonly" ]
これを入れてあげないと401などのエラーになってしまうので要注意。前述の作業の結果必要となっているものなので、必ず記述を変更しましょう。追加のスコープが必要な場合には、ここに記述の追記が必要となるので要注意。GASでメソッドを追加時に動かない場合は、スコープが足りない結果です。
準備ができたら適当な関数を作って実行し、初回認証は必ず行っておきましょう。
ソースコード
グローバル設定
ここでは、プログラム全体で利用するグローバル変数を定義しています。Project IDは自身のClaude4を利用可能にしてるプロジェクトのIDをCloud Console上で拾ってきます。
Locationは以前はus-east1だったのが現在は無いようで、us-east5がデフォルトのようですのでそのように指定しています。Model_IDはこちらのページに記載されています。現在は、「claude-sonnet-4@20250514」のようなので、その値を入れておきます。
そして、これらを組み合わせたGASからリクエストを送るためのエンドポイントURLを構築しておきます(Claude本家のリクエストエンドポイントとは違うので注意)。当然請求もGoogleから行われます。
//GCPのプロジェクトID const PROJECT_ID = 'ここにGCPのプロジェクトIDを入れる'; //リージョン const LOCATION = 'us-east5'; //ここにリージョン指定を入れる。 //利用するモデルID const MODEL_ID = 'claude-sonnet-4@20250514'; //ここにClaude4のモデルIDを入れる //リクエストエンドポイント const url = `https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/anthropic/models/${MODEL_ID}:streamRawPredict`;
ダミーデータを生成するコード
まずは手始めに、簡単なリクエストから実装してみる。今後の全ての基本となるコードです。プロンプト指示文自体は、Geminiと何ら変わらないスタイルで構築しています。
callClaude4関数がリクエストを実行するメインの関数ですが、Gemini APIを叩くケースとそこまで変わらない。但し、レスポンスの取り出し方は異なるので、そこだけ注意が必要です。ちょっと不思議なのが一度JSON.parseで取り出してるのに、もう一度該当の答えの部分だけ取った後にJSON.parseしないと配列として認識されない点。
そして最終的にスプシに書き出して完了となります。
//ダミーデータを生成する function generateDummyData() { //プロンプトの指定 const prompt = ` あなたは、プログラムの開発者です。開発で利用するダミーデータを生成することが得意です。以下の要件に合う、ダミーデータを生成し、出力形式にそった 配列として出力してください。 #重要事項 - 出力形式に従ったデータだけを返してください。余計な解説や説明は一切不要です。 #生成するデータの件数 10件 #出力するデータの種類 生成してほしいデータは10種類程度の野菜の仕入れと売上のダミーデータです。 #生成するデータの列について - ID : uuid形式のランダムな値(重複なし) - 日付 : yyyy/mm/ddの日付形式で、2025/1/1〜2025/5/31までの日付 - タイプ : 売上もしくは仕入のどちらか - 商品名 : 野菜の名前 - 単価 : 野菜の単価。同じ野菜には同じ単価を割り振ってください - 数量 : 野菜の数量。1〜10までの間でランダムに - 金額 : 単価 * 数量の計算結果 #出力形式 [ ["ID","日付","タイプ","商品名","単価","数量","金額"], ["abcdse-1010101-basfa", "2025/2/1","売上","しいたけ", "100", "5", "500"] ] `; try { //リクエストの実行 const generatedData = callClaude4(prompt); // 結果をログに出力します。[実行ログ]で確認できます。 SpreadsheetApp.getUi().alert('✅ ダミーデータを生成し、シートに出力しました。'); } catch (e) { console.log('エラーが発生しました: ' + e.message); SpreadsheetApp.getUi().alert('❌ エラーが発生しました。\n\n詳細はログを確認してください。'); } } //Claude APIをリクエスト function callClaude4(prompt) { //Apps Scriptの機能でOAuthアクセストークンを取得 const accessToken = ScriptApp.getOAuthToken(); // APIに送信するリクエストボディを定義 const requestBody = { "anthropic_version": "vertex-2023-10-16", "messages": [{ "role": "user", "content": [{ "type": "text", "text": prompt }] }], // --- 修正箇所:以下のパラメータを追加 --- "max_tokens": 8192, // 生成するトークンの最大数 "temperature": 0.8, // 応答のランダム性 (0.0〜1.0) "top_p": 1.0 // Top-Pサンプリング }; //APIリクエストのオプションを設定 const options = { 'method': 'post', 'contentType': 'application/json', 'headers': { 'Authorization': 'Bearer ' + accessToken }, 'payload': JSON.stringify(requestBody), 'muteHttpExceptions': true }; // APIにリクエストを送信 const response = UrlFetchApp.fetch(url, options); //レスポンスを取得する const responseCode = response.getResponseCode(); const responseBody = response.getContentText(); // レスポンスをハンドリング if (responseCode === 200) { //抽出したJSON文字列をパースし、テキストを取得する if (responseBody) { //データをパースする const parsedResponse = JSON.parse(responseBody); // 新しいレスポンス形式に合わせてテキスト部分を取得 let array = parsedResponse.content[0].text; //余計な文字を除外する let body = array.replace("```json",""); body = body.replace("***",""); body = body.replace("```",""); body = body.replace("```javascript",""); body = body.replace("\n",""); //スプレッドシートに書き出す const ss = SpreadsheetApp.getActiveSpreadsheet(); const sheet = ss.getSheetByName("DummyData"); //データをクリアする sheet.getRange("A2:G").clearContent(); //配列の先頭行を削除 body = JSON.parse(body) body.shift(); //データの一括出力 let lastColumn = body[0].length; //カラムの数を取得する let lastRow = body.length; //行の数を取得する sheet.getRange(2,1,lastRow,lastColumn).setValues(body); return true; } else { console.log('レスポンスから "message" イベントが見つかりませんでした。 Response Body: ' + responseBody); return false; } } else { // エラー内容をログに出力して例外をスロー console.log(`API Error: ${responseCode} ${responseBody}`); return false; } }