1. はじめに
生成AIを「ブラウザで使うもの」から「自分のツールに組み込むもの」へ変える唯一の入口が API です。
ExcelのシートにAIの回答を書き戻す、Accessのレコードを要約する、Pythonのバッチで数千件のテキストを分類する——こうした自動化は、いずれも「アプリケーションからAIサービスへHTTPリクエストを投げ、返ってきたJSONを解釈する」というごく単純な仕組みの上に成り立っています。
一方で、いざ実装しようとすると次のような壁にぶつかります。
- そもそもAPIキーはどこで取るのか
- ChatGPT・Claude・Geminiでリクエストの書き方が微妙に違う
- VBAだと日本語が文字化けする / JSONのパースが面倒
- 社内プロキシを越えられない
- 結局どれを選べばいいのか分からない
本記事では、この4つの論点——APIとは何か / 3大AI APIの違い / 具体的な呼び出し方(VBA・Python両方) / 自分に合うのはどれか——を、実際に動くコードとともに一気に整理します。
注意
本記事の料金・モデル名は 2026年8月10日時点 の公開情報に基づきます。この領域はモデルの世代交代が数ヶ月単位で起こるため、実装前に必ず各社の公式料金ページ・モデル一覧を確認してください(リンクは第10章にまとめています)。
2. この記事の対象者
| 対象 | 具体的なイメージ |
|---|---|
| VBAでAI連携ツールを作りたい人 | Excel VBA / Access VBA の実務経験はあるが、Web APIを叩いた経験がない |
| PythonでAI連携を始めたい人 | Pythonの基本文法は分かるが、LLMのSDKは触ったことがない |
| 3社の使い分けを知りたい人 | 「とりあえずChatGPT」で始めたが、コストや長文処理で行き詰まっている |
| 社内ツールとして展開したい人 | EUCツールにAIを載せたいが、鍵管理・プロキシ・ガバナンスが不安 |
逆に、以下の内容は本記事のスコープ外です。
- ローカルLLM(Ollama等)の構築
- RAG/ベクトルDBの設計
- LangChain等のフレームワーク解説
- ファインチューニング
3. そもそもAPIとは何なのか
3-1. APIの正体は「決められた作法での呼び出し口」
API(Application Programming Interface) とは、あるソフトウェアの機能を、別のプログラムから呼び出すための窓口 です。
VBAエンジニアにとって最も身近なAPIは、実は Excelのオブジェクトモデル です。
Range("A1").Value = "Hello"
このとき私たちは、Excelの内部でセルがどう管理されているかを一切知りません。ただ Range という窓口に、.Value という決められた作法でアクセスしているだけです。これがAPIの本質——内部実装を知らなくても、決められた作法で機能を使える ということです。
同じ発想が、Windows APIにも当てはまります。
Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
こちらは「同じPC内のDLLを呼ぶAPI」です。
3-2. Web APIは「ネットワーク越しのAPI」
AIサービスのAPIは、この延長線上にある Web API です。違いは呼び出し先がローカルのDLLではなく、インターネットの向こう側にあるサーバー だという点だけです。
[あなたのExcel/Python] ──── HTTPリクエスト ────▶ [OpenAI/Anthropic/Googleのサーバー]
◀─── HTTPレスポンス ────
現代のWeb APIはほぼすべて REST(RESTful API) と呼ばれるスタイルで作られています。REST APIのリクエストは、次の4つの要素に分解できます。
| 要素 | 意味 | AI APIでの例 |
|---|---|---|
| メソッド | 何をするか |
POST(データを送って処理させる) |
| URL(エンドポイント) | どこに送るか | https://api.openai.com/v1/chat/completions |
| ヘッダー | 付帯情報・認証 | Authorization: Bearer sk-... |
| ボディ | 送るデータ本体 | プロンプトを含むJSON |
3-3. JSON — データの共通言語
AI APIとのやり取りは、送りも受けも JSON(JavaScript Object Notation) で行われます。JSONは「キーと値の入れ子構造」を表現するテキスト形式です。
{
"model": "gpt-5.6-terra",
"messages": [
{ "role": "user", "content": "こんにちは" }
],
"temperature": 0.7
}
VBAエンジニアにとっては、Dictionary と Collection が入れ子になったもの と理解すると腑に落ちます。
-
{ }→Dictionary(キーで引く) -
[ ]→Collection/ 配列(順番で引く)
Pythonなら dict と list にそのまま対応します。
そして返ってくるJSONも同じ構造です。たとえばOpenAIのレスポンスはこうなっています。
{
"id": "chatcmpl-xxxx",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "こんにちは!" },
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 9, "completion_tokens": 6, "total_tokens": 15 }
}
欲しい回答文は choices[0].message.content という深い階層にあります。「どの階層を掘れば本文が取れるか」が3社で異なる——これが実装上、最初につまずくポイントです。
3-4. 認証 — APIキーという「鍵」
Web APIは誰でも叩けてしまうと課金主体が特定できません。そのため APIキー による認証が必須です。
APIキーは各社のコンソールで発行する、sk- などで始まる長い文字列です。これをHTTPヘッダーに載せて送ります。
Authorization: Bearer sk-proj-xxxxxxxxxxxxxxxx ← OpenAI
x-api-key: sk-ant-api03-xxxxxxxxxxxxxxxx ← Anthropic
x-goog-api-key: AIzaSyXXXXXXXXXXXXXXXX ← Google
⚠️ APIキーはパスワードと同格です
ソースコードへの直書き、Excelブックへの埋め込み、GitHubへのコミットは厳禁です。漏洩すると第三者があなたの請求先で課金を発生させられます。管理方法は第6章の共通編で扱います。
3-5. ステータスコード — 成否の判定
レスポンスにはHTTPステータスコードが付きます。実装では必ずこれを確認してください。
| コード | 意味 | AI APIでの典型的な原因 |
|---|---|---|
200 |
成功 | — |
400 |
リクエスト不正 | JSONの構造ミス、必須パラメータ不足 |
401 |
認証エラー | APIキーが誤り/未設定 |
403 |
権限エラー | 地域制限、モデル未許可 |
404 |
不存在 | モデル名やURLの綴り誤り |
429 |
レート超過 | 短時間に投げすぎ/残高不足 |
500 529
|
サーバー側障害 | 一時的。リトライ対象 |
429 と 5xx は 指数バックオフ(1秒→2秒→4秒…と待ち時間を倍にしてリトライ) で対処するのが定石です。
3-6. LLM APIならではの4つの特性
一般的なWeb APIと比べ、生成AIのAPIには次の特徴があります。ツール設計に直結するので押さえておいてください。
① ステートレス(会話を覚えない)
APIは前回のやり取りを一切記憶しません。「文脈のある会話」を実現するには、過去のやり取り全部を毎回送り直す必要があります。
"messages": [
{ "role": "user", "content": "私の名前は山田です" },
{ "role": "assistant", "content": "こんにちは、山田さん" },
{ "role": "user", "content": "私の名前は?" }
]
会話が長くなるほど送信トークンが増え、コストが二次関数的に膨らむ点に注意が必要です。
② トークン課金
課金単位は文字数ではなく トークン(単語や文字を分割した単位)です。料金は「100万トークンあたり◯ドル」で表示され、入力と出力で単価が違い、出力のほうが数倍高いのが通例です。
日本語は英語よりトークン効率が悪く、おおむね1文字あたり0.7〜1.5トークン 程度を消費します。見積もりの際は「日本語1,000文字 ≒ 1,000トークン前後」と大づかみに考えておくと安全です。
③ レスポンスが遅い
DBクエリが数ミリ秒で返るのに対し、LLM APIは 数秒〜数十秒 かかります。VBAで同期呼び出しすると、その間Excelが固まります。以下の対策が必須です。
-
Application.StatusBarで進捗表示 - タイムアウトを長めに設定(受信は180〜300秒)
- 大量処理はPython側に逃がす、またはバッチAPIを使う
④ 出力が非決定的
同じ入力でも毎回違う文章が返ります。temperature を 0 に近づけると揺らぎは減りますが、完全な再現性は保証されません。
そのため、「AIの出力をそのまま最終成果物にしない」設計が重要です。EUCツールでは、AIの出力は必ず人がレビューできる形(シートに書き出す、差分を見せる等)にしてください。
3-7. VBA / Python から見たWeb API
| VBA | Python | |
|---|---|---|
| HTTP通信 |
MSXML2.XMLHTTP.6.0 / MSXML2.ServerXMLHTTP.6.0
|
requests / 各社SDK |
| JSON生成・解析 | 外部モジュール VBA-JSON(JsonConverter.bas) |
標準ライブラリ json
|
| 文字コード | 内部はUTF-16。UTF-8変換が必須 | 標準でUTF-8 |
| 公式SDK | なし(自力でHTTPを組む) | あり(3社とも提供) |
| 難易度 | 中〜高 | 低 |
Pythonには公式SDKがあり、VBAにはない。 これが両者の最大の差です。VBAでは、UTF-8変換・JSON構築・エラー処理をすべて自前で用意する必要があります。
逆に言えば、その共通部品を一度作ってしまえば、3社どれでも同じ土台で叩けます。本記事の第6章では、まずその共通モジュールから作ります。
4. VBA・Pythonと連携して使用する主なAIのAPI
数あるAIサービスのうち、日本語ドキュメントが十分にあり、法人でも個人でも調達しやすく、VBA/Pythonから安定して呼べるという条件で絞ると、実質的に次の3つが選択肢になります。
4-1. ChatGPT(OpenAI API)
- 提供元:OpenAI
- 代表モデル(2026年8月時点):GPT-5.6 Sol / GPT-5.6 Terra / GPT-5.6 Luna
- 位置づけ:デファクトスタンダード
生成AI APIの事実上の標準です。日本語での解説記事・書籍・サンプルコードの量が圧倒的で、詰まったときに検索で解決できる確率が最も高いのが最大の実務メリットです。
「OpenAI互換」を名乗る他社サービスも多く、一度OpenAI形式でコードを書けば他へ乗り換えやすいという副次効果もあります。Microsoftの Azure OpenAI Service を経由すれば、国内リージョンでのデータ処理や企業向けのガバナンス要件にも対応できます。
4-2. Claude(Anthropic API)
- 提供元:Anthropic
- 代表モデル(2026年8月時点):Claude Fable 5 / Claude Opus 5 / Claude Sonnet 5 / Claude Haiku 4.5
- 位置づけ:長文処理とコード生成に強い実務派
現行の主要モデルはいずれも 100万トークンのコンテキストウィンドウ を備えており、長大な仕様書やコードベースをまるごと投入する用途に向きます。指示追従が厳密で、「この形式で出せ」という指定を守りやすい——つまり出力をプログラムでパースする前提のツールと相性が良いのが特徴です。
Amazon Bedrock / Google Cloud / Microsoft Foundry 経由でも提供されており、既にクラウド調達の枠組みがある組織では稟議を通しやすい点も実務上大きな利点です。
4-3. Gemini(Google Gemini API)
- 提供元:Google
- 代表モデル(2026年8月時点):Gemini 3.1 Pro / Gemini 3.6 Flash / Gemini 3.5 Flash-Lite
- 位置づけ:コスト最優先・マルチモーダル
Google AI Studio に無料枠があり、クレジットカード登録なしで試せる(レート制限あり)のが決定的な強みです。学習・PoC・個人開発の初手として最も敷居が低い選択肢です。
有償プランでも単価が3社中最安クラスで、大量処理のコスト効率に優れます。またテキストだけでなく PDF・画像・音声・動画 をネイティブに扱えるマルチモーダル性能を持ちます。
さらに OpenAI互換エンドポイント を公式に提供しているため、OpenAI向けに書いたコードをURLとモデル名の変更だけで流用できます。
5. ChatGPT・Claude・Gemini の特徴
5-1. API仕様の比較
| 項目 | ChatGPT(OpenAI) | Claude(Anthropic) | Gemini(Google) |
|---|---|---|---|
| 提供元 | OpenAI | Anthropic | |
| エンドポイント | https://api.openai.com/v1/chat/completions |
https://api.anthropic.com/v1/messages |
https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent |
| 認証ヘッダー | Authorization: Bearer {key} |
x-api-key: {key}anthropic-version: 2023-06-01
|
x-goog-api-key: {key} |
| モデル指定 | ボディの model
|
ボディの model
|
URLに埋め込む |
| 会話の表現 |
messages 配列 |
messages 配列 |
contents 配列(parts の入れ子) |
| システム指示 |
messages 内の role:"system"
|
トップレベルの system |
systemInstruction |
max_tokens |
任意 | 必須 | 任意(generationConfig 内) |
| 本文の取得パス | choices[0].message.content |
content[] から type=="text" を抽出 |
candidates[0].content.parts[] から text を抽出 |
| OpenAI互換 | ―(本家) | 一部SDKで対応 | 公式互換エンドポイントあり |
| 公式Python SDK | openai |
anthropic |
google-genai |
| 公式VBA SDK | なし | なし | なし |
5-2. モデル・料金・調達の比較
| 項目 | ChatGPT(OpenAI) | Claude(Anthropic) | Gemini(Google) |
|---|---|---|---|
| 主力モデル | GPT-5.6 Sol / Terra / Luna | Fable 5 / Opus 5 / Sonnet 5 / Haiku 4.5 | 3.1 Pro / 3.6 Flash / 3.5 Flash-Lite |
| コンテキスト | 約105万トークン | 100万トークン(Haiku 4.5は20万) | 約105万トークン |
|
参考単価 (100万トークン/USD) |
Sol $5 / $30Terra $2 / $12Luna $0.20 / $1.20
|
Fable 5 $10 / $50Opus 5 $5 / $25Sonnet 5 $3 / $15Haiku 4.5 $1 / $5
|
3.1 Pro $2 / $123.6 Flash $1.50 / $7.503.5 Flash-Lite $0.30 / $2.50
|
| 無料枠 | なし(最低$5の前払いが必要) | なし | あり(AI Studio、レート制限付き) |
| バッチ割引 | 50%オフ | 50%オフ | 50%オフ |
| プロンプトキャッシュ | あり(入力の約10%) | あり(最大90%減) | あり(最大90%減) |
| 主要クラウド経由 | Azure OpenAI Service | Amazon Bedrock / Google Cloud / Microsoft Foundry | Vertex AI |
| 日本語の情報量 | ◎ 非常に多い | ○ 増加中 | ○ 増加中 |
| マルチモーダル | 画像・音声 | 画像 | 画像・音声・動画・PDF |
※ 単価は
入力 / 出力の順。2026年8月10日時点の公開情報に基づく参考値です。Claude Sonnet 5は2026年8月31日まで$2 / $15の導入価格が適用されており、9月1日以降は標準価格に戻ります。必ず公式ページで最新値を確認してください。
6. 各APIの利用方法(詳細)
6-0. 【共通編】 まず準備するもの
ステップ1:APIキーを取得する
| サービス | 発行場所 | 事前準備 |
|---|---|---|
| OpenAI | platform.openai.com | クレカ登録+最低$5のチャージ |
| Anthropic | platform.claude.com | クレカ登録+クレジット購入 |
| Gemini | aistudio.google.com | Googleアカウントのみ(無料枠あり) |
いずれも表示は発行時の一度きりです。控え忘れたら再発行になります。
ステップ2:APIキーを安全に保管する
最悪の実装(絶対にやらないこと)
' ❌ ソースに直書き。ブックを配ったら全員に鍵が渡る
Const API_KEY As String = "sk-proj-xxxxxxxxxxxx"
推奨:ユーザー環境変数に置く
コマンドプロンプトで一度だけ実行します(PCごと、ユーザーごとの設定になります)。
setx OPENAI_API_KEY "sk-proj-xxxxxxxxxxxx"
setx ANTHROPIC_API_KEY "sk-ant-api03-xxxxxxxxxxxx"
setx GEMINI_API_KEY "AIzaSyXXXXXXXXXXXX"
以降、コードからはこう読み出します。
' VBA
Dim apiKey As String
apiKey = Environ$("OPENAI_API_KEY")
If Len(apiKey) = 0 Then
Err.Raise vbObjectError + 1, , "環境変数 OPENAI_API_KEY が未設定です。"
End If
# Python
import os
api_key = os.environ["OPENAI_API_KEY"]
setxの設定は新しく起動したプロセスから有効になります。設定後はExcelを再起動してください。
社内配布ツールでは、環境変数のほか「ユーザープロファイル配下の設定ファイル(ACL制限付き)」「Windows資格情報マネージャー」「APIゲートウェイに鍵を集約しクライアントには持たせない」といった選択肢があります。組織のセキュリティ規程を必ず確認してください。
ステップ3:VBA用の共通モジュールを用意する
VBA-JSON の導入
-
VBA-JSON から
JsonConverter.basをダウンロード - VBE →「ファイル」→「ファイルのインポート」で追加
- VBE →「ツール」→「参照設定」で Microsoft Scripting Runtime にチェック
VBA-JSONはMITライセンスです。社内配布時のライセンス確認も比較的容易な部類ですが、規程に従って手続きしてください。
共通モジュール modAiHttp
VBAでAI APIを叩くうえで避けて通れないのが UTF-8問題 です。VBAの文字列は内部UTF-16のため、そのまま送ると日本語が壊れます。ADODB.Stream を使って明示的にUTF-8のバイト列へ変換します。
Option Explicit
'==========================================================
' AI API 共通HTTPモジュール
' 参照設定: Microsoft Scripting Runtime
' 要インポート: JsonConverter.bas (VBA-JSON)
'==========================================================
'--- 文字列 → UTF-8バイト列(BOMを除去して返す) ---
Public Function Utf8Bytes(ByVal s As String) As Byte()
Dim st As Object
Set st = CreateObject("ADODB.Stream")
With st
.Type = 2 ' adTypeText
.Charset = "utf-8"
.Open
.WriteText s
.Position = 0
.Type = 1 ' adTypeBinary
.Position = 3 ' UTF-8 BOM(3byte) をスキップ
Utf8Bytes = .Read
.Close
End With
End Function
'--- UTF-8バイト列 → 文字列 ---
Public Function Utf8ToText(ByRef b() As Byte) As String
Dim st As Object
Set st = CreateObject("ADODB.Stream")
With st
.Type = 1 ' adTypeBinary
.Open
.Write b
.Position = 0
.Type = 2 ' adTypeText
.Charset = "utf-8"
Utf8ToText = .ReadText
.Close
End With
End Function
'--- JSONをPOSTしてレスポンス本文を返す ---
Public Function PostJson(ByVal url As String, _
ByVal headers As Object, _
ByVal jsonBody As String) As String
Dim http As Object, k As Variant
Set http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
' 解決 / 接続 / 送信 / 受信(ミリ秒)
' LLMは応答が遅いので受信タイムアウトは長めに
http.setTimeouts 10000, 10000, 30000, 300000
http.Open "POST", url, False
For Each k In headers.Keys
http.setRequestHeader CStr(k), CStr(headers(k))
Next k
http.send Utf8Bytes(jsonBody)
If http.Status < 200 Or http.Status >= 300 Then
Err.Raise vbObjectError + 1000, "PostJson", _
"HTTP " & http.Status & " " & http.statusText & vbCrLf & _
Utf8ToText(http.responseBody)
End If
' responseText ではなく responseBody を明示的にUTF-8デコードする
PostJson = Utf8ToText(http.responseBody)
End Function
'--- 429/5xx をリトライするラッパー(指数バックオフ) ---
Public Function PostJsonWithRetry(ByVal url As String, _
ByVal headers As Object, _
ByVal jsonBody As String, _
Optional ByVal maxRetry As Long = 3) As String
Dim i As Long, waitSec As Double
For i = 0 To maxRetry
On Error Resume Next
PostJsonWithRetry = PostJson(url, headers, jsonBody)
If Err.Number = 0 Then
On Error GoTo 0
Exit Function
End If
Dim msg As String: msg = Err.Description
Err.Clear
On Error GoTo 0
' リトライ対象でなければ即座に投げ直す
If InStr(msg, "HTTP 429") = 0 And InStr(msg, "HTTP 5") = 0 Then
Err.Raise vbObjectError + 1001, "PostJsonWithRetry", msg
End If
If i = maxRetry Then
Err.Raise vbObjectError + 1001, "PostJsonWithRetry", _
"リトライ上限に達しました。" & vbCrLf & msg
End If
waitSec = 2 ^ i ' 1, 2, 4 秒
Application.Wait Now + TimeSerial(0, 0, CLng(waitSec))
Next i
End Function
プロキシ環境について
MSXML2.ServerXMLHTTP.6.0は WinHTTP のプロキシ設定を参照します。IE/Edgeの設定を引き継ぐのはMSXML2.XMLHTTP.6.0のほうです。社内プロキシ配下でServerXMLHTTPが通らない場合は、
①MSXML2.XMLHTTP.6.0に差し替える
②http.setProxy 2, "proxy.example.co.jp:8080"で明示指定する
③ 管理者にnetsh winhttp import proxy source=ieを依頼する
のいずれかを試してください。また、AIサービスのドメインがファイアウォールで許可されているかを先に情シスへ確認しておくと手戻りが減ります。
ステップ4:Python側の準備
# 仮想環境を作ってから入れるのが安全
python -m venv .venv
.venv\Scripts\activate
pip install openai anthropic google-genai
6-1. ChatGPT(OpenAI API)の利用方法
リクエストの形
POST https://api.openai.com/v1/chat/completions
Authorization: Bearer {APIキー}
Content-Type: application/json
{
"model": "gpt-5.6-terra",
"messages": [
{ "role": "system", "content": "あなたは日本語で回答する経理アシスタントです。" },
{ "role": "user", "content": "この摘要から勘定科目を推定してください:ETC利用料" }
],
"temperature": 0.2
}
レスポンスの形
{
"id": "chatcmpl-xxxx",
"model": "gpt-5.6-terra",
"choices": [
{ "index": 0,
"message": { "role": "assistant", "content": "旅費交通費が妥当です。" },
"finish_reason": "stop" }
],
"usage": { "prompt_tokens": 62, "completion_tokens": 12, "total_tokens": 74 }
}
本文は choices[0].message.content です。3社の中で最も浅く、パースが容易です。
Python(公式SDK)
import os
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
resp = client.chat.completions.create(
model="gpt-5.6-terra",
messages=[
{"role": "system", "content": "あなたは日本語で回答する経理アシスタントです。"},
{"role": "user", "content": "この摘要から勘定科目を推定してください:ETC利用料"},
],
temperature=0.2,
)
print(resp.choices[0].message.content)
print(f"消費トークン: {resp.usage.total_tokens}")
Python(SDKを使わず requests で)
SDKを社内に入れられない環境では、requests だけでも書けます。
import os, requests
resp = requests.post(
"https://api.openai.com/v1/chat/completions",
headers={
"Authorization": f"Bearer {os.environ['OPENAI_API_KEY']}",
"Content-Type": "application/json",
},
json={
"model": "gpt-5.6-terra",
"messages": [{"role": "user", "content": "こんにちは"}],
},
timeout=120,
)
resp.raise_for_status()
print(resp.json()["choices"][0]["message"]["content"])
VBA
Option Explicit
Public Function AskChatGPT(ByVal userPrompt As String, _
Optional ByVal systemPrompt As String = "") As String
Dim body As New Dictionary
Dim msgs As New Collection
Dim headers As New Dictionary
Dim m As Dictionary
body.Add "model", "gpt-5.6-terra"
body.Add "temperature", 0.2
If Len(systemPrompt) > 0 Then
Set m = New Dictionary
m.Add "role", "system"
m.Add "content", systemPrompt
msgs.Add m
End If
Set m = New Dictionary
m.Add "role", "user"
m.Add "content", userPrompt
msgs.Add m
body.Add "messages", msgs
headers.Add "Content-Type", "application/json"
headers.Add "Authorization", "Bearer " & Environ$("OPENAI_API_KEY")
Dim res As String, j As Object
res = PostJsonWithRetry("https://api.openai.com/v1/chat/completions", _
headers, JsonConverter.ConvertToJson(body))
Set j = JsonConverter.ParseJson(res)
' JsonConverter の Collection は 1 始まり
AskChatGPT = j("choices")(1)("message")("content")
End Function
'--- 動作確認 ---
Sub TestChatGPT()
Debug.Print AskChatGPT("ETC利用料の勘定科目を一言で。", "簡潔に日本語で答えてください。")
End Sub
実務での注意点
-
Responses API について:OpenAIは新しい
/v1/responsesを推し進めており、Assistants APIは2026年8月頃のサンセットが案内されています。ただし Responses API はレスポンスがoutput配列に推論ブロック等を含む構造で、VBAから素で組むとパースが煩雑です。VBAからは当面 Chat Completions が扱いやすい選択肢です。 - モデルの使い分け:分類・整形・要約といった軽量タスクにまで上位モデルを使うのはコストの無駄です。Luna等の下位モデルへルーティングするだけで請求額が桁で変わります。
- 無料枠がない:クレカ登録と最低$5の入金が必要です。「まず無料で試したい」ならGeminiが適します。
6-2. Claude(Anthropic API)の利用方法
リクエストの形
POST https://api.anthropic.com/v1/messages
x-api-key: {APIキー}
anthropic-version: 2023-06-01
content-type: application/json
{
"model": "claude-sonnet-5",
"max_tokens": 1024,
"system": "あなたは日本語で回答する経理アシスタントです。",
"messages": [
{ "role": "user", "content": "この摘要から勘定科目を推定してください:ETC利用料" }
]
}
3つのハマりどころがあります。
-
max_tokensが必須。省略すると400エラーになります。 -
anthropic-versionヘッダーが必須。値は2023-06-01で固定です。 -
システム指示は
messagesの中ではなくトップレベルのsystem。OpenAI形式の癖でrole:"system"を入れるとエラーになります。
レスポンスの形
{
"id": "msg_xxxx",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-5",
"content": [
{ "type": "text", "text": "旅費交通費が妥当です。" }
],
"stop_reason": "end_turn",
"usage": { "input_tokens": 58, "output_tokens": 11 }
}
content は配列です。しかも思考機能が有効なモデルでは type が "thinking" のブロックが先頭に混ざることがあります。content[0].text を決め打ちすると将来壊れるので、必ず type == "text" のブロックを走査して連結してください。
Python(公式SDK)
import os
import anthropic
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
msg = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
system="あなたは日本語で回答する経理アシスタントです。",
messages=[
{"role": "user", "content": "この摘要から勘定科目を推定してください:ETC利用料"},
],
)
# textブロックだけを拾う
text = "".join(b.text for b in msg.content if b.type == "text")
print(text)
print(f"入力 {msg.usage.input_tokens} / 出力 {msg.usage.output_tokens} トークン")
VBA
Option Explicit
Public Function AskClaude(ByVal userPrompt As String, _
Optional ByVal systemPrompt As String = "") As String
Dim body As New Dictionary
Dim msgs As New Collection
Dim headers As New Dictionary
Dim m As New Dictionary
body.Add "model", "claude-sonnet-5"
body.Add "max_tokens", 1024 ' ★必須
If Len(systemPrompt) > 0 Then body.Add "system", systemPrompt
m.Add "role", "user"
m.Add "content", userPrompt
msgs.Add m
body.Add "messages", msgs
headers.Add "content-type", "application/json"
headers.Add "x-api-key", Environ$("ANTHROPIC_API_KEY")
headers.Add "anthropic-version", "2023-06-01" ' ★必須
Dim res As String, j As Object, blk As Variant, sb As String
res = PostJsonWithRetry("https://api.anthropic.com/v1/messages", _
headers, JsonConverter.ConvertToJson(body))
Set j = JsonConverter.ParseJson(res)
' content は配列。thinkingブロックが混ざる可能性があるため type で判定する
For Each blk In j("content")
If blk("type") = "text" Then sb = sb & blk("text")
Next blk
AskClaude = sb
End Function
'--- 動作確認 ---
Sub TestClaude()
Debug.Print AskClaude("ETC利用料の勘定科目を一言で。", "簡潔に日本語で答えてください。")
End Sub
実務での注意点
-
max_tokensは「上限」であって「目標」ではありません。小さすぎると文章が途中で切れます。切れたかどうかはstop_reasonが"max_tokens"かで判定できます。 - 長文投入に強い:100万トークンのコンテキストを活かし、規程集や仕様書をまるごと投入する使い方が現実的です。ただし当然ながら入力トークン分の料金がかかるため、繰り返し同じ文書を送るならプロンプトキャッシュの利用を検討してください。
- クラウド経由の選択肢:Amazon Bedrock / Google Cloud / Microsoft Foundry でも提供されています。組織の調達ルール上「AWSの請求に寄せたい」といった要求があるなら有力な選択肢です。ただしエンドポイントと認証方式が変わるため、VBAから直接叩く場合は署名処理の要否を先に確認してください。
6-3. Gemini(Google Gemini API)の利用方法
リクエストの形
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-3.6-flash:generateContent
x-goog-api-key: {APIキー}
Content-Type: application/json
モデル名がURLに埋め込まれるのが3社で唯一の特徴です。モデルを切り替えるコードを書くときはURL組み立てが必要になります。
{
"systemInstruction": {
"parts": [{ "text": "あなたは日本語で回答する経理アシスタントです。" }]
},
"contents": [
{
"role": "user",
"parts": [{ "text": "この摘要から勘定科目を推定してください:ETC利用料" }]
}
],
"generationConfig": { "temperature": 0.2, "maxOutputTokens": 1024 }
}
contents → parts → text という入れ子が一段深い点に注意してください。
APIキーは
?key=...のようにクエリ文字列でも渡せますが、URLはアクセスログやプロキシログに残ります。必ずx-goog-api-keyヘッダーを使ってください。
レスポンスの形
{
"candidates": [
{
"content": {
"role": "model",
"parts": [{ "text": "旅費交通費が妥当です。" }]
},
"finishReason": "STOP"
}
],
"usageMetadata": {
"promptTokenCount": 55,
"candidatesTokenCount": 10,
"totalTokenCount": 65
}
}
本文は candidates[0].content.parts[] の中です。parts も配列で、思考過程を返すモデルでは "thought": true が付いたパートが混ざることがあります。Claudeと同じく走査して除外するのが安全です。
Python(公式SDK)
import os
from google import genai
from google.genai import types
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
resp = client.models.generate_content(
model="gemini-3.6-flash",
contents="この摘要から勘定科目を推定してください:ETC利用料",
config=types.GenerateContentConfig(
system_instruction="あなたは日本語で回答する経理アシスタントです。",
temperature=0.2,
max_output_tokens=1024,
),
)
print(resp.text)
print(f"消費トークン: {resp.usage_metadata.total_token_count}")
⚠️ パッケージ名に注意
旧SDKgoogle-generativeai(import google.generativeai as genai)は非推奨で、2025年11月30日にサポート終了済みです。現行はgoogle-genai(from google import genai)です。ネット上には旧SDKのサンプルがまだ大量に残っているため、コピペ前に必ず確認してください。
VBA
Option Explicit
Private Const GEMINI_MODEL As String = "gemini-3.6-flash"
Public Function AskGemini(ByVal userPrompt As String, _
Optional ByVal systemPrompt As String = "") As String
Dim body As New Dictionary
Dim contents As New Collection
Dim c As New Dictionary
Dim parts As New Collection
Dim p As New Dictionary
Dim headers As New Dictionary
' contents
p.Add "text", userPrompt
parts.Add p
c.Add "role", "user"
c.Add "parts", parts
contents.Add c
body.Add "contents", contents
' systemInstruction
If Len(systemPrompt) > 0 Then
Dim si As New Dictionary, siParts As New Collection, sp As New Dictionary
sp.Add "text", systemPrompt
siParts.Add sp
si.Add "parts", siParts
body.Add "systemInstruction", si
End If
' generationConfig
Dim cfg As New Dictionary
cfg.Add "temperature", 0.2
cfg.Add "maxOutputTokens", 1024
body.Add "generationConfig", cfg
headers.Add "Content-Type", "application/json"
headers.Add "x-goog-api-key", Environ$("GEMINI_API_KEY")
Dim url As String, res As String, j As Object, pt As Variant, sb As String
url = "https://generativelanguage.googleapis.com/v1beta/models/" & _
GEMINI_MODEL & ":generateContent"
res = PostJsonWithRetry(url, headers, JsonConverter.ConvertToJson(body))
Set j = JsonConverter.ParseJson(res)
' parts を走査し、thought でない text だけを連結
For Each pt In j("candidates")(1)("content")("parts")
If pt.Exists("text") And Not pt.Exists("thought") Then
sb = sb & pt("text")
End If
Next pt
AskGemini = sb
End Function
'--- 動作確認 ---
Sub TestGemini()
Debug.Print AskGemini("ETC利用料の勘定科目を一言で。", "簡潔に日本語で答えてください。")
End Sub
OpenAI互換エンドポイントという裏道
Geminiは OpenAI互換のエンドポイント を公式に提供しています。
POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions
Authorization: Bearer {GEMINIのAPIキー}
ボディとレスポンスの構造はOpenAIと同一です。つまり 6-1 の AskChatGPT のURLとモデル名を差し替えるだけでGeminiが動きます。
VBAで「複数プロバイダを切り替えたいが、実装は1本にしたい」場合、この互換エンドポイントを使ってOpenAI形式に寄せるのは非常に有効なアプローチです(機能によっては互換モードで使えないものもあるため、必要な機能が対応しているかは公式ドキュメントで確認してください)。
実務での注意点
- 無料枠にはレート制限があります。本番運用や社内展開では有償プランへの切り替えが前提です。
- モデル名がURLにあるため、モデル切り替えUIを作るときは定数化しておくと保守が楽になります。
- マルチモーダル:PDFや画像を直接投げられます。VBAから使う場合はBase64エンコードが必要で、実装は一気に重くなります。この用途はPython側に寄せるのが現実的です。
6-4. 【共通編】VBAから直接叩くか、Python経由にするか
VBAエンジニアが実際に設計する際、最初に決めるべきはここです。
| VBAから直接API | VBA → Python → API | |
|---|---|---|
| 配布のしやすさ | ◎ ブック1つで完結 | △ Python環境 or exe が必要 |
| 実装難易度 | △ UTF-8・JSON・リトライを自作 | ◎ SDKに任せられる |
| 並列処理 | × 逐次のみ | ◎ 並列・非同期が容易 |
| 画像/PDF送信 | × 実質困難 | ◎ 容易 |
| エラー処理・ログ | △ 貧弱 | ◎ 充実 |
| 向いている規模 | 数件〜数十件/回 | 数百件〜/回 |
判断の目安
- 1リクエストずつ、シートのセルに結果を返すだけ → VBA直で十分。ブック1つで配れる利点が勝ちます。
-
数百件をまとめて処理する/画像・PDFを扱う/並列化したい → Python経由。
xlwingsのRunPython(配布時はRunFrozenPython+ PyInstaller)で、VBAをフロントエンド、Pythonをバックエンドにする構成が扱いやすいです。
VBAとPythonの橋渡しには、xlwings のほか、WScript.Shell.Run でexe化したPythonを起動し、CSV/JSONファイルで結果を受け渡す方式もあります。ファイル受け渡し方式は依存が少なく、社内の統制が厳しい環境ではむしろ堅い選択肢です。
7. どのAPIがどんなユーザーに適しているか
ここからは「どれが優れているか」ではなく、「あなたの状況ならどれか」 という観点で整理します。
7-1. ChatGPT(OpenAI API)が適しているユーザー
① API連携そのものが初めての人
3社の中で日本語の情報量が突出しています。エラーメッセージをそのまま検索すれば、ほぼ確実に同じ症状の記事が見つかります。
VBAという「公式SDKが存在しない」環境で開発する以上、詰まったときに自力で調べ切れるかどうかが完走できるかを決めます。学習コストの観点では、OpenAIから入るのが最短ルートです。
レスポンス構造が choices[0].message.content と最も浅いのも、VBAのJSONパースが手作業になることを考えると実務上の利点です。
② Microsoftエコシステムに寄せたい組織
Azure OpenAI Service を経由すれば、同じモデルを Azure の契約・課金・監査の枠内で利用できます。
Excel/Access/Power Automate Desktop を軸にEUCを組んでいる組織にとって、AIだけ別ベンダーの直接契約になるのは稟議上のノイズです。既にAzureテナントがあるなら、リージョン選択・ネットワーク制御・ログ保全を含めて既存のガバナンスに乗せられるメリットは大きいです。
③ 将来の乗り換え余地を残したい人
「OpenAI互換」がAPI仕様の事実上の共通語になっています。OpenAI形式でコードを書いておけば、Geminiの互換エンドポイントをはじめ、多くのサービスへURLとモデル名の差し替えだけで移行できます。
特定ベンダーに縛られたくない場合、まずOpenAI形式で書くのが結果的に最も自由度が高くなります。
④ 適さないケース
- 無料で試したいだけの人(無料枠がなく、最低$5のチャージが必要)
- とにかく単価を下げたい大量処理(下位モデルは安いが、無料枠のあるGeminiには及ばない)
7-2. Claude(Anthropic API)が適しているユーザー
① 長文ドキュメントを丸ごと処理したい人
現行モデルは 100万トークンのコンテキストを持ちます。日本語なら数十万文字規模——社内規程集、システム仕様書、長大な議事録をそのまま投入できる容量です。
「この規程に照らして、この申請は妥当か」「この仕様書の変更点を全部洗い出せ」といった、分割せずに一度で読ませたいタスクで最も力を発揮します。
分割(チャンキング)が不要になると、実装から「どう分割するか」「分割の境界で文脈が切れる問題」という厄介な設計課題が丸ごと消えます。これは開発工数に直結する利点です。
② AIの出力をプログラムでパースするツールを作る人
指示追従が厳密で、「必ずこのJSON形式で返せ」「余計な前置きを書くな」といった指定を守りやすい傾向があります。
EUCツールでは、AIの回答をそのまま人に見せるより、「AIの出力を解析してシートに転記する」 という使い方が主流です。このとき、勝手に「承知しました。以下が結果です:」と前置きを付けられると、パース処理が壊れます。出力フォーマットの安定性は、ツールの堅牢性そのものです。
③ コード生成・コードレビューを支援に使いたい人
コーディング用途での評価が高く、VBAのような情報量の少ない言語でも、長いコードを読ませて破綻しにくいのが実務上ありがたい点です。既存のVBAプロジェクトを丸ごと読ませてリファクタリング案を出させる、といった使い方に向きます。
④ クラウド調達の枠組みで契約したい組織
Amazon Bedrock / Google Cloud / Microsoft Foundry 経由で提供されています。「新規ベンダーとの直接契約は稟議が重いが、既存のAWS/Azure/GCP契約の中でなら通しやすい」——金融機関をはじめとする大企業では、この差が導入可否を分けることがあります。
⑤ 適さないケース
- 無料で試したい人(無料枠なし)
- 単発の短い質問を大量に投げる用途(コンテキストの広さが活きず、単価だけが効いてくる)
7-3. Gemini(Google Gemini API)が適しているユーザー
① まず無料で試したい人・学習者
Google AI Studio に無料枠があり、クレジットカード登録なしで始められます(レート制限あり)。
「API連携を学びたいが、いきなり課金するのは怖い」という段階では、これが決定的な差になります。とりあえず動かしてみて、APIの感覚を掴むフェーズにおいて、3社中最も敷居が低い選択肢です。
VBAからのAPI連携は、UTF-8変換・JSON構築・プロキシと、AI以前の部分で数日溶けることも珍しくありません。その試行錯誤に課金が発生しないのは実質的なメリットです。
② コストが最優先の大量処理
有償プランでも単価が3社中最安クラスです。数万件のテキスト分類、大量ログの要約、定型データの抽出——処理件数が多く、1件あたりの難易度が低いタスクでは、コスト差がそのまま運用可否を決めます。
バッチAPIの50%割引とコンテキストキャッシュ(最大90%減)を組み合わせれば、さらに下げられます。
③ PDF・画像・音声を扱いたい人
マルチモーダル対応が3社中最も広いです。
- 請求書PDFから明細を抽出
- スキャン帳票の読み取り
- 会議音声の文字起こしと要約
こうしたタスクをテキスト化の前処理なしで直接投げられます。ただし前述のとおり、VBAからバイナリを送るのは実装が重いため、この用途は Python 側で実装するのが現実的です。
④ Google Workspaceを使っている組織
Google Workspace を軸にしている組織なら、Google Apps Script(GAS)との連携を含め、同一エコシステム内で完結させやすい利点があります。
⑤ 適さないケース
- 無料枠のレート制限のまま本番運用しようとする(社内展開には有償化が必須)
-
旧SDKのサンプルをコピペしてしまう(
google-generativeaiは既にサポート終了。google-genaiを使うこと)
7-4. 迷ったときの実践的な選び方
フェーズで使い分けるという考え方が最も現実に即しています。
| フェーズ | 推奨 | 理由 |
|---|---|---|
| 学習・技術検証 | Gemini | 無料枠でノーリスクに試せる |
| PoC・部内試験運用 | OpenAI | 情報量が多く、詰まっても自力で進める |
| 本番・社内展開 | 用途で選択 | 長文=Claude/大量安価=Gemini/統合=Azure OpenAI |
そして設計上の推奨は、最初から特定の1社に固定しないことです。
' プロバイダ差異を1関数に閉じ込めておく
Public Function AskAI(ByVal prompt As String, _
Optional ByVal provider As String = "openai") As String
Select Case LCase$(provider)
Case "openai": AskAI = AskChatGPT(prompt)
Case "claude": AskAI = AskClaude(prompt)
Case "gemini": AskAI = AskGemini(prompt)
Case Else: Err.Raise vbObjectError + 2000, , "未知のプロバイダ: " & provider
End Select
End Function
呼び出し側が AskAI() しか知らない状態にしておけば、プロバイダの乗り換えがこの1関数の修正で済みます。モデルの世代交代が数ヶ月単位で起こるこの分野では、この抽象化が保守コストを大きく左右します。
8. 適したユーザーのまとめ
8-1. ユーザー像 × 推奨API
| こんな人・組織 | 第一候補 | 理由 |
|---|---|---|
| API連携がまったく初めて | ChatGPT | 日本語情報が最多。詰まっても自力で調べ切れる |
| 課金せずに試したい | Gemini | 無料枠あり。カード登録不要 |
| 長文の規程・仕様書を丸ごと読ませたい | Claude | 100万トークン。分割設計が不要になる |
| AIの出力をプログラムでパースする | Claude | 出力フォーマットの指示追従が厳密 |
| 数万件を安く回したい | Gemini | 単価最安クラス+バッチ割引 |
| PDF・画像・音声を扱いたい | Gemini | マルチモーダル対応が最も広い |
| Azure中心の情シス統制下 | ChatGPT(Azure OpenAI) | 既存のAzureガバナンスに乗せられる |
| AWS/GCPの調達枠で契約したい | Claude | Bedrock / Google Cloud 経由で提供 |
| Google Workspace中心 | Gemini | 同一エコシステムで完結 |
| ベンダーロックインを避けたい | ChatGPT形式で実装 | OpenAI互換が事実上の共通語 |
| VBAコードの生成・レビュー支援 | Claude | 長いコードを読ませても破綻しにくい |
| 社内ヘルプデスクの一次回答自動化 | ChatGPT or Gemini | 短い応答が大量。単価と速度で選ぶ |
8-2. 評価軸 × 3社の相対比較
| 評価軸 | ChatGPT | Claude | Gemini |
|---|---|---|---|
| 日本語の情報量・学習しやすさ | ◎ | ○ | ○ |
| 導入の手軽さ(無料枠) | △ | △ | ◎ |
| VBAからのパースのしやすさ | ◎ | ○ | △ |
| 長文コンテキストの活用 | ○ | ◎ | ○ |
| 出力フォーマットの安定性 | ○ | ◎ | ○ |
| コスト効率(大量処理) | ○ | △ | ◎ |
| マルチモーダル対応 | ○ | △ | ◎ |
| 企業ガバナンスとの適合 | ◎(Azure) | ◎(Bedrock等) | ○(Vertex AI) |
| 他社への移行のしやすさ | ◎ | ○ | ◎(互換EP) |
◎=特に優れる ○=十分実用的 △=他に比べると弱い(2026年8月時点の筆者評価)
9. おわりに
本記事では、APIの基礎から3社の具体的な呼び出し方、そして選定の考え方までを一気に見てきました。最後に、実際にツールを作り始める前に押さえておきたい点をまとめます。
技術的なポイント
① 共通モジュールを最初に作る
VBAでは、UTF-8変換・JSON構築・リトライ処理という「AI以前の部分」が最初の壁です。逆に、modAiHttp のような共通モジュールを一度作ってしまえば、3社どれでも同じ土台で叩けます。最初の一日をここに投資してください。
② レスポンスの階層を決め打ちしない
Claudeの content[]、Geminiの parts[] はいずれも配列で、思考ブロックが混ざる可能性があります。[0] 決め打ちは将来のモデル更新で必ず壊れます。type を見て走査してください。
③ プロバイダ差異は1関数に閉じ込める
モデル名も価格も、数ヶ月で変わります。AskAI() のような薄いラッパーを1枚挟んでおくだけで、乗り換えコストが劇的に下がります。
運用上のポイント
④ APIキーはパスワードと同格
ソース直書き・ブック埋め込みは絶対に避けてください。漏洩は「あなたの請求先で第三者が課金する」事態を意味します。
⑤ 機密情報の取り扱いは組織のルールに従う
顧客情報・個人情報・社外秘資料を外部APIへ送信することは、多くの組織で明確な統制対象です。特に金融機関等の規制業種では、技術的に可能かどうかとは無関係に、送信そのものが規程違反になり得ます。
各社ともAPI経由のデータは既定でモデル学習に利用しない方針を掲げていますが、方針は変わり得るものです。導入前に必ず、情シス・コンプライアンス部門と利用範囲を合意してください。
⑥ AIの出力を最終成果物にしない
LLMの出力は非決定的であり、事実誤認(ハルシネーション)も起こります。EUCツールでは、AIの出力は必ず人がレビューできる形で提示し、承認プロセスを経てから確定させる設計にしてください。「AIが出した数字がそのまま帳票に載る」構造は避けるべきです。
⑦ コストの上限を設定する
各社のコンソールで使用上限アラートを設定してください。ループ処理のバグで意図せず数千回リクエストを投げてしまう事故は、実際に起こります。
技術的には、AI APIの呼び出しは「JSONをPOSTして、返ってきたJSONをパースする」だけの、ごく普通のWeb API連携です。特別な魔法はありません。
一方で、VBAという環境の制約と、生成AIという非決定的な部品の性質が組み合わさると、設計上の判断は一気に増えます。本記事がその判断の助けになれば幸いです。
まずは無料枠のあるGeminiで Debug.Print にAIの回答を出すところから始めてみてください。そこから先は、いつものVBAの世界です。
10. 参考リンク
公式ドキュメント
OpenAI
Anthropic(Claude)
- Claude Platform Docs
- Messages API Reference
- Models overview
- Pricing
- Console(APIキー発行)
- Claude in Amazon Bedrock
Google(Gemini)
- Gemini API Documentation
- Gemini Developer API pricing
- Models
- Google AI Studio(APIキー発行)
- OpenAI互換エンドポイント
- Google GenAI SDK への移行ガイド
ライブラリ・ツール
- VBA-JSON(JsonConverter.bas) — VBA用JSONパーサ(MIT License)
- openai-python — OpenAI公式Python SDK
- anthropic-sdk-python — Anthropic公式Python SDK
- google-genai(python-genai) — Google公式Python SDK
- xlwings — ExcelとPythonの連携ライブラリ
VBA側の技術リファレンス
本記事の料金・モデル名は2026年8月10日時点の公開情報に基づく参考値です。最新の情報は必ず各社の公式ページでご確認ください。