Dify×LINE公式連携で作る!AIチャットボット構築
はじめに
みなさんこんな悩みはありませんか?
- AIを活用して業務を効率化したいけど、まだ複雑なコードは書けない…
- Webアプリを作ってみたいけど、プログラミングにはまだ自信がない…
- 自社向けのAI機能を、手軽に・すばやく試してみたい!
今回は、そんな悩みを解決してくれるかもしれないツール 「Dify」 を使って、
Solvio株式会社の情報に自動で応答できるLINE公式アカウントを構築してみました!
この記事ではDifyで作ったチャットボットをLINEのMessaging APIと連携し、運用するまでの手順を解説していきます。
Dify(ディファイ)とは
Dify は、ノーコード/ローコードでAIアプリやチャットボットを作れるオープンソースの開発プラットフォームです。
簡単な操作で AI を組み込んだチャットフローを構築できるだけでなく、作成したチャットボットは Python アプリやWebサイトにそのまま埋め込んで利用することも可能なので、実務でもすぐに活用できる、実践的で本格的なツールです。
また、視覚的に会話や処理の流れを設計できるため、AIがどんなロジックで解答を生成しているのかが一目でわかりやすいのも特徴。
AI開発の初学者にも、「Dify」は最適な学習環境と言えるのではないでしょうか。
チャットフローは、ユーザーとの会話体験を設計する機能です。
主な用途はカスタマーサポートやFAQチャットボットなど、手動でユーザーからの問い合わせに対応するケースです。会話の分岐や応答パターンを視覚的に設計できるため、ユーザーごとに異なる問い合わせに柔軟に対応可能です。Difyで作成したチャットフローはそのままWebサイトや社内ツール、各種アプリケーションに組み込んで利用できます。
チャットフローとワークフローの違い
チャットフロー | ワークフロー | |
---|---|---|
主な使い道 | ユーザーと対話・会話設計 | 業務・タスク処理の自動化 |
特徴 | 会話進行・対話の流れ重視 | 一方向の自動化フロー。複雑な条件分岐やAPI連携に強い |
代表的な用途 | カスタマーサポート、FAQなど | データ処理、レポート作成、外部API連携など |
適したシーン | リアルタイム対話など | バックエンド処理や定期実行など |
今回のゴール
質問を投げるとSolvio株式会社の情報を返してくれるLINEの公式アカウントの構築
今回使用した主な技術スタック
- Dify:チャットボット本体の構築・管理。AIによる会話フローや業務自動化フローを設計・実装
- LINE Messaging API(Webhookの利用):ユーザーとチャットボットを接続
- Fast API:Web APIサーバーの構築・実装
- AWS AppRunner:FastAPIアプリや関連バックエンドのデプロイと運用管理
具体的な構成
- ユーザーがLINE公式アカウントを通じてメッセージを送る
- LINE Messaging APIがFastAPIアプリのWebhookエンドポイントに連携
- DynamoDBにチャット履歴を保存し、最新の会話も参照させながらDifyにリクエスト
- 最新のチャット履歴をGoogle Sheetsに反映
- RAG構成はDifyで完結
【完成までの手順】
-
- 生成AIに渡すための情報をナレッジに格納
-
- Difyを使って簡単なラグ構成のチャットボット作成
-
- PythonでFast APIを使用しDifyと連携
-
- LINE公式アカウントの作成
-
- Messaging APIとFast APIを連携
-
- AppRunnerにデプロイし、Webhook URLを設定
実際に構築してみる
AIに渡すための情報をナレッジに格納
まずはAIに活用させるための情報をDifyのナレッジベースに登録します。ナレッジに情報を格納することで、AIは学習データには含まれていない最新情報や、企業独自のドキュメント、マニュアル、規程などのデータも自在に検索・参照できるようになります。
Difyのナレッジベースには、テキストファイル(PDF, Word, Markdownなど)やWebサイト、Notionなど多様な情報源をアップロード・連携できます。登録した情報は自動的に細かい単位(チャンク)でインデックス化され、ユーザーからの質問に対して適切な知識をAIが根拠として提示できるようになります。
【チャンク設定について】
Difyのナレッジベースでは、アップロードした文書データを「チャンク」と呼ばれる小さな単位に自動で分割してインデックス化します。チャンクサイズを適切に設定することは、AIによる検索精度と回答の質に大きく影響します。
チャンク設定とは、文書を小さな単位に分割する際に、テキストの長さや内容の区切り方を調整できる機能のことです。チャンクを短くしすぎると、文脈情報が分断されてしまい、AIが的確に回答できなくなる恐れがあります。一方で、チャンクが長すぎると、AIが内容全体を正しく把握できなかったり、関連性の低い情報まで含めてしまうことがあります。そのため、チャンクの長さは文書の種類や用途に応じて適切に設定することが重要です。
今回のチャンク設定とその意図
【データの長さを最適にするために】
- 最大チャンク長(1つのチャンクに含めることができるテキストの最大サイズ)を900に設定し、比較的大きめに
- チャンクのオーバーラップは500に設定し、隣接するチャンク間で情報が十分に重複するように
【チャンクが短すぎる事態を防ぐために】
- チャンク識別子に「\n」を設定しない。
- テキストの前処理ルールで改行ごとに置換が発生しないよう設定
【検索設定は、ハイブリッド検索がおすすめ】
検索設定の欄には「ベクトル検索」「全文検索」「ハイブリッド検索」が選択肢として用意されています。検索の精度や網羅性を重視する場合、基本的にはハイブリッド検索を選択するのがもっとも確実です。
検索種別 | 特徴 |
---|---|
ベクトル検索 | 数値の値で意味的に検索(意味や文脈の類似性を重視) |
全文検索 | キーワードに沿って検索(単語の一致や部分一致を重視) |
ハイブリッド検索 | ベクトル検索と全文検索を両方含んだ検索(両方の利点を活用) |
今回の検索設定とその意図
- トップKを10(最大)に設定し、AIが十分な情報を参照できるようにしています。
- セマンティクス検索(意味ベース)とキーワード検索(単語一致ベース)の割合を7:3に設定し、文脈要素をやや重視した検索結果となるよう調整
Difyを使って簡単なラグ構成のチャットボット作成
Difyのチャットフロー設計では、処理の流れをブロック(ノード)として視覚的に組み合わせることができます。
今回使用するブロックは以下の4つです。
- 知識検索:アップロードしたナレッジベースから関連情報を取得します。
- LLM:取得した情報とユーザーの質問をもとに、プロンプト設計や応答文の生成を行います。
- 回答:ユーザーへの返答メッセージを生成・整形します。定型文の追加や加工もここで行います。
- 質問分類機:ユーザーの入力内容に応じて処理を複数のルートに分岐させたい場合に使用します。
※今回は、公式LINEのリッチメニューを押すことで定型メッセージが送信されDify側がURL付きの定型文を返す機能を追加しているため、条件分岐も活用しています。
RAG構成での回答生成チャットフローのみを作成する場合は、条件分岐は不要です。
実際のチャットフロー構築はこんな感じ
- ユーザーからのリクエスト内容を「質問分類器」で判別し条件分岐。
リッチメニューで送信されたリクエストは定型分を返す分岐へ
【質問分類機】
- 「高度な設定」で自然言語を用いたプロンプトを記述し、各クラスには条件を設定
- キーワードによる確実な分岐を実現し、リッチメニュー起動時に対応したURL付き定型文を返します。
- 知識検索による関連データ取得
定型文返答でないルートは、ユーザー質問に基づきナレッジベースから関連知識を取得します。
【知識検索】
- ユーザーの質問に関連するナレッジを検索してAI応答の土台とします。
- 「LLM」による応答生成
システムにsys.query
(ユーザー質問)とresult Array[Object]
(検索結果)を渡し、文章を生成。
【LLM】
- 句読点や改行により回答の視認性を高めています。
- 回答ブロックで最終応答を生成
リッチメニュー起動ルートではURL付きの定型文を返し、それ以外はLLM生成の回答をそのまま返します。
【回答】
これでRAG構成によるAI回答生成のチャットフロー構築は完了です。
PythonでFast APIを使用しDifyと連携
次に、PythonのFastAPIを用いてDifyのAPIと連携し、ターミナル上で動作確認して期待値が返ってきているか確認します。
概要
- FastAPIでAPIサーバーを立てる
- Dify API(チャットフロー実行エンドポイント)にHTTPリクエストを送る関数を作成
- /Dify-chatなどのシンプルなエンドポイントにPOSTリクエストを送りDify連携動作を確認
- 最後にuvicornでローカル起動し、curlやHTTPクライアントで動作検証
事前準備
- 仮想環境下で必要なパッケージをインストール
uv init
uv add fastapi
uv add uvicorn
uv add httpx
uv add python-dotenv
uvを使ってパッケージをインストールすることでpyproject.toml
にパッケージ名が自動で記載されていきます。pyproject.toml
で依存を宣言し、uv.lock
バージョンを固定するためチームでの開発やCI/CDでの環境再現性が確保しやすいです。
- DifyのAPIキーとAPIエンドポイントURLを用意
- DifyでAPIキーを取得し
.env
ファイルに記載 - エンドポイントURLは
ベースURL
+/chat-message
DIFY_API_KEY=your-dify-api-key
DIFY_API_URL=your-dify-api-url
FastAPIアプリのコーディング(Dify連携のみ)
from fastapi import FastAPI
from pydantic import BaseModel
import os
import httpx
from dotenv import load_dotenv
load_dotenv()
app = FastAPI()
DIFY_API_KEY = os.getenv("DIFY_API_KEY")
DIFY_API_URL = os.getenv("DIFY_API_URL")
class UserQuery(BaseModel):
message: str
@app.post("/Dify-chat")
async def chat_with_dify(user_input: UserQuery):
headers = {
"Authorization": f"Bearer {DIFY_API_KEY}",
"Content-Type": "application/json"
}
payload = {
"query": user_input.message,
"inputs": {},
"user": {"id": "fastapi_user"},
"max_tokens": 400
}
async with httpx.AsyncClient() as client:
response = await client.post(DIFY_API_URL, json=payload, headers=headers)
if response.status_code == 200:
result = response.json()
return {"reply": result.get("answer", "回答がありません。")}
else:
return {"error": response.text}
-
load_dotenv()
で.env
ファイルに記載した環境変数を読み込みます。APIキーをソースコードに直接書かずに管理できるためセキュリティ的に必須です。 -
app = FastAPI()
でFastAPIアプリのインスタンス生成。これがWebサーバーとして動作します。 -
UserQuery
でcurl
やLINE bot
からJSONで送られてくるリクエストボディの型を定義しています。ここではmessageフィールドのみ受け取ります。 - エンドポイント
/Dify-chat
でクライアントからUserQuery形式のJSONを受け付け、Dify APIへ問い合わせを行います。 - Dify API問い合わせ時に
httpx.AsyncClient()
の非同期POSTリクエストを使用
非同期通信によりサーバーの処理が効率化されます。 - レスポンスのステータスコード判定が200(成功)の場合、返ってきたJSONからanswerフィールドを取り出し、
{"reply": ...}
として返却します。それ以外はエラーメッセージを{"error": ...}
形式で返します。
LINE公式アカウントの作成
次にLINE Official Account Manager
で公式アカウントの作成し、そこでチャンネルアクセストークンを取得します。またLINE Developers
でチャンネルシークレットを発行します。これらはFast API
とLINEのMessaging API
の連携で必要になります。
それぞれの役割
種別 | 役割 |
---|---|
チャンネルアクセストークン | Messaging APIを使ってメッセージ送信などのAPI操作を行うための認証トークン |
チャンネルシークレット | LINEプラットフォームから送られてくるWebhookリクエストの署名検証に使用する秘密鍵 |
詳しくはこちら↓
https://developers.line.biz/ja/docs/basics/channel-access-token/
Messaging APIとFast APIを連携
公式LINEの作成・トークンなどの取得が完了したらいよいよFast API
とMessaging API
の連携をし、
Messaging API
→Fast API
→Dify API
のリクエストの流れを完成させていきます。
この流れが確立すると、
- リクエストがリアルタイムでFastAPIに届く
- FastAPIがAI処理をDifyに委託し
- DifyからAIの返答を返す
という一連のチャットボット構築が実現します。
.envに以下を記載
LINE_CHANNEL_SECRET=your-line-channel-secret
LINE_CHANNEL_ACCESS_TOKEN=your-line-channel-access-token
line-bot-sdkをインストール
uv add line-bot-sdk
line-bot-sdk はWebhookの署名検証やMessaging APIの呼び出しを簡単にするLINE公式SDKです。
FastAPIにおけるLINE Messaging API連携
from fastapi import FastAPI, Request
from linebot.v3 import WebhookParser
from linebot.v3.messaging import MessagingApi, ApiClient, ReplyMessageRequest, TextMessage
from linebot.v3.messaging import Configuration
import logging
import os
app = FastAPI()
# 環境変数から取得(.env等で設定していることが前提)
LINE_CHANNEL_SECRET = os.getenv("LINE_CHANNEL_SECRET")
LINE_CHANNEL_ACCESS_TOKEN = os.getenv("LINE_CHANNEL_ACCESS_TOKEN")
logger = logging.getLogger("main")
# Webhookエンドポイント
@app.post("/webhook")
async def line_webhook(request: Request):
body = await request.body()
try:
# 署名検証
signature = request.headers.get("x-line-signature", "")
parser = WebhookParser(LINE_CHANNEL_SECRET)
events = parser.parse(body.decode("utf-8"), signature)
except Exception as e:
logger.error(f"Webhook parse failed: {e}")
return {"status": "error"}
configuration = Configuration(access_token=LINE_CHANNEL_ACCESS_TOKEN)
with ApiClient(configuration) as api_client:
line_bot = MessagingApi(api_client)
for event in events:
# メッセージイベントでテキストのみ処理
if event.type != "message" or getattr(event.message, "type", None) != "text":
continue
try:
user_id = event.source.user_id
user_message = event.message.text
# (ここにDifyとの連携やAI応答処理が入る)
reply_text = f"受け取ったメッセージ: {user_message}" # 仮の返信
if not event.reply_token:
logger.error("event.reply_token is None!")
continue
# LINE返信メッセージ作成と送信
message = TextMessage(text=reply_text)
line_bot.reply_message(
ReplyMessageRequest(
replyToken=event.reply_token,
messages=[message],
notificationDisabled=False
)
)
logger.info(f"[webhook] user_id={user_id} replied!")
except Exception as e:
logger.error(f"[webhook] error: {e}")
return {"status": "ok"}
- .envから
LINE_CHANNEL_SECRET
とLINE_CHANNEL_ACCESS_TOKEN
を安全に取得 - エンドポイント
/webhook
でWebhookリクエストのボディを非同期で取得しx-line-signature
ヘッダーを使って署名検証 - 解析した
events
からメッセージかつテキストタイプのみを処理対象としてフィルタ - 各イベントごとに送信ユーザーIDやテキストを取得し返信メッセージを
MessagingApi.reply_message
で送信
Fast APIとMessaging APIとDify APIの連携が完了
これで三つのAPI連携が完了し、/webhook
にリクエストが送られるとFast API
を通してDify側で関連する知識検索・回答生成が行われ、返答が返ってくるようになります。
AppRunnerにデプロイし、Webhook URLを設定
最後に、AppRunnerなどでWeb上にアップロードしたURLとエンドポイントを公式LINEのWebhook URL
に設定することで、ユーザーがLINEに送った文章がリクエストとして/webhook
エンドポイントにポストされるようになります。
今回AppRunnerで発行されたURLをLINE Official Account Manager
やLINE Developers
のWebhook URL
設定画面で以下のように設定します。
これで、質問を投げるとSolvio株式会社の情報を返してくれるLINEの公式アカウント完成です
実際に使ってみた
https://youtube.com/shorts/_ngNs-u8TFI?feature=shared
今回はリッチメニューを押すことで定型メッセージが送信されURL付きの定型文が返ってくる仕様があります。(Difyチャットフローの条件分岐)
また、最新10件分の会話履歴を参照させる機能も追加しているので、より自然で連続的な会話も可能です。
以下のQRコードから友だち追加してもらうといつでもこのチャットボットを利用できます!ぜひお試しください!
まとめ
今回はDifyを使用して簡単なRAG構成チャットボットを作成し、それを使用してSolvio株式会社の情報に自動で応答できるLINE公式アカウントを構築してみました。
DifyはAI開発の学習にも、日々の作業効率の向上にも役立つ大変便利な開発プラットフォームです。私自身も今後さらにDifyを使ってAIの学習・開発を進めていく予定です!
興味を持たれた方はぜひ参考にしてください!
私の記事がどなたかのお役に立てていたら嬉しいです。
Discussion