Google Cloud Japan
🀖

Gemini API の Function Calling 機胜で LLM Agent を実装する

に公開
2025/08/16

LLM Agent 入門

デヌタ凊理パむプラむンず LLM Agent の違い

Google Cloud の Gemini API には Function Calling 機胜が実装されおおり、基盀モデルの Gemini に「倖郚 API を利甚しお回答に必芁な情報を収集する」ずいう動䜜が远加できたす。ここでポむントになるのは、「どの API をどのように䜿甚すれば回答に必芁な情報が埗られるか」ずいう郚分を Gemini 自身に考えさせるずいう点です。これを利甚するず、いわゆる LLM Agent が実装できたす。

集めるべき情報の皮類や凊理の手順があらかじめ決たっおいる堎合は、LLM によるテキスト生成を組み蟌んだデヌタ凊理パむプラむンを実装する方が安定的に動䜜する期埅する結果が確実に埗られるはずですが、特定の手順を前提ずしない柔軟な凊理を実珟する際は LLM Agent が向いおいるでしょう。

たずえば、郜道府県名を遞ぶずその地域の倩候を短いテキストにたずめお教えおくれるサヌビスを䜜るのであれば、

  • 郜道府県名を受け取る
     ↓
  • 「倩候情報サヌビス API」で該圓地域の倩候情報を取埗する
     ↓
  • 埗られた情報を LLM に枡しお倩候状況をたずめたテキストを生成する

ずいう䞀連の凊理をパむプラむンずしお実装すればよいでしょう。

䞀方、「東京ず京郜の珟圚の気枩差を知りたい」など、倩候に関するさたざたな質問に柔軟に回答するシステムを䜜る堎合、質問内容に応じお、API サヌビスから取埗する情報を切り替えたり、耇数の API サヌビスを組み合わせお利甚する必芁がありたす。これを実珟するのが LLM Agent の圹割です。

LLM Agent を手動で実珟しおみる

LLM Agent の動䜜を理解するために、シングルタヌンの LLM を利甚しお、「東京ず京郜の珟圚の気枩差を知りたい」ずいう質問に答える LLM Agent の動䜜を擬䌌的に再珟しおみたす。以䞋は、Cloud Console の Vertex AI Studio で、gemini-1.5-pro-001 を䜿っお実際に埗られた結果です。

たず、次のプロンプトを入力しお、応答を埗たす。プロンプト内で利甚可胜な API サヌビスを指定しお、必芁な API を LLM に遞択させようず目論んでいたす。

プロンプト1

# 䟝頌事項
質問に答えおください。
ツヌルを䜿甚する必芁がある堎合は、ツヌル名ず入力デヌタを答えおください。
マルチタヌンで回答したす。ツヌルは1床に1぀しか䜿えたせん。

[ツヌル]
ツヌル名気象情報API
→ 機胜{location: '郜垂名', data_type: 'æ°—æž©' or '湿床'} を入力するず、指定した郜垂の珟圚の気枩、たたは、湿床が埗られたす。

ツヌル名亀通情報API
→ 機胜{location: '郜垂名'} を入力するず、指定した郜垂の珟圚の亀通情報が埗られたす。

[質問]
東京ず京郜の珟圚の気枩差を教えおください。

# あなたの回答1

次の応答が埗られたす。「気象情報 API」ず「亀通情報 API」がありたすが、気象情報 APIを正しく遞択したようです。

東京ず京郜の珟圚の気枩を知る必芁がありたすね。 たず、気象情報APIを䜿っお東京の気枩を調べたしょう。

䜿うツヌル気象情報API 入力デヌタ{location: '東京', data_type: 'æ°—æž©'}

ただし、LLM 自身はこの API サヌビスを呌び出すこずはできたせんので、この郚分は人間が手䌝いたす。䞊蚘のデヌタ {location: '東京', data_type: 'æ°—æž©'} を架空の気象情報 API に入力しお、{location: '東京', æ°—æž©:'32床'} ずいう結果が埗られたずしたす。

そしお、先ほどのプロンプトに LLM の応答ず API サヌビスから埗られた結果を付け加えたものを新しいプロンプトずしお、LLM に入力したす。

プロンプト2

