【Chatbot UI】複数の生成AIをAPIで呼び出せるChatbot UIをローカルデプロイなしでいきなりクラウドデプロイした話


## はじめに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755504/1a89948a-b78a-4537-bee9-be42ac94bd47.png)

いろんな生成AI(LLM)をAPIで動かしたかったので[Chatbot UI](https://github.com/mckaywrigley/chatbot-ui)をさくっと動かしたかったのですが、大ハマりしたので残します。


この記事では、ほぼローカルなしでChatbot UIをVercelにデプロイする手順を紹介します。
### 動作環境
動作環境は以下の通りです：

- **使用ツール**: GitHub, Vercel, Supabase, npm(node.js)
- **前提**: ローカルでの開発環境構築はスキップ

## Chatbot UIとは
https://github.com/mckaywrigley/chatbot-ui
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Chatbot UI overhaul drops next week.<br><br>It’s honestly really, really good.<br><br>Powerful &amp; polished. <br><br>And as always, 100% open-source. <a href="https://t.co/enLG83iTNe">pic.twitter.com/enLG83iTNe</a></p>&mdash; Mckay Wrigley (@mckaywrigley) <a href="https://twitter.com/mckaywrigley/status/1738273242283151777?ref_src=twsrc%5Etfw">December 22, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Chatbot UIとは、**ChatGPTのクローンの様なUIを複数の生成AIを使い分けながら** 体感できるオープンソースのツールです。
ChatGPTのWebUIには無い機能として、会話履歴のフォルダ分けやキーワードによる検索、さらにはよく使うプロンプトをテンプレートとして保存するといった機能があります。

また、ChatGPTの利用においては、入力データが言語モデルの学習に利用されてしまいますが、API経由の場合はデータの収集が行われません。
つまり、Chatbot UIはAPI経由でGPTを利用するので、ChatGPTの様な操作感を保ちつつ、データが保護された環境で利用できるのです。

ChatGPTのWebUIには無い機能として、会話履歴のフォルダ分けやキーワードによる検索、さらにはよく使うプロンプトをテンプレートとして保存するといった機能があります。

また、ChatGPTの利用においては、入力データが言語モデルの学習に利用されてしまいますが、API経由の場合はデータの収集が行われません。
つまり、Chatbot UIはAPI経由でGPTを利用するので、ChatGPTの様な操作感を保ちつつ、データが保護された環境で利用できるのです。


## なぜローカルデプロイなしでVercelにデプロイしたいのか

Chatbot UIの公式README（[こちら](https://github.com/mckaywrigley/chatbot-ui?tab=readme-ov-file)）を見ると、1回ローカルでデプロイしてからクラウド(Versel)にデプロイする流れが推奨されてます：

> 1. リポジトリをローカルにクローン
> 2. 必要なパッケージをインストール
> 3. Supabaseをローカルで設定、デプロイしてデータベースをプッシュ
> 4. その後でVercelにデプロイ

でも、「外でスマホからアクセスしたいし、**ローカルで1回動かすの面倒くさいな**」と感じました。
だって、ローカルでDockerとかScoopとか色々インストールするの、正直だるいですよね？

だから、いきなりVercelにデプロイすることにしました。結果的にはできましたが、Supabaseとの連携で結構ハマりました。その記録を残しておきます。

## やり方

###  手順1: GitHubリポジトリの準備
**公式README.mdと同じ**

まず、Chatbot UIをVercelにデプロイするには、GitHubリポジトリが必要です。：

1. GitHubで空のプライベートリポジトリを新規作成（たとえば`my-chatbot-ui`）
2. 公式リポジトリ（`https://github.com/mckaywrigley/chatbot-ui`）をローカルにクローン
3. クローンしたファイルをさっきの空リポジトリにプッシュ

```bash
git clone https://github.com/mckaywrigley/chatbot-ui.git
cd chatbot-ui
git remote set-url origin https://github.com/あなたのユーザー名/my-chatbot-ui.git
git push origin main
```

ここまでは簡単です。
ただ、ローカルでの`npm install`とか一切スキップしています。なぜなら**ローカルで動かす気がないから…**



### 手順2: Supabaseの設定とハマりポイント

#### Supabaseプロジェクトの作成
**ここは公式のREADME.mdと同じ**

Chatbot UIはSupabaseをデータベースに使っているので、Supabaseでプロジェクトを作ります：
1. [Supabase](https://supabase.com)にログイン。
2. 「New Project」をクリックして、適当な名前（例: `chatbot-ui-db`）でプロジェクト作成。
3. 作成が終わると、プロジェクトIDとデータベースパスワードが手に入ります。場所は：
   - **プロジェクトID**: ダッシュボードの「Settings > General」
   - **データベースパスワード**: 「Settings > Database」


#### Supabaseに接続、プッシュ

:::note
最初はGithub actionsで全部済ませようとしましたが、なんかうまくいかなかったのでローカルでやります
:::

公式READMEだと、ローカルでDockerとSupabase CLIをインストールして、こんな感じで進めるみたいです：

> ```
> scoop install supabase
> supabase init
> supabase start
> ```

「DockerとかScoopとか面倒くさい！」って思ったので、もっとシンプルにできないか探しました。
で、[Supabase CLIの公式README](https://github.com/supabase/cli/blob/develop/README.md)を見ると、`npm`で済ませる方法がありました。
ローカルでの実行(start)にはdockerが必要ですが、**dbのpushには不要です。** 

#### Supabase CLIのインストール
まず、ローカルでSupabase CLIを使うために、最低限の準備をします：
```bash
npm i supabase --save-dev
```
これでSupabase CLIが開発環境に追加されます。依存関係をプロジェクトに含めたくない場合は、`npx`を使うのでもOKです。


#### Supabase CLIで接続

Supabase CLIを使ってプロジェクトに接続します。まずはログイン：
```bash
npx supabase login
```
ブラウザ認証します。`You are now logged in. Happy coding!`と出たら成功。

次に、プロジェクトをリンクします：
```bash
npx supabase link --project-ref <プロジェクトID>
```
データベースのパスワードを入力してEnterしてください。

:::note warn
ここでハマったポイントとしては、「Enter your database password」と出て、パスワードを入力しても何も反応しないってところです。
マスクされてるから入力できてるのか分からなくて、何度も打ち直したり、Enter連打したり、Ctrl+Cでやり直したりしました。
生成AIに聞いたら「マスクされてるだけですよ」って言われて解決しました。
:::



#### データベースのプッシュ
READMEに従って、公式のスキーマ（`supabase/migrations/20240108234540_setup.sql`）の中の`project_url`と`service_role_key`を自分のプロジェクトのものに書き換えてGitHubにプッシュしてます：
- **project_url**: 「Settings > API」の「Project URL」
- **service_role_key**: 「Settings > API」の「Service Role Key」

書き換えたら、supabaseにプッシュ：
```bash
npx supabase db push
```
成功したら、Supabaseでテーブルが反映されてるか確認します。ちゃんと反映されたので一安心です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755504/9b15e0fc-9926-46c0-85aa-0f00465f1660.png)
**スクリーンショットの提案**: ここでSupabaseのGUIの「Table Editor」にテーブルが反映されてる画面のスクリーンショットがあると、読者の「できた！」感がアップしますよ。

---

### 手順3: Vercelにデプロイ
**公式のREADME.md通りです。**

[Vercel](https://vercel.com)にリポジトリをデプロイします：
1. Vercelのダッシュボードにログイン・サインアップ
2. 「New Project」をクリックして、先ほどプッシュしたGitHubリポジトリを選択します
3. Supabaseから取得した環境変数を設定します。以下のキーと値を追加します：
   - `NEXT_PUBLIC_SUPABASE_URL`: Supabaseの「Settings > API」から「Project URL」
   - `NEXT_PUBLIC_SUPABASE_ANON_KEY`: 同じく「Anon Key」
   - `SUPABASE_SERVICE_ROLE_KEY`: 「Service Role Key」
4. 設定はそのまま（フレームワークは自動でNext.jsに設定されます）で「Deploy」

少し待つと、デプロイされたURLが手に入ります。

この時点でログインUIが立ち上がりますが、**チャット画面に入れません**。次が本番です。




### 手順4: メール認証で大ハマり

デプロイが終わってURLにアクセスしたら、サインアップ画面が出てきました。
メール認証が必要なので、届いた認証メールのリンクをクリックすると、`localhost:3000`にリダイレクトされます。**ローカルホストなんてものは存在しない**ので一生認証できません。

公式READMEはローカル前提なので、こういう落とし穴がありますね。

#### 解決策: 認証をぶった切る
**面倒くせ～**と割り切って、Supabaseで認証をオフにしました：
1. Supabaseのダッシュボードで「Authentication > Users」から登録ユーザーを一旦削除
2. 「Authentication > Sign In/Up > Email >」で「Confirm email」をオフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755504/7cf004c4-d5ee-4e16-9504-87260609b1c8.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755504/4771bc25-1af7-4b3f-b0e5-d33318fd5814.png)


これで認証なしでログインできるようになりました。セキュリティ的には微妙ですけど、個人プロジェクトならこれで十分でしょう。


:::note warn
APIキーはログインしてから入れることだけ注意。Verselデプロイ時の環境変数に突っ込むのはやめたほうがいいでしょう。
本番環境ならちゃんと認証設定を調整してください。楽しただけ！

:::

### 手順5. 動作確認
あらためてサインアップして、サインイン
APIキーを入力して適当にチャットして帰ってきたら成功。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755504/f2f052d1-6c17-4f26-bcbd-e7e61569ca25.png)


## まとめ

ローカル構築ほぼなしでVercelにデプロイできたので安心しています。
Supabaseのプッシュ周りとメール認証で予想以上に苦労しました。特に「何が必須で何が不要か」を探るのが大変で、`localhost`が出てきたときは絶望しましたが、無事に動いたので良かったです。

次は機能を追加して、Claude 3.7 Sonnetみたいなモデルに対応させたいと思ってます。
APIの構造を少しいじるだけだと思うので、デプロイし直すだけだとは思っています。


## 参考資料

https://github.com/mckaywrigley/chatbot-ui

https://bou7254.com/posts/chatbot-ui-2-vercel-supabase-free-deploy

https://bou7254.com/posts/chatgpt-clone-ui-v2-local-setup

https://github.com/supabase/cli/blob/develop/README.md

https://vercel.com/docs

https://supabase.com/docs

https://www.ai-souken.com/article/using-chatgpt-in-local-environment