関数呼び出しの概要

大規模言語モデル(LLM)は、さまざまな問題の解決に効果的です。ただし、次のような制限があります。

  • トレーニングが完了するとその後は更新されないため、知識が最新ではなくなります。
  • 外部データのクエリや変更はできません。

関数呼び出しを使用すると、こうした欠点を克服することができます。関数呼び出しは「ツールの使用」と呼ばれることもあります。これは、関数呼び出しによってモデルが API や関数などの外部ツールを使用できるためです。

ユーザーは、LLM にプロンプトを送信するときに、モデルがプロンプトへの応答に使用できる一連のツールも提供します。たとえば、関数 get_weather を提供できます。この関数は、位置情報パラメータを受け取り、その場所の天候に関する情報を返します。

モデルはプロンプトの処理中に、ユーザー指定の関数に特定のデータ処理タスクを委任できます。モデルは関数を直接呼び出しません。代わりに、呼び出す関数と使用するパラメータ値を含む構造化データの出力を提供します。たとえば、「What is the weather like in Boston?」というプロンプトの場合、モデルは処理を get_weather 関数に委任し、位置情報パラメータの値 Boston, MA を渡します。

モデルからの構造化出力を使用して、外部 API を呼び出すことができます。たとえば、天気予報サービスの API に接続し、場所 Boston, MA を渡して、気温、雲量、風の状態などの情報を取得できます。

その後、API の出力をモデルに提供し、プロンプトに対する回答を完成させることができます。この天気の例では、モデルは「It is currently 38 degrees Fahrenheit in Boston, MA with partly cloudy skies.」という回答を返す可能性があります。

関数呼び出しのインタラクション 

サポートされているモデル

次のモデルは関数呼び出しをサポートしています。

モデル バージョン 関数呼び出しのリリース ステージ 並列関数呼び出しのサポート 強制関数呼び出しのサポート
Gemini 1.0 Pro all versions 一般提供 × ×
Gemini 1.5 Flash all versions 一般提供
Gemini 1.5 Pro all versions 一般提供

関数呼び出しのユースケース

関数呼び出しは、次のようなタスクに使用できます。

ユースケース 例の説明 例のリンク
外部 API と統合する 気象 API を使用して天気情報を取得する ノートブックのチュートリアル
住所を緯度経度の座標に変換する ノートブックのチュートリアル
為替 API を使用して通貨を換算する Codelab
高度な chatbot を構築する プロダクトやサービスに関するお客様の質問に回答する ノートブックのチュートリアル
企業の財務情報やニュースに関する質問に回答するアシスタントを作成する ノートブックのチュートリアル
関数呼び出しを構造化して制御する 未加工のログデータから構造化されたエンティティを抽出する ノートブックのチュートリアル
ユーザー入力からパラメータを抽出する ノートブックのチュートリアル
関数呼び出しでネストされたデータ構造とリストを処理する ノートブックのチュートリアル
関数呼び出しの動作を処理する 並列関数呼び出しとレスポンスを処理する ノートブックのチュートリアル
モデルが呼び出せる関数とそのタイミングを管理する ノートブックのチュートリアル
自然言語でデータベースにクエリを実行する 自然言語の質問を BigQuery の SQL クエリに変換する サンプルアプリ
マルチモーダル関数呼び出し 入力として画像、動画、音声、PDF を使用して関数呼び出しをトリガーする ノートブックのチュートリアル

さらに、次のようなユースケースもあります。

  • 音声コマンドを解釈する: 車載機能に対応する関数を作成します。たとえば、ラジオをオンにする関数や、エアコンをつける関数を作成できます。ユーザーのコマンドの音声ファイルをモデルに送信し、モデルに対して音声をテキストに変換してユーザーが呼び出したい関数を特定するように指示します。

  • 環境的なトリガーに基づいてワークフローを自動化する: 自動化できるプロセスを表す関数を作成します。環境センサーからのデータをモデルに提供し、モデルに対してそのデータを解析、処理して1 つ以上のワークフローを起動すべきかどうかを判断するように指示します。たとえば、モデルが倉庫内の温度データを処理してスプリンクラー機能を起動するといったプロセスが可能です。

  • サポート チケットの割り当てを自動化する: サポート チケット、ログ、コンテキストアウェア ルールをモデルに提供します。モデルに対して、チケットを割り当てるユーザーを判断するためにこれらの情報をすべて処理するように指示します。チケットをモデルによって提案された人に割り当てる関数を呼び出します。

  • ナレッジベースから情報を取得する: 特定のテーマに関する学術論文を取得して要約する関数を作成します。モデルが学術的なテーマに関する質問に答え、その回答の引用元を提示できるようにします。

関数呼び出しのアプリケーションを作成する方法

ユーザーがモデルとインターフェースを接続して関数呼び出しを使用できるようにするには、次のタスクを実行するコードを作成する必要があります。

  1. 環境を設定する
  2. 関数宣言を使用して、使用可能な一連の関数を定義、記述する
  3. ユーザーのプロンプトと関数宣言をモデルに送信する
  4. モデルから出力された構造化データを使用して、関数を呼び出す
  5. 関数の出力をモデルに提供する

これらすべてのタスクを管理するアプリケーションを作成できます。このようなアプリケーションには、テキスト chatbot、音声エージェント、自動ワークフローなどがあります。

関数呼び出しを使用して、単一のテキスト レスポンスを生成することや、チャット セッションをサポートすることが可能です。アドホックなテキスト レスポンスは、コードの生成など、特定のビジネスタスクで役立ちます。チャット セッションは、ユーザーがフォローアップの質問をする可能性が高い自由形式の会話のシナリオで役立ちます。

関数呼び出しを使用して単一のレスポンスを生成する場合は、やり取りの完全なコンテキストをモデルに提供する必要があります。一方、チャット セッションのコンテキストで関数呼び出しを使用する場合、セッションではコンテキストが保存され、すべてのモデル リクエストにそれが追加されます。どちらの場合も、Vertex AI はやり取りの履歴をクライアント側に保存します。

このガイドでは、関数呼び出しを使用して単一のテキスト レスポンスを生成する方法について説明します。エンドツーエンドのサンプルについては、テキストの例をご覧ください。関数呼び出しを使用してチャット セッションをサポートする方法については、チャットの例をご覧ください。

ステップ 1: 環境を設定する

必要なモジュールをインポートしてモデルを初期化します。

Python

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

# Initialize Vertex AI
# TODO(developer): Update and un-comment below lines
# PROJECT_ID = 'your-project-id'
vertexai.init(project=PROJECT_ID, location="us-central1")

# Initialize Gemini model
model = GenerativeModel(model_name="gemini-1.5-flash-002")

ステップ 2: 一連の関数を宣言する

アプリケーションでは、モデルがプロンプトを処理するために使用できる一連の関数を宣言する必要があります。

リクエストで指定できる関数宣言の最大数は 128 です。

関数宣言は、OpenAPI スキーマと互換性のあるスキーマ形式で指定する必要があります。Vertex AI は、OpenAPI スキーマを限定的にサポートしています。サポートされている属性は、typenullablerequiredformatdescriptionpropertiesitemsenum です。属性 defaultoptionalmaximumoneOf はサポートされていません。名前と説明に関するヒントなど、関数宣言に関するベスト プラクティスについては、ベスト プラクティスをご覧ください。