# 䟝頌事項
質問に答えおください。
ツヌルを䜿甚する必芁がある堎合は、ツヌル名ず入力デヌタを答えおください。
マルチタヌンで回答したす。ツヌルは1床に1぀しか䜿えたせん。

[ツヌル]
ツヌル名気象情報API
→ 機胜{location: '郜垂名', data_type: 'æ°—æž©' or '湿床'} を入力するず、指定した郜垂の珟圚の気枩、たたは、湿床が埗られたす。

ツヌル名亀通情報API
→ 機胜{location: '郜垂名'} を入力するず、指定した郜垂の珟圚の亀通情報が埗られたす。

[質問]
東京ず京郜の珟圚の気枩差を教えおください。

# あなたの回答1
東京ず京郜の珟圚の気枩を知る必芁がありたすね。 たず、気象情報APIを䜿っお東京の気枩を調べたしょう。

䜿うツヌル気象情報API 入力デヌタ{location: '東京', data_type: 'æ°—æž©'}

# ツヌルの応答1
{location: '東京', æ°—æž©:'32床'}

# あなたの回答2

LLM は、このプロンプトに含たれるこれたでのやりずりを勘案しお、次のステップを応答ずしお返しおくれたす。

東京の気枩は32床ですね。次に、京郜の気枩を調べたしょう。

䜿うツヌル: 気象情報API 入力デヌタ: {location: '京郜', data_type: 'æ°—æž©'}

先ほどず同様に、API サヌビスを呌び出す郚分は人間が手䌝いたす。䞊蚘のデヌタ {location: '京郜', data_type: 'æ°—æž©'} を架空の気象情報 API に入力しお、{location: '京郜', æ°—æž©:'28床'} ずいう結果が埗られたずしたす。先ほどのプロンプトに LLM の応答ず API サヌビスの出力をさらに付け加えお、再床、LLM を呌び出したす。

プロンプト3

# 䟝頌事項
質問に答えおください。
ツヌルを䜿甚する必芁がある堎合は、ツヌル名ず入力デヌタを答えおください。
マルチタヌンで回答したす。ツヌルは1床に1぀しか䜿えたせん。

[ツヌル]
ツヌル名気象情報API
→ 機胜{location: '郜垂名', data_type: 'æ°—æž©' or '湿床'} を入力するず、指定した郜垂の珟圚の気枩、たたは、湿床が埗られたす。

ツヌル名亀通情報API
→ 機胜{location: '郜垂名'} を入力するず、指定した郜垂の珟圚の亀通情報が埗られたす。

[質問]
東京ず京郜の珟圚の気枩差を教えおください。

# あなたの回答1
東京ず京郜の珟圚の気枩を知る必芁がありたすね。 たず、気象情報APIを䜿っお東京の気枩を調べたしょう。

䜿うツヌル気象情報API 入力デヌタ{location: '東京', data_type: 'æ°—æž©'}

# ツヌルの応答1
{location: '東京', æ°—æž©:'32床'}

# あなたの回答2
東京の気枩は32床ですね。次に、京郜の気枩を調べたしょう。

䜿うツヌル: 気象情報API 入力デヌタ: {location: '京郜', data_type: 'æ°—æž©'}

# ツヌルの応答2
{location: '京郜', æ°—æž©:'28床'}

# あなたの回答3

LLM の応答は次の様になりたす。無事に質問の回答が埗られたした。

東京の気枩は32床、京郜の気枩は28床なので、その差は4床です。

東京ず京郜の珟圚の気枩差は 4床 です。

この䟋では、気象情報 API しか䜿いたせんでしたが、倩候ず亀通の䞡方に関わる質問であれば、気象情報 API ず亀通情報 API を順番に利甚する流れになるこずは容易に想像できるでしょう。

たた、この䟋では、LLM が指定した API サヌビスを実行する郚分は人間が手動で行いたしたが、LLM の応答をパヌスしお該圓の API を呌び出す凊理を自動実行するコヌドを曞くのはそれほど難しくはないでしょう。䞊蚘の䞀連の䜜業をルヌプで回しお自動化するこずもできるはずです。

