GASからClaude APIを叩く最小構成|UrlFetchAppのコードと、月いくらかかるかの計算
GASからClaude APIを叩く最小構成|UrlFetchAppのコードと、月いくらかかるかの計算
スプレッドシートに溜まった問い合わせを自動で仕分けたい。フォームの回答を要約して店長に送りたい。こういう処理は、Google Apps Script(GAS)からClaude APIを直接呼べば数十行で書けます。
ただ、動くコードよりも先に知りたいのは「で、月いくらかかるのか」のはずです。この記事では最小構成のコードと料金の計算方法、そしてそもそもAPIを使うべきかの判断基準までを順に書きます。弊社で本番稼働しているClaude API連携と業務用GASの運用から得た内容です。
最小構成は3つの部品でできている
必要なのは、APIキーの保管場所、UrlFetchAppによるPOST、レスポンスからのテキスト取り出しの3つだけです。これがそのまま動く最小構成です。
function askClaude(prompt) {
var apiKey = PropertiesService.getScriptProperties().getProperty('ANTHROPIC_API_KEY');
var res = UrlFetchApp.fetch('https://api.anthropic.com/v1/messages', {
method: 'post',
contentType: 'application/json',
headers: {
'x-api-key': apiKey,
'anthropic-version': '2023-06-01'
},
payload: JSON.stringify({
model: 'claude-haiku-4-5',
max_tokens: 1024,
messages: [
{ role: 'user', content: prompt }
]
}),
muteHttpExceptions: true
});
var code = res.getResponseCode();
if (code !== 200) {
Logger.log('Claude API error ' + code + ': ' + res.getContentText());
return null;
}
var body = JSON.parse(res.getContentText());
return body.content[0].text;
}
このコードで押さえるべき点は4つです。
**APIキーはスクリプトプロパティに置く。** コードに直書きすると、GASのプロジェクトやスプレッドシートの編集権限を渡した相手に、そのままキーが渡ります。プロジェクトの設定画面からスクリプトプロパティに `ANTHROPIC_API_KEY` として登録し、コードからは取得するだけにします。キーの流出は請求に直結するので、ここは最初から正しくやる価値があります。
**ヘッダーは2つとも必須。** `x-api-key` だけでなく `anthropic-version: 2023-06-01` も必要です。バージョンヘッダーを忘れると400番台で弾かれます。
**`muteHttpExceptions: true` を最初から付ける。** これを付けないと、GASはHTTPエラー時に例外を投げてスクリプトを止めてしまい、しかもAPI側が返してきたエラー本文が読めません。「なぜ落ちたか」を判断する材料がログに残らないという事態を防ぐため、レスポンスコードを自分で見て分岐する形にしておきます。
**`max_tokens` は出力の上限であって、目安ではない。** ここで指定した長さを超えると、応答は文の途中で切れて `stop_reason` が `max_tokens` になります。要約や分類なら1024前後で足りますが、長文を生成させるなら数千単位に引き上げてください。
なお、モデルIDに日付のサフィックスを足すと404になります。`claude-haiku-4-5`、`claude-sonnet-5`、`claude-opus-4-8` はこの文字列のままで完成形です。
月いくらかかるのかを、実際に計算する
Claude APIは従量課金で、入力トークンと出力トークンで単価が違います。100万トークンあたりの単価は次のとおりです。
- Claude Haiku 4.5:入力1ドル/出力5ドル
- Claude Sonnet 5:入力3ドル/出力15ドル
- Claude Opus 4.8:入力5ドル/出力25ドル
1回あたりの費用は「入力トークン数 × 入力単価 + 出力トークン数 × 出力単価」です。仮に入力2,000トークン・出力1,000トークンの処理を1回走らせると、Haiku 4.5なら約0.007ドル、Sonnet 5なら約0.021ドル、Opus 4.8なら約0.035ドルになります。1ドル150円換算で、1回あたり約1円・約3円・約5円です。
これを月間の回数に掛けます。1日10件のフォーム回答を要約するなら月300回。Haiku 4.5なら月300円前後、Opus 4.8でも月1,500円前後で収まります。軽い仕分けや要約であれば、GASからClaude APIを叩くコストは月数百円のオーダーだというのが、最初に掴んでおくべき感覚です。
一方、長文を書かせると桁が変わります。弊社でブログ記事の自動生成を設計したときの試算では、記事1本あたり100〜200円、月8本で1,600〜3,200円という規模になりました。入力に参考資料を大量に積み、出力も数千字になるためです。「AIに任せる処理が短いか長いか」で費用の桁が1つ変わると考えてください。
トークン数を正確に知りたい場合は、目分量で見積もらずにトークンカウント用のエンドポイント(`/v1/messages/count_tokens`)に実際のプロンプトを投げて数えます。他社製AIのトークナイザで概算するとClaudeでは大きくずれます。
費用を削る2つの正攻法
**モデルを処理に合わせる。** 分類・抽出・定型の言い換えはHaiku 4.5で十分です。判断や文章の質が成果を左右する処理だけ上位モデルに回します。弊社でも、生産計画を読ませて判断させるツールは最上位モデル固定、記事の骨子生成は中位モデル、という具合に処理ごとに分けています。
**急がない処理はまとめて投げる。** 即時性が不要なら、Batches APIを使うと同じ内容が半額になります。夜間に一括で走らせる集計や分類はこちらに寄せる価値があります。
プロンプトキャッシュで入力側を10分の1にする
同じ指示文(システムプロンプト)を毎回送るタイプの処理では、プロンプトキャッシュが効きます。キャッシュから読まれた部分は通常の入力単価の約10分の1になり、書き込み時は1.25倍(5分間有効の場合)です。2回目のリクエストから元が取れる計算なので、繰り返し実行する処理では基本的に入れておく設定です。
指定はリクエストのsystem側に `cache_control` を付けるだけです。
payload: JSON.stringify({
model: 'claude-haiku-4-5',
max_tokens: 1024,
system: [
{
type: 'text',
text: LONG_INSTRUCTION,
cache_control: { type: 'ephemeral' }
}
],
messages: [{ role: 'user', content: prompt }]
})
弊社のブログ生成パイプラインも、note向けの記事生成ツールも、システムプロンプト側にこの指定を入れて運用しています。ここで重要なのは、キャッシュが「先頭からの一致」で判定されるという仕様です。プロンプトの前方に1バイトでも変化があると、それ以降は全部キャッシュが無効になります。
つまり、次のような書き方は無意味になります。
- システムプロンプトの冒頭に実行日時や実行IDを埋め込む
- 条件分岐でシステムプロンプトの中身を毎回組み替える
- ユーザー名や店舗名を指示文の先頭に差し込む
これらは「キャッシュを指定したのに一切効かない、しかしエラーは出ない」という状態を作ります。変わらない指示は前に、毎回変わる情報は後ろに置く。これだけ守れば防げます。効いているかどうかはレスポンスの `usage.cache_read_input_tokens` を見れば分かるので、導入したら一度ログに出して確認してください。
なお、キャッシュには最低サイズがあります。Opus 4.8とHaiku 4.5では約4,096トークン以上の共通部分がないと、指定しても静かにキャッシュされません。短い指示文なら、そもそもキャッシュを気にする必要はないということです。
GAS側で先に決めておくこと
APIが動いても、GAS側の作りで詰まることのほうが多いのが実情です。業務用のGASを複数本運用してきた経験から、最初に決めておくと後の手戻りが減る点を挙げます。
**エラーコードごとに挙動を分ける。** 429(レート上限)と500番台・529(過負荷)は時間を置けば成功する種類のエラーなので、待って再実行する価値があります。一方400(リクエストが不正)・401(キーが無効)・404(モデルIDの誤り)は何度投げても通りません。再試行するコードを一律に書くと、通らないリクエストを延々と投げ続けて実行時間を食い潰すことになります。リトライは429と500番台だけ、と最初に決めておくのが正解です。429の場合はレスポンスの `retry-after` ヘッダーに待つべき秒数が入っています。
**APIが使えない状態でも止まらない設計にする。** キーが未設定、キーが失効、API側が一時的に不調。この3つはいつでも起こります。弊社のブログ生成パイプラインでは、ライブラリ未導入・APIキー未設定・API例外・応答JSONの異常・必須項目の欠落という5パターンすべてで、AI生成をあきらめて従来のロジックに自動的に切り替わるようにしてあります。有効なキー・無効なキー・キーなしの3条件で実際に動作確認まで済ませてあり、どの状態でも処理そのものは完走します。GASのトリガーで無人運転させるなら、この「AIが使えなくても業務は止まらない」構造を先に作ってください。
**AI呼び出しは遅い前提で設計する。** 実測でAPIを1回挟むとレイテンシが5〜10秒伸びます。GASには1回の実行時間に上限があるため、スプレッドシートの全行をループでAPIに投げるような書き方は、行数が増えた時点で途中終了します。処理対象を差分だけに絞る、1回のトリガーで処理する件数に上限を設ける、といった設計を最初から入れておくのが安全です。トリガーやデプロイの反映ルールはClaude CodeでGAS開発を回す実務フローにまとめています。
**結果をシートに書き戻すときは型に注意する。** シートは値を自動で型変換するため、AIが返した「1」のような文字列が数値として保存され、後段の厳密比較が通らなくなることがあります。判定に使う値は書き込み時に明示的に文字列化しておけば防げます。
そもそもGASからAPIを叩くべきか
ここは正直に書きます。APIを使うべきなのは、人が関与しないタイミングで処理が自動的に走る必要がある場合だけです。
深夜に走るトリガー、フォーム送信をきっかけにした自動仕分け、LINEからのメッセージに対する自動応答。これらは人が画面の前にいないので、APIで組む以外に方法がありません。
逆に、自分が画面の前にいて実行するだけの作業なら、API課金は不要なことが多いです。弊社では案件ごとの応募文をAIに生成させていますが、これはターミナルからClaude Codeをヘッドレスで呼ぶ形にしてあり、サブスクの枠内で動くのでAPIの従量課金は発生しません。「毎回自分で起動していい作業」に従量課金を払う必要はない、という線引きです。
判断の順番はこうなります。
- その処理は、人が起動しなくても走る必要があるか。ないならAPIは不要
- 走らせる回数は月に何回か。回数 × 1回あたりの単価で月額を出す
- その月額に見合う手作業が消えるか。消えないなら作らない
3番目が一番大事です。月300円のAPI費用で月5時間の手作業が消えるなら圧倒的に得ですが、月10分の作業のために仕組みを作って保守するのは割に合いません。
まとめ
GASからClaude APIを叩く最小構成は、スクリプトプロパティに置いたキー、UrlFetchAppのPOST、レスポンスの取り出しの3点です。ヘッダーは `x-api-key` と `anthropic-version` の2つ、`muteHttpExceptions: true` は最初から付ける。これだけで動きます。
費用は「入力トークン × 単価 + 出力トークン × 単価」で計算できます。短い要約や分類なら月数百円のオーダー、長文生成なら1本100〜200円のオーダー。繰り返し実行するならプロンプトキャッシュで入力側を約10分の1にでき、急がない処理はバッチで半額になります。
そのうえで、無人で走る必要のない処理にAPI課金を選ぶ必要はありません。月額と、消える手作業の量を先に比べてから作る。この順番を守れば、費用も保守の手間も想定内に収まります。
GASにClaudeで書かせるコードの指示の出し方はClaudeにGASを書かせるプロンプトの型、LINEを入力口にしてGAS経由で処理を動かす構成はLINEに送った文章をClaudeに処理させるで扱っています。スプレッドシート業務そのものをGASで減らす話はスプレッドシート業務はGASでここまで減らせるが参考になります。