DockerでAnythingLLMをデプロイ:マルチユーザー対応のエンタープライズ向けRAGチャットボットを構築

AI tutorial - IT technology blog
AI tutorial - IT technology blog

背景と選定理由

エンジニアやサポート担当者、人事スタッフから、社内Wikiやアーキテクチャ仕様書を検索・照会できる社内アシスタントを求める声は絶えません。しかし、社内ドキュメントをパブリックなSaaSチャットボットに貼り付けることは、重大なセキュリティリスクを招きます。アーキテクチャの設計図やソースコード、従業員情報などがファイアウォールを越えて外部へ容易に流出しかねないからです。

社内向けのRetrieval-Augmented Generation(RAG)システムをゼロから構築するには多大な時間がかかります。ドキュメントパーサー、チャンク分割パイプライン、ベクターデータベースに加え、きめ細かな権限管理を備えた認証レイヤーが必要です。しかし、オープンソースのUIラッパーの多くは単一のユーザーアカウントしかサポートしていません。ロールベースのアクセス制御がなければ、ジュニア開発者や業務委託者が誤って給与データなどを照会してしまう危険性があります。

AnythingLLMは、こうした環境構築の煩わしさを解消します。ドキュメント解析(PDF、DOCX、CSV)、LanceDBによるローカルベクターストレージ、そしてマルチテナント権限管理を単一のコンテナにパッケージ化しています。OllamaやvLLM、あるいはAnthropicやOpenAIといった商用APIと接続可能です。データは完全に自社の仮想プライベートクラウド(VPC)内に保持されます。

インストール

AnythingLLMをコンテナ化することで、アップデートが容易になり、ストレージボリュームも分離できます。Docker Engine 24.0以上、Docker Compose、および最低4GBのRAMを搭載したホストマシンが必要です(ローカルLLMを同一マシンで実行する場合は8GB以上に増設してください)。

1. ディレクトリ構成とストレージマウントの作成

AnythingLLMは、SQLiteデータベースのレコード、アップロードされた元ファイル、およびLanceDBベクターファイルを単一の永続マウント内に保存します。ホスト側で対象ディレクトリを作成します。

sudo mkdir -p /opt/anythingllm/storage
cd /opt/anythingllm
sudo chown -R 1000:1000 storage
chmod -R 775 storage

2. Docker Composeによるデプロイ

Docker Composeを使用することで環境変数を適切に管理し、ホストネットワークをすっきりと整理できます。/opt/anythingllm配下にdocker-compose.ymlファイルを作成します。

services:
  anythingllm:
    image: mintplexlabs/anythingllm:latest
    container_name: anythingllm
    restart: unless-stopped
    ports:
      - "3001:3001"
    environment:
      - SERVER_PORT=3001
      - STORAGE_DIR=/app/server/storage
    volumes:
      - ./storage:/app/server/storage
    extra_hosts:
      - "host.docker.internal:host-gateway"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3001/api/ping"]
      interval: 30s
      timeout: 10s
      retries: 3

extra_hostsのマッピングに注目してください。Linux環境では、この記述によってポート11434でリッスンしているOllamaインスタンスなど、ホスト上で直接実行されているサービスとコンテナ間の通信が可能になります。

バックグラウンドでコンテナを起動します。

docker compose up -d

起動ログをリアルタイムで確認し、初期化シーケンスを検証します。

docker logs -f anythingllm

約15〜30秒ほどで、サーバーがポート3001でリッスンを開始したことが確認できるはずです。

設定手順

ブラウザでhttp://<your-server-ip>:3001を開き、初期セットアップのウォークスルーを開始します。

1. 管理者設定とマルチユーザーモードの有効化

初期ウィザードに従ってプライマリ管理者アカウントを作成します。ダッシュボードに入ったら、Settings > Securityに移動し、Multi-user Modeを有効にします。これにより、3つの異なる権限レベルが有効化されます。

  • Admin(管理者): グローバルパラメータの制御、APIトークンの管理、LLMプロバイダーの設定、およびすべてのワークスペースへのアクセスが可能です。
  • Manager(マネージャー): 割り当てられたワークスペース内のドキュメントやプロンプトを管理できますが、サーバー全体のグローバル設定は変更できません。
  • Default User(一般ユーザー): 管理者が明示的にアカウントへ共有したワークスペース内でのみチャットが可能です。

