4
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?

OpenAIのSDKでOpenAIとGeminiの二刀流API使いになる

Last updated at Posted at 2025-12-24

やりたいこと

これまでOpenAIを使っていたのを、Geminiも使えるようにしたい!!!

背景

先日Googleが、Gemini3をリリースしました。

かなりクオリティが上がったと話題になっていますね。
かくいう私も、毎日Gemini3さんとおしゃべりしています。

そのクオリティゆえか、OpenAIのサム・アルトマンCEOは非常事態を宣言したとか。

これまで、自分が作ったツールでは、OpenAIのAPIを使って、
いくつかのモデルから対話相手を選ぶ機能があるのですが、これをGeminiのモデルも選べるようにすることとなりました。

環境

方針

Geminiは、OpenAI SDKから呼べます。(←!?)

以上。

リクエストの形式などはそのままで基本OK!

対応方法

概要

もともとOpenAIに対してリクエストは下記のように行えました。

const client = new OpenAI();

const response = await client.responses.create({
    model: "gpt-5-nano",
    messages: [
        { role: "system", content: "You are a helpful assistant." },
        {
            role: "user",
            content: "Explain to me how AI works",
        },
    ],
});

これを、こう!

const openai = new OpenAI({
    apiKey: "GEMINI_API_KEY",
    baseURL: "https://generativelanguage.googleapis.com/v1beta/openai/"
});

const response = await openai.chat.completions.create({
    model: "gemini-2.0-flash",
    messages: [
        { role: "system", content: "You are a helpful assistant." },
        {
            role: "user",
            content: "Explain to me how AI works",
        },
    ],
});

見ての通り、apiKeyとbaseUrlを指定すれば、GeminiのModelにもchat.completions.createが行えるようになります。

ただし、今回は、VertexAIで発行したサービスアカウントを使ってGeminiAPIを使います。
VertexAIの場合も同様に互換性がありますが、指定する内容が少し違うため注意が必要です。

違いとしては、下記があります。

gemini Vertex AI
api key geminiのAPIキー Google Cloud Authで取得したアクセストークン
base url https://ai.google.dev/gemini-api/docs/openai https://aiplatform.googleapis.com/v1/projects/${projectId}/locations/${location}/endpoints/openapi
model名の指定(例) gemini-2.5-flash google/gemini-2.5-flash(Vertex AIの場合は、google/をつける)
認証 キーがあればOK Google Cloud Auth認証が必要
ドキュメント https://ai.google.dev/gemini-api/docs/openai https://docs.cloud.google.com/vertex-ai/generative-ai/docs/start/openai

Googleの認証

VertexAI経由でGeminiを使う場合は、Google Cloud Auth認証を通す必要があります。
そのためにこれを使います。

npm install google-auth-library

その上で、下記のようにJWTでの認証をしています。

const client = new JWT({
    email: process.env.GCP_OAUTH_CLIENT_EMAIL,
    key: process.env.GCP_OAUTH_PRIVATE_KEY?.replace(/¥n/g, '\n'),
    scopes: ['https://www.googleapis.com/auth/cloud-platform'],
});

const apiKey = (await client.getAccessToken()).token;

下記のようにGoogleAuthで認証をするのが最初に見つかりますが、
これだと、Application Default Credentialsを使って、環境変数からキーを読み込まずに済みます。(環境変数から取得したキーをcredentialsとして渡すのは非推奨になっています。)

const auth = new GoogleAuth({
  scopes: 'https://www.googleapis.com/auth/cloud-platform'
});

今回はAWSにデプロイするため、それだと都合が悪いので、上述のようにJWTで行いました。

実際の処理

あとは、よしなにModelがOpenAIかGeminiかを判定して、apiKeyとbaseUrlを分岐してあげればOK。

//modelを引数にopenAIなのか、geminiなのかを判定する関数
const modelProvider = getProviderFromModel(model); 

let apiKey: string | null | undefined;
let baseUrl: string | undefined;
if (modelProvider === ModelProvider.OpenAI) {
    apiKey = process.env.OPENAI_API_KEY;
} else if (modelProvider === ModelProvider.Gemini) {
    const client = new JWT({
        email: process.env.GCP_OAUTH_CLIENT_EMAIL,
        key: process.env.GCP_OAUTH_PRIVATE_KEY?.replace(/¥n/g, '\n'),
        scopes: ['https://www.googleapis.com/auth/cloud-platform'],
    });

    apiKey = (await client.getAccessToken()).token;

    //previewモデルなどはglobalしか使えなかったりする
    const location = getLocationFromModel(model);
    baseUrl = `https://aiplatform.googleapis.com/v1/projects/${process.env.GCP_PROJECT_ID}/locations/${location}/endpoints/openapi`;
}

