一般的なチャットボットは、自社の製品、価格、手順、社内文書を知りません。かといって、それらを公開 AI サービスに貼り付けることは、多くの場合許されません。検索拡張生成(RAG)を使えば、アシスタントはまず自社の文書を検索し、見つかった内容をもとに出典付きで回答します。この記事では、自社サーバー上で Ollama が提供するローカルモデルを使い、AnythingLLM を構築します。インストール、言語モデルと埋め込みモデルの接続、ワークスペースへの文書アップロード、文書の範囲内で回答させる設定、ユーザーの追加、HTTPS での公開までを解説します。より大規模な導入の計画(リージョン、ベクトルデータベース、データ保護)については、専用サーバーでプライベート AI サポートナレッジベースを構築するをご覧ください。
RAG では 2 つのモデルを使います。文書の各パッセージと質問を検索用のベクトルに変換する埋め込みモデルと、回答を作成するチャットモデルです。どちらも Ollama で動かします。
ollama pull nomic-embed-text # embedding model (small and fast on CPU)
ollama pull qwen2.5:7b # chat model; good with Chinese and English
ollama list
# AnythingLLM runs in a container, so Ollama must accept connections from Docker
# (OLLAMA_HOST=0.0.0.0 plus the firewall rules from the Ollama guide). Check:
curl -s http://172.17.0.1:11434/api/tags | head -c 300; echo
8 コア以上、メモリ 16 GB 以上のサーバーであれば、小規模なチームでこの組み合わせを快適に動かせます。多数のファイルをアップロードすると、文書の埋め込み処理でしばらく CPU を使用します。回答の生成にはチャットモデルが使われます。
AnythingLLM は Docker で動かします(Docker のインストール手順を参照)。
export STORAGE_LOCATION=/opt/anythingllm
mkdir -p $STORAGE_LOCATION && touch "$STORAGE_LOCATION/.env"
chown -R 1000:1000 $STORAGE_LOCATION # the container runs as user ID 1000
docker run -d --name anythingllm --restart always \
-p 127.0.0.1:3002:3001 \
--cap-add SYS_ADMIN \
--add-host=host.docker.internal:host-gateway \
-v ${STORAGE_LOCATION}:/app/server/storage \
-v ${STORAGE_LOCATION}/.env:/app/server/.env \
-e STORAGE_DIR="/app/server/storage" \
mintplexlabs/anythingllm
docker logs -f anythingllm # wait until the server reports it is listening
Web インターフェースはコンテナ内のポート 3001 で待ち受けます。ホスト側では 127.0.0.1:3002 にマッピングしているため、ステップ3の HTTPS プロキシ経由でのみアクセスできます。
kb.example.com などのサブドメインをサーバーに向け、証明書を取得し(Certbot または acme.sh で無料 SSL を導入を参照)、コンテナへプロキシします。
server {
listen 443 ssl;
http2 on;
server_name kb.example.com;
ssl_certificate /etc/letsencrypt/live/kb.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/kb.example.com/privkey.pem;
client_max_body_size 100m; # document uploads
location / {
proxy_pass http://127.0.0.1:3002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 600s;
}
}
https://kb.example.com を開いて初期設定を完了します(設定はあとから Settings(設定)ですべて変更できます)。
http://host.docker.internal:11434、チャットモデルは qwen2.5:7b。nomic-embed-text(または AnythingLLM 内蔵の埋め込み機能)。何かをアップロードする前に、セキュリティ設定でマルチユーザーモードを有効にし、管理者パスワードを設定します。その後、同僚ごとに Default ロールのアカウントを作成します。このロールでは、割り当てられたワークスペースでチャットはできますが、設定を変更したり他のワークスペースを閲覧したりはできません。
ワークスペースは、独自の文書と設定を持つ独立したナレッジベースです。例えば「製品カタログ」「サポート手順」「人事規程」のように分けて作成します。
テキストベースの整った文書ほど良い結果が得られます。スキャンした PDF は先に OCR が必要です。長い文書は、すべてを詰め込んだ巨大なファイル 1 つにするより、見出しを明確にしたほうが検索しやすくなります。
ワークスペースの設定で、次のように構成します。
各回答には出典が表示されます。クリックすると、どの文書のどのパッセージが使われたかを確認できます。
文書が更新されたら、古い価格や手順が引用されないよう、旧バージョンをワークスペースから削除して新しいものをアップロードします。/opt/anythingllm は定期的にバックアップしてください。文書、ベクトル、ユーザー、チャット履歴が含まれています。AnythingLLM には API と埋め込み可能なチャットウィジェットもあるため、後から自社の Web サイトやアプリケーションでワークスペースを利用することもできます。
ワークスペースを Query モードに切り替え、システムプロンプトをより厳しくし、出典を確認してください。正しいパッセージがまったく見つからない場合は、文書を明確なタイトルの小さなファイルに分割するか、より大きなチャットモデルを試してください。
時間の大部分は、チャットモデルが CPU でテキストを生成している時間です。簡単な調べものには小さめのモデルを使い、1 回の回答あたりのパッセージ数を減らし、モデルを読み込んだままにしておきます(Ollama の記事のパフォーマンスに関するヒントを参照)。
はい、AnythingLLM は多くのプロバイダーに対応しています。ただしその場合、文書と質問がそのプロバイダーに送信されることに注意し、利用規約で認められたプロバイダーとリージョンのみを使用してください。機密性の高い資料であれば、この記事のローカル構成ならすべてをお客様のサーバー内にとどめられます。
上記の手順で解決しない場合は、サポートチケットを送信して IMIDC の 24 時間 365 日対応テクニカルサポートへご連絡ください。サーバー IP、OS バージョン、CPU とメモリ、docker logs anythingllm の出力、エラーメッセージ全文を添えていただくと、より迅速に調査できます。