中級向け

n8nとDifyの使い分け

n8n と Dify を、同じパソコンの Docker で動かして、「Q&A に答えるボット」を作って比べました。起動の重さ(1コンテナと15コンテナ)、画面の日本語、つまずいた点(既定の埋め込みモデルが動かない、モデルの設定の場所が変わっていた)、答える・答えないの判断を誰が持つか、そして2つをつなぐ方法(n8n から Dify はそのまま動き、Dify から n8n は SSRF 保護で止まる)を、確認していないことも含めて書きました。

動作確認: — n8n 2.42.6(Docker)/2.36.8(npm) / Dify 1.17.1(セルフホスト、Docker Compose) / Gemini 3.8 Flash / gemini-embedding-001 / Docker Desktop 29.8.0(Windows 11 Home)

「n8n と Dify、どちらを使えばいいのか」。AI を使った自動化を始めると、必ず出てくる疑問だと思います。

この記事は、同じパソコンで、両方を動かして、同じ「Q&A に答えるボット」を作って、つないでみた記録です。解説ではなく、動かして分かったことと、つまずいたことを、書きます。

先に結論です。

  • 「資料に答えるボットを、早く立てる」なら Dify。ナレッジの登録、分割、検索、チャットの画面が、最初から揃っていて、画面は日本語です
  • 「受け取る → 判断する → 承認する → 記録する → 知らせる」という業務の流れをつなぐなら n8n。LINE や Gmail、Slack などとつなぐ部品が、ノードとして揃っています
  • 2つは、HTTP でつながります。 筆者の試験では、n8n から Dify を呼ぶ向きは、そのまま動きました。Dify から n8n を呼ぶ向きは、Dify の安全のための設定(SSRF 保護)が止め、許可を足して、通りました
  • 重さが、まるで違います。 n8n は1コンテナ(待機中のメモリ約 360MB)、Dify は15コンテナ(約 2.4〜3GB、イメージ約 11GB)でした
n8nHTTP RequestDify の API(/v1/chat-messages)+ API キーDify公開したアプリそのまま動いた(約 4 秒、答えと類似度が返る)n8nWebhookDify の HTTP リクエストノードが呼ぶDifyHTTP リクエスト最初は SSRF 保護で止まった → 許可の設定を足して通った(ドメインの許可だけでは足りず、IPv4 のアドレスの許可が要った)筆者が Dify 1.17.1 と n8n 2.42.6 を、同じパソコンの Docker で動かして試した結果
n8n から Dify を呼ぶ向きは、すぐに動いた。Dify から n8n を呼ぶ向きは、Dify の安全のための設定を、先に緩める必要があった。

比べた条件

  • 題材: お店の問い合わせに、過去の Q&A だけを根拠に答え、答えられないときは、人に回すボット
  • Dify 側: 1.17.1(セルフホスト)。チャットフロー(ノードをつなぐ形)で、4つのノード(開始 → 知識検索 → LLM → 回答)。モデルは Gemini 3.8 Flash、埋め込みは gemini-embedding-001
  • n8n 側: 筆者が作った RAG のワークフロー(34ノード)。回答は Claude Haiku 4.5、埋め込みは Gemini。担当者の回答から学習し、個人情報を伏せ、答えられないものを「担当者待ち」として記録する、より大きな範囲の作りです
  • 同じ条件ではない点: 回答のモデルが違い(Gemini と Claude)、作った範囲も違います(Dify は答えるところだけ、n8n は学習・個人情報のマスク・記録まで)。作る量の比較は、この違いを割り引いて読んでください

動かすまで

どちらも、筆者の Windows のパソコンの Docker(Docker Desktop)で動かしました。

n8n Dify
コンテナの数 1 15(api、worker、web、プラグイン用、ベクトル DB、データベース、nginx など)
イメージの大きさ 1.79GB 約 11GB
待機中のメモリ 約 360MB(公開した1つのワークフローあり) 約 2.4〜3GB(Dify の公式の最低条件は 4GiB 以上)
初回の取得 1つのイメージ(1.79GB) 筆者の回線で10分前後(正確には測っていません)
画面の言語 英語のみ(日本語化の記事) 日本語
Dify にログインした直後のホーム画面。左のメニューは、ホーム、スタジオ、Agents、ナレッジ、Skills、連携、マーケットプレイス。上に、おかえりなさいの挨拶と、メモリアシスタントや患者受付チャットボットなどのテンプレートが並び、すべて日本語で表示されている
Dify のホーム画面(1.17.1)。画面は日本語で、テンプレートが並ぶ

