Gemini ProでFunction Callingを試してみた

## はじめに
Gemini ProでFunction Callingを試します。

## 環境
- Google Cloud
- Python 3.11.5
- Google Cloud Vertex AI

## 実装
### 事前準備とライブラリのインポート

test.pyを作成し、以下のコマンドでgoogle-cloud-aiplatformをインストールします。

```terminal
pip install --upgrade google-cloud-aiplatform
```
　　
以下を参考にGoogle Cloud CLIをインストールします。

https://cloud.google.com/sdk/docs/install?hl=ja

Google Cloud CLIのインストールが完了したら以下のコマンドを入力し、設定を進めます。

```terminal
gcloud init
```

googleアカウントとprojectはご自身の環境に合わせてください。プロジェクトIDはGoogle Cloudの「ダッシュボード」から確認できます。
　　
test.pyを作成し必要なライブラリをインストールします。
```python
import vertexai
from vertexai.preview.generative_models import (
    FunctionDeclaration,
    GenerativeModel,
    Tool,
)
```
　　
### Vertex AIの初期化
次に、Vertex AIを初期化するためにプロジェクトIDとロケーションを設定します。

```python
PROJECT_ID = "プロジェクトID"
LOCATION = "プロジェクトのロケーション"

vertexai.init(project=PROJECT_ID, location=LOCATION)
```
　　
### Gemini Proモデルのインスタンス生成
Gemini Proモデルのインスタンスを生成します。

```python
model = GenerativeModel("gemini-pro")
```
　　
### 関数の定義
特定の地域の人口を返す関数 `get_current_population` を定義します。

```python
def get_current_population(location):
    if location == "東京":
        return "1396万"
    elif location == "熊本":
        return "175万"
    else:
        return "不明"
```
　　
### 関数の登録
この関数をGemini Proで使用できるように、FunctionDeclarationとToolを使用して登録します。

```python
get_current_population_func = FunctionDeclaration(
    name="get_current_population",
    description="指定された場所の人口を取得する",
    parameters={
        "type": "object",
        "properties": {
            "location": {
                "type": "string",
                "description": "場所"
            }
        }
    },
)

population_tool = Tool(
    function_declarations=[get_current_population_func],
)
```
　　
### プロンプトに基づく関数の呼び出し
ユーザーからのプロンプトに基づいて、関数を呼び出す `function_calling` 関数を定義します。

```python
def function_calling(prompt) -> dict:
    response = model.generate_content(
        prompt,
        generation_config={"temperature": 0},
        tools=[population_tool],
    )
    return response
```
　　
### レスポンスの処理
ユーザーからのプロンプトに対して、適切な関数を呼び出し、結果を表示します。

```python
prompt = "熊本の人口は？"

response = function_calling(prompt)

print(response)

if response.candidates[0].content.parts[0].function_call:
    function_name = response.candidates[0].content.parts[0].function_call.name
    location = response.candidates[0].content.parts[0].function_call.args.get("location")

    available_functions = {
        "get_current_population": get_current_population
    }
    exec_function = available_functions[function_name]

    function_response = exec_function(location)
    print(f"「{location}」の人口は、「{function_response}」です。")
else:
    print(f"最適な関数 : 何もなし")
```
　　
### Pythonファイルの実行
Pythonファイルを実行します。実行結果は以下のとおりです。

```terminal
candidates {
  content {
    role: "model"
    parts {
      function_call {
        name: "get_current_population"
        args {
          fields {
            key: "location"
            value {
              string_value: "熊本"
            }
          }
        }
      }
    }
  }
  finish_reason: STOP
  safety_ratings {
    category: HARM_CATEGORY_HARASSMENT
    probability: NEGLIGIBLE
  }
  safety_ratings {
    category: HARM_CATEGORY_HATE_SPEECH
    probability: NEGLIGIBLE
  }
  safety_ratings {
    category: HARM_CATEGORY_SEXUALLY_EXPLICIT
    probability: NEGLIGIBLE
  }
  safety_ratings {
    category: HARM_CATEGORY_DANGEROUS_CONTENT
    probability: NEGLIGIBLE
  }
}
usage_metadata {
  prompt_token_count: 5
  total_token_count: 5
}

「熊本」の人口は、「175万」です。
```

## おわりに
お疲れ様でした！
以下で情報発信しています！

https://twitter.com/t___tatsuki

## 参考文献
https://blog.g-gen.co.jp/entry/using-function-calling-with-gemini