REST API を使用する場合は、JSON を使用してスキーマを指定します。Vertex AI SDK for Python を使用する場合は、Python 辞書を使用して手動でスキーマを指定するか、from_func ヘルパー関数を使用して自動的にスキーマを指定できます。

JSON

{
  "contents": ...,
  "tools": [
    {
      "function_declarations": [
        {
          "name": "find_movies",
          "description": "find movie titles currently playing in theaters based on any description, genre, title words, etc.",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
              },
              "description": {
                "type": "string",
                "description": "Any kind of description including category or genre, title words, attributes, etc."
              }
            },
            "required": [
              "description"
            ]
          }
        },
        {
          "name": "find_theaters",
          "description": "find theaters based on location and optionally movie title which are is currently playing in theaters",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
              },
              "movie": {
                "type": "string",
                "description": "Any movie title"
              }
            },
            "required": [
              "location"
            ]
          }
        },
        {
          "name": "get_showtimes",
          "description": "Find the start times for movies playing in a specific theater",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
              },
              "movie": {
                "type": "string",
                "description": "Any movie title"
              },
              "theater": {
                "type": "string",
                "description": "Name of the theater"
              },
              "date": {
                "type": "string",
                "description": "Date for requested showtime"
              }
            },
            "required": [
              "location",
              "movie",
              "theater",
              "date"
            ]
          }
        }
      ]
    }
  ]
}

Python 辞書

次の関数宣言は、単一の string パラメータを受け取ります。

function_name = "get_current_weather"
get_current_weather_func = FunctionDeclaration(
    name=function_name,
    description="Get the current weather in a given location",
    # Function parameters are specified in JSON schema format
    parameters={
        "type": "object",
        "properties": {
            "location": {"type": "string", "description": "The city name of the location for which to get the weather."}
        },
    },
)

次の関数宣言は、オブジェクト パラメータと配列パラメータの両方を受け取ります。

extract_sale_records_func = FunctionDeclaration(
  name="extract_sale_records",
  description="Extract sale records from a document.",
  parameters={
      "type": "object",
      "properties": {
          "records": {
              "type": "array",
              "description": "A list of sale records",
              "items": {
                  "description": "Data for a sale record",
                  "type": "object",
                  "properties": {
                      "id": {"type": "integer", "description": "The unique id of the sale."},
                      "date": {"type": "string", "description": "Date of the sale, in the format of MMDDYY, e.g., 031023"},
                      "total_amount": {"type": "number", "description": "The total amount of the sale."},
                      "customer_name": {"type": "string", "description": "The name of the customer, including first name and last name."},
                      "customer_contact": {"type": "string", "description": "The phone number of the customer, e.g., 650-123-4567."},
                  },
                  "required": ["id", "date", "total_amount"],
              },
          },
      },
      "required": ["records"],
  },
)

関数からの Python の実行

次のコードサンプルは、数値の配列を乗算する関数を宣言し、from_func を使用して FunctionDeclaration スキーマを生成します。

# Define a function. Could be a local function or you can import the requests library to call an API
def multiply_numbers(numbers):
  """
  Calculates the product of all numbers in an array.

  Args:
      numbers: An array of numbers to be multiplied.

  Returns:
      The product of all the numbers. If the array is empty, returns 1.
  """

  if not numbers:  # Handle empty array
      return 1

  product = 1
  for num in numbers:
      product *= num

  return product

multiply_number_func = FunctionDeclaration.from_func(multiply_numbers)

'''
multiply_number_func contains the following schema:

name: "multiply_numbers"
description: "Calculates the product of all numbers in an array."
parameters {
  type_: OBJECT
  properties {
    key: "numbers"
    value {
      description: "An array of numbers to be multiplied."
      title: "Numbers"
    }
  }
  required: "numbers"
  description: "Calculates the product of all numbers in an array."
  title: "multiply_numbers"
}
'''

ステップ 3: プロンプトと関数宣言をモデルに送信する

ユーザーがプロンプトを指定すると、アプリケーションはモデルにユーザー プロンプトと関数宣言を渡す必要があります。モデルが結果を生成する方法を構成するには、アプリケーションでモデルに生成構成を指定します。モデルが関数宣言を使用する方法を構成するには、アプリケーションでモデルにツール構成を渡します。

ユーザー プロンプトを定義する

ここでは、「What is the weather like in Boston?」というユーザー プロンプトの例を示します。

このユーザー プロンプトを次の例のように定義します。

Python

# Define the user's prompt in a Content object that we can reuse in model calls
user_prompt_content = Content(
    role="user",
    parts=[
        Part.from_text("What is the weather like in Boston?"),
    ],
)

ユーザー プロンプトに関するベスト プラクティスについては、ベスト プラクティス - ユーザー プロンプトをご覧ください。

生成構成

このモデルは、パラメータ値によって異なる結果を生成できます。温度パラメータは、この生成におけるランダム性の度合いを制御します。温度が低いほど、確定的なパラメータ値を必要とする関数に適しています。一方、温度が高いほど、より多様で創造的なパラメータ値を受け入れることができる関数に適しています。温度を 0 にすると、確定的になります。この場合、特定のプロンプトに対するレスポンスはほとんど確定的ですが、わずかに変動する可能性は残ります。詳細については、Gemini API をご覧ください。

このパラメータを設定するには、プロンプト、関数宣言とともに生成構成(generation_config)を送信します。Vertex AI API と更新された generation_config を使用して、チャット セッション中に temperature パラメータを更新できます。temperature パラメータの設定例については、プロンプトと関数宣言を送信する方法をご覧ください。

生成構成に関するベスト プラクティスについては、ベスト プラクティス - 生成構成をご覧ください。

ツール構成

モデルが提供する関数宣言の使用方法に制約を課すことができます。たとえば、モデルに自然言語によるレスポンスと関数呼び出しのどちらかを選択させるのではなく、関数呼び出しのみを予測するように強制できます(「強制関数呼び出し」または「生成制御機能による関数呼び出し」)。関数宣言の全セットをモデルに提供し、そのレスポンスをこれらの関数のサブセットに制限することもできます。

これらの制約を適用するには、プロンプトと関数宣言とともにツール構成(tool_config)を送信します。構成では、次のいずれかのモードを指定できます。

モード 説明
AUTO デフォルトのモデル動作。関数呼び出しと自然言語によるレスポンスのどちらを予測するかは、モデルが決定します。
ANY モデルは関数呼び出しのみを予測する必要があります。モデルを関数のサブセットに制限するには、allowed_function_names で許可される関数名を定義します。
NONE モデルは関数呼び出しを予測しません。この動作は、関連する関数宣言のないモデル リクエストと同じです。

ANY モード(「強制関数呼び出し」)をサポートするモデルのリストについては、サポートされているモデルをご覧ください。

詳細については、Function Calling API をご覧ください。

プロンプトと関数の宣言を送信する方法

プロンプトと関数宣言をモデルに送信し、get_current_weather 関数呼び出しのみを予測するようにモデルを制限する方法の例を次に示します。

Python

# Define a tool that includes some of the functions that we declared earlier
tool = Tool(
    function_declarations=[get_current_weather_func, extract_sale_records_func, multiply_number_func],
)

# Send the prompt and instruct the model to generate content using the Tool object that you just created
response = model.generate_content(
    user_prompt_content,
    generation_config=GenerationConfig(temperature=0),
    tools=[tool],
    tool_config=ToolConfig(
        function_calling_config=ToolConfig.FunctionCallingConfig(
            # ANY mode forces the model to predict only function calls
            mode=ToolConfig.FunctionCallingConfig.Mode.ANY,
            # Allowed function calls to predict when the mode is ANY. If empty, any  of
            # the provided function calls will be predicted.
            allowed_function_names=["get_current_weather"],
        )
    )
)

モデルが特定の関数の出力が必要と判断した場合、アプリケーションがモデルから受け取るレスポンスには、関数名と、その関数を呼び出すためのパラメータ値が含まれます。

ユーザー プロンプト「ボストンの天気は?」に対するモデル レスポンスの例を次に示します。モデルは、パラメータ Boston, MA を指定して get_current_weather 関数を呼び出すことを提案します。

candidates {
  content {
    role: "model"
    parts {
      function_call {
        name: "get_current_weather"
        args {
          fields {
            key: "location"
            value {
              string_value: "Boston, MA"
            }
          }
        }
      }
    }
  }
  ...
}

「Get weather details in New Delhi and San Francisco?」のようなプロンプトでは、モデルが複数の並列関数呼び出しを提案する場合があります。詳細については、並列関数呼び出しの例をご覧ください。

ステップ 4: 外部 API を呼び出す

アプリケーションがモデルから関数名とパラメータ値を受け取った場合、アプリケーションは外部 API に接続して関数を呼び出す必要があります。

次の例では、擬似データを使用して外部 API からのレスポンス ペイロードをシミュレートします。

Python