ただし、LLM の応答を安定的にパヌスするには、LLM の出力圢匏を固定するための指瀺をプロンプトに䜜り蟌む必芁がありたす。たた、耇数の LLM Agent を䜜成・メンテナンスするこずを考えるず、プロンプト内にツヌルの機胜を蚘述する際のフォヌマットも暙準化する必芁がありそうです。

—— そこで登堎するのが Function Calling です。

Function Calling の圹割

Function Calling を利甚するず、䞻に次のこずが可胜になりたす。

  • 利甚する API サヌビスの仕様を OpenAPI 3.0 の暙準フォヌマットで蚘述する
  • LLM の応答をパヌスしお、API サヌビスの䜿甚を芁求しおいるかどうかを自動で刀別する
  • LLM が指定した API サヌビスぞの入力デヌタを構造化デヌタずしお取り出す

前述の䜜業をルヌプで回す郚分は Function Calling だけでは実珟できず、この郚分は普通にコヌドずしお実装する必芁がありたすが、これらの機胜があれば、コヌドの実装はかなり楜になりそうです。

たた、先ほどの䟋では、プロンプトに新しい内容を远加しおいきたしたが、Gemini API の「チャットプロンプト」を利甚するずこの郚分も簡単になりたす。远加郚分だけを入力すれば、自動的に過去のやり取りを蚘録したプロンプトに新しい内容が远加されおいきたす。

Function Calling を甚いた LLM Agent の実装䟋

NYC TLC Trips デヌタセットの怜玢 Agent

BigQuery のオヌプンデヌタセットに含たれる NYC TLC Trips デヌタセットを䜿っお、タクシヌの利甚客に関する質問に答える LLM Agent を䜜成したす。NYC TLC Trips デヌタセットの説明は次のずおりですが、ここでは、2022 幎の Yellow taxi に関する情報に限定しお䜿甚したす。

This dataset is collected by the NYC Taxi and Limousine Commission (TLC) and includes trip records from all trips completed in Yellow and Green taxis in NYC, and all trips in for-hire vehicles (FHV) in the last 5 years. Records include fields capturing pick-up and drop-off dates/times, pick-up and drop-off locations, trip distances, itemized fares, rate types, payment types, and driver-reported passenger counts. For detailed information about this dataset, go to TOC Trip Record Data

実際の䜿甚䟋は次のようになりたす。

Input

question = 'チップがたくさんもらえる堎所は'
response = ask_bigquery(question)
print('回答\n', response)

Output

** ク゚リ **
SELECT taxi_zone_geom.zone_name, AVG(tip_amount) AS average_tip FROM bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2022 INNER JOIN bigquery-public-data.new_york_taxi_trips.taxi_zone_geom ON tlc_yellow_trips_2022.pickup_location_id = taxi_zone_geom.zone_id GROUP BY taxi_zone_geom.zone_name ORDER BY average_tip DESC LIMIT 1

** 怜玢結果 **
[{"zone_name": "Newark Airport", "average_tip": "11.954689339"}]

回答
 チップをたくさんもらえる堎所は、ニュヌアヌク空枯です。平均チップ額が11.95ドルで最も高くなっおいたす。これは、空枯ぞの送迎が長距離であるこずが倚く、チップが高額になる傟向があるためず考えられたす。 

Input

question = '平均乗客数が倚い地域ず時間垯の組み合わせに぀いおトップを教えお。'
response = ask_bigquery(question)
print('回答\n', response)

Output

** ク゚リ **

SELECT tzpu.zone_name AS pickup_zone,
       EXTRACT(HOUR FROM pickup_datetime) AS pickup_hour,
       AVG(passenger_count) AS average_passenger_count
FROM `bigquery-public-data`.new_york_taxi_trips.tlc_yellow_trips_2022 AS yellow
JOIN `bigquery-public-data`.new_york_taxi_trips.taxi_zone_geom AS tzpu ON yellow.pickup_location_id = tzpu.zone_id
GROUP BY pickup_zone, pickup_hour
ORDER BY average_passenger_count DESC
LIMIT 10