n8n を Docker で動かす手順は n8nをDockerで動かす に書いています。

同じボットを作って、つまずいたこと(Dify)

Dify で、モデルの設定から、ナレッジの登録、アプリの作成まで進める間に、次の点でつまずきました。

  1. 「設定」の中に、モデルプロバイダーが見つからなかった。 古い解説にある「設定 → モデルプロバイダー」は、このバージョン(1.17.1)には無く、左のメニューの「連携」の中(/integrations/model-provider)にありました(Dify の画面のソースコードで確かめました)
  2. モデルの提供元は、プラグインとして、先に入れる。 Gemini も、マーケットプレイスから入れてから、API キーを設定しました
  3. 既定の埋め込みモデルが、動かなかった。 既定は embedding-001 でしたが、Gemini の API は、「このモデルは見つからない」(404)と返し、ナレッジの登録が、エラーで止まりました。プラグインが出す、使える埋め込みモデルは、gemini-embedding-001 などでした
  4. 既定のモデルを直して、ナレッジを作り直しても、新しいナレッジに、古い embedding-001 が付いたままだった。 原因は、確かめられていません(設定の保存のタイミングかもしれません)。Dify の API で、ナレッジの埋め込みモデルを直して、再試行して、6つに分けたかたまりすべてが、約 10 秒で完了しました
  5. 新しいチャットフローは、「開始 → LLM → 回答」だけが、最初に並ぶ。 知識検索のノードを足し、モデル・コンテキスト・指示を設定する作業が、別に要ります(この部分は、筆者が Dify の API で設定しました。画面での手間は、測っていません)

n8n でも、つまずいた点は、いくつもあります(LINE×Slack の記録など)。「Dify のほうが、つまずかない」とは言えません。 違うのは、つまずく場所です。

答えと、答えない判断

Dify のチャットフローに、3つの質問をしました(モデルは Gemini 3.8 Flash、1回あたり 244〜275 トークン、約 6 秒)。

質問 Dify の答え 検索の類似度(上位3件)
ギフト包装はやってる? 「1点につき300円で承っております。…」(ナレッジのとおり) 0.84、0.76、0.67
土曜は開いてる? 「土曜日も平日と同じく10時から18時まで営業しております。」 0.80、0.77、0.65
ポイントカードはある?(ナレッジに無い) 「確認して、担当者からご連絡します。」 0.68、0.65、0.65

3つとも、期待どおりでした。ただ、見ておきたいのは、ナレッジに無い質問でも、検索は、上位3件を、いつも返すことです(類似度 0.68)。筆者が作った Dify の知識検索のノードは、類似度のしきい値を、設定していません(設定値は「なし」)。「答えるか、人に回すか」の判断は、LLM への指示(「コンテキストに書かれたことだけで答える。無ければ、担当者に確認と答える」)に任せました。

n8n で作った RAG は、しきい値(0.75)と、「答えられるか」の判定を、仕組みで持ち、人に回すものを記録に残します。Dify の知識検索のノードにも、スコアのしきい値の項目があることは、Dify のソースコードで確認しましたが、筆者は、使っていません。1回の試験では、指示だけで、うまくいきました。本番で、答えてはいけない質問に、答えてしまわないかは、質問を増やして確かめる必要があります。

つなぐ:n8n から Dify

Dify のアプリを公開して、API キーを作ると、外から呼べます。

  1. Dify のアプリを、公開する
  2. API キーを作る
  3. n8n の HTTP Request ノードで、POST /v1/chat-messages を呼ぶ(Authorization: Bearer キー、本文に inputs、query(質問)、response_mode: blocking、user)

筆者の試験では、次のとおりでした。

  • キーなしは 401、キーありは 200。 答えの文章と、根拠にしたナレッジの類似度(metadata.retriever_resources)が返りました
  • n8n の HTTP Request ノードから呼ぶと、約 4 秒で、同じ答えが返りました

