8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Dify(クラウド版 or ローカル版)+LLM(オープン型 or ローカル)の組み合わせをElixirから呼んで生成AIチャットを作る

8
Last updated at Posted at 2025-12-19

この記事は、Elixir Advent Calendar 2025その5 の3日目です

昨日は @torifukukaiou さんで、「Advent of Code 2025 Day 8: PlaygroundをElixirで解くことを楽しむ」 でした


piacere です、ご覧いただいてありがとございます :bow:

生成AI利用に強いノーコード/RPAの「Dify」とローカルLLM基盤である「Ollama」を使って、Dify APIを呼び出すElixirコードを書いてみます

Elixirは下記を見ながらインストールしておいてください

なお、コラムの検証環境はWindows WSL2ですが、Ubuntuやmac、Windows等で各環境をインストールする手順さえあれば、ElixirコードからDify APIを呼び出す部分は共通ですので、この手順だけでうまくいかなかったときはコラムをフォークしてくださいませ

Elixirアドベントカレンダー、応援よろしくお願いします :bow:

今年もやっています

ローカル版Dify+ローカルLLMがもたらす優位性

ローカル版Dify+ローカルLLMの組み合わせは、クラウド版Difyもしくはオープン型LLMを使ったときには得られない、下記のような大きな利点があり、これまでのAI活用とは全く異なる変化があります

image.png

更に、ローカル版Dify+ローカルLLMが各拠点に分散した場合、下記のようなインパクトがあります

image.png

この構成は、非力なノートPCやエッジデバイス/IoTデバイスでも利用が出来るため、下記のような業務や現場への大きな変化ももたらします

image.png

image.png

DifyとLLMの組み合わせ

Difyには「クラウド版」と「ローカル版」の2種類あり、LLMにも「オープン型LLM(Gemini、ChatGPTなど)」と「ローカルLLM」の2種類あるので、組み合わせは下記4パターンあります

ElixirからどのパターンのDify+LLMを呼ぶかで本コラムの進め方が変わりますが、DifyやローカルLLMに慣れていない方は、頭から順にやっていけば、「ローカル版Dify+オープン型LLM」を動かした後、「ローカル版Dify+ローカルLLM」でElixirからの呼出を一通り学べます

パターン Dify LLM 本コラムの進め方
a クラウド版 オープン型LLM → ⑥
b クラウド版 ローカルLLM
c ローカル版 オープン型LLM
d ローカル版 ローカルLLM

①Dockerのインストール【ローカル版Difyのみ】

DifyはDockerで動くので、まずDockerをインストールします

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
sudo service docker start

②Difyのインストール【ローカル版Difyのみ】

DifyをGithubからインストールし、Dockerで起動します

git clone https://github.com/langgenius/dify.git
cd dify/docker
cp .env.example .env
docker compose up -d

③Difyでチャットアプリ作成

ブラウザで http://localhost を見ると、ローカル版Difyのセットアップページが出るので、設定すればDifyが使えるようになります

クラウド版Difyを使うなら、下記から「始める」で同じ画面が出ます

「アプリを作成する」から「最初から作成」をクリックし、「チャットフロー」を選び、「アプリ名」を入力して「作成する」ボタンを押せば、下記のようなチャットアプリが作成されます

image.png

④GeminiをDifyから使う【オープン型LLMのみ】

ローカルLLM化をする前に、オープン型LLMのGeminiをローカルDifyから使うことで、Difyの基本的な流れを掴みます

まず、GeminiのAPIキーを取得するために、下記のGoogle AI Studioにアクセスします(慣れてる方はGCPからでも作れます)

左下の「Get API Key」から、APIキーを作り、コピーしておきます

image.png

次にDifyに戻って、「LLM」の箱を選択し、「AIモデル」プルダウンをクリックし、「モデル」プルダウンをクリックします

image.png

上図は設定済なのでモデル群が並んでいますが、最初は選択できるモデルが空で「モデルプロバイダーの選択↗」リンクのみ出ているので、クリックすると、下記モデル設定画面となります

