🍀

無料Gemini と LiteLLM で Tool Calling を使いこなそう!~初心者向け徹底解説~

2024/07/23に公開

はじめに

Gemini とは?

Google AI Studio が提供する、最先端の大規模言語モデル (LLM) です。高度な言語処理能力を持ち、人間のような自然な文章生成、翻訳、要約など、様々なタスクをこなします。Gemini-Pro はその中でも特に高性能なモデルです。

LiteLLM とは?

複数の LLM を簡単に利用できる Python ライブラリです。LiteLLM を使うことで、Gemini を含む様々な LLM を統一的なインターフェースで呼び出すことができます。

Tool Calling とは?

LLM に外部ツールを使わせる技術です。LLM 単体ではできない計算やデータ取得などを、外部ツールに依頼することで、LLM の可能性を大きく広げます。

準備

必要なライブラリのインストール

まずは必要なライブラリをインストールしましょう。

!pip install litellm google-generativeai loguru
  • litellm: 様々な LLM を利用するためのライブラリです。
  • google-generativeai: Google AI Platform の API を利用するためのライブラリです。
  • loguru: ログ出力を見やすくしてくれるライブラリです。

API キーの取得

Google AI Studio から API キーを取得します。API キーは、Google AI Platform のサービスを利用する際に必要となる、あなた専用の鍵のようなものです。

  1. Google AI Studio にアクセスします。
  2. 画面の指示に従って、API キーを作成します。
  3. 作成した API キーは、後ほどプログラム内で使用しますので、安全な場所に保管しておいてください。

Gemini-Pro を使ってみよう!

コード例

以下のコードは、LiteLLM を使って Gemini-Pro を呼び出し、「LiteLLM からこんにちは」と表示するプログラムです。

from litellm import completion
import os

# 取得した API キーを設定します
os.environ['GEMINI_API_KEY'] = "YOUR_API_KEY"

# Gemini-Pro を呼び出して、メッセージを生成します
response = completion(
    model="gemini/gemini-pro", 
    messages=[{"role": "user", "content": "write code for saying hi from LiteLLM"}]
)

# 結果を出力します
print(response)

コード解説

  1. ライブラリのインポート: litellmos ライブラリをインポートします。
  2. API キーの設定: 取得した API キーを環境変数 GEMINI_API_KEY に設定します。
  3. Gemini-Pro の呼び出し: completion 関数を使って Gemini-Pro を呼び出します。
    • model: 利用するモデルを指定します。ここでは gemini/gemini-pro を指定しています。
    • messages: LLM に送信するメッセージを指定します。ここでは、ユーザーの役割で「LiteLLM からこんにちはと表示するコードを書いて」という内容を送信しています。
  4. 結果の出力: 生成されたメッセージを print 関数で出力します。

Tool Calling を使ってみよう!

Tool Calling の仕組み

Tool Calling は、LLM に外部ツールを使わせることで、LLM 単体ではできない処理を実現する技術です。

例えば、「今日の東京の天気は?」という質問に対して、LLM 単体では最新の情報にアクセスできません。そこで、天気予報 API という外部ツールを呼び出すことで、最新の天気情報を取得し、「今日の東京の天気は晴れです」のように、適切な回答を生成することができます。

コード例

以下のコードは、Tool Calling を使って、ボストン市の現在の天気を取得するプログラムです。

# Tool Calling
from litellm import completion
from google.colab import userdata
import os
from loguru import logger
import json
from typing import Any, Dict

# モデルの応答をログ出力する関数
def log_model_response(response: Dict[str, Any]) -> None:
    logger.info("ModelResponse:")
    logger.info(f"ID: {response['id']}")
    logger.info(f"Created: {response['created']}")
    logger.info(f"Model: {response['model']}")
    logger.info(f"Object: {response['object']}")
    logger.info(f"System Fingerprint: {response['system_fingerprint']}")

    logger.info("Usage:")
    usage = response['usage']
    logger.info(f"  Prompt Tokens: {usage['prompt_tokens']}")
    logger.info(f"  Completion Tokens: {usage['completion_tokens']}")
    logger.info(f"  Total Tokens: {usage['total_tokens']}")

    logger.info("Choices:")
    for idx, choice in enumerate(response['choices']):
        logger.info(f"  Choice {idx}:")
        logger.info(f"    Finish Reason: {choice['finish_reason']}")
        logger.info(f"    Index: {choice['index']}")

        message = choice['message']
        logger.info(f"    Message:")
        logger.info(f"      Content: {message['content']}")
        logger.info(f"      Role: {message['role']}")

        if message['tool_calls']:
            logger.info(f"    Tool Calls:")
            for tool_call in message['tool_calls']:
                logger.info(f"      Index: {tool_call['index']}")
                logger.info(f"      ID: {tool_call['id']}")
                logger.info(f"      Type: {tool_call['type']}")
                logger.info(f"      Function:")
                logger.info(f"        Name: {tool_call['function']['name']}")
                logger.info(f"        Arguments: {tool_call['function']['arguments']}")

# API キーの設定
os.environ["GEMINI_API_KEY"] = userdata.get('GEMINI_API_KEY')

# 利用するツールの定義
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather", # ツール名
            "description": "Get the current weather in a given location", # 説明
            "parameters": { # パラメータ
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA",
                    },
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                },
                "required": ["location"],
            },
        },
    }
]

