DB-GPTとOllamaでデータベースを操作してみる

# はじめに

DB-GPTは 、Text2SQL効果の最適化、RAGフレームワークと最適化、マルチエージェントフレームワークの協力などを通して、データを使用した大規模モデルアプリケーションをよりシンプルで便利にするAIネイティブデータアプリ開発フレームワークです。Text2SQLによってデータベースの操作を自然言語で行う事ができます。

https://dbgpt.site/

https://github.com/eosphoros-ai/DB-GPT


# セットアップ

DB-GPTは様々なデータベースを扱う事が出来ますが、今回はSQLiteで動かしてみます。また、LLMにはOllamaを使用します。
セットアップ方法はいくつかありますが、 公式の[Dockerを用いる方法](https://docs.dbgpt.site/docs/latest/installation/docker#run-through-sqlite-database)を参考に、下記の様に `docker-compose.yaml` を作成します。`docker-compose.yaml` には各種設定も記述してしまいました。また、Ollamaも同時に起動する様にしました。

```yaml
services:
  dbgbt:
    image: eosphorosai/dbgpt
    container_name: dbgpt
    ports:
    - 5670:5670
    environment:
      # 言語選択 en(英語) or zh(中国語)
      - LANGUAGE=en 
      # DBの設定
      - LOCAL_DB_TYPE=sqlite
      - LOCAL_DB_PATH=data/default_sqlite.db
      # (Ollamaを使用する場合の)LLMの設定
      - LLM_MODEL=ollama_proxyllm 
      - PROXY_SERVER_URL=http://ollama:11434
      - PROXYLLM_BACKEND=command-r:35b-v0.1-q4_K_M # 使用するモデル名
      - PROXY_API_KEY=not_used                     # 何かを設定しないとエラーになる
      # (Ollamaを使用する場合の)Embeddingモデルの設定
      - EMBEDDING_MODEL=proxy_ollama
      - proxy_ollama_proxy_server_url=http://ollama:11434
      - proxy_ollama_proxy_backend=mxbai-embed-large:v1 # 使用するモデル名
    volumes:
      # DB-GPTで継続的に使用するフォルダおよびファイル
      - ./data/pilot/data:/app/pilot/data
      - ./data/pilot/message:/app/pilot/message
      - ./data/pilot/meta_data/alembic/versions:/app/pilot/meta_data/alembic/versions
      - ./data/pilot/meta_data/dbgpt.db:/app/pilot/meta_data/dbgpt.db
      - ./data/models:/app/models
      # SQLiteのdbファイルを置く場所
      - ./data/input:/input 

  ollama:
    image: ollama/ollama
    container_name: ollama
    ports:
      - 11434:11434
    volumes:
      - $HOME/apps/ollama/.ollama:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
```

```sh
mkdir -p data/pilot/meta_data
touch data/pilot/meta_data/dbgpt.db
```

初回は上記の様にDB-GPTの設定ファイルをホスト側に確保してから、起動します。

```sh
docker compose up -d
```

# 実行

`http://localhost:5670/` にアクセスすると下の画面が表示されます。

![dbgpt_01](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/efdbc0fc-59db-f47b-927d-a5194486ef64.png)

## DB登録

左下の `Database` を選択するとデータベース登録画面になります。

![dbgpt_02](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/e4402026-e2fb-443c-bfa8-bb9f32609a4f.png)

今回は、MySQLのサンプルデータベースSakilaをSQLiteに変換したものを使います。

https://github.com/bradleygrant/sakila-sqlite3

上記サイトなどから `sakila_master.db` をダウンロードし、`./data/input/` に置いてから、上部の `+Create` をクリックして、データベースを登録します。Dockerの設定で、ホストの `./data/input/` は コンテナ内の `/input/` に接続されているので、 `Path` は `/input/sakila_master.db` とします。

![dbgpt_03](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/79cd96d3-7ac3-f202-02d2-a773d285cb2d.png)

登録が完了すると、下の様に赤丸の数字が表示されます。

![dbgpt_04](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/7adcd966-36d3-b657-f20a-951435cb6f2f.png)

## DB操作

データベースの登録が完了したので、データベースの操作を試してみます。
トップ画面に戻り、`Chat Data`を選択すると、下記の画面になります。上部に、データベースとして先ほど登録した`Sakila`が選択されているのを確認し、下部のチャット欄にデータベースに関する質問を入力します。

![dbgpt_05](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/28b68971-68e0-72e2-e09b-f104d5150046.png)

今回は下記サイトの問題を質問として入力してみました。

https://zenn.dev/yamadadayo123/scraps/9ee01e09aaefd1

1. 俳優のフルネーム
   ![dbgpt_06](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/be7528a7-857a-6a56-835a-1ad4d7da671a.png)
   正解してくれました。`SQL` タブで使用したコマンドも確認できます。
   ![dbgpt_07](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/ff6b9644-8e89-b8e2-1b1d-7ebb617034ec.png)
  

1. エジプトに住んでいる客のフルネーム
   ![dbgpt_08](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/f0b16915-075b-803d-10b0-4364c66b8dc6.png)
   これも正解です。

1. 出演している俳優の数が多い映画ランキング
   ![dbgpt_10](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/294adfc5-3539-9f5b-d9fe-fb21e8f78146.png)
   参考にしたサイトとは出演数が12名の映画のタイトルが異なりますが、同人数の映画が4件以上あり、10件を超えてしまったためなので、正解として良いでしょう。

1. 各顧客が支払った合計
   ![dbgpt_12](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/26f063a1-4232-a5d9-74aa-5b6725f00488.png)
   上手くコマンドが生成出来なかった様で、エラーになってしまいましたが、質問を変えると上手く行きました(ついでに金額を200ドルから150ドルに変えていますが、意味はありません)。
   ![dbgpt_13](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/05345c46-f233-794b-8344-3e3451262851.png)
   なお、同じ質問をしても、正解する場合とエラーになる場合があったので、何度か試してみる事も必要です。この点はLLMの性能にもよるので、できるだけ高性能なモデルやText2SQLに特化したモデルを使う方が良いでしょう。

1. 売上トップ5のカテゴリ
   ![dbgpt_15](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/4829e807-fdb6-24a4-71ea-3bb8fb0d9169.png)
   この様に数値が先頭に来る場合は、グラフも作成してくれます。グラフの形式は選択できますし、他と同様に表でも確認できます。
   ![dbgpt_18](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/84b2231f-232e-cffa-1740-17e6e2e4270a.png)
   ![dbgpt_17](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/1afe8caa-b4df-a137-d389-0ed19fbe4d83.png)

1. 年別で売上順のカテゴリ
   ![dbgpt_19](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791334/f39d4d8d-780f-05fb-38a1-5697fae4daf0.png)
   この問題と次の問題は、どう質問を変えてもエラーになってしまいました。今回使用したLLMの限界かと思われます。

# まとめ

DB-GPTでデータベースを操作してみました。SQLはほぼ初めてでしたが、この様に自然言語で質問できると簡単です。結果と共にコマンドも確認できるので、SQL初心者の勉強にも使えそうです。