ワークスペースにより、チーム間の厳密なデータ境界が確保されます。例えば、経営層向けにfinance-restrictedワークスペースを作成し、開発者向けにeng-onboardingワークスペースを作成できます。一般ユーザーは、自身に割り当てられていないワークスペースのデータを検索したり照会したりすることはできません。

2. LLMおよび埋め込み(Embedding)プロバイダーの接続

AnythingLLMでは、テキスト生成(Completion)モデルと埋め込み(Embedding)モデルを個別に設定します。Settings > AI Providersに移動してパイプラインをセットアップします。

  • ローカル環境(Ollama): プロバイダーURLをhttp://host.docker.internal:11434に設定します。テキスト生成にはllama3.1:8bやqwen2.5:7bを選択します。埋め込みには、CPUのオーバーヘッドを抑えながらドキュメントのインデックス作成が可能なnomic-embed-text(768次元)を選択してください。
  • クラウドAPI: OpenAI、Anthropic、またはAzureのAPIキーを入力します。gpt-4o-mini(入力100万トークンあたり0.15ドル)とtext-embedding-3-smallを組み合わせることで、クラウドアカウントの予算を浪費することなく、1秒未満の高速なクエリ応答を実現できます。

3. ワークスペースのプロビジョニングとドキュメントの取り込み

テスト用のワークスペースとしてdevops-runbooksを作成します。ワークスペースの設定からドキュメントマネージャーを開き、20ページ程度のインフラランブック(PDFまたはMarkdown)などのサンプルファイルをアップロードします。Move to Workspaceをクリックし、Save and Embedを選択します。

内部処理では、AnythingLLMがテキストを解析してセグメントに分割し(一般的には200トークンのオーバーラップを含む1,000トークン単位)、ベクター埋め込みを生成して/opt/anythingllm/storage/lancedb内のLanceDBに保存します。

動作検証とモニタリング

検索精度の検証やリソース制限の設定を行わずに、エンドユーザーへインスタンスを公開しないでください。

1. RAG(Retrieval-Augmented Generation)精度の検証

新規作成したワークスペースでチャット画面を開きます。AnythingLLMには2つのクエリ戦略が用意されています。

  • Query Mode(検索モード): 厳密な情報抽出を行います。アップロードされた抜粋情報のみを使用して回答します。要求された情報が存在しない場合、ハルシネーション(事実無根の回答)を起こさず回答を辞退します。
  • Chat Mode(チャットモード): ハイブリッドな対話コンテキストです。モデルは取得したチャンク情報と事前学習済みの一般的な知識ベースを組み合わせて回答します。

Query Modeを選択し、「プライマリPostgresクラスターの目標復旧時点(RPO)は何ですか?」といった具体的な質問を投げかけてみます。回答の下に表示される引用バッジを確認してください。該当するテキストセグメントとLanceDBからのベクター類似度スコアが表示されます。技術ドキュメントの場合、類似度スコアは0.70以上を目指してください。

2. コンテナのヘルスチェックとリソース監視

50MBのPDF解析やCSVの一括アップロード時には、CPUおよびメモリの使用率が一時的に急増します。Docker CLIを使用してリアルタイムのリソース使用状況を監視します。

docker stats anythingllm --no-stream

アイドル時のベースラインとして、AnythingLLMは約180MB〜250MBのRAMを消費します。解析処理によるスパイクがホストマシンの制限を超える場合は、docker-compose.ymlにdeployブロックを追加してリソース使用量を制限します。

    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 4096M

docker compose up -dを実行して変更を適用します。

3. 自動バックアップのルーティン設定

LanceDBとSQLiteはすべてのアプリケーションデータを./storage配下に保存しているため、ディザスタリカバリ(障害復旧)もシンプルです。毎晩午前2時にディレクトリをバックアップするcronジョブを追加します。

0 2 * * * tar -czf /opt/backups/anythingllm-$(date +\%F).tar.gz -C /opt/anythingllm storage

ステージング環境などでアーカイブからの復旧テストを定期的に実施してください。適切なスナップショットがあれば、破損したワークスペースや消失したデータベースファイルを2分未満で復旧できます。

Share: