関数呼び出しの概要

関数呼び出し(ツールの使用とも呼ばれます)は、LLM に外部ツール(get_current_weather 関数など)の定義を提供します。プロンプトを処理する際、モデルはツールが必要かどうかをインテリジェントに判断し、必要であれば、呼び出すツールとそのパラメータ(get_current_weather(location='Boston') など)を指定する構造化データを出力します。アプリケーションはこのツールを実行し、結果をモデルにフィードバックします。これにより、モデルは動的な実世界の情報やアクションの結果を使用してレスポンスを完了できます。これにより、LLM とシステムが効果的に連携し、機能が拡張されます。

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

関数呼び出しでは、次の 2 つの主なユースケースが可能です。

  • データの取得: 現在の天候、通貨換算、ナレッジベースや API からの特定のデータ(RAG)など、モデルのレスポンスに必要な最新情報を取得します。

  • アクションの実行: フォームの送信、アプリケーションの状態の更新、エージェント ワークフローのオーケストレーション(会話の引き継ぎなど)などの外部オペレーションを実行します。

関数呼び出しを活用したその他のユースケースと例については、ユースケースをご覧ください。

機能と制限事項

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

関数呼び出しを使用するには、次のタスクを行います。

  1. 関数宣言とプロンプトをモデルに送信する
  2. API 出力をモデルに提供する

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

OpenAPI スキーマと互換性のあるスキーマ形式で Tool を宣言します。詳細については、スキーマの例をご覧ください。

次の例では、プロンプトと関数宣言を Gemini モデルに送信します。

REST

PROJECT_ID=myproject
LOCATION=us-central1
MODEL_ID=gemini-2.0-flash-001

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:generateContent \
  -d '{
    "contents": [{
      "role": "user",
      "parts": [{
        "text": "What is the weather in Boston?"
      }]
    }],
    "tools": [{
      "functionDeclarations": [
        {
          "name": "get_current_weather",
          "description": "Get the current weather in a given location",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city name of the location for which to get the weather.",
                "default": {
                  "string_value": "Boston, MA"
                }
              }
            },
            "required": [
              "location"
            ]
          }
        }
      ]
    }]
  }'

Python

スキーマは、Python 辞書を使用して手動で指定することも、from_func ヘルパー関数を使用して自動的に指定することもできます。次の例は、関数��手動で宣言する方法を示しています。

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

# Initialize Vertex AI
# TODO(developer): Update the project
vertexai.init(project="PROJECT_ID", location="us-central1")

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

# Manual function declaration
get_current_weather_func = FunctionDeclaration(
    name="get_current_weather",
    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.",
              "default": {
                "string_value": "Boston, MA"
              }
           }
        },
    },
)

response = model.generate_content(
    contents = [
      Content(
        role="user",
          parts=[
              Part.from_text("What is the weather like in Boston?"),
          ],
      )
    ],
    generation_config = GenerationConfig(temperature=0),
    tools = [
      Tool(
        function_declarations=[get_current_weather_func],
      )
    ]
)

次の例に示すように、from_func ヘルパー関数を使用して関数を自動的に宣言することもできます。

def get_current_weather(location: str = "Boston, MA"):
  """
  Get the current weather in a given location

  Args:
      location: The city name of the location for which to get the weather.

  """
  # This example uses a mock implementation.
  # You can define a local function or import the requests library to call an API
  return {
    "location": "Boston, MA",
    "temperature": 38,
    "description": "Partly Cloudy",
    "icon": "partly-cloudy",
    "humidity": 65,
    "wind": {
        "speed": 10,
        "direction": "NW"
    }
  }
get_current_weather_func = FunctionDeclaration.from_func(get_current_weather)

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-2.0-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: 'ASSISTANT',
        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);
  }
}

Go

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

Go をインストールまたは更新する方法について学びます。

詳しくは、SDK リファレンス ドキュメントをご覧ください。

Vertex AI で Gen AI SDK を使用するための環境変数を設定します。

# Replace the `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` values
# with appropriate values for your project.
export GOOGLE_CLOUD_PROJECT=GOOGLE_CLOUD_PROJECT
export GOOGLE_CLOUD_LOCATION=global
export GOOGLE_GENAI_USE_VERTEXAI=True

import (
	"context"
	"fmt"
	"io"

	genai "google.golang.org/genai"
)

// generateWithFuncCall shows how to submit a prompt and a function declaration to the model,
// allowing it to suggest a call to the function to fetch external data. Returning this data
// enables the model to generate a text response that incorporates the data.
func generateWithFuncCall(w io.Writer) error {
	ctx := context.Background()

	client, err := genai.NewClient(ctx, &genai.ClientConfig{
		HTTPOptions: genai.HTTPOptions{APIVersion: "v1"},
	})
	if err != nil {
		return fmt.Errorf("failed to create genai client: %w", err)
	}

	weatherFunc := &genai.FunctionDeclaration{
		Description: "Returns the current weather in a location.",
		Name:        "getCurrentWeather",
		Parameters: &genai.Schema{
			Type: "object",
			Properties: map[string]*genai.Schema{
				"location": {Type: "string"},
			},
			Required: []string{"location"},
		},
	}
	config := &genai.GenerateContentConfig{
		Tools: []*genai.Tool{
			{FunctionDeclarations: []*genai.FunctionDeclaration{weatherFunc}},
		},
		Temperature: genai.Ptr(float32(0.0)),
	}

	modelName := "gemini-2.5-flash"
	contents := []*genai.Content{
		{Parts: []*genai.Part{
			{Text: "What is the weather like in Boston?"},
		},
			Role: "user"},
	}

	resp, err := client.Models.GenerateContent(ctx, modelName, contents, config)
	if err != nil {
		return fmt.Errorf("failed to generate content: %w", err)
	}

	var funcCall *genai.FunctionCall
	for _, p := range resp.Candidates[0].Content.Parts {
		if p.FunctionCall != nil {
			funcCall = p.FunctionCall
			fmt.Fprint(w, "The model suggests to call the function ")
			fmt.Fprintf(w, "%q with args: %v\n", funcCall.Name, funcCall.Args)
			// Example response:
			// The model suggests to call the function "getCurrentWeather" with args: map[location:Boston]
		}
	}
	if funcCall == nil {
		return fmt.Errorf("model did not suggest a function call")
	}

	// Use synthetic data to simulate a response from the external API.
	// In a real application, this would come from an actual weather API.
	funcResp := &genai.FunctionResponse{
		Name: "getCurrentWeather",
		Response: map[string]any{
			"location":         "Boston",
			"temperature":      "38",
			"temperature_unit": "F",
			"description":      "Cold and cloudy",
			"humidity":         "65",
			"wind":             `{"speed": "10", "direction": "NW"}`,
		},
	}

	// Return conversation turns and API response to complete the model's response.
	contents = []*genai.Content{
		{Parts: []*genai.Part{
			{Text: "What is the weather like in Boston?"},
		},
			Role: "user"},
		{Parts: []*genai.Part{
			{FunctionCall: funcCall},
		}},
		{Parts: []*genai.Part{
			{FunctionResponse: funcResp},
		}},
	}

	resp, err = client.Models.GenerateContent(ctx, modelName, contents, config)
	if err != nil {
		return fmt.Errorf("failed to generate content: %w", err)
	}

	respText := resp.Text()

	fmt.Fprintln(w, respText)

	// Example response:
	// The weather in Boston is cold and cloudy with a temperature of 38 degrees Fahrenheit. The humidity is ...

	return nil
}

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-2.0-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;
    }
}

Java

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-2.0-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;
    }
  }
}

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

ユーザー プロンプト「ボストンの天気は?」に対するモデル レスポンスの例を次に示します。モデルは、パラメータ 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"
            }
          }
        }
      }
    }
  }
  ...
}

ステップ 2: API 出力をモデルに提供する

外部 API を呼び出し、API 出力をモデルに返します。

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

REST

PROJECT_ID=myproject
MODEL_ID=gemini-2.0-flash
LOCATION="us-central1"

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:generateContent \
-d '{
"contents": [
{
  "role": "user",
  "parts": {
    "text": "What is the weather in Boston?"
  }
},
{
  "role": "model",
  "parts": [
    {
      "functionCall": {
        "name": "get_current_weather",
        "args": {
          "location": "Boston, MA"
        }
      }
    }
  ]
},
{
  "role": "user",
  "parts": [
    {
      "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 name of the location for which to get the weather."
          }
        },
        "required": [
          "location"
        ]
      }
    }
  ]
}
]
}'

Python

function_response_contents = []
function_response_parts = []

# Iterates through the function calls in the response in case there are parallel function call requests
for function_call in response.candidates[0].function_calls:
    print(f"Function call: {function_call.name}")

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    if (function_call.args['location'] == "Boston, MA"):
      api_response = { "location": "Boston, MA", "temperature": 38, "description": "Partly Cloudy" }
    if (function_call.args['location'] == "San Francisco, CA"):
      api_response = { "location": "San Francisco, CA", "temperature": 58, "description": "Sunny" }

    function_response_parts.append(
        Part.from_function_response(
            name=function_call.name,
            response={"contents": api_response}
        )
    )
    # Add the function call response to the contents
    function_response_contents = Content(role="user", parts=function_response_parts)

# Submit the User's prompt, model's response, and API output back to the model
response = model.generate_content(
  [
    Content( # User prompt
      role="user",
      parts=[
          Part.from_text("What is the weather like in Boston?"),
      ],
    ),
    response.candidates[0].content,  # Function call response
    function_response_contents   # API output
  ],
  tools=[
    Tool(
      function_declarations=[get_current_weather_func],
    )
  ],
)
# Get the model summary response
print(response.text)

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

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

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

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

It is currently 38 degrees Fahrenheit in Boston, MA with partly cloudy skies.

思考を伴う関数呼び出し

thinking を有効にして関数を呼び出す場合は、モデル レスポンス オブジェクトから thought_signature を取得し、関数の実行結果をモデルに送信するときに返す必要があります。例:

Python

# Call the model with function declarations
# ...Generation config, Configure the client, and Define user prompt (No changes)

# Send request with declarations (using a thinking model)
response = client.models.generate_content(
  model="gemini-2.5-flash", config=config, contents=contents)

# See thought signatures
for part in response.candidates[0].content.parts:
  if not part.text:
    continue
  if part.thought and part.thought_signature:
    print("Thought signature:")
    print(part.thought_signature)

思考シグネチャを表示する必要はありませんが、ステップ 2 を調整して、関数実行の結果とともにシグネチャを返す必要があります。これにより、思考を最終レスポンスに組み込むことができます。

Python

# Create user friendly response with function result and call the model again
# ...Create a function response part (No change)

# Append thought signatures, function call and result of the function execution to contents
function_call_content = response.candidates[0].content
# Append the model's function call message, which includes thought signatures
contents.append(function_call_content)
contents.append(types.Content(role="user", parts=[function_response_part])) # Append the function response

final_response = client.models.generate_content(
    model="gemini-2.5-flash",
    config=config,
    contents=contents,
)

print(final_response.text)

思考シグネチャを返す場合は、次のガイドラインに従ってください。

  • モデルは、レスポンスの他の部分(関数呼び出し、テキスト、思考サマリーなど)にシグネチャを返します。後続のターンで、すべての部分を含む���スポンス全体をモデルに返します。
  • シグネチャを含むパートを、シグネチャを含む別のパートと結合しないでください。シグネチャを連結することはできません。
  • シグネチャ付きのパートとシグネチャなしのパートを結合しないでください。結合すると、シグネチャで表される思考の正しい位置付けが損なわれます。

思考シグネチャの制限事項と使用方法、および思考モデル全般については、思考のページをご覧ください。

並列関数呼び出し

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

REST

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

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

{
"candidates": [
  {
    "content": {
      "role": "model",
      "parts": [
        {
          "functionCall": {
            "name": "get_current_weather",
            "args": {
              "location": "Boston"
            }
          }
        },
        {
          "functionCall": {
            "name": "get_current_weather",
            "args": {
              "location": "San Francisco"
            }
          }
        }
      ]
    },
    ...
  }
],
...
}

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

モデルのリクエスト

PROJECT_ID=my-project
MODEL_ID=gemini-2.0-flash
LOCATION="us-central1"
curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:generateContent \
-d '{
"contents": [
{
  "role": "user",
  "parts": {
    "text": "What is difference in temperature in Boston and San Francisco?"
  }
},
{
  "role": "model",
  "parts": [
    {
      "functionCall": {
        "name": "get_current_weather",
        "args": {
          "location": "Boston"
        }
      }
    },
    {
      "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 name of the location for which to get the weather."
          }
        },
        "required": [
          "location"
        ]
      }
    }
  ]
}
]
}'
  

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

モデルのレスポンス

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

Python

この例では、1 つの get_current_weather 関数を使用するシナリオを示します。ユーザー プロンプトは「What is the weather like in Boston and San Francisco?」です。

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

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

# Initialize Vertex AI
# TODO(developer): Update the project
vertexai.init(project="my-project", location="us-central1")

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

# Manual function declaration
get_current_weather_func = FunctionDeclaration(
    name="get_current_weather",
    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.",
              "default": {
                "string_value": "Boston, MA"
              }
          }
        },
    },
)

response = model.generate_content(
    contents = [
      Content(
        role="user",
          parts=[
              Part.from_text("What is the weather like in Boston and San Francisco?"),
          ],
      )
    ],
    generation_config = GenerationConfig(temperature=0),
    tools = [
      Tool(
        function_declarations=[get_current_weather_func],
      )
    ]
)

次のコマンドは、関数の出力をモデルに提供する方法を示しています。

function_response_contents = []
function_response_parts = []

# You can have parallel function call requests for the same function type.
# For example, 'location_to_lat_long("London")' and 'location_to_lat_long("Paris")'
# In that case, collect API responses in parts and send them back to the model

for function_call in response.candidates[0].function_calls:
    print(f"Function call: {function_call.name}")

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    if (function_call.args['location'] == "Boston, MA"):
      api_response = { "location": "Boston, MA", "temperature": 38, "description": "Partly Cloudy" }
    if (function_call.args['location'] == "San Francisco, CA"):
      api_response = { "location": "San Francisco, CA", "temperature": 58, "description": "Sunny" }

    function_response_parts.append(
        Part.from_function_response(
            name=function_call.name,
            response={"contents": api_response}
        )
    )
    # Add the function call response to the contents
    function_response_contents = Content(role="user", parts=function_response_parts)

function_response_contents

response = model.generate_content(
    contents = [
        Content(
        role="user",
          parts=[
              Part.from_text("What is the weather like in Boston and San Francisco?"),
          ],
        ),  # User prompt
        response.candidates[0].content,  # Function call response
        function_response_contents,  # Function response
    ],
    tools = [
      Tool(
        function_declarations=[get_current_weather_func],
      )
    ]
)
# Get the model summary response
print(response.text)

Go

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

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

