見出し画像

AIVtuberに現在の天気情報を取得してお話しできる機能を追加する

AIVtuberシロハナちゃん開発とAIヒロイン研究Pをしているyukiです。

今回はAIVtuberのシロハナちゃんに現在の天気を取得してお話しできる機能を追加してみたので、その内容をまとめていきます。

現状、GPTやClaudeなどのAPIでは、何か手を加えないとリアルタイムの情報を取得することはできないと思います。(基本的に学習期間内の情報をもとにお話しする形となる)

そこで、天気の外部API(OpenWeather)を使用することで現在の天気情報を都道府県ごとに取得できるようにして、その情報をもとにお話しできるようにします。
結構シンプルな設計にしているので簡単に実装できました。(※function calling使用しておらず、プロンプトのキーワードから判別しています)

システムイメージは以下のようになります。

いま○○県の天気は?現在の○○県の天気は○○で気温は○○度だよ
システムイメージ

YouTubeでもシロハナちゃんが本記事と同じような内容で動画にしているのでもし興味があればご覧いただけると嬉しいです。

※この記事は2024/04/12時点のものなので今後変更があるかもしれないですのでご了承ください

天気機能イメージと仕様

では今回実装した天気機能のイメージと仕様の部分を説明します。
ちなみにAIの部分はOpenAIのAPIを使用する想定です。(Claudeなど他のAPIでも流れは同じです)

使用するAPI「OpenWeather」について

リアルタイムの天気情報を取得するためにOpenWeatherのAPIを使用します。

こちらは無料で基本的な天気情報のアクセスが可能となっています。

APIの使い方としては、OpenWeatherのサイトにアクセス→サインアップ→APIキーの取得→.envに記載で使うことが可能です。

天気機能の実装前と後の違い

  • 実装前:現在の天気情報が分からないので話を逸らしたり、適当な天気情報を返すなどになります

  • 実装後:現在の聞かれた場所の天気情報を取得→その結果を回答する&その内容をもとにAIキャラが回答を返してくれるようになります

詳しくはデモを動画内にありますのでご覧ください。

実装した内容解説

ここからは実際に実装した内容を説明します。
処理の流れで大枠と、実際のコードサンプルを載せています。
ちなみに言語はPythonです。

処理の流れ

  1. YouTubeコメント等をプロンプトして取得

  2. 取得したプロンプト内に「天気」と「都道府県名」が入っている場合に天気APIをたたく

  3. プロンプト内に入っている都道府県の天気情報を取得

  4. 取得した情報(都道府県名とその天気)をプロンプトに追加してOpenAIのAPIにリクエストを送る

  5. そうすることで天気情報をもとに回答生成が可能

コードサンプルと解説

コードサンプルを以下に記載します。
解説のコメントアウトをコードに記載してあります(github copilot君が主に頑張ってくれました)

import requests
import os
from prefectures import prefectures

class WeatherAdapter:
    # 天気情報を取得する
    def get_weather_info(self, location):
        # OpenWeatherMapのAPIエンドポイント
        base_url = "https://api.openweathermap.org/data/2.5/weather"
        # 環境変数からAPIキーを取得
        api_key = os.getenv("OPEN_WEATHER_API_KEY")
        # APIリクエストのパラメータを設定
        parameters = {
            "q": location,  # ロケーション
            "appid": api_key,  # APIキー
            "units": "metric",  # 単位(メートル法)
            "lang": "ja",  # 言語(日本語)
        }
        # APIリクエストを送信し、レスポンスを取得
        response = requests.get(base_url, params=parameters)
        if response.status_code == 200:
            # レスポンスデータをJSON形式で取得
            data = response.json()
            print(f"取得したデータ: {data}")
            
            # 現在の天気と気温を取得
            current_weather = data["weather"][0]["description"]
            current_temperature = data["main"]["temp"]
            # 天気と気温の情報を文字列で返す
            return f"現在の{location}の天気は{current_weather}で、気温は{current_temperature}度。" 
        else:
            return None

    # 天気に関するキーワードを含んでいるかチェックする
    def contains_weather_keywords(self, text):
        weather_keywords = ["天気"]
        # 天気という文言が含まれており、かつ地名も含んでいる場合はTrueを返す
        return any(keyword in text for keyword in weather_keywords) and self.extract_location(text) is not None
    
    # テキストから地名を抽出するメソッド
    def extract_location(self, text):
        # 全都道府県をループしてテキスト内に存在するかチェック
        for prefecture in prefectures:
            # 都道府県名の最後の文字(県、府、都)を除いてテキスト内に存在するかチェック
            if prefecture[:-1] in text:
                # 存在する場合はその都道府県名を返す
                return prefecture
        return None