// トークン数の上限を超えないように切り詰める(モデルによって上限が異なるため、それに合わせた切り詰めをしている)
const truncatedMessages = truncateMessages(model, messages);

// OpenAIの時と基本同じパラメータでOK
// モデルによっては指定できないパラメータがある点に注意(後述)
// modelはVertexAIの場合、google/gemini-2.5-flashのように、'google/'が必要な点に注意
const params = createChatCompletionParams({ model, truncatedMessages}); 

// OpenAIでもGeminiでも同様
const completion = (await client.chat.completions.create({
    ...params,
}));

注意事項・補足

モデルによって対応していないパラメータがありそう

パラメータはそのままでOKと書きましたが、モデルによっては対応していないケースがあります。

例えば、下記のように、画像をインプットする場合です。

const messages = [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "What is in this image?",
        },
        {
          "type": "image_url",
          "image_url": {
            "url": `data:image/jpeg;base64,${base64Image}`
          },
        },
      ],
    }
];

この形式において、OpenAIの場合、detailとして画像の解像度を指定できました。
(少なくとも、gpt40やgpt5など最近のモデルでは)

{
  "type": "image_url",
  "image_url": {
    "url": `data:image/jpeg;base64,${base64Image}`,
    "detail":'high'
  },
},

しかし、これをこのままGeminiの2.5flashや2.5proに上述のやり方でリクエストを送ると、エラーになります。
3pro previewならエラーにならずできたので、モデルによって対応可否が一定ありそうです。
なので、モデルによっては、detailをundefinedにする必要がありました。
もしかしたら、同様のことは他のパラメータ×モデルの組み合わせでもあるかもしれません。

とはいえ、これはOpenAIのSDKでGeminiを使うから、というよりは、複数のモデルを併用する際には、起こり得ることではあります。
(OpenAIだけの場合でも、モデルによって対応していないパラメータがあったりするので)

reasoning_effortの互換

OpenAIでは、reasoning_effortというパラメータを指定できます。
ざっくりいうと、どれくらい深く考えるか、です。
Geminiの場合は、thinking_level(gemini3)、thinking_badget(gemini2.5)と呼ぶようです。

上述のようにOpenAI SDKでGeminiを利用する際は、
reasoning_effortの指定のままで行うことができます。
その際は、下記の表のように、対応するthinking_level,thinking_badgetとして扱ってくれるようです。

スクリーンショット 2025-12-24 17.27.01.png
出典:https://ai.google.dev/gemini-api/docs/openai より

thinking_level,thinking_badgetで指定したい場合は、下記のように指定することも可能です。

const response = await openai.chat.completions.create({
    model: "gemini-2.5-flash",
    messages: [{role: "user", content: "Explain to me how AI works",}],
    extra_body: {
      "google": {
        "thinking_config": {
          "thinking_budget": "low",
          "include_thoughts": true
        }
      }
    }
});

まとめ

今回はOpenAIのSDKでGeminiのAPIを使う方法をまとめました。
GeminiのAPIをフル活用するのであれば、上述のようにreasoning_effortで指定するより、thinking_levelで指定した方が細かく指定可能です。
また、今回は使っていないので確認していないですが、音声のインプットや画像生成、embeddingなどを行う際も互換性はあるようですが、reasoning_effort同様、限界はあるかもしれません。
とはいえ、モデルの違いを試すには便利で良いなと感じました。

ところで、
なんでOpenAIのSDKなのに、ライバルのGeminiのAPIが使えてしまうのだろう・・・
と私は疑問に感じましたが、それをGeminiに聞いたところ下記のように返ってきました。

OpenAIのSDKでGeminiが動く理由は、以下の力学によるものです。

- ライバルの追随: Googleなどが、開発者を取り込むためにOpenAIの仕様に合わせた(OpenAI互換エンドポイントを作った)。

- 標準化の勝利: OpenAIの書き方が、事実上の「AI開発の世界標準」になった。

- 流動性の確保: 簡単に乗り換えられる環境を作ることで、逆に「いつでもOpenAIに戻れる」安心感を与えている。

なるほど。
後発の戦略として、勉強になります。

参考リンク集

4
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
4
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?