image.png

上図はGeminiとOllamaが既にインストール済の表示になっていますが、インストール前だと各カードにマウスを重ねると上図OpenAIのように「インストール」ボタンが出てくるので、Geminiの上で「インストール」ボタンを押してください

インストール後、この画面の上部にGeminiが追加されるので、「セットアップ」ボタンを押し、APIキーを設定し、「X」ボタンを押せば、「LLM」の箱 → 「AIモデル」プルダウン → 「モデル」プルダウンでGeminiモデル群がリストアップされるようになるので、Gemini 2.5 Flash-Lite を選択してください

image.png

この状態で、Dify上部の「▷ プレビュー」ボタンをクリックすると、内部でGeminiが動くチャットアプリが起動(下図赤枠部分)し、プロンプトが入力可能となり、AIチャットが遊べるようになります

image.png

Difyでの最も簡単なアプリ開発は、たったこれだけです

⑤Gemma3をDifyから使う【ローカルLLMのみ】

ここからは、軽量で高精度なローカルLLM「Gemma3」をDifyで使えるようにしていきます

まず、Gemma3入りのOllamaコンテナをビルドし、そのOllamaコンテナをOllamaサーバーのTCPポート11434を空けながらDifyコンテナと共通ネットワーク上に立てたら、Difyモデル設定にてOllamaコンテナのGemma3が使えるようになります

なおOllamaコンテナは、下記コラム通りにビルドしてから下記に進んでください

Difyコンテナ群にOllamaコンテナ追加

Difyインストール先の dify/docker 配下にあるDocker Composeに、上記Ollamaコンテナを追加ロードする下記設定を追加します

dify/docker/docker-compose.yaml
services:
+ ollama:
+   image: ollama-with-llms
+   container_name: ollama_dify
+   ports:
+     - ":11434:11434"
+   volumes:
+     - ollama:/root/.ollama
+   environment:
+     - OLLAMA_HOST=0.0.0.0:11434
+   restart: unless-stopped

volumes:
+ ollama:

Difyを再起動します … このとき同時にOllamaも起動します

docker compose restart

Difyモデル設定でOllamaコンテナのGemma3を指定

Difyに戻り、「LLM」の箱 → 「AIモデル」プルダウン → 「モデル」プルダウン → 「モデルプロバイダーの選択↗」リンクでモデル設定画面に行き、先ほどGeminiをインストールしたのと同じように、今度はOllamaをインストールします

image.png

インストール後、この画面の上部にOllamaが追加されるので、「⊕モデルを追加」ボタンをクリックすると、Ollama設定画面が表示されるので、下記を入力してください

  • 「Model Name」 … gemma3:1b を入力
  • 「Model Type」プルダウン … 「LLM」を選択
  • 「Base URL」 … http://ollama_dify:11434 を入力

image.png

その後、「追加」ボタンを押し、「X」ボタンを押せば、「LLM」の箱 → 「AIモデル」プルダウン → 「モデル」プルダウンでGeminiモデル群の下にOllamaモデルもリストアップされるようになるので、gemma3:1b を選択してください

image.png

Dify上部の「▷ プレビュー」ボタンをクリックすると、今度は内部でgemma3が動くチャットアプリが起動します

こちらでもプロンプトを入力してみて、Gemini版との返答の違いをお楽しみください

gemma3版の出力

image.png

Gemini版の出力

image.png

Difyを使う大きな利点

このように、Difyを使うことで、LLMを切り替えたり、変更しても、アプリ本体は特に変えずに運用できるところが素晴らしいです

またLLMだけに限らず、多種多様なプラグインによるアプリ開発も可能なので、Dify上部の「検索」タブや「ツール」タブから面白そうなものを探して、Difyアプリを作ってみてください

⑥ElixirからDify APIを使う

まず、先ほど作ったDifyチャットアプリにて、Dify APIを作成します

