「OpenAI API × Spotify API」でチャット型音楽レコメンドツールを作った

こんにちは。

タイトルにもある通り、「OpenAI API × Spotify API」でチャット形式で音楽をレコメンドするTUI（Terminal User Interface）ツール**Chatify**を作成したので、使用した技術や仕組みを踏まえながら紹介したいと思います。

Chatifyという名前はSpotifyとChatを混ぜ合わせて付けました（安直）。

https://github.com/JunNishimura/Chatify

## DEMO
質問に回答することで、音楽のレコメンド結果が更新されます。レコメンド一覧から聞きたい曲を選択することで、音楽を聞くことができます（ストリーミング機能はないので、バックグラウンドでSpotifyアプリを起動しておく必要があります）。
![chatify.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191216/733fe4dc-3c78-088d-17bf-1e9506eaf280.gif)


## 必要なもの
Chatifyを利用するには以下の二つを準備してもらう必要があります。
- [Spotify Premium](https://www.spotify.com/jp/premium/)プランへの加入（Spotify API利用のため）
- [OpenAI API](https://platform.openai.com/signup)へのサインアップ(OpenAI API利用のため)

※上記2つは有料のため、Chatifyの利用も有料になります。

## 使い方
1. `chatify greeting`
Chatifyをインストールしたら1度以下の3つを教える必要があります。
- Spotify API Client ID
- Spotify API Client Secret
- OpenAI API Key

上記3つを手元に用意したら、`greeting`コマンドでChatifyに伝えましょう。
![スクリーンショット 2023-09-03 151906.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191216/7effcf57-0b9e-5466-a182-2b2eddf45b69.png)


2. `chatify hey`
`hey`コマンドでChatifyに話しかけると、いくつか質問をしてくれます。その質問に回答すると音楽をレコメンドしてくれます。

多くの質問に回答するほど、あなたの求めている音楽レコメンドしてくれます。
![スクリーンショット 2023-09-03 152152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191216/79de518a-a8a4-138c-b6f7-612dd2d1c1fa.png)


## 背景
Spotifyは自分が一番好きなアプリです。毎日使っています。音楽が大好きということもあり、Spotifyがないと生きていけないです。

他にもApple Musicなどの音楽ストリーミングサービスは使用していますが、Spotifyは単純に音楽を提供しているのではなく、「新しい音楽との出会い」という体験価値を提供している点が他のサービスとは違う点だと思っています。（Spotifyは音質に難がありますが、Spotify HiFiが年内に提供されるみたいなので期待）

僕個人としても「新しい音楽との出会い」を模索したいというモチベーションがありました。ChatGPTなどのAIサービスを日々利用している中で、ChatGPTみたいなAIチャットボットとの会話を通じて音楽をレコメンドしてくれたら面白いんじゃねと思い、Chatifyを作るに至りました。

## 仕組み
皆さんもChatGPTを使っていて日々感じているかもしれませんが、AIアプリではプロンプトが重要になります。本ツールでもかなり細かくプロンプトを作り込んでいます。

https://github.com/JunNishimura/Chatify/blob/main/ai/prompt/prompt.go

音楽のレコメンドにはSpotify APIの`Get Recommendations`という機能を活用しました。

https://developer.spotify.com/documentation/web-api/reference/get-recommendations

`Get Recommendations`ではかなり細かくパラメータを指定することができるのですが、今回は
1. Genre
2. Danceability
3. Valence
4. Popularity
5. Acousticness
6. Energy
7. Instrumentalness
8. Liveness
9. Speechiness

の9項目に関してユーザーから聞き出すことで音楽をレコメンドするようにしました。

genre以外の項目に関しては、リクエストに含めると時は0.5といった数値にする必要があります。ボットからユーザーに質問する際に、「danceabilityは0~1の中でどれくらいですか」といった内容で質問すると、ユーザー体験が損なわれると思ったので、「Do you want to dance with the music?」といった数値を直接聞かない内容を質問させるように指示しています。

```
[First Rule]
The possible values for the analysis elements Danceability, Valence, Popularity, Acousticness, Energy, Instrumentalness, Liveness and Speechiness are numerical values such as 0.5.
But the bot cannot ask questions that force the interlocutor to directly answer with a numerical value such as "How much is your danceability from 0 to 1?".
Instead the bot asks questions to analyze how much danceability music the interlocutor is looking for, such as "Do you want to dance with music?".
```

ただ、上述した通りリクエストには数値として含める必要があるので、ユーザーの回答を数値に変換する作業をAIにさせています。例えば「Yes, I want to dance with the music」というユーザーの回答に対して「よしdanceabilityは0.8くらいだな」といった感じでAIに推測させています。

```
[Third Rule]
For the interlocutor's answers on danceability, valence, popularity, acousticness, energy, instrumentalness, liveness and speechiness, convert them into numerical values and output them. 
For example, if the interlocutor answers, "I want to dance," please guess in the form of "Danceability: 0.8" and report the guess result to the interlocutor.
```

ユーザーから回答が得られる度にリクエスト内容を更新して`Get Recommendations`よりレコメンド結果を取得して、ユーザーに提供するようにしています。


## こだわったポイント
1. コマンド名
　Chatifyのメイン機能呼び出しのコマンドは`chatify hey`になっています。AIチャットボットとの会話の中で音楽に出会うという体験がChatifyの核であるため、機能の呼び出しであるコマンド入力もAIチャットボットへの呼びかけのようにユーザーに感じて欲しいという思いからそうしました。これは「Hey, Siri!」からヒントを得ました。
2. 質問の仕方
　「仕組み」の章でも書きましたが、ボットからユーザーへの質問の仕方を工夫しました。リクエストには数値で渡すというシステム上の都合があったのですが、ユーザーに直接「貴方がも音楽にもとめているenergyは0から1の間でどれくらいですか」といった事を聞いてしまうと、ユーザー体験を損ねてしまうので、「音楽を聞いてで元気になりたいですか」といったように言い換えて質問するようにプロンプトを作成しました。
4. UI
　本ツールの提供する機能は極めてシンプルです。機能数では勝負できないと分かっていたので、「ボットとの会話の中で音楽に出会う」という単一機能をより質の高いものにすることで、より良いユーザー体験を提供できるよう努めました。
　ターミナル上で動くツールなので文字だけで完結するCLIツールにしても良かったのですが、それだとユーザー体験が安っぽいなと思いました。よりAIボットとチャットをしているような体験を提供できるような、そしてレコメンド結果が見やすく、捜索しやすいようなUIを模索しました。
　その結果、ターミナルの画面を2分割してチャット画面とレコメンド画面を同時に表示するようなUIを実装するに至りました。UIの実装には、Bubble Teaというライブラリを使用しました。
 
https://github.com/charmbracelet/bubbletea

## 最後に
Chatifyを通じて、自分が大好きな音楽との新しい出会い方を実現することができとても嬉しいです。今まで複数のアプリケーションを作ってきましたが、個人的に一番満足度が高く、自信のある制作物を世に公開できました。

今後も新しい音楽体験を作り出せないか模索していきます🎵

ぜひ遊んでみてください〜！「こんな機能ほしい！」「もっとこうして欲しい！」といったフィードバックも絶賛募集中です！

https://github.com/JunNishimura/Chatify