さくらの生成AIプラットフォームで作るローカルLLMとDifyによるチャットボット(1) Difyの起動

みなさんは最近、生成AIのトレンドでDifyというキーワードを聞いたことはありますでしょうか。この記事ではさくらの生成AIプラットフォームやGPUを活用し、ローカルLLMを用いたチャットボットを構築する過程を複数回連載でやっていきます。

Difyとは

ChatGPTなどの大規模言語モデル(LLM)を活用できる「AIアプリ開発・運用基盤」です。ノーコードで、ナレッジとの連携を活用したRAG(拡張検索)やチャットボット、ワークフローの作成ができます。

コードブロックという機能を用いることで、例えば入出力のJSONを操作するといったことも可能ですが、主要な機能などはあらかじめ準備されていますので、基本的なアプリケーション構築であればノーコードで構築を行うことができます。

2種類の提供形態

DifyはOSSとして開発が進められており、そのソースコードは以下で公開されています。

https://github.com/langgenius/dify

一方、LangGenius社がクラウドサービスとしても提供を行っています。

https://cloud.dify.ai/apps

検索に用いるプライベートな情報をすべて自社でコントロールしたい場合は、オンプレミスないしはクラウド上の独自プライベートネットワークの中でOSS版を展開する形態を選択可能です。一方クラウドサービスの場合、マルチテナントSaaS型なので、疑似的なプライベート情報空間に環境が構築されます。この場合、基盤の運用を考慮する必要がないというメリットがあります。

ローカルにナレッジデータベースを作成し検索や回答の生成に用いるRAGを構築する場合、社内機密資料、お客様情報やメールでのやり取りなどをどこで保管しておくかが判断のポイントになります。

Difyのクラウドサービス自体はSOC 2 Type I & Type II、ISO/IEC 27001:2022等の認定を取得しGDPRへの準拠も表明しており、監査レポートも入手できますのでそれ自体は安全といえます。選択の分岐としてはあくまで自分たちでその環境をどこまでコントロールしたいか?になります。

Dify on さくらの生成AIプラットフォーム

さくらの生成AIプラットフォームでDifyをホスティングするメリットしては以下が挙げられます。

  • 機密性の高い情報を、自分たちで管理可能なストレージやデータベースを使うことができる
  • 自社システムと専用接続などを行うことで完全閉域網での生成AI利用が可能となる
  • 高火力シリーズというクラウド型GPUサービスを活用することで独自やオープンソース型LLMモデル(LLama 3、Mistral、Nous Hermes など)をホスティングすることで、更なる機密性や低コストのLLM利用が期待できる

とくに3点目は昨今ローカルLLMというキーワードで注目を集めている領域です。ローカルLLMについては、次回の記事で触れながら高火力シリーズを活用したオープンソースのLLMモデルをホスティングしてDifyに組み込む手順をご紹介させていただく予定です。

さっそくやってみる

1回目の記事では、Dify本体をさくらのクラウド上の仮想サーバにインストールし、OpenAIを使ったシンプルなチャットを行うところまでの手順をご紹介します。

仮想サーバの起動とDifyのインストール

コントロールパネルの左ペインでサーバを選択して、右上の追加をクリックします。

Difyの起動だけであれば1コア、2GBで十分ですが、このシナリオではRAGの構築を予定しているため、少し大きめのサーバプランを指定します。

Difyのインストールはシェルから行うことができますが、このブログでは自動でインストールを行うcloud-init用スクリプトを提供します。さくらのクラウドでcloud-initを使うためにはイメージにcloudimgと記載されているものを選択する必要があります。

 

ディスクサイズは100GBを指定します。

さくらのクラウドでcloud-initを使う場合、公開鍵が必須となります。パスワードでのログインも可能ですが非推奨となっています。手元で作成した任意の公開鍵を貼り付けます。

利用可能な鍵をお持ちでない方は以下のコマンドで生成できます。

ssh-keygen -t rsa -b 4096 -f ~/.ssh/my_custom_key

次に以下のcloud-init用スクリプトを貼り付けます。

# cloud-config
# ubuntu 24.04 LTS

ssh_pwauth: true
chpasswd:
  list: |
    ubuntu:<password>
  expire: false

package_update: true
package_upgrade: false

users:
  - default

groups:
  - docker: [ubuntu]

packages:
  - git

