2025.05.19

DifyとRemixの連携によるチャットボット構築

Shuji
- Dify
- AI
- Remix
Difyは、ノーコード/ローコードでAIチャットボットを構築できるオープンソースプラットフォームです。Difyで作成したチャットボットは、API経由で外部アプリケーションと連携できます。今回はRemixでreactアプリを作成して連携するところまで行っています。
アプリのDBを外部ナレッジAPIとして利用する続編こちらです。
https://topaz-inc.dev/articles/dify-knowledge-api-remix-app/

Dify上でチャットbotを作成
まずは、difyにログインしチャットボットを作成します。今回は例として製品案内をしてくれるボットという内容で、名前や説明を設定しました。

「オーケストレーション」にAIに伝えるプロンプトを書いていきます。

モデルを設定
モデルプロバイダーの選択も行なっておきます。モデルによって有料のものや無料でも使えるものがあります。

今回は簡易的に、ナレッジを利用せず、オーケストレーションに製品内容を入れておきました。
デバッグとプレビューを行なってみて、問題なければ「公開」します。

API キーの発行
サイドメニューのAPIアクセスからAPIキーを作成し、コピーしておきます。

連携アプリの用意
今回はRemixのgrunge-stackでサクッとアプリを構築しました。
npx create-remix@latest dify-chat-app --template remix-run/grunge-stack
先のほどのAPIキーを使ってPOSTリクエストする関数を用意します。https://api.dify.ai/v1/chat-messages
のurlを指定します。
const DIFY_API_KEY = 'app-xxx';
const DIFY_API_URL = 'https://api.dify.ai/v1/chat-messages';
export interface DifyMessage {
role: 'user' | 'assistant';
content: string;
}
export async function sendMessageToDify(message: string): Promise<string> {
try {
const response = await fetch(DIFY_API_URL, {
method: 'POST',
headers: {
'Authorization': Bearer ${DIFY_API_KEY},
'Content-Type': 'application/json',
},
body: JSON.stringify({
inputs: {},
query: message,
response_mode: 'blocking',
conversation_id: '',
user: 'user',
}),
});
if (!response.ok) {
throw new Error(`Dify API error: ${response.statusText}`);
}
const data = await response.json();
return data.answer;
} catch (error) {
console.error('Error sending message to Dify:', error);
throw error;
}
}
簡易的なチャットができるUIを作成。
import type { MetaFunction } from "@remix-run/node";
import { useState } from "react";
import { sendMessageToDify } from "~/utils/dify";
export const meta: MetaFunction = () => [{ title: "Dify Chat App" }];
export default function Index() {
const [messages, setMessages] = useState<{ role: 'user' | 'assistant'; content: string }[]>([]);
const [input, setInput] = useState("");
const [isLoading, setIsLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!input.trim() || isLoading) return;
const userMessage = input.trim();
setInput("");
setMessages(prev => [...prev, { role: 'user', content: userMessage }]);
setIsLoading(true);
try {
const response = await sendMessageToDify(userMessage);
setMessages(prev => [...prev, { role: 'assistant', content: response }]);
} catch (error) {
console.error('Error:', error);
setMessages(prev => [...prev, { role: 'assistant', content: '申し訳ありません。エラーが発生しました。' }]);
} finally {
setIsLoading(false);
}
};
return (
<main className="relative min-h-screen bg-white">
<div className="mx-auto max-w-7xl px-4 py-8 sm:px-6 lg:px-8">
<div className="mb-8">
<h1 className="text-3xl font-bold text-gray-900">Dify Chat App</h1>
</div>
<div className="mb-8 h-[60vh] overflow-y-auto rounded-lg border border-gray-200 p-4">
{messages.map((message, index) => (
<div
key={index}
className={`mb-4 ${
message.role === 'user' ? 'text-right' : 'text-left'
}`}
>
<div
className={`inline-block rounded-lg px-4 py-2 ${
message.role === 'user'
? 'bg-blue-500 text-white'
: 'bg-gray-100 text-gray-900'
}`}
>
{message.content}
</div>
</div>
))}
{isLoading ? <div className="text-left">
<div className="inline-block rounded-lg bg-gray-100 px-4 py-2 text-gray-900">
考え中...
</div>
</div> : null}
</div>
<form onSubmit={handleSubmit} className="flex gap-2">
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="メッセージを入力してください..."
className="flex-1 rounded-lg border border-gray-300 px-4 py-2 focus:border-blue-500 focus:outline-none"
disabled={isLoading}
/>
<button
type="submit"
disabled={isLoading}
className="rounded-lg bg-blue-500 px-4 py-2 text-white hover:bg-blue-600 disabled:bg-gray-400"
>
送信
</button>
</form>
</div>
</main>
);
}
次のような画面ができました。

送信すると、問題なくレスポンスしてくれます。

おわりに
DifyをAPIから利用することで、簡単に生成AIを組み込むことができました。Difyは様々な活用方法があるようですが、実際の運用では自前のアプリ側ではどんどんと製品データが増えていくことを想定して、次回はアプリ側のDBをRAGとして利用するために外部ナレッジAPIを活用しています。urlはこちら。
https://topaz-inc.dev/articles/dify-knowledge-api-remix-app/
Other Articles
FastAPI × React LeafletでGoogle Earth Engineの衛星データを扱う
Google Earth Engine で衛生データを表示する
DifyのワークフローをNode Cronで定期実行
Difyの外部ナレッジAPIでNotion APIのデータを取得
Dify × NotionでAIチャットボットを構築する
Gatsby × Tailwindcss × ダークモードでSEO対策
[Gatsby.js] gatsby-plugin-canonical-urlsでcanonicalタグを生成する
[Gatsby.js] gatsby-plugin-robots-txtでrobot.txtを生成する
[Gatsby.js] gatsby-plugin-sitemapでサイトマップを生成する