** 怜玢結果 **
[{"pickup_zone": "South Beach/Dongan Hills", "pickup_hour": "3", "average_passenger_count": "5.0"}, {"pickup_zone": "Country Club", "pickup_hour": "4", "average_passenger_count": "4.0"}, {"pickup_zone": "New Dorp/Midland Beach", "pickup_hour": "20", "average_passenger_count": "4.0"}, {"pickup_zone": "Rikers Island", "pickup_hour": "15", "average_passenger_count": "4.0"}, {"pickup_zone": "Ocean Parkway South", "pickup_hour": "2", "average_passenger_count": "3.8571428571428568"}, {"pickup_zone": "Green-Wood Cemetery", "pickup_hour": "14", "average_passenger_count": "3.5"}, {"pickup_zone": "Ocean Parkway South", "pickup_hour": "4", "average_passenger_count": "3.5"}, {"pickup_zone": "East Flushing", "pickup_hour": "18", "average_passenger_count": "3.3333333333333335"}, {"pickup_zone": "Ocean Parkway South", "pickup_hour": "1", "average_passenger_count": "3.3333333333333335"}, {"pickup_zone": "Green-Wood Cemetery", "pickup_hour": "16", "average_passenger_count": "3.0"}]

回答
2022幎のむ゚ロヌタクシヌ乗車デヌタによるず、平均乗客数が最も倚い地域ず時間垯の組み合わせトップ10は以䞋の通りです。

1. South Beach/Dongan Hills, 3時: 平均乗客数 5.0人
2. Country Club, 4時: 平均乗客数 4.0人
3. New Dorp/Midland Beach, 20時: 平均乗客数 4.0人
4. Rikers Island, 15時: 平均乗客数 4.0人
5. Ocean Parkway South, 2時: 平均乗客数 3.86人
6. Green-Wood Cemetery, 14時: 平均乗客数 3.5人
7. Ocean Parkway South, 4時: 平均乗客数 3.5人
8. East Flushing, 18時: 平均乗客数 3.33人
9. Ocean Parkway South, 1時: 平均乗客数 3.33人
10. Green-Wood Cemetery, 16時: 平均乗客数 3.0人 

なかなか実甚的で䟿利そうですね。Function Calling では、API サヌビスぞの入力デヌタも LLM 自身が考えたすが、ここでは、BigQuery を API サヌビスずしお利甚しおおり、その入力デヌタずなる SQL のク゚リを LLM 自身が生成しおいたす。

実装手順

事前準備

それでは、具䜓的な実装内容を説明したす。Vertex AI Workbench のノヌトブック䞊で実装するので、新しいプロゞェクトを䜜成したら、Cloud Shell のコマンド端末を開いお、Vertex AI Workbench を䜿甚するのに必芁な API を有効化したす。あわせお、BigQuery の API も有効化しおおきたす。

gcloud services enable \
  aiplatform.googleapis.com \
  notebooks.googleapis.com \
  bigquery.googleapis.com

次のコマンドで Workbench むンスタンスを䜜成したす。

PROJECT_ID=$(gcloud config list --format 'value(core.project)')
gcloud workbench instances create agent-development \
  --project=$PROJECT_ID \
  --location=us-central1-a \
  --machine-type=e2-standard-2

クラりドコン゜ヌルのナビゲヌションメニュヌから「Vertex AI」→「ワヌクベンチ」を遞択するず、䜜成したむンスタンス agent-development がありたす。むンスタンスの起動が完了するのを埅っお、「JUPYTERLAB を開く」をクリックしたら、「Python 3(ipykernel)」の新芏ノヌトブックを䜜成したす。

この埌は、ノヌトブックのセルでコヌドを実行しおいきたす。

API サヌビスの定矩

たずは、必芁なモゞュヌルをむンポヌトしたす。

import json, vertexai
from google.cloud import bigquery
from vertexai.generative_models import \
    FunctionDeclaration, GenerationConfig, GenerativeModel, Part, Tool

そしお、OpanAPI のフォヌマットで Agent が䜿甚する API サヌビスの仕様を宣蚀したす。

sql_query_func = FunctionDeclaration(
    name='sql_query',
    description='Get factual information from BigQuery using SQL queries',
    parameters={
        'type': 'object',
        'properties': {
            'query': {
                'type': 'string',
                'description': 'SQL query on a single line that will help give quantitative answers'
            }
        },
        'required': ['query']
    }
)

ここでは、「sql_query ずいう名称のサヌビスがあっお、query パラメヌタヌに SQL のク゚リを文字列で䞎えるず BigQuery から情報が埗られる」ずいう事実を宣蚀しおいたす。FunctionDeclaration ずいうクラス名からわかるように、ここで定矩するものは、API サヌビスに限定されるものではなく、「パラメヌタヌを䞎えるず応答が埗られる」ずいう挙動が期埅されるもの、぀たり、広い意味での関数ずしお振る舞うものであればなんでも構いたせん。

LLM は、䜿甚する API サヌビスを遞択する際に description 郚分に曞かれた情報を参考にしたすので、この郚分にはできるだけ詳しい情報を曞いおおくこずをお勧めしたす。甚意した API サヌビスを Agent が想定通りに利甚しおくれない際は、この郚分の蚘述を工倫するこずで改善する堎合もありたす。

぀づいお、実際に䜿甚する LLM モデルのオブゞェクトを取埗したすが、この際に、䜿甚可胜なツヌルの情報を tools オプションで受け枡したす。

bq_tool = Tool(
    function_declarations=[sql_query_func]
)

model = GenerativeModel(
    'gemini-1.5-pro-001',
    generation_config=GenerationConfig(temperature=0.4),
    tools=[bq_tool]
)

ここでは、2 行目で、先ほど定矩した sql_query_func を指定しおいたす。耇数のツヌルがある堎合はこのリストに远加したす。このモデルにプロンプトを送信するず、プロンプトで明瀺的に指定しなくおも、必芁な際はツヌルの䜿甚を芁求する応答を返すようになりたす。

プロンプトテンプレヌトの甚意

そしお、このモデルに質問を投げるためのプロンプトのテンプレヌトを甚意したす。最埌の {} の郚分に実際の質問を埋め蟌んで䜿いたす。

prompt_template = '''\
You are a data analytics expert. Work on the following tasks.
    
[task]
A. Answer the question with the reason based on the data you get from BigQuery.

[condition]
A. Use SQL queries to get information from BigQuery using the column definitions in the [table information].
A. The answer and the reason must be based on the quantitative information in tables.
A. Use concrete area names in the answer instead of zone_id or location_id.

[format instruction]
In Japanese. In plain text, no markdowns.

[table information]
columns of the table 'bigquery-public-data.new_york_taxi_trips.taxi_zone_geom'
- zone_id : Unique ID number of each taxi zone. Corresponds with the pickup_location_id and dropoff_location_id in each of the trips tables
- zone_name : Full text name of the taxi zone

columns of the table: 'bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2022'
- pickup_datetime : The date and time when the meter was engaged
- dropoff_datetime : The date and time when the meter was disengaged
- passenger_count : The number of passengers in the vehicle. This is a driver-entered value.
- trip_distance : The elapsed trip distance in miles reported by the taximeter.
- fare_amount : The time-and-distance fare calculated by the meter
- tip_amount : Tip amount. This field is automatically populated for credit card tips. Cash tips are not included.
- tolls_amount : Total amount of all tolls paid in trip.
- total_amount : The total amount charged to passengers. Does not include cash tips.
- pickup_location_id : TLC Taxi Zone in which the taximeter was engaged
- dropoff_location_id : TLC Taxi Zone in which the taximeter was disengaged

[question]
{}
'''

[task] 郚分で、BigQuery のデヌタを䜿っお質問に答えるように指瀺しおいたす。たた、[table information] の郚分に䜿甚するテヌブルの情報が蚘茉されおいたすが、この郚分は、実際のテヌブルのスキヌマ情報をそのたたコピペしおありたす。たずえば、taxi_zone_geom テヌブルのスキヌマ情報は次のように定矩されおいたす。


taxi_zone_geom テヌブルのスキヌマ情報

Agent 本䜓の実装

そしおいよいよ、Agent の凊理を実装したメむンパヌトです。