# LLMへの質問
messages = [{"role": "user", "content": "What's the weather like in Boston today?"}]

# Gemini-Pro を呼び出して、メッセージを生成します
response = completion(
    model="gemini/gemini-1.5-flash",
    messages=messages,
    tools=tools,
)

# 結果を出力します
print(response)
log_model_response(response)

コード解説

  1. ツールの定義: tools 変数に、利用するツールを定義します。

    • type: ツールの種類を指定します。ここでは function を指定しています。
    • function: ツールの詳細情報を指定します。
      • name: ツール名を指定します。ここでは get_current_weather としています。
      • description: ツールの説明を記述します。
      • parameters: ツールが受け取るパラメータを定義します。
        • type: パラメータのデータ型を指定します。
        • properties: 各パラメータの詳細情報を定義します。
          • location: 都市と州を指定します。
          • unit: 温度の単位を指定します。
        • required: 必須パラメータを指定します。
  2. LLMへの質問: messages 変数に、ユーザーの質問を設定します。ここでは、「ボストン市の今日の天気は?」と聞いています。

  3. Gemini-Proの呼び出し: completion 関数を使って Gemini-Pro を呼び出します。

    • model: 利用するモデルを指定します。ここでは gemini/gemini-1.5-flash を指定しています。
    • messages: LLM に送信するメッセージを指定します。ここでは、ユーザーの役割で「ボストン市の今日の天気は?」という質問を送信しています。
    • tools: 利用するツールを指定します。
  4. 結果の出力: 生成されたメッセージを print 関数で出力します。log_model_response 関数は、モデルの応答の詳細をログ出力します。

より複雑な Tool Calling を使ってみよう!

掃除ロボットを操作する例

以下のコードは、Tool Calling を使って、ルンバのような掃除ロボットを操作する例です。

tools = [
    {
        "type": "function",
        "function": {
            "name": "start_cleaning",
            "description": "Start cleaning in a specified room",
            "parameters": {
                "type": "object",
                "properties": {
                    "room": {
                        "type": "string",
                        "description": "The room to clean, e.g. living room, kitchen",
                    },
                },
                "required": ["room"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "stop_cleaning",
            "description": "Stop the Roomba's current cleaning operation",
            "parameters": {
                "type": "object",
                "properties": {
                    "confirm": {
                        "type": "boolean",
                        "description": "Confirm to stop cleaning",
                    },
                },
                "required": ["confirm"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "set_cleaning_mode",
            "description": "Set the Roomba's cleaning mode",
            "parameters": {
                "type": "object",
                "properties": {
                    "mode": {
                        "type": "string",
                        "enum": ["auto", "spot", "edge"],
                        "description": "The cleaning mode to set",
                    },
                },
                "required": ["mode"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "schedule_cleaning",
            "description": "Schedule a cleaning operation",
            "parameters": {
                "type": "object",
                "properties": {
                    "time": {
                        "type": "string",
                        "description": "The time to start cleaning, in HH:MM format",
                    },
                    "days": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "enum": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
                        },
                        "description": "The days of the week to schedule cleaning",
                    },
                },
                "required": ["time", "days"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "get_battery_level",
            "description": "Get the current battery level of the Roomba",
            "parameters": {
                "type": "object",
                "properties": {
                    "format": {
                        "type": "string",
                        "enum": ["percentage", "raw"],
                        "description": "The format of the battery level",
                    },
                },
                "required": ["format"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "control_wheels",
            "description": "Control the Roomba's wheel movements",
            "parameters": {
                "type": "object",
                "properties": {
                    "direction": {
                        "type": "string",
                        "enum": ["forward", "backward", "left", "right"],
                        "description": "The direction to move the Roomba",
                    },
                    "duration": {
                        "type": "number",
                        "description": "The duration of the movement in seconds",
                    },
                },
                "required": ["direction", "duration"],
            },
        },
    },
]

messages = [{"role": "user", "content": "ルンバをリビングで掃除させて、その後キッチンに移動させてください。"}]

# LLMへの指示
messages = [{"role": "user", "content": "ルンバをリビングで掃除させて、その後キッチンに移動させてください。"}]

response = completion(
    model="gemini/gemini-1.5-flash",
    messages=messages,
    tools=tools,
)

# 結果を出力します
print(response)
log_model_response(response)

コード解説

このコードでは、掃除ロボットを操作するための複数のツールを定義しています。

  • start_cleaning: 指定された部屋の掃除を開始します。
  • stop_cleaning: 掃除を停止します。
  • set_cleaning_mode: 掃除モードを設定します。
  • schedule_cleaning: 掃除のスケジュールを設定します。
  • get_battery_level: バッテリー残量を取得します。
  • control_wheels: 車輪を制御します。

これらのツールを組み合わせることで、LLM はユーザーの複雑な指示を理解し、掃除ロボットを思い通りに操作することができます。

まとめ

この記事では、LiteLLM を使った Gemini の基本的な使い方と、Tool Calling の活用方法について解説しました。Tool Calling を使うことで、LLM の可能性は大きく広がります。ぜひ、あなたのアイデアを活かして、LLM を使った新しいアプリケーション開発に挑戦してみてください!

📒ノートブック

https://colab.research.google.com/drive/1yrKJb1SG5kcSszGWiGukzzdX-BHv2XDY?usp=sharing

Discussion