// parallelFunctionCalling shows how to execute multiple function calls in parallel
// and return their results to the model for generating a complete response.
func parallelFunctionCalling(w io.Writer, projectID, location, modelName string) error {
	// location = "us-central1"
	// modelName = "gemini-2.0-flash-001"
	ctx := context.Background()
	client, err := genai.NewClient(ctx, projectID, location)
	if err != nil {
		return fmt.Errorf("failed to create GenAI client: %w", err)
	}
	defer client.Close()

	model := client.GenerativeModel(modelName)
	// Set temperature to 0.0 for maximum determinism in function calling.
	model.SetTemperature(0.0)

	funcName := "getCurrentWeather"
	funcDecl := &genai.FunctionDeclaration{
		Name:        funcName,
		Description: "Get the current weather in a given location",
		Parameters: &genai.Schema{
			Type: genai.TypeObject,
			Properties: map[string]*genai.Schema{
				"location": {
					Type: genai.TypeString,
					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.",
				},
			},
			Required: []string{"location"},
		},
	}
	// Add the weather function to our model toolbox.
	model.Tools = []*genai.Tool{
		{
			FunctionDeclarations: []*genai.FunctionDeclaration{funcDecl},
		},
	}

	prompt := genai.Text("Get weather details in New Delhi and San Francisco?")
	resp, err := model.GenerateContent(ctx, prompt)

	if err != nil {
		return fmt.Errorf("failed to generate content: %w", err)
	}
	if len(resp.Candidates) == 0 {
		return errors.New("got empty response from model")
	} else if len(resp.Candidates[0].FunctionCalls()) == 0 {
		return errors.New("got no function call suggestions from model")
	}

	// In a production environment, consider adding validations for function names and arguments.
	for _, fnCall := range resp.Candidates[0].FunctionCalls() {
		fmt.Fprintf(w, "The model suggests to call the function %q with args: %v\n", fnCall.Name, fnCall.Args)
		// Example response:
		// The model suggests to call the function "getCurrentWeather" with args: map[location:New Delhi]
		// The model suggests to call the function "getCurrentWeather" with args: map[location:San Francisco]
	}

	// Use synthetic data to simulate responses from the external API.
	// In a real application, this would come from an actual weather API.
	mockAPIResp1, err := json.Marshal(map[string]string{
		"location":         "New Delhi",
		"temperature":      "42",
		"temperature_unit": "C",
		"description":      "Hot and humid",
		"humidity":         "65",
	})
	if err != nil {
		return fmt.Errorf("failed to marshal function response to JSON: %w", err)
	}

	mockAPIResp2, err := json.Marshal(map[string]string{
		"location":         "San Francisco",
		"temperature":      "36",
		"temperature_unit": "F",
		"description":      "Cold and cloudy",
		"humidity":         "N/A",
	})
	if err != nil {
		return fmt.Errorf("failed to marshal function response to JSON: %w", err)
	}

	// Note, that the function calls don't have to be chained. We can obtain both responses in parallel
	// and return them to Gemini at once.
	funcResp1 := &genai.FunctionResponse{
		Name: funcName,
		Response: map[string]any{
			"content": mockAPIResp1,
		},
	}
	funcResp2 := &genai.FunctionResponse{
		Name: funcName,
		Response: map[string]any{
			"content": mockAPIResp2,
		},
	}

	// Return both API responses to the model allowing it to complete its response.
	resp, err = model.GenerateContent(ctx, prompt, funcResp1, funcResp2)
	if err != nil {
		return fmt.Errorf("failed to generate content: %w", err)
	}
	if len(resp.Candidates) == 0 || len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("got empty response from model")
	}

	fmt.Fprintln(w, resp.Candidates[0].Content.Parts[0])
	// Example response:
	// The weather in New Delhi is hot and humid with a humidity of 65 and a temperature of 42°C. The weather in San Francisco ...

	return nil
}

関数呼び出しモード

function_calling_config 内でモードを設定することで、モデルが提供されたツール(関数宣言)を使用する方法を制御できます。

モード 説明
AUTO デフォルトのモデル動作。モデルは、コンテキストに基づいて関数呼び出しを予測するか、自然言語で応答するかを決定します。これは最も柔軟なモードであり、ほとんどのシナリオにおすすめです。
VALIDATED(プレビュー) モデルは、関数呼び出しまたは自然言語のいずれかを予測するように制約され、関数スキーマの準拠が保証されます。allowed_function_names が指定されていない場合、モデルは使用可能なすべての関数宣言から選択します。allowed_function_names が指定されている場合、モデルは許可された関数のセットから選択します。
ANY モデルは、常に 1 つ以上の関数呼び出しを予測するように制約され、関数スキーマの準拠が保証されます。allowed_function_names が指定されていない場合、モデルは使用可能なすべての関数宣言から選択します。allowed_function_names が指定されている場合、モデルは許可された関数のセットから選択します。すべてのプロンプトに関数呼び出しのレスポンスが必要な場合は、このモードを使用します(該当する場合)。
NONE モデルは関数呼び出しを行うことが禁止されています。これは、関数宣言なしでリクエストを送信するのと同じです。このモードを使用すると、ツール定義を削除せずに関数呼び出しを一時的に無効にできます。

強制関数呼び出し

モデルに自然言語によるレスポンスと関数呼び出しのどちらかを選択させるのではなく、関数呼び出しのみを予測するように強制できます。これは強制関数呼び出しと呼ばれます。関数宣言の全セットをモデルに提供し、そのレスポンスをこれらの関数のサブセットに制限することもできます。

次の例では、get_weather 関数呼び出しのみを予測するように強制されています。

Python

response = model.generate_content(
    contents = [
      Content(
        role="user",
          parts=[
              Part.from_text("What is the weather like in Boston?"),
          ],
      )
    ],
    generation_config = GenerationConfig(temperature=0),
    tools = [
      Tool(
        function_declarations=[get_weather_func, some_other_function],
      )
    ],
    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_weather"],
        )
    )
)