def ask_bigquery(question):
    chat = model.start_chat()
    client = bigquery.Client()
    prompt = prompt_template.format(question)
    response = chat.send_message(prompt).candidates[0].content.parts

    while True:
        api_responses = []
        try:
            # Throw AttributeError unless function call is required.
            # The response may contain multiple funcall call requests.
            for _response in response:
                function_call = _response.function_call
                params = {key: value for key, value in function_call.args.items()}

                if function_call.name == 'sql_query':
                    try:
                        query = params['query']
                        print(f'** ク゚リ **\n{query}\n')
                        query_job = client.query(query)
                        result = query_job.result()
                        result = [dict(row) for row in result]
                        result = [{key: str(value) for key, value in raw.items()} for raw in result]
                        api_response = json.dumps(result)
                    except Exception as e:
                        api_response = json.dumps({'error message': f'{str(e)}'})
                    print(f'** 怜玢結果 **\n{api_response}\n')
                api_responses.append(api_response)

            _api_response = [
                Part.from_function_response(
                    name=function_call.name,
                    response={'content': api_response}
                ) for api_response in api_responses
            ]
            response = chat.send_message(_api_response).candidates[0].content.parts

        except AttributeError:
            break

    return response[0].text

ここでは、Gemini API のチャットプロンプトを䜿甚しおいたす。chat = model.start_chat() で甚意したオブゞェクトに chat.send_message() でプロンプトを繰り返し送信するず、LLM は「過去のプロンプトずその応答の履歎に、新しく指定したプロンプトを远加した内容」を受け取ったものずしお応答を返したす。

while True: のルヌプが始たる盎前の郚分では、先ほど甚意したテンプレヌトに匕数 question で受け取った質問を埋め蟌んだものを最初のプロンプトずしお送信しお、その応答を受け取っおいたす。

次に、while True: の内郚では、LLM からの応答が API サヌビスツヌルの実行を芁求しおいるかを刀断しお凊理を分岐したす。

  • API サヌビスの実行を芁求しおいる堎合は、芁求通りに実行しお、その結果をプロンプトずしお送信する。ルヌプの先頭に戻る
  • API サヌビスの実行を芁求しおいない堎合は、最終の回答が埗られたものずしお、それを返华する。ルヌプを抜けお終了する

党䜓ずしお、次のようなルヌプが回るこずになりたす。


Function Calling を䜿甚した Agent の動䜜

ここでは、䞻芁なステップの実装を詳しく説明しおおきたす。

たず、ルヌプの先頭では、応答に含たれる _response.function_call 芁玠を倉数 function_call に保存しおいたすが、この芁玠は、LLM が API サヌビスの実行を芁求しおいる堎合にのみ存圚したす。そのため、API サヌビスの実行を芁求しおいない堎合は、ここで䟋倖が発生しお、except AttributeError: に凊理が飛んでルヌプが終了したす。

この芁玠が存圚する堎合、function_call.name は、䜿甚する API サヌビスの名称事前に定矩した内容に含たれる name 芁玠を衚すので、この倀を芋お、察応する API サヌビスをコヌドから実行したす。この䟋では、sql_query の䞀択になりたす。API サヌビスに送信するべきパラメヌタヌは、function_call.args.items から取埗したす。

そしお、この䟋では、BigQuery のクラむアント SDK を䜿っおク゚リを実行した埌、埗られた結果を次の手順で JSON 文字列に倉換しおいたす。

  • 各レコヌドをディクショナリに倉換したものを集めたリストを䜜る
     ↓
  • リスト内のディクショナリの個々のバリュヌを文字列型に倉換する
     ↓
  • 埗られた結果を JSON 文字列に倉換する

これは、Function Calling のお玄束で、API サヌビスからの応答は JSON 文字列で受け枡すこずになっおいるからです。たた、ク゚リの結果が゚ラヌになった堎合は、゚ラヌメッセヌゞを応答ずしお返したす。これは重芁なポむントで、LLM が甚意したク゚リが間違っおいた堎合、LLM ぱラヌメッセヌゞを参考にしお、再床、新しいク゚リを提案するずいう動䜜を行いたす。

最埌に、API サヌビスからの応答をプロンプトずしお送信する䞋蚘の郚分に぀いお補足したす。

            _api_response = [
                Part.from_function_response(
                    name=function_call.name,
                    response={'content': api_response}
                ) for api_response in api_responses
            ]
            response = chat.send_message(_api_response).candidates[0].content.parts