write_files:
  - path: /opt/install-docker.sh
    content: |
      #!/bin/bash
      set -e
      
      echo "Docker公式インストールを開始します..." | systemd-cat -t docker-install
      
      # 必要なパッケージをインストール
      apt-get update
      apt-get install -y ca-certificates curl
      
      # GPGキー用のディレクトリを作成
      install -m 0755 -d /etc/apt/keyrings
      
      # Docker公式のGPGキーをダウンロード
      curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
      chmod a+r /etc/apt/keyrings/docker.asc
      
      # Docker公式リポジトリをAPTソースに追加
      echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
      
      # パッケージリストを更新
      apt-get update
      
      # Docker関連パッケージをインストール
      apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
      
      # ubuntuユーザーをdockerグループに追加
      usermod -aG docker ubuntu
      
      # Dockerサービスを有効化・起動
      systemctl enable --now docker
      
      # インストール確認
      docker --version | systemd-cat -t docker-install
      docker compose version | systemd-cat -t docker-install
      
      echo "Docker公式インストールが完了しました!" | systemd-cat -t docker-install
    permissions: '0755'
    owner: root:root
  - path: /opt/setup-dify.sh
    content: |
      #!/bin/bash
      set -e
      
      generate_password() {
        # 英数字のランダムな16文字のパスワードを生成
        openssl rand -base64 24 | tr -d "=+/" | head -c 16
      }
      generate_secret_key() {
        # 英数字のランダムな42文字のシークレットキーを生成
        openssl rand -base64 64 | tr -d '=+/' | head -c 42
      }
      
      # INIT_PASSWORDにランダムなパスワードを設定
      INIT_PASSWORD=$(generate_password)
      # SECRET_KEYにランダムなシークレットキーを設定
      SECRET_KEY=$(generate_secret_key)
      
      # 生成されたパスワードをログに記録
      echo "Generated INIT_PASSWORD: $INIT_PASSWORD" | systemd-cat -t dify-setup
      echo "Generated SECRET_KEY: $SECRET_KEY" | systemd-cat -t dify-setup

      echo "Starting Dify setup..." | systemd-cat -t dify-setup
      
      # Dify を取得
      echo "Cloning Dify repository..." | systemd-cat -t dify-setup
      git clone --depth 1 --branch 1.5.0 https://github.com/langgenius/dify.git /opt/dify
      
      # ディレクトリの所有者を変更
      chown -R ubuntu:ubuntu /opt/dify
      
      # .env ファイルを準備
      cd /opt/dify/docker
      cp .env.example .env

      # .env ファイルの INIT_PASSWORD を設定
      sed -i "s/INIT_PASSWORD=/INIT_PASSWORD=$INIT_PASSWORD/" /opt/dify/docker/.env
      
      # .env ファイルの SECRET_KEY を設定
      sed -i "s/SECRET_KEY=/SECRET_KEY=$SECRET_KEY/" /opt/dify/docker/.env
      
      # .env ファイルの所有者を変更
      chown -R ubuntu:ubuntu /opt/dify/docker/.env

      # 必要なディレクトリを作成
      mkdir -p /opt/dify/docker/volumes
      chown -R ubuntu:ubuntu /opt/dify/docker/volumes
      
      # Docker images を事前にプル
      echo "Pulling Docker images..." | systemd-cat -t dify-setup
      sudo -u ubuntu docker compose pull
      
      # Docker Compose でサービスを起動
      echo "Starting Dify services..." | systemd-cat -t dify-setup
      sudo -u ubuntu docker compose up -d
      
      # 起動完了を待機
      sleep 30
      
      # サービスの状態を確認
      echo "Checking service status..." | systemd-cat -t dify-setup
      sudo -u ubuntu docker compose ps | systemd-cat -t dify-setup
      
      # 完了メッセージ
      echo "Dify installation completed!" | systemd-cat -t dify-setup
      echo "Dify admin setup page: http://$(hostname -I | awk '{print $1}')/install" | systemd-cat -t dify-setup
      echo "Dify web interface: http://$(hostname -I | awk '{print $1}')/" | systemd-cat -t dify-setup
    permissions: '0755'
    owner: root:root

runcmd:
  - /opt/install-docker.sh
  - /opt/setup-dify.sh

演習目的として簡単にOSへログインできるようにパスワードも設定していますが、商用環境ではssh_pwauth: falseに書き換えておいてください。またパスワードは <password> を十分複雑なものに書き換えて下さい。

再度作成ボタンをクリックするとOSの起動が開始され、起動後cloud-initスクリプトが実行されます。完了まで数分待ちます。

起動が完了したらNICのIPアドレスに対してブラウザからアクセスを行います。初回起動時はレポジトリからDifyのコンテナイメージをダウンロードしていますので少し時間がかかります。また一部のブラウザはIPアドレスのみを入力するとhttpsで接続を行うためエラーとなります。この場合 http:// と明示的に指定してください。

OSに先ほど指定したSSH鍵を用いてアクセスを行ったあと、以下のコマンドを実行すると1行目に生成されたパスワードが表示されますので、それを入力し検証をクリックします。

journalctl -t dify-setup

次に管理者情報の入力を行ったのちセットアップをクリックすると完了です。

ログインが完了するとトップページが表示されます。

OpenAIのAPI組み込みとチャットボットの起動

この記事の冒頭で触れたローカルLLMは次回の記事で構築手順をまとめますので、この記事では最もポピュラーなOpenAIを使ったチャットボットを起動します。

まず以下のURLにアクセスします。アカウントが無い方は登録を求められますので、クレジットカードを用意して登録を行ってから再度以下のURLにアクセスします。

https://platform.openai.com/settings/organization/api-keys

APIキーを発行します。

sk-で始まる文字列が発行されたらそれを手元にメモしておきます。同じく左ペインのGeneralをクリックして表示されるOrganization IDをコピーしておきます。

Difyコンソールの画面右上から設定をクリックします。

左ペインからモデルプロバイダーを選択します。

OpenAIのプラグインをインストールします。

セットアップをクリックします。

以下のようにランプが緑になれば完了です。

これでOpenAIの組み込みが完了したので、いよいよチャットボットを起動します。

スタジオから最初から作成を選択します。

チャットボットを選択し、適当な名前を入力して作成するをクリックします。

アプリが起動したら話かけて応答があれば完成です!

次回予告

この記事では、Difyをさくらのクラウド上で起動しOpenAIを組み込んだチャットボットを作成しました。次回の記事ではオープンソースのモデルを用いたローカルLLMを、さくらのGPUクラウドサービスを使って起動しDifyに組み込んでいきます。