関数スキーマの例

関数宣言は OpenAPI スキーマと互換性があります。サポートされている属性は、typenullablerequiredformatdescriptionpropertiesitemsenumanyOf$ref$defs です。残りの属性はサポートされていません。

オブジェクト パラメータと配列パラメータを含む関数

次の例では、Python 辞書を使用して、オブジェクト パラメータと配列パラメータの両方を受け取る関数を宣言しています。

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 辞書を使用して、整数 enum パラメータを受け取る関数を宣言しています。

set_status_func = FunctionDeclaration(
  name="set_status",
  description="set a ticket's status field",
  # Function parameters are specified in JSON schema format
  parameters={
      "type": "object",
      "properties": {
        "status": {
          "type": "integer",
          "enum": [ "10", "20", "30" ],   # Provide integer (or any other type) values as strings.
        }
      },
  },
)
  

ref と def を含む関数

次の JSON 関数宣言では、ref 属性と defs 属性を使用しています。

{
  "contents": ...,
  "tools": [
    {
      "function_declarations": [
        {
          "name": "get_customer",
          "description": "Search for a customer by name",
          "parameters": {
            "type": "object",
            "properties": {
              "first_name": { "ref": "#/defs/name" },
              "last_name": { "ref": "#/defs/name" }
            },
            "defs": {
              "name": { "type": "string" }
            }
          }
        }
      ]
    }
  ]
}
  

使用上の注意:

  • OpenAPI スキーマとは異なり、$ 記号なしで refdefs を指定します。
  • refdefs の直接の子を参照する必要があります。外部参照は使用できません。
  • ネストされたスキーマの最大深度は 32 です。
  • defs(自己参照)の再帰回数は 2 に制限されています。

配列パラメータを持つ from_func

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

from typing import List

# Define a function. Could be a local function or you can import the requests library to call an API
def multiply_numbers(numbers: List[int] = [1, 1]) -> int:
  """
  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': {'properties': {'numbers': {'items': {'type': 'INTEGER'},
    'description': 'list of numbers',
    'default': [1.0, 1.0],
    'title': 'Numbers',
    'type': 'ARRAY'}},
  'description': 'Calculates the product of all numbers in an array.',
  'title': 'multiply_numbers',
  'property_ordering': ['numbers'],
  'type': 'OBJECT'}}
"""
  

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

明確で詳細な関数名、パラメータの説明、手順を記述する

  • 関数名は英字またはアンダースコアで始め、a~z、A~Z、0~9、アンダースコア、ピリオド、ダッシュのみを含め、64 文字以内にする必要があります。

  • 関数とパラメータの説明は、非常に明確かつ具体的に記述します。モデルは、この説明に基づいて正しい関数を選択し、適切な引数を指定します。たとえば、book_flight_ticket 関数に book flight tickets after confirming users' specific requirements, such as time, departure, destination, party size and preferred airline という説明を付けることができます。

厳密に型指定されたパラメータを使用する

パラメータ値が有限集合の場合、値の集合を説明に入れるのではなく、enum フィールドを追加します。パラメータ値が常に整数の場合は、型を number ではなく integer に設定します。

ツールの選択

モデルでは任意の数のツールを使用できますが、ツールが多すぎると、誤ったツールや最適でないツールが選択されるリスクが高まる可能性があります。最良の結果を得るには、コンテキストやタスクに関連するツールのみを提供することを目指します。理想的には、アクティブなセットを最大 10~20 個に保ちます。ツールの合計数が多い場合は、会話のコンテキストに基づく動的なツール選択を検討してください。

汎用的なローレベルのツール(bash など)を提供すると、モデルがそのツールをより頻繁に使用する可能性がありますが、精度は低下します。特定のハイレベルのツール(get_weather など)を指定すると、モデルはツールをより正確に使用できますが、ツールの使用頻度は低くなる可能性があります。

システム指示を使用する

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

��ロンプト エンジニアリング

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

  • モデルの追加コンテキスト(例: 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.

生成構成を使用する

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

API 呼び出しを検証する

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

思考シグネチャを使用する

思考シグネチャは、最適な結果を得るために、常に関数呼び出しとともに使用する必要があります。

料金

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

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

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

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

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

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

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

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

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

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

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

次のステップ