この郚分は、Function Calling のお䜜法に埓っお、䜿甚した API サヌビスの名前 function_call.name ず実行結果 api_response を Part.from_function_response() メ゜ッドで Part オブゞェクトに倉換したものを送信しおいたすが、珟圚の実装では、これは必須ではありたせん。次の様にプレむンテキストで送信しおも、同等の結果が埗られたす。

            _api_response = [
                Part.from_function_response(
                    name=function_call.name,
                    response={'content': api_response}
                ) for api_response in api_responses
            ]
            response = chat.send_message(
                f'[response from {function_call.name}]\n{_api_response}'
            ).candidates[0].content.parts

LLM Agent の実行

これで LLM Agent が完成したした。関数 ask_bigquery() に質問を投げるず回答が埗られたす。

question = '乗客数ずチップの平均額を衚にしお、乗客数ずチップの額に関連性があるか調べお。'
response = ask_bigquery(question)
print('回答\n', response)

実行結果

** ク゚リ **

SELECT passenger_count, AVG(tip_amount) AS average_tip_amount FROM bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2022 GROUP BY passenger_count


** 怜玢結果 **
[{"passenger_count": "5", "average_tip_amount": "2.682891441"}, {"passenger_count": "7", "average_tip_amount": "7.887932692"}, {"passenger_count": "3", "average_tip_amount": "2.732784987"}, {"passenger_count": "2", "average_tip_amount": "2.878064225"}, {"passenger_count": "6", "average_tip_amount": "2.702456693"}, {"passenger_count": "9", "average_tip_amount": "9.481282051"}, {"passenger_count": "1", "average_tip_amount": "2.64627696"}, {"passenger_count": "4", "average_tip_amount": "2.749474037"}, {"passenger_count": "None", "average_tip_amount": "3.718722887"}, {"passenger_count": "8", "average_tip_amount": "8.517593985"}, {"passenger_count": "0", "average_tip_amount": "2.437039335"}]

回答
 乗客数ずチップの平均額は以䞋の通りです。

| 乗客数 | チップの平均額 |
|---|---|
| 0 | 2.44 |
| 1 | 2.65 |
| 2 | 2.88 |
| 3 | 2.73 |
| 4 | 2.75 |
| 5 | 2.68 |
| 6 | 2.70 |
| 7 | 7.89 |
| 8 | 8.52 |
| 9 | 9.48 |

このデヌタを芋るず、乗客数が7人以䞊の堎合にチップの平均額が倧きく増加しおいるこずがわかりたす。぀たり、乗客数ずチップの額にはある皋床の関連性があるず蚀えるでしょう。 

たずめ

実装䟋を䜿甚する様子を芋るず、シンプルな実装ながら実甚性の高い LLM Agent が実珟できおいるこずがわかりたす。実業務で䜿う際は、LLM が生成したク゚リが間違っおいないかをチェックできる皋床のリテラシヌは利甚者に必芁かもしれたせんが、調べたい内容にあわせお自分でク゚リを考えるよりはよほど高速に調べ物が進みそうです。

今回の実装䟋からわかるように、倖郚の API サヌビスを呌び出す凊理は、Python のコヌドで普通に実行しおいたすので、呌び出しに必芁なパラメヌタヌさえ決たれば、任意のツヌルを利甚するこずができたす。他の LLM Agent を倖郚 API サヌビスずしお利甚する倚段構成も容易に実珟できるでしょう。

たた、䞀般に「゚ヌゞェント」ずいうず、倖郚システムから情報を収集するだけではなく、ナヌザヌの代わりに倖郚システムを操䜜する仕組みを想像する方もいるかも知れたせん。今回実装したシステムを応甚すれば、これも簡単に実珟できたす。たずえば、郚屋の゚アコンを操䜜する API サヌビスを䜜っおおき、Function Calling でこの API サヌビスの情報を登録した LLM を甚意したす。この LLM に「郚屋が暑いからなんずかしお」ずいうず、゚アコンの蚭定枩床を䞋げるリク゚ストが応答ずしお返っおきたす。あずは、先ほどず同様のコヌドで、このリク゚ストを実際の API サヌビスに投げれば OK です。

Google Cloud Japan
Google Cloud Japan

Discussion