Gemini で関数呼び出しを使用して API を操作する方法

1. 概要

Gemini の関数呼び出しとは

Vertex AI Gemini API は、Google DeepMind が開発した生成 AI モデルのファミリーで、マルチモーダル ユースケース用に設計されています。関数呼び出しは Gemini モデルの機能であり、デベロッパーは生成モデルから構造化データの出力を簡単に取得できます。

デベロッパーは、これらの出力を使用して他の API を呼び出し、関連するレスポンス データをモデルに返すことができます。つまり、関数呼び出しは、生成モデルを外部システムに接続し、生成されるコンテンツに最新かつ正確な情報を含めるのに役立ちます。

関数呼び出しの仕組み

関数は、関数宣言を使用して記述します。これにより、生成モデルが関数の目的とパラメータを理解しやすくなります。クエリで関数宣言を生成モデルに渡すと、モデルは、ユーザーのクエリに基づいて、関連する関数の名前とその引数を含む構造化オブジェクトを返します。関数呼び出しでは、モデルが実際に関数を呼び出すわけではないことに注意してください。代わりに、返された関数とパラメータを使用して、任意の言語、ライブラリ、フレームワークで関数を呼び出すことができます。

API インターフェース

作成するアプリの概要

この Codelab では、Vertex AI Gemini API と Python を使用して生成 AI パイプラインを構築します。アプリを使用して、ユーザーが為替レートを尋ねると、システムは外部 API から最新のデータを取得して、ユーザーに回答を返します。

学習内容

  • Python クライアント ライブラリを使用して Gemini モデルを操作する方法
  • 関数宣言を定義してツールとして登録する方法
  • Gemini を呼び出して関数呼び出しのレスポンスを取得する方法
  • 関数のレスポンスを Gemini に返し、ユーザーに応答する方法

必要なもの

2. 設定と要件

Gemini で関数呼び出しを使用する前に、Vertex AI API を有効にして、Vertex AI Python クライアント ライブラリの最新バージョンをインストールする必要があります。

Vertex AI API を有効にする

Vertex AI API を有効にする手順は次のとおりです。

  1. ブラウザで、Vertex AI API サービスの詳細ページに移動します。
  2. [有効にする] ボタンをクリックして、Google Cloud プロジェクトで Vertex AI API を有効にします。

Vertex AI 用の Python クライアント ライブラリをインストールする

Vertex AI 用の Python クライアント ライブラリをインストールするには、次の操作を行います。

  1. 開発環境でターミナルを開きます。
  2. 有効な Python 開発環境があることを確認し、必要に応じてこちらのガイドラインをご覧ください。
  3. 次のコマンドを実行して、Vertex AI 用の Python クライアント ライブラリをインストールします。
    pip install --upgrade google-cloud-aiplatform
    
  4. ノートブック環境で実行している場合、新しくインストールされたパッケージを使用するためにランタイムまたはカーネルの再起動が必要になることがあります。

これで、Vertex AI API を使用する準備が整いました。

3. 問題を理解する

大規模言語モデルや生成 AI モデルとやり取りして、リアルタイムまたは最新の情報について尋ねただけで、古い情報や不正確な情報しか返ってこなかったことはありませんか?

やってみましょう!まず、関連する Python パッケージをインポートし、Gemini モデルを初期化します。次のコードは、ColabColab Enterprise などの Python 開発環境で、Vertex AI SDK for Python の最新バージョンをインストールすることで実行できます。

import vertexai
from vertexai.generative_models import GenerativeModel
model = GenerativeModel("gemini-1.5-pro-001")

では、今日のさまざまな通貨の為替レートについて質問しましょう。

response = model.generate_content(
    "What's the exchange rate for euros to dollars today?"
)
print(response.text)

モデルによって、次のように、限定されたレスポンスまたは古いレスポンスが生成される可能性があります。

As an AI language model, I don't have access to real-time currency exchange
rates. However, as of my last update in September 2021, the approximate exchange
rate between euros (EUR) and US dollars (USD) was:

1 EUR ≈ 1.18 USD

