NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

注目のタグ

    Vertex AI 入門 Function Calling(関数呼び出し)を使ってみよう

    本記事は  【Advent Calendar 2025】  8日目の記事です。
    🌟🎄  7日目  ▶▶ 本記事 ▶▶  9日目  🎅🎁

    こんにちは。横田です。 今回はVertex AIのFunction Calling(関数呼び出し)機能を使って、計算機能を持った簡易的なAIチャットボットを作成する方法をご紹介します。 想定する読者層は以下の通りです。

    • Vertex AIを使い始めたばかりの方
    • Function Calling(関数呼び出し)を実際に試してみたい方

    1. はじめに

    使用するサービスはVertex AIです。 開発環境にはVertex AI Workbenchを使用します。 Vertex AI Workbenchは、Jupyterノートブックベースのフルマネージドな開発環境です。 Vertex AI Workbenchを利用することで、認証周りの設定や環境構築の手間を省き、即座に開発に取り掛かることが可能です。

    https://docs.cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling?hl=jaから引用

    Function Calling(関数呼び出し)とは、LLMに外部ツール(自作関数やAPI)の定義をあらかじめ教えておき、ユーザーの質問に対して「ツールを使う必要があるか」をモデル自身に判断させる機能です。 Function Callingを使うことで、外部APIで最新情報を取得したり、正確な計算を行ったりすることが可能になります。 これにより、ハルシネーション(もっともらしい嘘)の抑制や、回答精度の向上が期待できます。

    2. 実装

    それでは、実装していきます。 参考にしたドキュメントは下記になります。

    Vertex AI Workbench の概要  |  Google Cloud Documentation

    関数呼び出しの概要  |  Generative AI on Vertex AI  |  Google Cloud Documentation

    関数呼び出しのリファレンス  |  Generative AI on Vertex AI  |  Google Cloud Documentation

    2.1 開発のための初期設定

    まずは、必要なライブラリのインストールと環境設定を行います。 Vertex AI SDKのバージョンは1.128.0を使用しています。

    #ライブラリのインストール
    ! pip3 install --upgrade --quiet --user google-cloud-aiplatform==1.128.0
    
    #カーネル再起動
    import IPython
    app = IPython.Application.instance()
    app.kernel.do_shutdown(True)
    

    出力

    次に、Project IDやRegionなどの環境変数を設定し、Vertex AI SDKを初期化します。

    #初期設定
    import vertexai
    PROJECT_ID = ! gcloud config get-value project
    PROJECT_ID = PROJECT_ID[0]
    LOCATION = "us-central1" # @param {type:"string"}
    print(PROJECT_ID)
    vertexai.init(project=PROJECT_ID, location=LOCATION)
    
    # Geminiモデルを使うための準備
    import requests
    from vertexai.generative_models import (
        Content,
        FunctionDeclaration,
        GenerationConfig,
        GenerativeModel,
        Part,
        Tool,
    )
    

    出力

    2.2 関数の作成とツールの定義

    呼び出しを行うための関数を作成します。 シンプルに「加算(足し算)」と「乗算(掛け算)」を行う2つのPython関数を用意しました。

    #関数作成
    #2つの数値入力を加算し、結果を返す関数
    def add_fun(x,y):
        print("Calling add function")
        return int(x)+int(y)
    
    #2つの数値入力を乗算し、結果を返す関数
    def multiply_func(x,y):
        print("Calling multiply function")
        return int(x)*int(y)
    
    #関数宣言を作成
    add_function = FunctionDeclaration(
        name="add",
        description="質問から計算方法を判別し、加算を算出します。",
        parameters={
            "type": "object",
            "properties": {
                "x": {"type": "string", "description": "x."},
                "y": {"type": "string", "description": "y."},
            },
        },
    )
    
    multiply_function = FunctionDeclaration(
        name="multiply",
        description="質問から計算方法を判別し、乗算を算出します。",
        parameters={
            "type": "object",
            "properties": {
                "x": {"type": "string", "description": "x."},
                "y": {"type": "string", "description": "y."},
            },
        },
    )
    

    関数機能を使用するためのToolsを定義し、AIモデルを初期化します。 使用するAIモデルは「gemini-2.5-flash」です。 ここで注目して欲しいのが「system_instruction」パラメータです。 これはAIに対する「役割の設定」を自然言語で行っています。 今回はFunction Callingの挙動を明確にするため、提供された関数で計算できない質問には「答えない」というルールを設定しています。

    tool = Tool(
        function_declarations=[
            add_function,
            multiply_function,
        ],
    )
    
    # モデルの定義
    model = GenerativeModel(
        model_name="gemini-2.5-flash",
        generation_config=GenerationConfig(temperature=0),
        system_instruction=[
            """
            あなたはユーザーの指示に従います。
            用意された関数を求められたら、用意された関数を呼び出します。
            必要であれば、もう一度用意された関数を呼び出します。
            用意された関数に関係ないことを聞かれた場合は、「その質問には答えられません。違うエージェントに聞いてみてください。」と答えてください。
            """,
        ],
        tools=[tool],
    )
    

    ユーザーの入力に対し、モデルが「関数の呼び出し」を要求した場合、自動でその関数を実行して結果を返すロジックを実装します。

    def handle_response(response):
        if response.candidates[0].function_calls:
            function_call = response.candidates[0].function_calls[0]
        else:
            print(response.text)
            return
        # add関数を要求した場合
        if function_call.name == "add":  
            # 関数で使用する引数を抽出
            x_args = function_call.args.get('x')
            y_args = function_call.args.get('y')
            # 関数を呼び出す
            z_add = add_fun(x_args,y_args) 
            # 結果をモデル経由でチャットセッションに送信
            response = chat.send_message(
                Part.from_function_response(
                    name=function_call.name,
                    response={
                        "content": z_add,
                    },
                ),
            )
            # 再帰処理
            return handle_response(response)
    
        # multiply関数を要求した場合
        elif function_call.name == "multiply":
            # 関数内で使用する引数を抽出
            x_args = function_call.args.get('x')
            y_args = function_call.args.get('y')
            # 関数を呼び出す
            z_add = multiply_func(x_args,y_args)
            # 結果をモデルと共にチャット セッションに送信
            response = chat.send_message(
                Part.from_function_response(
                    name=function_call.name,
                    response={
                        "content": z_add,
                    },
                ),
            )
            # 再帰処理
            return handle_response(response)
        else:
            # 例外処理
            print(function_call)
    

    2.3 チャットの開始

    モデルを使用して、対話を行うためのチャットセッションを開始します。

    chat = model.start_chat()
    

    2.4 チャットしてみる

    準備が整いました。実際にチャットを開始して挙動を確認しましょう。 まずは加算処理を行うようにチャットします。 出力の1行目は呼び出した関数、2行目にチャットの回答を表示しています。

    response = chat.send_message("大谷選手は54本の本塁打を打ちました。昨年は44本打ちました。大谷選手は合計で何本の本塁打を打ちましたか。")
    handle_response(response)
    

    出力

    次に、乗算処理を行うようにメッセージを入力します。

    # 関数呼び出しの確認(multiply_func関数)
    response = chat.send_message("54本塁打を5年続けると何本塁打になりますか。")
    handle_response(response)
    

    出力

    関数の再帰処理を行うようにチャットします。

    # 関数の再帰呼び出しの確認
    response = chat.send_message("大谷選手は54本塁打を打ちました。鈴木選手は21本塁打を打ちました。1本塁打につき4塁打になります。合わせて何塁打になりますか。")
    handle_response(response)  
    

    出力

    最後に、関数呼び出しを行わない「計算以外の質問」をしてみます。

    # 関数で定義していない質問に対しての回答
    response = chat.send_message("東京の天気は?")
    handle_response(response)
    

    出力

    設定通り、定義されていない質問には回答しない(ハルシネーションを起こさない)ことが確認できました。

    3. まとめ

    本ブログでは、Vertex AI Workbenchを使用してFunction Calling(関数呼び出し)機能をもつAIチャットボットモデルを作成しました。ポイントをまとめると以下になります。

    • 関数呼び出し機能を使うことでAIモデルの出力精度を高めることが可能
    • System Instructionを使うことで、回答のルールを制御できる

    最後までお読みいただきありがとうございました。

    執筆者横田真斗

    インフラエンジニア

    Google Cloud Partner All Certification Holders 2025

    執筆記事一覧:https://tech.nri-net.com/archive/author/m2-yokota