Dify上部の「公開する」プルダウンボタンをクリックし、「更新を公開」ボタンをクリックします

image.png

それから、「APIアクセス」をクリックした後、右上の「APIキー」ボタンで「新しいシークレットキーを作成」ボタンを押し、表示されたキーをコピーします

image.png

それからiexを起動し、Reqを使ってDify APIを下記のように叩けば、DifyチャットアプリをElixirから使うことができ、LLMによる回答が得られます

なお、下記コード中、緑帯の {"Authorization", "Bearer 【Dify APIキー】"}, のAPIキー部分は、前述で取得したAPIキーに入れ替えてください

iex> Mix.install([{:req, "~> 0.5"}])
iex> body = %{
  "query" => "LiveViewについて教えて",
  "user" => "fromElixirToDify",
  "inputs" => %{},
  "response_mode" => "blocking",
  "conversation_id" => ""
}
iex> headers = [
  {"Authorization", "Bearer 【Dify APIキー】"},
  {"Content-Type", "application/json"}
]
iex> response = Req.post!("http://localhost/v1/chat-messages", json: body, headers: headers)
iex> response |> Map.keys
[:private, :status, :__struct__, :body, :headers, :trailers]
iex> response.body |> Map.keys
iex> ["answer", "conversation_id", "created_at", "event", "id", "message_id",
 "metadata", "mode", "task_id"]
iex> response.body["answer"]
 "LiveView(ライブビュー)は、Elixir言語で書かれたWebフレームワークである …(以下略)

なお、下記のようにpost先URLを変更すれば、クラウド版Difyの方を呼べます

iex> response = Req.post!("https://api.dify.ai/v1/chat-messages", json: body, headers: headers)

bodyの各パラメータは以下の通りです

パラメータ 説明
query プロンプト
inputs チャットフローの「開始」ノードで設定した変数(例:user_nameなど)
response_mode streamingかblockingを選択
user ユーザー名(ログ記載時の表記)
conversation_id 前回会話の文脈を引き継ぐときに必要で、初回は空、以降は返ってきたIDを指定

2回目以降のpost時、conversation_id を指定すると巷のオープン型LLMと同様、文脈を続け、未指定ならゼロベースで返ってきます

文脈を続けた場合

前のプロンプトに対する回答を文脈としているので、LiveViewの通信チャネルであるWebSocketについて回答が返ってきます

iex> body = body |> Map.put("conversation_id", response.body["conversation_id"])
iex> body = body |> Map.put("query", "通信チャネルはどう確立する?")
iex> response.body["answer"]
"LiveViewの通信チャネルは、主に**WebSocket**を使用して確立されます。 …(以下略)

ゼロベースの場合

回答を文脈として持っていないので、LiveView前提で無い通信チャネル全般の回答が返ってきます

iex> body = body |> Map.put("conversation_id", "")
iex> body = body |> Map.put("query", "通信チャネルはどう確立する?")
iex> response.body["answer"]
"通信チャネルの確立方法は、どのような種類の通信を行うかによって大きく異なります。 …(以下略)

終わりに

最後に、コンテナ群を落として終了してください

docker compose down

Difyローカル環境を構築し、オープン型LLMでのチャットアプリを作った後、ローカルLLM化を行い、それをAPI化したものをElixirから叩いてみました

ノーコード/RPAから容易にオープン型/ローカルを問わずLLMをアプリに組み込めることと、ElixirからもLLMアプリが簡単に利用できることが伝わったかと思います

これは同時に、LLM周辺処理の改良はノーコードだけで済ませられ、Elixir側は改修しなくて良いという役割分担が魅力的です

またLLMの変更は、Dify側で吸収できる点も利点です

【2025/12/23追記】

Phoniex/LiveViewを使ったDify API経由のLLMチャットアプリも作ってみたので、下記をご覧ください


明日は @t-yamanashi さんで 「Elixir使いがC#を学ぶ 〜関数パターンマッチ風に書きたい〜」 です

8
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?