Please note that currency exchange rates constantly fluctuate and can vary
depending on various factors such as economic conditions, supply and demand,
political events, and more. To obtain the most up-to-date and accurate exchange
rate, I recommend using a reliable currency converter or financial website that
provides live rates.

[...]

エンドユーザーがこのようなレスポンスを受け取った場合、コンテキストを切り替えて関心のある通貨を検索し、最新の為替レートを取得して、自分自身で換算する必要があります。

生成モデルのパイプラインが、これらのタスクの一部またはすべてをユーザーの代わりに処理できれば理想的です。次のセクションでは、生成モデルから構造化されたレスポンスを取得して外部システムを呼び出すための一般的な回避策を試します。

4. 一般的な回避策を試す

最新の情報や外部ソースからのデータが必要になるシナリオで生成モデルを操作する場合は、外部 API を呼び出して、結果を生成モデルにフィードバックし、レスポンスで使用できます。

外部システムを呼び出す前に、使用する適切な関数を決定し、ユーザーから関連パラメータを抽出して構造化データ オブジェクトに配置する必要があります。これには通常、生成モデルが有効な構造化データを出力するように強制する、網羅的なプロンプト エンジニアリングが含まれます。

前のセクションで尋ねた質問をもう一度確認し、モデルに対する追加の指示をいくつか追加してみましょう。次のリクエストを Gemini モデルに送信してみてください。

user_prompt = "What's the exchange rate from euros to US dollars today?"

response = model.generate_content("""
Your task is to extract parameters from the user's input and return it as a
structured JSON payload. The user will ask about the exchange rate and which
currency they are converting from and converting to.

User input: {user_prompt}

Please extract the currencies as parameters and put them in a JSON object.
""".format(user_prompt=user_prompt))
print(response.text)

次のようなテキスト レスポンスが返されます。これは有効な JSON ではないため、操作は困難です。

```json
{
  "currency_from": "euros",
  "currency_to": "US dollars"
}
```

特に、テキスト レスポンスの最初と最後の行にはコードブロックを区切るバッククォートが含まれており、最初の行には言語指定子が含まれています。また、JSON オブジェクトの値は、通貨交換 API が入力パラメータとして想定する標準の 3 文字の通貨略語ではありません。

Python を使用して、このテキストを有効な JSON と辞書に後処理したり、プロンプトに指示を追加したり、目的の出力の例を 1 つ以上指定したり、モデルをファインチューニングしたり、生成モデルを再度呼び出して JSON のクリーンアップを依頼したりするなど、さまざまな処理を試すことができます。

しかし、もっと決定的な方法があります。Gemini の関数呼び出しを使用して外部サービスの情報をクエリし、エンドユーザーに適切なレスポンスを返す方法を学習しましょう。

5. 関数呼び出しの仕組み

パラメータ抽出と関数呼び出しを開始する前に、関数呼び出しの手順と、ランタイム時に使用されるコンポーネントを確認しましょう。

Gemini での関数呼び出しの概要

Gemini API へのユーザー入力

ユーザーからのプロンプトは Gemini API に送信され、Gemini モデルへの API 呼び出しで、デベロッパーはツール内で 1 つ以上の関数宣言を定義しています。これにより、Gemini モデルは呼び出すことができる関数とその呼び出し方法を認識できます。

Gemini API が関数呼び出しを返す

Gemini は、ユーザー入力とプロンプトの内容に基づいて、呼び出す関数の名前と、使用する対応するパラメータを含む構造化データを含む関数呼び出しのレスポンスを返します。

API リクエストを発行する

次に、関数名とパラメータを使用して API リクエストを行い、外部システムまたは API から情報を取得します。この API リクエストとレスポンスは、デベロッパーがアプリケーション コードで実装するものであり、Gemini API および SDK のスコープ外で行われます。たとえば、Python で requests ライブラリを使用して REST API を呼び出し、JSON レスポンスを受け取ることができます。または、お好みの方法とクライアント ライブラリを使用して関数を呼び出すこともできます。

API レスポンスを Gemini に返す

