Open-Meteo APIを使って天気に基づくコーディネートを提案するスキルを作ってみた

これは 「satto | [生成AIエージェント Advent Calendar 2024](https://qiita.com/advent-calendar/2024/satto)」 7日目の記事です。

こんにちは。「学びの探究者」です。普段はnoteで活動しています。

https://note.com/lovely_hawk768/

普段は、エンジニアではありません。
そんな私でも「satto」を使えば自分の好きなスキルができちゃうんだーということでサッとご紹介できればと思います。

この記事では、無料でできる天気APIと生成AIを組み合わせて、日常で役立つ簡単なスキルを作る方法を紹介します。生成AIを使ったアプリケーション開発に興味がある方や、非エンジニアでも手軽に生成AIを試してみたい方におすすめです。

* * *
# スキルの概要
- **目的**: 天気予報データをもとに、その日の服装を提案する。
- **仕組み**:
  1. ユーザーが地域情報（例: 東京）を入力。
  2. Open-Meteo APIを使って指定地域の天気データを取得。
  3. 取得したデータをAIノードに渡し、「寒い日はコート」「雨の日は傘」などの具体的な服装アドバイスを返却。
- **想定される利用シーン**:
  - 朝の忙しい時間に、適切な服装を選ぶ手助けをしたい方。
  - 天気情報または予報を取得して、自分のアプリに実装したい方。

# Open-Meteo APIの使い方
## Open-Meteo APIとは
- **概要**: Open-Meteoはオープンソースの天気APIで、商用でなければ無料で利用可能です。
- **特徴**:
  - 登録やAPIキーが不要で、手軽に試せる。
  - 緯度・経度を指定するだけで簡単に天気データを取得できる。
  - その他、パラメータは簡潔で、1時間ごとの天気予報や降水確率なども取得できる。
- **公式サイト**: [Open-Meteo API](https://open-meteo.com/)

## 東京の7日間の天気予報を取得する例
以下のURLにリクエストを送ると、1時間ごとの温度、降水確率、雨量、天気コードを含むデータを取得できます。

## Open-Meteo公式サイトでのリクエストURL生成
Open-Meteo APIでは、公式サイト上で自分が取得したいデータ項目を選択し、リクエストURLを自動生成する機能が用意されています。これにより、プログラミング初心者でも簡単にカスタマイズしたリクエストを作成できます。

### 使い方の手順
Open-Meteo公式サイト（Open-Meteo API）にアクセスします。
「APIドキュメント」セクションに移動します。
取得したいデータ項目をチェックボックスで選択します。
例: 気温（temperature_2m）、降水確率（precipitation_probability）、最大風速10m（wind_speed_10m_max）など。
必要に応じて、緯度・経度や期間を指定します。
ページ下部に自動生成されたリクエストURLが表示されます。

### リクエスト例
```plaintext
https://api.open-meteo.com/v1/forecast?latitude=35.6895&longitude=139.6917&hourly=temperature_2m,precipitation_probability,rain,weather_code&timezone=auto
```
# sattoの実装例
:::note info
このスキルはAIノードを複数使ってチューニングを多くしているため、現在、安定稼働するスキルを再検討中です。
:::
## フロー
```mermaid
graph TD
    A[ユーザーが地域情報・天気予報を知りたい日時・利用シーンを入力] --> B[AIノード①で、Open-Meteo APIリクエストURLを生成]
    B --> C[AIノード②で知りたい日時を解釈]
    C --> D[AIノード③でAIノード②で解釈した日時を天気APIの形式に合わせる]
    D --> E[AIノード④で知りたい場所・日時の天気情報を日本語で解釈する]
    E --> F[AIノード⑤で知りたい場所・日時の最高気温・最低気温を算出]
    F --> G[AIノード⑥で知りたい場所・日時の寒暖差を把握して服装の補足情報を生成]
    G --> H[AIノード⑦で服装を提案]
    H --> I[結果をユーザーに返却]
```

## AIノード①のプロンプト
```text
# 指示
1. {入力.天気が知りたい地域} から位置情報を取得します。
2. 位置情報から緯度（latitude）と経度（longitude）を抽出します。
3. 取得した緯度と経度を使用して、以下のフォーマットに従ってOpen-MeteoのAPIリクエストURLを生成します。

https://api.open-meteo.com/v1/forecast?latitude=[緯度]&longitude=[経度]&hourly=temperature_2m,wind_speed_10m,precipitation,weather_code&timezone=auto


# 補足
- 指示の復唱はしないでください。
- 自己評価はしないでください。
- 結論やまとめは書かないでください。
- 最終成果物以外は出力しないでください。
- 出力結果をダブルクォーテーション("")で囲わないでください
```

## AIノード②のプロンプト
```text
ユーザーが入力したタイムスタンプ{入力.天気が知りたい日}を分析し、分をすべて「00分」に変換して、以下の形式で出力してください。

### 入力形式:
"2024-12-05T19:30:00+09:00" 
### 出力形式:
- 日付："2024-12-05"
-時間："19:00"
```

## AIノード③のプロンプト
```text
次のデータを、次の形式にして出力してください

データ
- {AIノード②生成.日付}
- {AIノード②生成.時間}

### 処理手順:
"日付"と"時間"を結合します。

### 出力形式:
"2024-12-05T19:00"
```

## AIノード④のプロンプト
```text
あなたは天気予報を解析するAIアシスタントです。APIリクエストURL {AIノード①生成.output} をコールし、`hourly.time` 配列と {AIノード③生成.日時} と一致する要素のインデックスを取得します。

### 指示

APIリクエスト結果は以下のようになっているので参考にして、`hourly.time.temperature_2m` 配列などの対応するデータを取得してください。

"hourly": {
"time": [
"2024-12-05T00:00",
"2024-12-05T01:00"],
"temperature_2m": [10.3, 10.1],
"wind_speed_10m": [10.2, 12.1],
"precipitation_probability": [0, 8],
"weather_code": [1, 1]
}

1. 次の情報を取得してください：
- 気温 (`temperature_2m`)
- 降水確率 (`precipitation_probability`)
- 天気コード (`weather_code`)
- 風速 (`wind_speed_10m`)

2. 天気コード (`weather_code`) をWMO codesを使って日本語に翻訳し"天気"とします：1: 晴れ 2: 主に晴れ 3: 曇り ...

3.結果を出力してください： 天気, 気温, 降水確率, 風速

# 取得したデータは、計算や変換は行わず、元の値をそのまま使用してください。
```

## AIノード⑤のプロンプト
```text
あなたは天気予報を解析するAIアシスタントです。APIリクエストURL {AIノード①生成.output} をコールし、
JSONデータの `hourly.time` 配列が  {AIノード③生成.日時}と前方一致する要素のインデックスを取得します。

### 指示

1. 次の情報を取得してください：

- 気温 (`temperature_2m`)を0:00~23:00の1時間ごとに取得して、最高気温と最低気温を算出します

2. 結果を出力してください： `最高気温: <最高気温>°C,最低気温: <最低気温>°C
```

## AIノード⑥のプロンプト
```text
あなたは気温データを解析するAIアシスタントです。以下のAPIレスポンス {AIノード⑥.output} を解析し、気温データを基に寒暖差を計算し、補足情報を生成してください。

### 指示

1. {AIノード⑥生成.最高気温}、 {AIノード⑥生成.最低気温}を基に、最高気温、最低気温、寒暖差を計算します。
2. 寒暖差に基づき以下の補足情報を生成します：
- 寒暖差が大きい場合：「本日は寒暖差が大きいため、昼間は暖かいですが、朝晩は冷え込む可能性があります。」
- 寒暖差が小さい場合：「気温の変動が少なく、快適に過ごせる一日です。」
3. 補足情報を簡潔に出力してください。

補足情報:
```

## AIノード⑦のプロンプト
```text
あなたは天気予報を元に適切な服装を提案するアシスタントです。以下の手順に従って処理を行ってください。

1. {AIノード④.output}、{AIノード⑥.補足情報} から の天気情報を取得します。
2. 抽出した情報を元に、 {入力.利用シーン} と {AIノード⑥.補足情報} を考慮して、その日に適した服装を選んで提案してください。
- 気温が低い場合は、防寒対策を提案します。
- 気温が高い場合は、涼しい服装を提案します。
- 雨が予想される場合は、雨具や防水対策を提案します。
- {AIノード④.風速} より、風が強い場合は、風を防ぐ服装を提案します。
-
4. 提案する服装は、上着・インナー・ボトム・アクセサリー (例: 帽子、マフラー、日傘など) ・靴に分けて記載してください。
5.出力するものは以下です。
-地域 、日付
- 天気、気温、降水確率
- 提案する服装
- 服装のアドバイス
- 補足情報

# 補足
- 指示の復唱はしないでください。
- 自己評価はしないでください。
- 結論やまとめは書かないでください。
- 最終成果物以外は出力しないでください。
- 出力結果をダブルクォーテーション("")で囲わないでください
- `precipitation_probability` はすでに整数で表現されているため、100倍や変換は不要です。そのまま後ろに `%` を付けて表示してください。
```

# 最後に
この記事では、Open-Meteo APIとSattoを活用した天気予報スキルの実装例を紹介しました。背景や作成の動機については、[こちら](https://note.com/lovely_hawk768/n/na6ed8ac838e3)の記事で詳しく紹介しています！

今回紹介した手法を参考に、ぜひ自分だけのオリジナルスキルを作ってみてください！
また、生成AIを活用した面白い事例があればぜひコメントで教えてくださいね。

この記事が役に立った場合は、ぜひコメントやいいねをお願いします！