0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GAS × Gemini 2.5 Flash — Vertex AI OAuthを諦めてAPIキーで叩いたら月$0.2で動いた

0
Last updated at Posted at 2026-03-22

Vertex AIのOAuthで半日溶かした

GASからGemini APIを叩きたい。やりたいことはシンプルだった。

スプレッドシートに溜まったFAQの質問文を投げて、回答案を自動生成する。それだけ。なのにVertex AI経由で正攻法を選んだ瞬間、半日が消えた。

Service Accountを作る。JSONキーをダウンロードする。GASにOAuth2ライブラリを追加する。JWTを自前で組み立てる。アクセストークンを取得する。スコープを設定する。

ここまでやって、ようやく「あれ、トークン取れたのにAPIが403返してくる」という地獄にたどり着く。権限の問題だった。IAMロールを確認して、Vertex AI Userを付与して、反映を待って——。

正直、やりたいことに対して道のりが長すぎた。

やりたかったこと

事務局の問い合わせ対応を半自動化したかった。FAQが400件以上ある。定型的な質問(「住所変更したいんですが」「年会費はいくらですか」)は、AIに回答案を出させて人間が確認するだけでいい。

ポイントは「定型FAQ」に絞っていること。専門的な判断が必要な問い合わせは別ルートで処理する前提だった。だから、モデルに求める精度はそこまで高くなくていい。安くて速ければ勝ち。

OAuthの壁、3つ

Vertex AI経由でGeminiを叩こうとすると、こんな壁がある。

1. Service Accountの鍵管理

GASにはファイルシステムがない。JSONキーをどこに置くか。スクリプトプロパティに丸ごと突っ込む? 長すぎて切れる。分割して格納? 正気の沙汰じゃない。

2. JWTの自前生成

OAuth2ライブラリを使えば楽——と思いきや、GASのOAuth2ライブラリはService Account認証のJWT生成にクセがある。Utilities.computeRsaSha256SignatureでJWTに署名する必要があり、PEM形式の秘密鍵をパースする処理を自分で書くことになる。

3. トークンの有効期限管理

アクセストークンは1時間で切れる。リフレッシュの仕組みを入れないと、翌日のトリガー実行で確実にコケる。

どれも解決できなくはない。でも「FAQ回答案を自動生成する」というゴールに対して、認証基盤の構築に工数の8割を使っている。これは設計がおかしい。

APIキーに切り替えたら5分で動いた

Google AI StudioでAPIキーを発行する。GASのスクリプトプロパティに格納する。UrlFetchApp.fetchで叩く。

以上。動いた。

function callGemini(prompt) {
  const API_KEY = PropertiesService.getScriptProperties().getProperty("GEMINI_API_KEY");
  // モデル名は2026年3月時点。最新はGoogle AI Studioで確認
  const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-04-17:generateContent?key=${API_KEY}`;

  const payload = {
    contents: [{
      parts: [{ text: prompt }]
    }]
  };

  const options = {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  };

  const response = UrlFetchApp.fetch(url, options);
  const json = JSON.parse(response.getContentText());
  return json.candidates[0].content.parts[0].text;
}

これをスプレッドシートのカスタム関数として使うなり、トリガーでバッチ処理するなり、好きにすればいい。

エラーハンドリングを足すならこんな感じ。

function callGeminiSafe(prompt) {
  try {
    const response = callGemini(prompt);
    if (\!response) return "回答生成失敗: 空レスポンス";
    return response;
  } catch (e) {
    return `エラー: ${e.message}`;
  }
}

APIキーをスクリプトプロパティに入れておけば、コードに直書きしなくて済む。GASの「プロジェクトの設定」→「スクリプトプロパティ」からGEMINI_API_KEYを登録するだけ。

5件テストの結果

FAQから5件抜き出して投げてみた。

# 質問カテゴリ 回答品質 判定
1 住所変更手続き そのまま使える
2 年会費の金額 正確
3 退会方法 手順が正しい
4 資格更新の条件 おおむね正確(細部要確認)
5 制度の解釈に関する質問 的外れ ×

5件中、定型FAQ(1〜3)は全問正解。条件分岐がある4はやや怪しい。専門的判断が必要な5は完全に外した。

想定通りの結果だった。定型FAQならFlashで十分。

「Flashじゃ無理でしょうね」

テスト結果を上司に見せたとき、5番目の回答を見て一言。

「Flashじゃ無理でしょうね」

これで線引きが決まった。どこまでFlashに任せて、どこから上位モデルに回すか。PoCの価値は「全部うまくいきました」じゃない。「ここまではいける、ここからは無理」という境界線が引けることだ。

棲み分けの結論

結局こうなった。

定型FAQ(住所変更、会費、手続き系)
  → GAS × Gemini 2.5 Flash
  → 月額$0.2以下。自動生成→人間チェック

専門FAQ(制度解釈、例外処理、判断が必要)
  → Claude Projects × Opus 4.6
  → 精度重視。RAGでドキュメント参照

将来のチャットボット化
  → Dify等のプラットフォーム
  → 上記2つの知見を統合

全部を一つのモデルでやろうとすると、オーバースペックかアンダースペックか、どちらかになる。用途で切り分けるのが現実解。

コストの話

Gemini 2.5 Flashの料金(2026年3月時点)。

  • 入力: $0.15 / 1Mトークン
  • 出力: $0.60 / 1Mトークン

FAQの質問文は平均100トークン、回答は平均300トークン程度。月に500件処理しても入力5万トークン+出力15万トークン。合計で$0.1もいかない。

Vertex AI経由でもAPIキー経由でもモデルの料金は同じ。認証方式が違うだけで、叩いているモデルは同一。だったら楽な方を選ぶ。

Vertex AIが必要になるとき

APIキー認証でダメなケースもある。

  • VPC Service ControlsでAPIアクセスを制限したい企業環境
  • リクエストの監査ログをCloud Loggingに統合したい場合
  • モデルのファインチューニングContext Cachingを使いたい場合
  • データの所在地指定(リージョン制御)が必要な場合

個人や小規模チームのPoC段階でこれらが必要になることは、まずない。必要になったら移行すればいい。認証方式を変えるだけで、アプリケーションコードはほぼそのまま使える。

PoCの価値は「成功」じゃない

半日かけてVertex AI OAuthと格闘したのは無駄だったか。そうは思わない。

OAuthの壁にぶつかったから「本当にこの認証方式が必要か?」という問いが生まれた。APIキーに切り替えたから5分で動くことがわかった。テストで5番目が外れたから、モデルの境界線が引けた。上司の一言で棲み分けが決まった。

回り道した分だけ、判断の精度が上がっている。

GASからGemini APIを叩くだけなら、この記事のコードをコピペすれば30秒で終わる。でも「なぜその方式を選んだか」を自分の言葉で説明できるかどうかで、次に別のAPI連携をやるときの判断速度が変わる。

PoCは「動いた」で終わらせない。「どこまで使えて、どこから使えないか」——その線を引くためにやる。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?