つなぐ:Dify から n8n

Dify の「HTTP リクエスト」ノードで、n8n の Webhook を呼ぶ向きも、試しました。最初は、Dify に止められました。

Access to 'http://host.docker.internal:5678/webhook/dify-hook' was blocked by SSRF protection
(e.g. SSRF_PROXY_ALLOW_PRIVATE_IPS=172.21.0.0/16 to allow 172.21.0.0/16).
The URL resolves to a private, loopback, link-local, or otherwise non-public network address.

Dify は、外へ出る通信を、自分のパソコンの中のアドレス(プライベートな住所)に向けさせない安全の仕組み(SSRF 保護)を、既定で入れています。許可は、Dify の docker/.env に、書きます。

  1. SSRF_PROXY_ALLOW_PRIVATE_DOMAINS=host.docker.internal を足して、コンテナを作り直す → 保護の確認は通ったが、今度は、中継役(squid)が「Network is unreachable」で失敗した。host.docker.internal が、IPv6 のアドレスを返していたためです
  2. IPv4 のアドレス(Docker Desktop のホストの入口、192.168.65.254)に替えて、SSRF_PROXY_ALLOW_PRIVATE_IPS=192.168.65.254/32 を足す → 通りました(n8n が 200 で返事をした)

本番で、Dify から社内のシステムを呼ぶなら、この許可を、必要な宛先だけに絞ることが、大事だと考えます(筆者は、そこまでは試していません)。

使い分けの目安(筆者の読み)

この小さな試験からの読みです。鵜呑みにせず、自分の題材で、確かめてください。

やりたいこと 向いているもの 理由(試験から)
手元の資料に答える、社内のチャットを、早く立てる Dify ナレッジの登録・検索・チャットの画面が最初から揃い、日本語
LINE・Gmail・Slack などを受けて、判断・承認・記録・通知まで流す n8n 受け口と部品が、ノードで揃っている。承認や記録を、流れの中に組める
答えてよい質問か、人に回すかを、仕組みで決めたい n8n(Dify でも、設定次第) しきい値と判定を、流れの中に組める。Dify は、筆者は未確認
両方 流れは n8n、知識への質問は Dify n8n の HTTP Request から、Dify の API を呼べた
小さなサーバー(メモリ 1GB など)で動かす n8n Dify の公式の最低条件は 4GiB 以上。筆者の測定でも、約 2.4GB を使った

確認していないこと

  • 質問は3つだけで、ナレッジは3つの Q&A です。大量の資料や、紛らわしい質問での精度は、見ていません
  • Dify のクラウド版は、使っていません。セルフホスト(Docker Compose)だけです
  • Dify のエージェント、ワークフロー、トリガーの機能は、試していません。チャットフロー(4ノード)だけです
  • Dify の画面での操作の手間は、測っていません。アプリのノードの設定は、筆者が Dify の API で行いました。ナレッジの登録とモデルの設定は、画面で行っています
  • Dify のしきい値の設定と、Claude を使った Difyは、試していません(Dify は Gemini で動かしました)
  • 本番の運用(認証、HTTPS、バックアップ、更新)は、試していません
  • 料金(API 利用料、サーバー代)は、比較していません。測ったのは、トークンの数だけです
  • Windows の Docker Desktop だけで確かめました。Linux のサーバーでの動きは、確かめていません
  • バージョンは、Dify 1.17.1、n8n 2.42.6(Docker)と 2.36.8(npm)です。画面や設定の場所は、バージョンで変わります

後片づけ

試験用の Dify と n8n は、使い終わったあと、docker compose down -v で、コンテナとデータごと消し、Dify を取得したフォルダも消しました。最後に、イメージも docker rmi で消しました(Docker のディスク使用量が、13.05GB から 1.82GB に減りました。残りは、n8n のイメージです)。Dify のフォルダは、ファイル名が長いものがあり、Windows で普通に消そうとすると、「パスが見つからない」というエラーになりました(\\?\ を付けた長いパスの指定で、消せました)。

次に読む

次に読む