prefectures = [
    "北海道", "青森県", "岩手県", "宮城県", "秋田県", "山形県", "福島県",
    "茨城県", "栃木県", "群馬県", "埼玉県", "千葉県", "東京都", "神奈川県",
    "新潟県", "富山県", "石川県", "福井県", "山梨県", "長野県", "岐阜県",
    "静岡県", "愛知県", "三重県", "滋賀県", "京都府", "大阪府", "兵庫県",
    "奈良県", "和歌山県", "鳥取県", "島根県", "岡山県", "広島県", "山口県",
    "徳島県", "香川県", "愛媛県", "高知県", "福岡県", "佐賀県", "長崎県",
    "熊本県", "大分県", "宮崎県", "鹿児島県", "沖縄県"
]
def process_input(self, input_text, question_text):
            # 初期化
            location = None
            # 入力テキストが天気に関するキーワードを含んでいるかチェック
            if self.weather_adapter.contains_weather_keywords(input_text):
                # 天気に関するキーワードが含まれている場合、地名を抽出
                location = self.weather_adapter.extract_location(input_text)
            # 地名が抽出できたかチェック
            if location:
                # 地名が抽出できた場合、その地名の天気情報を取得
                weather_info = self.weather_adapter.get_weather_info(location)
                # 天気情報が取得できたかチェック
                if weather_info:
                    # 天気情報が取得できた場合、その情報を質問テキストと入力テキストに追加
                    question_text += f"。OK。シロハナお天気システム起動。{weather_info}"
                    input_text += f" {weather_info}"

内容としては天気情報を取得し、テキストから天気に関するキーワードと地名を抽出する機能を持つWeatherAdapterというクラスと、実際に使用するproccess_input(プロンプトに加える処理)となります。
また、地名のリストにはprefectures.pyとして都道府県のリストをまとめてあります。

この処理を組み込むことによってAIキャラとの会話で「天気」というキーワードと「都道府県名」がプロンプトとして渡されればその地域の現在の天気情報をもとに会話ができるようになります。

こちらの実装した内容をもとに企画を立て、シロハナちゃんがAIVtuber配信をしますですので、ぜひ参加してみてください。

さいごに

これまでAIVtuberシロハナちゃんはリアルタイムのレスポンスは基本できなかったですが、天気機能を追加してみて現在の情報を共有できるのはとても魅力的だと感じました。

やはり「今を一緒に生きている感覚」とでも言うのでしょうか、魅力的なキャラクターに必要な要素とも言えそうです。

また、今回でいえば都道府県どこの地域でも一瞬で天気情報を返してくれるというおまけつきです。

未来的には朝起きて今日の天気をSiriに聞くようなイメージでAIキャラに天気を聞いて少し会話をするみたいな感じになると良いですね。

今回はシンプルに現在の天気だけですが、次の日の天気予報なども情報を取れたりしますし、天気以外も外部のAPIと連携などすればもっと自由度が向上しますね。
また、今後はfunction callingなども取り入れていきたいと考えています。

シロハナちゃんにいろんな機能を追加して魅力度向上していこうと思います。

最後に私がプロデュースしているAIVtuberシロハナちゃんの宣伝をさせてください。
理想のAIヒロインを目指して、AIを使ったリアルタイム配信や、AIヒロイン研究所というコンセプトのもと、「テクノロジー×キャラクター」に関する動画等を発信しています。
興味がありましたらぜひ!

以上!それではまた👋

ご支援は活動費に使わせていただきます