はじめに
前回の続きです。前回のDifyアプリはテキストジェネレーターでしたが、今回はChatflowでLINE Botを作成してみます。
Chatflowアプリを作成する
タイプチャットボット
、オーケストレーション方法Chatflow [BETA]
を選択して適当な名前をつけて作成
ボタンをクリックします
アプリが作成されると下記のようにワークフローを編集する画面が表示されます
すでに作成されているワークフローでもチャットを開始できますが、今回はRAGを試してみようと思い、こちらの記事を参考にワークフローを編集してみました。ナレッジは記事のドキュメントの準備
を参考にマンガペディアのソードアート・オンラインのドキュメントを作成しました
デバッグとプレビュー
で動作を確認してみます
動作を確認できたら、公開する
ボタンをクリックしてアプリを公開状態にします
APIを叩いてみる
APIリファレンスを参考にcurlでAPIを叩いてみます。ENTER-YOUR-SECRET-KEYは先程控えたAPIシークレットキーに差し替えてください。APIパスがテキストジェネレーターのときはcompletion-messages
でしたが、チャットボットの場合はchat-messages
となります
curl -X POST 'https://api.dify.ai/v1/chat-messages' \
--header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
"inputs": {},
"query": "アインクラッドとは?",
"response_mode": "blocking",
"user": "abc-123"
}'|jq .
回答が返ってきました。チャットボットの場合はquery
にLINEメッセージを入力してリクエストしてレスポンスのanswerをリプライするようです
{
"event": "message",
"task_id": "3f6c385c-593d-4d20-a0ea-2a95503ad2d2",
"id": "d6ae0243-c556-4886-ae66-02ebc162c5a2",
"message_id": "d6ae0243-c556-4886-ae66-02ebc162c5a2",
"conversation_id": "12eabc7e-7b9f-40ca-8f13-bc202e3371a1",
"mode": "advanced-chat",
"answer": "アインクラッドは、『ソードアート・オンライン』の舞台となる架空の城です。この城は100の階層に分かれており、各階層にはフィールドや迷宮区、フロアボスが存在します。プレイヤーたちは階層をクリアすることで上の階層に進むことができます。また、各階層には転移門があり、クリアした階層へ簡単に移動することができます。#ナレッジ\n\nナレッジによると、浮遊城アインクラッドは非常に広大で、最初の階層だけでも直径が10kmに及ぶほどの規模を持っています。",
"metadata": {
"usage": {
"prompt_tokens": 715,
"prompt_unit_price": "0.001",
"prompt_price_unit": "0.001",
"prompt_price": "0.0007150",
"completion_tokens": 229,
"completion_unit_price": "0.002",
"completion_price_unit": "0.001",
"completion_price": "0.0004580",
"total_tokens": 944,
"total_price": "0.0011730",
"currency": "USD",
"latency": 3.527997043915093
}
},
"created_at": 1719190372
}
LINE Botサーバーをカスタマイズする
前回のコードをチャットボットのAPI向けにカスタマイズします。次のAPIトークンの値は適宜差し替えてください。
-
YOUR_CHANNEL_ACCESS_TOKEN
: LINEチャンネルアクセストークン -
YOUR_CHANNEL_SECRET
: LINEチャンネルシークレット -
ENTER-YOUR-SECRET-KEY
: Dify APIシークレットキー
下記のようにroutes/api/messaging.ts
を更新します。
import type { Handlers, FreshContext } from "$fresh/server.ts";
import { messagingApi, MessageEvent } from "npm:@line/bot-sdk@9.2.2";
import type { ClientConfig, TextEventMessage } from "npm:@line/bot-sdk@9.2.2";
declare interface DifyChatMessageResponse {
event: string;
task_id: string;
id: string;
message_id: string;
conversation_id: string;
mode: string;
answer: string;
metadata: {
usage: {
prompt_tokens: number;
prompt_unit_price: string;
prompt_price_unit: string;
prompt_price: string;
completion_tokens: number;
completion_unit_price: string;
completion_price_unit: string;
completion_price: string;
total_tokens: number;
total_price: string;
currency: string;
latency: number;
}
},
created_at: number;
}
const config: ClientConfig = {
channelAccessToken: "YOUR_CHANNEL_ACCESS_TOKEN",
channelSecret: "YOUR_CHANNEL_SECRET",
};
const client = new messagingApi.MessagingApiClient(config);
export const handler: Handlers = {
async POST(_req: Request, _ctx: FreshContext): Promise<Response> {
const body = await _req.json();
const event: MessageEvent = body.events[0];
const textMessage = event.message as TextEventMessage;
console.log(textMessage.text);
// request to Dify API
const requestData = {
inputs: {},
query: textMessage.text,
response_mode: "blocking",
user: "line-bot",
};
const resp = await fetch("https://api.dify.ai/v1/chat-messages", {
method: "POST",
headers: {
"Authorization": "Bearer ENTER-YOUR-SECRET-KEY",
"Content-Type": "application/json",
},
body: JSON.stringify(requestData),
});
const res = await resp.json() as DifyChatMessageResponse;
await client.replyMessage({
replyToken: event.replyToken,
messages: [
{
type: "text",
text: res.answer,
},
],
});
return new Response(null, { status: 204 });
}
};
使ってみる
実行します
deno task start
Task start deno run -A --watch=static/,routes/ dev.ts
Watcher Process started.
The manifest has been generated for 6 routes and 1 islands.
🍋 Fresh ready
Local: http://localhost:8000/
正常に実行できました
おわりに
今回はDifyでRAGを用いたチャットアプリを作成し、LINE Bot化してみました。これを使うと手軽にAI LINE Botが作成できそうですね。なによりDifyでAIアプリ側をノーコードでアップデートしていく運用ができることが魅力だと感じました。