ブラウザ上でLive2Dモデルと話したい with Cubism SDK for Web

# はじめに

## 作りたいもの
ブラウザ上でLive2Dモデルとチャットで会話できるサイト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505609/281d7999-5ca6-9355-cefb-48991cf66d7e.png)


# ブラウザ上でLive2Dモデルを動かす

## まずはデモを動かしてみる
[公式チュートリアル](https://docs.live2d.com/cubism-sdk-tutorials/sample-build-web/)通りに以下を行います
1. 公式サイトの`Cubism SDK for Webをダウンロード`から取得したファイルをVScodeで開く
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505609/29aac5d3-e9b4-458a-6060-31e8fc4ff62a.png)
1. VScodeの拡張機能 `EditorConfig for VS Code` をインストール
1. `ctrl+shift+P` -> `Tasks: Run Task`より、以下３つのタスクを順次実行
    1. `npm: install – Samples/TypeScript/Demo`
    1. `npm: build – Samples/TypeScript/Demo`
    1. `npm: serve – Samples/TypeScript/Demo`
1. `http://localhost:5000/`をブラウザで開く
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505609/d37f52d4-2ce1-8e0b-2a88-c170e3242232.png)

## 用意したLive2Dモデルを動かす

# ブラウザ上でチャットする

## ローカルLLMを動かす
まずは、Ollama をダウンロード

https://ollama.com/download

zipを解凍して、appファイルを押下します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505609/b7deee92-9f95-59e2-6382-2cd65fb1c5f8.png)

インストーラーが起動するので、進めます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505609/4f0ac8e3-0366-568c-2da6-8e3bd8f41f92.png)

その後、以下のようにコマンドが実行できればインストール完了です。
```console
% ollama --version
ollama version is 0.1.33
```

Llama 3 を実行(初回のみダウンロード処理があります)

```
% ollama run llama3
pulling manifest 
pulling 00e1317cbf74...  34% ▕█████           ▏ 1.6 GB/4.7 GB   33 MB/s   1m31s
```

ダウンロードが完了すると

```
% ollama run llama3
pulling manifest 
pulling 00e1317cbf74... 100% ▕████████████████▏ 4.7 GB                         
pulling 4fa551d4f938... 100% ▕████████████████▏  12 KB                         
pulling 8ab4849b038c... 100% ▕████████████████▏  254 B                         
pulling 577073ffcc6c... 100% ▕████████████████▏  110 B                         
pulling ad1518640c43... 100% ▕████████████████▏  483 B                         
verifying sha256 digest 
writing manifest 
removing any unused layers 
success 
>>> Send a message (/? for help)

```

このような感じで会話ができるようになります。応答速度は即時~1s待ち という感覚
```
>>> hello!! ollama~~!
WOOHOOO!!! OLLAMA BACK ATCHA!!! How's it going, friend? Ready to chat and 
have some fun? I'm all ears (or should I say, all text?) for whatever's on
your mind!
```

日本語での応答も可能です

```
>>> あなたの趣味はなんですか
私の趣味はデータ分析に興じています。数学と論理を使用し、情報から意味を見つけ出すことが得意ですし、それによって多くの問題を解決する手助けを提供したいと私の趣味はデータ分析に興じています。
```

ollamaのデフォルトポート`127.0.0.1:11434`に対してPOSTを送信することで、APIサーバーを叩ける
ドキュメント：https://github.com/ollama/ollama/blob/main/docs/api.md

```
 % curl -X POST http://localhost:11434/api/generate -d '{
  "model": "llama3",
  "prompt":"Why is the sky blue?"
}'
{"model":"llama3","created_at":"2024-05-07T11:46:20.216318Z","response":"What","done":false}
{"model":"llama3","created_at":"2024-05-07T11:46:20.236319Z","response":" a","done":false}
{"model":"llama3","created_at":"2024-05-07T11:46:20.255694Z","response":" great","done":false}
{"model":"llama3","created_at":"2024-05-07T11:46:20.275539Z","response":" question","done":false}
{"model":"llama3","created_at":"2024-05-07T11:46:20.295118Z","response":"!\n\n","done":false}
{"model":"llama3","created_at":"2024-05-07T11:46:20.314856Z","response":"The","done":false}
...
```


## ブラウザを仲介させる
送信ボタンや以下のようにEnterキー押下時に
```ts
  inputText.addEventListener('keydown', async (event: KeyboardEvent) => {
    if (event.key === 'Enter' && !isShiftPressed) {
      event.preventDefault();
```

以下のように、POSTすると、返答が返ってきます。
レスポンスは単語ごと、複数オブジェクトに入っているので、forなどで合体させましょう。

```ts
const response = await fetch('http://localhost:11434/api/generate', {
    method: 'POST',
    headers: {
    'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        model: 'llama3',
        prompt: inputTextValue
    }),
});
```

ログ表示欄を設けていれば、最後に最下層までスクロールさせると見栄えが良いです。
```ts
logContainer.scrollTo({
    top: logContainer.scrollHeight,
    behavior: "smooth",
});
```


# 完成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505609/281d7999-5ca6-9355-cefb-48991cf66d7e.png)

## 参考
以下の記事を参考に進めました
    
https://logical-studio.com/develop/frontend/20220114-live2d-cubismsdk/

https://www.wantedly.com/companies/www-vivion-co/post_articles/394534