最後に、API レスポンスを Gemini モデルに渡し、エンドユーザーの初期プロンプトに対するレスポンスを生成するか、Gemini モデルが追加情報が必要であると判断した場合に別の関数呼び出しのレスポンスを呼び出すことができるようにします。

6. API を選択する

関数呼び出しの全体的なフローと具体的な手順を理解したところで、次は最新の為替レートを取得する生成 AI パイプラインを構築します。まず、情報源として使用する API を選択する必要があります。

今回の通貨交換アプリでは、REST API(https://www.frankfurter.app/)を使用して国際為替レートに関する最新情報を取得します。

この REST API を操作するには、次のように Python で requests を指定して REST API 呼び出しを行います。

import requests
url = "https://api.frankfurter.app/latest"
response = requests.get(url)
response.text

または次のような cURL リクエスト。

curl https://api.frankfurter.app/latest

次のようなレスポンスが返されます。

{
  "amount": 1,
  "base": "EUR",
  "date": "2023-12-20",
  "rates": {
    "AUD": 1.6186, "BGN": 1.9558, "BRL": 5.3287,
    "CAD": 1.4609, "CHF": 0.946, "CNY": 7.8121,
    "CZK": 24.538, "DKK": 7.4565, "GBP": 0.86555,
    "HKD": 8.5439, "HUF": 385.23, "IDR": 16994,
    "ILS": 3.9983, "INR": 91.06, "ISK": 150.3,
    "JPY": 157.12, "KRW": 1425.62, "MXN": 18.6867,
    "MYR": 5.0977, "NOK": 11.2895, "NZD": 1.7421,
    "PHP": 60.991, "PLN": 4.3413, "RON": 4.9699,
    "SEK": 11.129, "SGD": 1.4562, "THB": 38.252,
    "TRY": 31.883, "USD": 1.0944, "ZAR": 20.111
  }
}

Gemini の関数呼び出しは実際には外部 API 呼び出しを行わないため、使用する API の種類にそのような制限はありません。Cloud Run サービス、Cloud Functions の関数、Google Cloud サービスへの API リクエスト、外部 REST API を使用できます。

7. 関数とツールを定義する

使用する REST API が選択されたので、API 仕様を定義して、ツールに関数を登録できます。

Vertex AI SDK for Python の最新バージョンがインストールされていることを確認します。

次に、Python SDK から必要なモジュールをインポートして、Gemini モデルを初期化します。

from vertexai.generative_models import (
    Content,
    FunctionDeclaration,
    GenerativeModel,
    Part,
    Tool,
)

model = GenerativeModel("gemini-1.5-pro-001")

https://api.frankfurter.app/ の REST API を見ると、次の入力パラメータを受け入れることがわかります。

パラメータ

説明

from

文字列

換算元の通貨

to

文字列

換算後の通貨

date

文字列

為替レートを取得する日付

これらのパラメータを使用すると、この REST API の部分的な OpenAPI 仕様を YAML 形式で表すと、次のようになります。

openapi: 3.0.0
info:
  title: Frankfurter Exchange Rate API
  description: This API provides current and historical exchange rates
  version: 1.0.0
servers:
  - url: https://api.frankfurter.app
paths:
  /{date}:
    get:
      summary: Get the latest currency exchange rates.
      parameters:
        - name: date
          in: path
          description: Get currency rates for a specific date or 'latest' if a date is not specified
          required: true
          schema:
            type: string
        - name: from
          in: query
          description: The currency to convert from.
          required: true
          schema:
            type: string
        - name: to
          in: query
          description: The currency to convert to.
          schema:
            type: string

次に、Python SDK for Gemini を使用して、これを FunctionDeclaration として登録します。

get_exchange_rate_func = FunctionDeclaration(
    name="get_exchange_rate",
    description="Get the exchange rate for currencies between countries",
    parameters={
    "type": "object",
    "properties": {
        "currency_date": {
            "type": "string",
            "description": "A date that must always be in YYYY-MM-DD format or the value 'latest' if a time period is not specified"
        },
        "currency_from": {
            "type": "string",
            "description": "The currency to convert from in ISO 4217 format"
        },
        "currency_to": {
            "type": "string",
            "description": "The currency to convert to in ISO 4217 format"
        }
    },
         "required": [
            "currency_from",
            "currency_date",
      ]
  },
)

関数とパラメータの説明では、できるだけ詳細な情報を使用してください。生成モデルでは、この情報を使用して、選択する関数と、関数呼び出しのパラメータの入力方法を決定します。

最後に、関数宣言を含む Tool を定義します。

exchange_rate_tool = Tool(
    function_declarations=[get_exchange_rate_func],
)

ここでは、ツール内で 1 つの関数宣言を使用していますが、ツールに 1 つ以上の関数宣言を登録でき、モデルが実行時に使用する適切な関数を選択することに注意してください。Gemini SDK for Python の FunctionDeclarationTool、および関連するクラスの詳細については、Gemini API での関数呼び出しのドキュメントをご覧ください。

これで関数とツールの定義の構成が完了しました。次のセクションでは、このツールを使用して生成モデルを呼び出し、REST API の呼び出しに使用できる関数呼び出しを返します。

8. 関数呼び出しを生成する

これで、生成モデルにプロンプトを送信し、定義した tool を含めることができます。

prompt = """What is the exchange rate from Australian dollars to Swedish krona?
How much is 500 Australian dollars worth in Swedish krona?"""

response = model.generate_content(
    prompt,
    tools=[exchange_rate_tool],
)

レスポンス オブジェクトを見てみましょう。

print(response.candidates[0].content)

role: "model"
parts {
  function_call {
    name: "get_exchange_rate"
    args {
      fields {
        key: "currency_to"
        value {
          string_value: "SEK"
        }
      }
      fields {
        key: "currency_from"
        value {
          string_value: "AUD"
        }
      }
      fields {
        key: "currency_date"
        value {
          string_value: "latest"
        }
      }
    }
  }
}

モデルは使用可能な関数を 1 つ選択し、get_exchange_rate 関数の関数呼び出しをパラメータとともに返したようです。パラメータは必要な正しい形式になっています。これで、生成モデルから構造化されたレスポンスを取得できました。

次のセクションでは、レスポンスの情報を使用して API リクエストを作成します。

9. API リクエストを行う

Gemini の関数呼び出しでは、外部 API 呼び出しは行われません。任意の言語、ライブラリ、フレームワークを自由に使用できます。

ここでは、Python の requests ライブラリを使用して為替レート REST API を呼び出します。

レスポンスを Python 辞書に展開してみましょう。

params = {}
for key, value in response.candidates[0].content.parts[0].function_call.args.items():
    params[key[9:]] = value
params

これで、requests またはその他のメソッドを呼び出すことができます。

import requests
url = f"https://api.frankfurter.app/{params['date']}"
api_response = requests.get(url, params=params)
api_response.text

次のようなレスポンスが返されます。

'{"amount":1.0,"base":"AUD","date":"2024-01-16","rates":{"SEK":6.8682}}'

REST API からのレスポンスには、今日の最新の為替レート情報が含まれています。次のセクションでは、この情報をモデルに渡し、モデルがユーザーに適したレスポンスを生成できるようにします。

10. 回答を生成する

最後に、次の会話ターンで関数のレスポンスをモデルに渡して、ユーザーのレスポンスを生成しましょう。

response = model.generate_content(
    [
    Content(role="user", parts=[
        Part.from_text(prompt + """Give your answer in steps with lots of detail
            and context, including the exchange rate and date."""),
    ]),
    Content(role="function", parts=[
        Part.from_dict({
            "function_call": {
                "name": "get_exchange_rate",
            }
        })
    ]),
    Content(role="function", parts=[
        Part.from_function_response(
            name="get_exchange_rate",
            response={
                "content": api_response.text,
            }
        )
    ]),
    ],
    tools=[exchange_rate_tool],
)


response.candidates[0].content.parts[0].text

関数レスポンスをモデルに渡すと、モデルはユーザーのプロンプトと API レスポンスからの関連情報に応答します。

The exchange rate from Australian dollars to Swedish krona on January 16, 2024,
is 1 Australian dollar is equal to 6.8663 Swedish krona.

So, 500 Australian dollars would be worth 500 * 6.8663 = 3,433.15 Swedish krona.

11. コードサンプルの全文を表示する

この時点で、Cloud Run サービス、Cloud Functions、または別の Cloud サービスを使用して Python コードをバックエンド API に配置し、このバックエンド API を使用してモデルクエリと API 呼び出しを実行するフロントエンド アプリをデプロイできます。

以下は、最終的なソリューションの完全なコード例です。

import requests
from vertexai.generative_models import (
    Content,
    FunctionDeclaration,
    GenerativeModel,
    Part,
    Tool,
)

model = GenerativeModel("gemini-1.5-pro-001")

get_exchange_rate_func = FunctionDeclaration(
    name="get_exchange_rate",
    description="Get the exchange rate for currencies between countries",
    parameters={
    "type": "object",
    "properties": {
        "currency_date": {
            "type": "string",
            "description": "A date that must always be in YYYY-MM-DD format or the value 'latest' if a time period is not specified"
        },
        "currency_from": {
            "type": "string",
            "description": "The currency to convert from in ISO 4217 format"
        },
        "currency_to": {
            "type": "string",
            "description": "The currency to convert to in ISO 4217 format"
        }
    },
         "required": [
            "currency_from",
            "currency_date",
      ]
  },
)

exchange_rate_tool = Tool(
    function_declarations=[get_exchange_rate_func],
)

prompt = """What is the exchange rate from Australian dollars to Swedish krona?
How much is 500 Australian dollars worth in Swedish krona?"""

response = model.generate_content(
    prompt,
    tools=[exchange_rate_tool],
)

response.candidates[0].content

params = {}
for key, value in response.candidates[0].content.parts[0].function_call.args.items():
    params[key[9:]] = value
params

import requests
url = f"https://api.frankfurter.app/{params['date']}"
api_response = requests.get(url, params=params)
api_response.text

response = model.generate_content(
    [
    Content(role="user", parts=[
        Part.from_text(prompt + """Give your answer in steps with lots of detail
            and context, including the exchange rate and date."""),
    ]),
    Content(role="function", parts=[
        Part.from_dict({
            "function_call": {
                "name": "get_exchange_rate",
            }
        })
    ]),
    Content(role="function", parts=[
        Part.from_function_response(
            name="get_exchange_rate",
            response={
                "content": api_response.text,
            }
        )
    ]),
    ],
    tools=[exchange_rate_tool],
)


response.candidates[0].content.parts[0].text

この実装では、生成モデルに対して 2 つのリクエストを使用しました。1 つは関数呼び出しを生成するためのリクエスト、もう 1 つは関数レスポンスを返すリクエストです。これは、Gemini で関数呼び出しと関数レスポンスを処理する方法の一つにすぎません。また、追加の関数呼び出しを行ってクエリの詳細情報を取得したり、チャットや非同期のメソッドで関数呼び出しを使用したりすることもできます。

その他のコードサンプルについては、Gemini での関数呼び出しのサンプル ノートブックをご覧ください。

12. 完了

Gemini の関数呼び出しを使用して、Vertex AI Gemini API と Python で使用する生成 AI パイプラインを構築することができました。ユーザーが為替レートを尋ねると、システムが外部 API から最新のデータを取得して回答を返します。

エンドユーザーからのプロンプトに応じて、Gemini の関数呼び出しが適切な関数を選択し、プロンプトからパラメータを抽出し、外部 API 呼び出しを行うための構造化データ オブジェクトを返します。

Gemini の関数呼び出しの設計は、要約とコンテンツの作成を生成モデルに任せ、決定論的にパラメータを抽出する際に両方の長所を活かせることを目的としています。パイプラインで他の API やプロンプトを試したり、Vertex AI Gemini API に関連する利用可能な他の機能を試してみてください。

API インターフェース

クリーンアップ

この Codelab で使用したリソースについて、Google Cloud アカウントに課金されないようにするには、次のクリーンアップを実行します。

詳細

会話型 AI と生成 AI について引き続き学習するには、以下のガイドとリソースを参考にしてください。

ライセンス

この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。