# Check the function name that the model responded with, and make an API call to an external system
if (response.candidates[0].function_calls[0].name == "get_current_weather"):
    # Extract the arguments to use in your API call
    location = response.candidates[0].function_calls[0].args["location"]

    # Here you can use your preferred method to make an API request to fetch the current weather, for example:
    # api_response = requests.post(weather_api_url, data={"location": location})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = """{ "location": "Boston, MA", "temperature": 38, "description": "Partly Cloudy",
                    "icon": "partly-cloudy", "humidity": 65, "wind": { "speed": 10, "direction": "NW" } }"""

API 呼び出しに関するベスト プラクティスについては、ベスト プラクティス - API 呼び出しをご覧ください。

ステップ 5: 関数の出力をモデルに提供する

アプリケーションが外部 API からレスポンスを受け取ったら、アプリケーションは、そのレスポンスをモデルに提供しなければなりません。Python を使用してこれを行う方法の例を次に示します。

Python

response = model.generate_content(
    [
        user_prompt_content,  # User prompt
        response.candidates[0].content,  # Function call response
        Content(
            parts=[
                Part.from_function_response(
                    name="get_current_weather",
                    response={
                        "content": api_response,  # Return the API response to Gemini
                    },
                )
            ],
        ),
    ],
    tools=[weather_tool],
)
# Get the model summary response
summary = response.text

モデルが複数の並列関数呼び出しを提案した場合、アプリケーションはすべてのレスポンスをモデルに返す必要があります。詳細については、並列関数呼び出しの例をご覧ください。

モデルは、プロンプトに応答するために別の関数の出力が必要であると判断する場合があります。この場合、アプリケーションがモデルから受信するレスポンスには、別の関数名と別のパラメータ値のセットが含まれます。

API のレスポンスがユーザーのプロンプトへの回答に十分であるとモデルが判断した場合、モデルは自然言語レスポンスを作成してアプリケーションに返します。この場合、ユーザーには、アプリケーションがレスポンスを返す必要があります。レスポンスの例を次に示します。

It is currently 38 degrees Fahrenheit in Boston, MA with partly cloudy skies. The humidity is 65% and the wind is blowing at 10 mph from the northwest.

関数呼び出しの例

テキストの例

関数呼び出しを使用して、単一のテキスト レスポンスを生成できます。アドホックなテキスト レスポンスは、コードの生成など、特定のビジネスタスクで役立ちます。

関数呼び出しを使用して単一のレスポンスを生成する場合は、やり取りの完全なコンテキストをモデルに提供する必要があります。Vertex AI は、やり取りの履歴をクライアント側に保存します。

Python

この例では、1 つの関数と 1 つのプロンプトを使用したテキストのシナリオを示します。GenerativeModel クラスとそのメソッドを使用します。Gemini マルチモーダル モデルで Vertex AI SDK for Python を使用する方法については、Vertex AI SDK for Python でのマルチモーダル クラスの概要をご覧ください。

Python

Vertex AI SDK for Python のインストールまたは更新の方法については、Vertex AI SDK for Python をインストールするをご覧ください。 詳細については、Python API リファレンス ドキュメントをご覧ください。

import vertexai

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

# TODO(developer): Update & uncomment below line
# PROJECT_ID = "your-project-id"

# Initialize Vertex AI
vertexai.init(project=PROJECT_ID, location="us-central1")

# Initialize Gemini model
model = GenerativeModel("gemini-1.5-flash-002")

# Define the user's prompt in a Content object that we can reuse in model calls
user_prompt_content = Content(
    role="user",
    parts=[
        Part.from_text("What is the weather like in Boston?"),
    ],
)

# Specify a function declaration and parameters for an API request
function_name = "get_current_weather"
get_current_weather_func = FunctionDeclaration(
    name=function_name,
    description="Get the current weather in a given location",
    # Function parameters are specified in JSON schema format
    parameters={
        "type": "object",
        "properties": {"location": {"type": "string", "description": "Location"}},
    },
)

# Define a tool that includes the above get_current_weather_func
weather_tool = Tool(
    function_declarations=[get_current_weather_func],
)

# Send the prompt and instruct the model to generate content using the Tool that you just created
response = model.generate_content(
    user_prompt_content,
    generation_config=GenerationConfig(temperature=0),
    tools=[weather_tool],
)
function_call = response.candidates[0].function_calls[0]
print(function_call)

# Check the function name that the model responded with, and make an API call to an external system
if function_call.name == function_name:
    # Extract the arguments to use in your API call
    location = function_call.args["location"]  # noqa: F841

    # Here you can use your preferred method to make an API request to fetch the current weather, for example:
    # api_response = requests.post(weather_api_url, data={"location": location})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = """{ "location": "Boston, MA", "temperature": 38, "description": "Partly Cloudy",
                    "icon": "partly-cloudy", "humidity": 65, "wind": { "speed": 10, "direction": "NW" } }"""

# Return the API response to Gemini so it can generate a model response or request another function call
response = model.generate_content(
    [
        user_prompt_content,  # User prompt
        response.candidates[0].content,  # Function call response
        Content(
            parts=[
                Part.from_function_response(
                    name=function_name,
                    response={
                        "content": api_response,  # Return the API response to Gemini
                    },
                ),
            ],
        ),
    ],
    tools=[weather_tool],
)

# Get the model response
print(response.text)
# Example response:
# The weather in Boston is partly cloudy with a temperature of 38 degrees Fahrenheit.
# The humidity is 65% and the wind is blowing from the northwest at 10 mph.

C#

この例では、1 つの関数と 1 つのプロンプトを使用したテキストのシナリオを示します。

C#

このサンプルを試す前に、Vertex AI クイックスタート: クライアント ライブラリの使用にある C# の設定手順を完了してください。詳細については、Vertex AI C# API のリファレンス ドキュメントをご覧ください。

Vertex AI に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。


using Google.Cloud.AIPlatform.V1;
using System;
using System.Threading.Tasks;
using Type = Google.Cloud.AIPlatform.V1.Type;
using Value = Google.Protobuf.WellKnownTypes.Value;

public class FunctionCalling
{
    public async Task<string> GenerateFunctionCall(
        string projectId = "your-project-id",
        string location = "us-central1",
        string publisher = "google",
        string model = "gemini-1.5-flash-001")
    {
        var predictionServiceClient = new PredictionServiceClientBuilder
        {
            Endpoint = $"{location}-aiplatform.googleapis.com"
        }.Build();

        // Define the user's prompt in a Content object that we can reuse in
        // model calls
        var userPromptContent = new Content
        {
            Role = "USER",
            Parts =
            {
                new Part { Text = "What is the weather like in Boston?" }
            }
        };

        // Specify a function declaration and parameters for an API request
        var functionName = "get_current_weather";
        var getCurrentWeatherFunc = new FunctionDeclaration
        {
            Name = functionName,
            Description = "Get the current weather in a given location",
            Parameters = new OpenApiSchema
            {
                Type = Type.Object,
                Properties =
                {
                    ["location"] = new()
                    {
                        Type = Type.String,
                        Description = "Get the current weather in a given location"
                    },
                    ["unit"] = new()
                    {
                        Type = Type.String,
                        Description = "The unit of measurement for the temperature",
                        Enum = {"celsius", "fahrenheit"}
                    }
                },
                Required = { "location" }
            }
        };

        // Send the prompt and instruct the model to generate content using the tool that you just created
        var generateContentRequest = new GenerateContentRequest
        {
            Model = $"projects/{projectId}/locations/{location}/publishers/{publisher}/models/{model}",
            GenerationConfig = new GenerationConfig
            {
                Temperature = 0f
            },
            Contents =
            {
                userPromptContent
            },
            Tools =
            {
                new Tool
                {
                    FunctionDeclarations = { getCurrentWeatherFunc }
                }
            }
        };

        GenerateContentResponse response = await predictionServiceClient.GenerateContentAsync(generateContentRequest);

        var functionCall = response.Candidates[0].Content.Parts[0].FunctionCall;
        Console.WriteLine(functionCall);

        string apiResponse = "";

        // Check the function name that the model responded with, and make an API call to an external system
        if (functionCall.Name == functionName)
        {
            // Extract the arguments to use in your API call
            string locationCity = functionCall.Args.Fields["location"].StringValue;

            // Here you can use your preferred method to make an API request to
            // fetch the current weather

            // In this example, we'll use synthetic data to simulate a response
            // payload from an external API
            apiResponse = @"{ ""location"": ""Boston, MA"",
                    ""temperature"": 38, ""description"": ""Partly Cloudy""}";
        }

        // Return the API response to Gemini so it can generate a model response or request another function call
        generateContentRequest = new GenerateContentRequest
        {
            Model = $"projects/{projectId}/locations/{location}/publishers/{publisher}/models/{model}",
            Contents =
            {
                userPromptContent, // User prompt
                response.Candidates[0].Content, // Function call response,
                new Content
                {
                    Parts =
                    {
                        new Part
                        {
                            FunctionResponse = new()
                            {
                                Name = functionName,
                                Response = new()
                                {
                                    Fields =
                                    {
                                        { "content", new Value { StringValue = apiResponse } }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            Tools =
            {
                new Tool
                {
                    FunctionDeclarations = { getCurrentWeatherFunc }
                }
            }
        };

        response = await predictionServiceClient.GenerateContentAsync(generateContentRequest);

        string responseText = response.Candidates[0].Content.Parts[0].Text;
        Console.WriteLine(responseText);

        return responseText;
    }
}

Node.js

この例では、1 つの関数と 1 つのプロンプトを使用したテキストのシナリオを示します。

Node.js

このサンプルを試す前に、Vertex AI クイックスタート: クライアント ライブラリの使用で説明している Node.js の設定手順を完了してください。詳細については、Vertex AI Node.js API のリファレンス ドキュメントをご覧ください。

Vertex AI に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

const {
  VertexAI,
  FunctionDeclarationSchemaType,
} = require('@google-cloud/vertexai');

const functionDeclarations = [
  {
    function_declarations: [
      {
        name: 'get_current_weather',
        description: 'get weather in a given location',
        parameters: {
          type: FunctionDeclarationSchemaType.OBJECT,
          properties: {
            location: {type: FunctionDeclarationSchemaType.STRING},
            unit: {
              type: FunctionDeclarationSchemaType.STRING,
              enum: ['celsius', 'fahrenheit'],
            },
          },
          required: ['location'],
        },
      },
    ],
  },
];

const functionResponseParts = [
  {
    functionResponse: {
      name: 'get_current_weather',
      response: {name: 'get_current_weather', content: {weather: 'super nice'}},
    },
  },
];

/**
 * TODO(developer): Update these variables before running the sample.
 */
async function functionCallingStreamContent(
  projectId = 'PROJECT_ID',
  location = 'us-central1',
  model = 'gemini-1.5-flash-001'
) {
  // Initialize Vertex with your Cloud project and location
  const vertexAI = new VertexAI({project: projectId, location: location});

  // Instantiate the model
  const generativeModel = vertexAI.getGenerativeModel({
    model: model,
  });

  const request = {
    contents: [
      {role: 'user', parts: [{text: 'What is the weather in Boston?'}]},
      {
        role: 'model',
        parts: [
          {
            functionCall: {
              name: 'get_current_weather',
              args: {location: 'Boston'},
            },
          },
        ],
      },
      {role: 'user', parts: functionResponseParts},
    ],
    tools: functionDeclarations,
  };
  const streamingResp = await generativeModel.generateContentStream(request);
  for await (const item of streamingResp.stream) {
    console.log(item.candidates[0].content.parts[0].text);
  }
}

REST

この例では、3 つの関数と 1 つのプロンプトを使用するテキストのシナリオを示します。

この例では、生成 AI モデルを 2 回呼び出します。

最初のモデル リクエスト

リクエストでは、text パラメータにプロンプトを定義する必要があります。この例では、「Which theaters in Mountain View show the Barbie movie?」というプロンプトを定義します。

リクエストでは、ツール(tools)と一連の関数宣言(functionDeclarations)も定義する必要があります。これらの関数宣言は、OpenAPI スキーマと互換性のある形式で指定する必要があります。この例では、次の関数を定義します。

  • find_movies は、映画館で上映されている映画のタイトルを検索します。
  • find_theatres は、場所に基づいて映画館を検索します。
  • get_showtimes は、特定の映画館で上映される映画の開始時間を検索します。

モデル リクエストのパラメータの詳細については、Gemini API をご覧ください。

my-project は、Google Cloud プロジェクトの名前で置き換えます。

最初のモデル リクエスト

PROJECT_ID=my-project
MODEL_ID=gemini-1.0-pro
API=streamGenerateContent
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json"  https://us-central1-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/us-central1/publishers/google/models/${MODEL_ID}:${API} -d '{
"contents": {
  "role": "user",
  "parts": {
    "text": "Which theaters in Mountain View show the Barbie movie?"
  }
},
"tools": [
  {
    "function_declarations": [
      {
        "name": "find_movies",
        "description": "find movie titles currently playing in theaters based on any description, genre, title words, etc.",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
            },
            "description": {
              "type": "string",
              "description": "Any kind of description including category or genre, title words, attributes, etc."
            }
          },
          "required": [
            "description"
          ]
        }
      },
      {
        "name": "find_theaters",
        "description": "find theaters based on location and optionally movie title which are is currently playing in theaters",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
            },
            "movie": {
              "type": "string",
              "description": "Any movie title"
            }
          },
          "required": [
            "location"
          ]
        }
      },
      {
        "name": "get_showtimes",
        "description": "Find the start times for movies playing in a specific theater",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
            },
            "movie": {
              "type": "string",
              "description": "Any movie title"
            },
            "theater": {
              "type": "string",
              "description": "Name of the theater"
            },
            "date": {
              "type": "string",
              "description": "Date for requested showtime"
            }
          },
          "required": [
            "location",
            "movie",
            "theater",
            "date"
          ]
        }
      }
    ]
  }
]
}'
  

「マウンテンビューのどの映画館でバービー映画が上映されていますか?」というプロンプトに対して、モデルはパラメータ BarbieMountain View, CA を使用して関数 find_theatres を返します。

最初のモデル リクエストに対するレスポンス

[{
"candidates": [
  {
    "content": {
      "parts": [
        {
          "functionCall": {
            "name": "find_theaters",
            "args": {
              "movie": "Barbie",
              "location": "Mountain View, CA"
            }
          }
        }
      ]
    },
    "finishReason": "STOP",
    "safetyRatings": [
      {
        "category": "HARM_CATEGORY_HARASSMENT",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_HATE_SPEECH",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
        "probability": "NEGLIGIBLE"
      }
    ]
  }
],
"usageMetadata": {
  "promptTokenCount": 9,
  "totalTokenCount": 9
}
}]
  

2 番目のモデル リクエスト

この例では、外部 API を呼び出す代わりに合成データを使用します。2 つの結果があり、それぞれに 2 つのパラメータ(nameaddress)があります。

  1. name: AMC Mountain View 16address: 2000 W El Camino Real, Mountain View, CA 94040
  2. name: Regal Edwards 14address: 245 Castro St, Mountain View, CA 94040

my-project は、Google Cloud プロジェクトの名前で置き換えます。

2 番目のモデル リクエスト

PROJECT_ID=my-project
MODEL_ID=gemini-1.0-pro
API=streamGenerateContent
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json"  https://us-central1-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/us-central1/publishers/google/models/${MODEL_ID}:${API} -d '{
"contents": [{
  "role": "user",
  "parts": [{
    "text": "Which theaters in Mountain View show the Barbie movie?"
  }]
}, {
  "role": "model",
  "parts": [{
    "functionCall": {
      "name": "find_theaters",
      "args": {
        "location": "Mountain View, CA",
        "movie": "Barbie"
      }
    }
  }]
}, {
  "parts": [{
    "functionResponse": {
      "name": "find_theaters",
      "response": {
        "name": "find_theaters",
        "content": {
          "movie": "Barbie",
          "theaters": [{
            "name": "AMC Mountain View 16",
            "address": "2000 W El Camino Real, Mountain View, CA 94040"
          }, {
            "name": "Regal Edwards 14",
            "address": "245 Castro St, Mountain View, CA 94040"
          }]
        }
      }
    }
  }]
}],
"tools": [{
  "functionDeclarations": [{
    "name": "find_movies",
    "description": "find movie titles currently playing in theaters based on any description, genre, title words, etc.",
    "parameters": {
      "type": "OBJECT",
      "properties": {
        "location": {
          "type": "STRING",
          "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
        },
        "description": {
          "type": "STRING",
          "description": "Any kind of description including category or genre, title words, attributes, etc."
        }
      },
      "required": ["description"]
    }
  }, {
    "name": "find_theaters",
    "description": "find theaters based on location and optionally movie title which are is currently playing in theaters",
    "parameters": {
      "type": "OBJECT",
      "properties": {
        "location": {
          "type": "STRING",
          "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
        },
        "movie": {
          "type": "STRING",
          "description": "Any movie title"
        }
      },
      "required": ["location"]
    }
  }, {
    "name": "get_showtimes",
    "description": "Find the start times for movies playing in a specific theater",
    "parameters": {
      "type": "OBJECT",
      "properties": {
        "location": {
          "type": "STRING",
          "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
        },
        "movie": {
          "type": "STRING",
          "description": "Any movie title"
        },
        "theater": {
          "type": "STRING",
          "description": "Name of the theater"
        },
        "date": {
          "type": "STRING",
          "description": "Date for requested showtime"
        }
      },
      "required": ["location", "movie", "theater", "date"]
    }
  }]
}]
}'
  

モデルのレスポンスは次のようになります。

2 番目のモデル リクエストに対するレスポンス

{
"candidates": [
  {
    "content": {
      "parts": [
        {
          "text": " OK. Barbie is showing in two theaters in Mountain View, CA: AMC Mountain View 16 and Regal Edwards 14."
        }
      ]
    }
  }
],
"usageMetadata": {
  "promptTokenCount": 9,
  "candidatesTokenCount": 27,
  "totalTokenCount": 36
}
}
  

チャットの例

関数呼び出しを使用して、チャット セッションをサポートできます。チャット セッションは、ユーザーがフォローアップの質問をする可能性が高い、自由形式の会話のシナリオで役立ちます。

チャット セッションのコンテキストで関数呼び出しを使用する場合、セッションでコンテキストが保存され、すべてのモデル リクエストにそれが追加されます。Vertex AI は、やり取りの履歴をクライアント側に保存します。

Python

次の例では、2 つの関数と 2 つの連続したプロンプトを使用したチャットのシナリオを示します。GenerativeModel クラスとそのメソッドを使用します。マルチモーダル モデルで Vertex AI SDK for Python を使用する方法については、Vertex AI SDK for Python でのマルチモーダル クラスの概要をご覧ください。

Python をインストールまたは更新する方法については、Vertex AI SDK for Python をインストールするをご覧ください。詳細については、Python API リファレンス ドキュメントをご覧ください。

import vertexai

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

# TODO(developer): Update & uncomment below line
# PROJECT_ID = "your-project-id"

# Initialize Vertex AI
vertexai.init(project=PROJECT_ID, location="us-central1")

# Specify a function declaration and parameters for an API request
get_product_sku = "get_product_sku"
get_product_sku_func = FunctionDeclaration(
    name=get_product_sku,
    description="Get the SKU for a product",
    # Function parameters are specified in OpenAPI JSON schema format
    parameters={
        "type": "object",
        "properties": {
            "product_name": {"type": "string", "description": "Product name"}
        },
    },
)

# Specify another function declaration and parameters for an API request
get_store_location_func = FunctionDeclaration(
    name="get_store_location",
    description="Get the location of the closest store",
    # Function parameters are specified in JSON schema format
    parameters={
        "type": "object",
        "properties": {"location": {"type": "string", "description": "Location"}},
    },
)

# Define a tool that includes the above functions
retail_tool = Tool(
    function_declarations=[
        get_product_sku_func,
        get_store_location_func,
    ],
)

# Initialize Gemini model
model = GenerativeModel(
    model_name="gemini-1.5-flash-001",
    generation_config=GenerationConfig(temperature=0),
    tools=[retail_tool],
)

# Start a chat session
chat = model.start_chat()

# Send a prompt for the first conversation turn that should invoke the get_product_sku function
response = chat.send_message("Do you have the Pixel 8 Pro in stock?")

function_call = response.candidates[0].function_calls[0]
print(function_call)

# Check the function name that the model responded with, and make an API call to an external system
if function_call.name == get_product_sku:
    # Extract the arguments to use in your API call
    product_name = function_call.args["product_name"]  # noqa: F841

    # Here you can use your preferred method to make an API request to retrieve the product SKU, as in:
    # api_response = requests.post(product_api_url, data={"product_name": product_name})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = {"sku": "GA04834-US", "in_stock": "Yes"}

# Return the API response to Gemini, so it can generate a model response or request another function call
response = chat.send_message(
    Part.from_function_response(
        name=get_product_sku,
        response={
            "content": api_response,
        },
    ),
)
# Extract the text from the model response
print(response.text)

# Send a prompt for the second conversation turn that should invoke the get_store_location function
response = chat.send_message(
    "Is there a store in Mountain View, CA that I can visit to try it out?"
)

function_call = response.candidates[0].function_calls[0]
print(function_call)

# Check the function name that the model responded with, and make an API call to an external system
if function_call.name == "get_store_location":
    # Extract the arguments to use in your API call
    location = function_call.args["location"]  # noqa: F841

    # Here you can use your preferred method to make an API request to retrieve store location closest to the user, as in:
    # api_response = requests.post(store_api_url, data={"location": location})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = {"store": "2000 N Shoreline Blvd, Mountain View, CA 94043, US"}

# Return the API response to Gemini, so it can generate a model response or request another function call
response = chat.send_message(
    Part.from_function_response(
        name="get_store_location",
        response={
            "content": api_response,
        },
    ),
)

# Extract the text from the model response
print(response.text)
# Example response:
# name: "get_product_sku"
# args {
#   fields { key: "product_name" value {string_value: "Pixel 8 Pro" }
#   }
# }
# Yes, we have the Pixel 8 Pro in stock.
# name: "get_store_location"
# args {
#   fields { key: "location" value { string_value: "Mountain View, CA" }
#   }
# }
# Yes, there is a store located at 2000 N Shoreline Blvd, Mountain View, CA 94043, US.

Java

このサンプルを試す前に、Vertex AI クイックスタート: クライアント ライブラリの使用にある Java の設定手順を完了してください。詳細については、Vertex AI Java API のリファレンス ドキュメントをご覧ください。

Vertex AI に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.Content;
import com.google.cloud.vertexai.api.FunctionDeclaration;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.api.Schema;
import com.google.cloud.vertexai.api.Tool;
import com.google.cloud.vertexai.api.Type;
import com.google.cloud.vertexai.generativeai.ChatSession;
import com.google.cloud.vertexai.generativeai.ContentMaker;
import com.google.cloud.vertexai.generativeai.GenerativeModel;
import com.google.cloud.vertexai.generativeai.PartMaker;
import com.google.cloud.vertexai.generativeai.ResponseHandler;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;

public class FunctionCalling {
  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-google-cloud-project-id";
    String location = "us-central1";
    String modelName = "gemini-1.5-flash-001";

    String promptText = "What's the weather like in Paris?";

    whatsTheWeatherLike(projectId, location, modelName, promptText);
  }

  // A request involving the interaction with an external tool
  public static String whatsTheWeatherLike(String projectId, String location,
                                           String modelName, String promptText)
      throws IOException {
    // Initialize client that will be used to send requests.
    // This client only needs to be created once, and can be reused for multiple requests.
    try (VertexAI vertexAI = new VertexAI(projectId, location)) {

      FunctionDeclaration functionDeclaration = FunctionDeclaration.newBuilder()
          .setName("getCurrentWeather")
          .setDescription("Get the current weather in a given location")
          .setParameters(
              Schema.newBuilder()
                  .setType(Type.OBJECT)
                  .putProperties("location", Schema.newBuilder()
                      .setType(Type.STRING)
                      .setDescription("location")
                      .build()
                  )
                  .addRequired("location")
                  .build()
          )
          .build();

      System.out.println("Function declaration:");
      System.out.println(functionDeclaration);

      // Add the function to a "tool"
      Tool tool = Tool.newBuilder()
          .addFunctionDeclarations(functionDeclaration)
          .build();

      // Start a chat session from a model, with the use of the declared function.
      GenerativeModel model = new GenerativeModel(modelName, vertexAI)
          .withTools(Arrays.asList(tool));
      ChatSession chat = model.startChat();

      System.out.println(String.format("Ask the question: %s", promptText));
      GenerateContentResponse response = chat.sendMessage(promptText);

      // The model will most likely return a function call to the declared
      // function `getCurrentWeather` with "Paris" as the value for the
      // argument `location`.
      System.out.println("\nPrint response: ");
      System.out.println(ResponseHandler.getContent(response));

      // Provide an answer to the model so that it knows what the result
      // of a "function call" is.
      Content content =
          ContentMaker.fromMultiModalData(
              PartMaker.fromFunctionResponse(
                  "getCurrentWeather",
                  Collections.singletonMap("currentWeather", "sunny")));
      System.out.println("Provide the function response: ");
      System.out.println(content);
      response = chat.sendMessage(content);

      // See what the model replies now
      System.out.println("Print response: ");
      String finalAnswer = ResponseHandler.getText(response);
      System.out.println(finalAnswer);

      return finalAnswer;
    }
  }
}

Go

このサンプルを試す前に、Vertex AI クイックスタート: クライアント ライブラリの使用にある Go の設定手順を完了してください。詳細については、Vertex AI Go API のリファレンス ドキュメントをご覧ください。

Vertex AI に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"

	"cloud.google.com/go/vertexai/genai"
)

// functionCallsChat opens a chat session and sends 4 messages to the model:
// - convert a first text question into a structured function call request
// - convert the first structured function call response into natural language
// - convert a second text question into a structured function call request
// - convert the second structured function call response into natural language
func functionCallsChat(w io.Writer, projectID, location, modelName string) error {
	// location := "us-central1"
	// modelName := "gemini-1.5-flash-001"
	ctx := context.Background()
	client, err := genai.NewClient(ctx, projectID, location)
	if err != nil {
		return fmt.Errorf("unable to create client: %w", err)
	}
	defer client.Close()

	model := client.GenerativeModel(modelName)

	// Build an OpenAPI schema, in memory
	paramsProduct := &genai.Schema{
		Type: genai.TypeObject,
		Properties: map[string]*genai.Schema{
			"productName": {
				Type:        genai.TypeString,
				Description: "Product name",
			},
		},
	}
	fundeclProductInfo := &genai.FunctionDeclaration{
		Name:        "getProductSku",
		Description: "Get the SKU for a product",
		Parameters:  paramsProduct,
	}
	paramsStore := &genai.Schema{
		Type: genai.TypeObject,
		Properties: map[string]*genai.Schema{
			"location": {
				Type:        genai.TypeString,
				Description: "Location",
			},
		},
	}
	fundeclStoreLocation := &genai.FunctionDeclaration{
		Name:        "getStoreLocation",
		Description: "Get the location of the closest store",
		Parameters:  paramsStore,
	}
	model.Tools = []*genai.Tool{
		{FunctionDeclarations: []*genai.FunctionDeclaration{
			fundeclProductInfo,
			fundeclStoreLocation,
		}},
	}
	model.SetTemperature(0.0)

	chat := model.StartChat()

	// Send a prompt for the first conversation turn that should invoke the getProductSku function
	prompt := "Do you have the Pixel 8 Pro in stock?"
	fmt.Fprintf(w, "Question: %s\n", prompt)
	resp, err := chat.SendMessage(ctx, genai.Text(prompt))
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has returned a function call to the declared function `getProductSku`
	// with a value for the argument `productName`.
	jsondata, err := json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "function call generated by the model:\n\t%s\n", string(jsondata))

	// Create a function call response, to simulate the result of a call to a
	// real service
	funresp := &genai.FunctionResponse{
		Name: "getProductSku",
		Response: map[string]any{
			"sku":      "GA04834-US",
			"in_stock": "yes",
		},
	}
	jsondata, err = json.MarshalIndent(funresp, "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "function call response sent to the model:\n\t%s\n\n", string(jsondata))

	// And provide the function call response to the model
	resp, err = chat.SendMessage(ctx, funresp)
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has taken the function call response as input, and has
	// reformulated the response to the user.
	jsondata, err = json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "Answer generated by the model:\n\t%s\n\n", string(jsondata))

	// Send a prompt for the second conversation turn that should invoke the getStoreLocation function
	prompt2 := "Is there a store in Mountain View, CA that I can visit to try it out?"
	fmt.Fprintf(w, "Question: %s\n", prompt)

	resp, err = chat.SendMessage(ctx, genai.Text(prompt2))
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has returned a function call to the declared function `getStoreLocation`
	// with a value for the argument `store`.
	jsondata, err = json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "function call generated by the model:\n\t%s\n", string(jsondata))

	// Create a function call response, to simulate the result of a call to a
	// real service
	funresp = &genai.FunctionResponse{
		Name: "getStoreLocation",
		Response: map[string]any{
			"store": "2000 N Shoreline Blvd, Mountain View, CA 94043, US",
		},
	}
	jsondata, err = json.MarshalIndent(funresp, "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "function call response sent to the model:\n\t%s\n\n", string(jsondata))

	// And provide the function call response to the model
	resp, err = chat.SendMessage(ctx, funresp)
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has taken the function call response as input, and has
	// reformulated the response to the user.
	jsondata, err = json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "Answer generated by the model:\n\t%s\n\n", string(jsondata))
	return nil
}

Node.js

このサンプルを試す前に、Vertex AI クイックスタート: クライアント ライブラリの使用にある Node.js の設定手順を完了してください。詳細については、Vertex AI Node.js API のリファレンス ドキュメントをご覧ください。

Vertex AI に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

const {
  VertexAI,
  FunctionDeclarationSchemaType,
} = require('@google-cloud/vertexai');

const functionDeclarations = [
  {
    function_declarations: [
      {
        name: 'get_current_weather',
        description: 'get weather in a given location',
        parameters: {
          type: FunctionDeclarationSchemaType.OBJECT,
          properties: {
            location: {type: FunctionDeclarationSchemaType.STRING},
            unit: {
              type: FunctionDeclarationSchemaType.STRING,
              enum: ['celsius', 'fahrenheit'],
            },
          },
          required: ['location'],
        },
      },
    ],
  },
];

const functionResponseParts = [
  {
    functionResponse: {
      name: 'get_current_weather',
      response: {name: 'get_current_weather', content: {weather: 'super nice'}},
    },
  },
];

/**
 * TODO(developer): Update these variables before running the sample.
 */
async function functionCallingStreamChat(
  projectId = 'PROJECT_ID',
  location = 'us-central1',
  model = 'gemini-1.5-flash-001'
) {
  // Initialize Vertex with your Cloud project and location
  const vertexAI = new VertexAI({project: projectId, location: location});

  // Instantiate the model
  const generativeModel = vertexAI.getGenerativeModel({
    model: model,
  });

  // Create a chat session and pass your function declarations
  const chat = generativeModel.startChat({
    tools: functionDeclarations,
  });

  const chatInput1 = 'What is the weather in Boston?';

  // This should include a functionCall response from the model
  const result1 = await chat.sendMessageStream(chatInput1);
  for await (const item of result1.stream) {
    console.log(item.candidates[0]);
  }
  await result1.response;

  // Send a follow up message with a FunctionResponse
  const result2 = await chat.sendMessageStream(functionResponseParts);
  for await (const item of result2.stream) {
    console.log(item.candidates[0]);
  }

  // This should include a text response from the model using the response content
  // provided above
  const response2 = await result2.response;
  console.log(response2.candidates[0].content.parts[0].text);
}

並列関数呼び出しの例

「Get weather details in New Delhi and San Francisco?」のようなプロンプトでは、モデルが複数の並列関数呼び出しを提案する場合があります。並列関数呼び出しをサポートするモデルの一覧については、サポートされているモデルをご覧ください。

REST

この例では、1 つの get_current_weather 関数を使用するシナリオを示します。ユーザー プロンプトは「Get weather details in New Delhi and San Francisco?」です。モデルは、パラメータ New Delhi を指定した場合と、パラメータ San Francisco を指定した場合の get_current_weather 関数の 2 つの並列呼び出しを提案しています。

モデル リクエストのパラメータの詳細については、Gemini API をご覧ください。

candidates {
content {
  role: "model"
  parts: [
    {
      function_call {
        name: "get_current_weather"
        args {
          fields {
            key: "location"
            value {
              string_value: "New Delhi"
            }
          }
        }
      }
    },
    {
      function_call {
        name: "get_current_weather"
        args {
          fields {
            key: "location"
            value {
              string_value: "San Francisco"
            }
          }
        }
      }
    }
  ]
}
...
}

次のコマンドは、関数の出力をモデルに提供する方法を示しています。my-project は、Google Cloud プロジェクトの名前で置き換えます。

モデルのリクエスト

PROJECT_ID=my-project
MODEL_ID=gemini-1.5-pro-002
VERSION="v1"
LOCATION="us-central1"
ENDPOINT=${LOCATION}-aiplatform.googleapis.com
API="generateContent"
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json"  https://${ENDPOINT}/${VERSION}/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:${API} -d '{
"contents": [
    {
        "role": "user",
        "parts": {
            "text": "What is difference in temperature in New Delhi and San Francisco?"
        }
    },
    {
        "role": "model",
        "parts": [
            {
                "functionCall": {
                    "name": "get_current_weather",
                    "args": {
                        "location": "New Delhi"
                    }
                }
            },
            {
                "functionCall": {
                    "name": "get_current_weather",
                    "args": {
                        "location": "San Francisco"
                    }
                }
            }
        ]
    },
    {
        "role": "user",
        "parts": [
            {
                "functionResponse": {
                    "name": "get_current_weather",
                    "response": {
                        "temperature": 30.5,
                        "unit": "C"
                    }
                }
            },
            {
                "functionResponse": {
                    "name": "get_current_weather",
                    "response": {
                        "temperature": 20,
                        "unit": "C"
                    }
                }
            }
        ]
    }
],
"tools": [
    {
        "function_declarations": [
            {
                "name": "get_current_weather",
                "description": "Get the current weather in a specific location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
                        }
                    },
                    "required": [
                        "location"
                    ]
                }
            }
        ]
    }
]
}'
  

モデルによって作成された自然言語のレスポンスは次のようになります。

モデルのレスポンス

[
{
    "candidates": [
        {
            "content": {
                "parts": [
                    {
                        "text": "The temperature in New Delhi is 30.5C and the temperature in San Francisco is 20C. The difference is 10.5C. \n"
                    }
                ]
            },
            "finishReason": "STOP",
            ...
        }
    ]
    ...
}
]
  

Python

import vertexai

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

# TODO(developer): Update & uncomment below line
# PROJECT_ID = "your-project-id"

# Initialize Vertex AI
vertexai.init(project=PROJECT_ID, location="us-central1")

# Specify a function declaration and parameters for an API request
function_name = "get_current_weather"
get_current_weather_func = FunctionDeclaration(
    name=function_name,
    description="Get the current weather in a given location",
    parameters={
        "type": "object",
        "properties": {
            "location": {
                "type": "string",
                "description": "The location for which to get the weather. \
                  It can be a city name, a city name and state, or a zip code. \
                  Examples: 'San Francisco', 'San Francisco, CA', '95616', etc.",
            },
        },
    },
)

# In this example, we'll use synthetic data to simulate a response payload from an external API
def mock_weather_api_service(location: str) -> str:
    temperature = 25 if location == "San Francisco" else 35
    return f"""{{ "location": "{location}", "temperature": {temperature}, "unit": "C" }}"""

# Define a tool that includes the above function
tools = Tool(
    function_declarations=[get_current_weather_func],
)

# Initialize Gemini model
model = GenerativeModel(
    model_name="gemini-1.5-pro-002",
    tools=[tools],
)

# Start a chat session
chat_session = model.start_chat()
response = chat_session.send_message(
    "Get weather details in New Delhi and San Francisco?"
)

function_calls = response.candidates[0].function_calls
print("Suggested finction calls:\n", function_calls)

if function_calls:
    api_responses = []
    for func in function_calls:
        if func.name == function_name:
            api_responses.append(
                {
                    "content": mock_weather_api_service(
                        location=func.args["location"]
                    )
                }
            )

    # Return the API response to Gemini
    response = chat_session.send_message(
        [
            Part.from_function_response(
                name="get_current_weather",
                response=api_responses[0],
            ),
            Part.from_function_response(
                name="get_current_weather",
                response=api_responses[1],
            ),
        ],
    )

    print(response.text)
    # Example response:
    # The current weather in New Delhi is 35°C. The current weather in San Francisco is 25°C.

関数呼び出しのベスト プラクティス

関数名

関数名にピリオド(.)、ダッシュ(-)、スペース文字は使用しないでください。代わりに、アンダースコア(_)か他の文字を使用します。

関数の説明

関数の説明はわかりやすく丁寧に記述します。たとえば、book_flight_ticket 関数の場合:

  • 関数の適切な説明の例: book flight tickets after confirming users' specific requirements, such as time, departure, destination, party size and preferred airline
  • 関数の不適切な説明の例: book flight ticket

関数のパラメータ

説明

パラメータの説明は、希望する形式や値などの詳細を含めて、明確かつ詳細に記述します。たとえば、book_flight_ticket 関数の場合:

  • departure パラメータの適切な説明の例: Use the 3 char airport code to represent the airport. For example, SJC or SFO. Don't use the city name.
  • departure パラメータの不適切な説明の例: the departure airport

可能であれば、モデルのハルシネーションを減らすために、厳密に型指定されたパラメータを使用してください。たとえば、パラメータ値が有限集合の場合、値の集合を説明に入れるのではなく、enum フィールドを追加します。パラメータ値が常に整数の場合は、型を number ではなく integer に設定します。

システム指示

日付、時刻、位置情報のパラメータを伴う関数を使用する場合は、現在の日付、時刻、関連する位置情報(都市や国など)をシステム指示に含めます。これにより、ユーザーのプロンプトに詳細情報が含まれない場合でも、リクエストを正確に処理するために必要なコンテキストが提供されます。

ユーザー プロンプト

最適な結果を得るには、ユーザー プロンプトの先頭に次の詳細を付加します。

  • モデルの追加コンテキスト(例: You are a flight API assistant to help with searching flights based on user preferences.
  • 関数の使用方法と使用のタイミングに関する詳細や手順(例: Don't make assumptions on the departure or destination airports. Always use a future date for the departure or destination time.
  • ユーザーからの質問があいまいな場合に、質問を明確にするための指示(例: Ask clarifying questions if not enough information is available.

生成構成

温度パラメータには、0 または別の小さい値を使用します。これにより、より確信度の高い結果を生成してハルシネーションを減らすようにモデルに指示します。

API 呼び出し

注文の送信やデータベースの更新など、重大な結果をもたらすような関数の呼び出しをモデルが提案する場合は、それを実行する前にユーザーにその関数呼び出しの妥当性を確認してください。

料金

関数呼び出しの料金は、テキストの入力と出力の文字数に基づいて決まります。詳細については、Vertex AI の料金をご覧ください。

ここで、テキスト入力(プロンプト)は、現在の会話ターンのユーザー プロンプト、現在の会話ターンの関数宣言、会話の履歴を参照します。会話の履歴には、以前の会話ターンのクエリ、関数呼び出し、関数レスポンスが含まれます。Vertex AI は、会話の履歴を 32,000 文字で切り捨てます。

テキスト出力(レスポンス)は、現在の会話ターンの関数呼び出しとテキスト レスポンスを表します。

次のステップ