見出し画像

【DifyxGAS×GPT】Chatwork連携-クレーム対応AIアシスタントの作り方

Difyというプラットフォームで社内のマニュアルや会話履歴をAIに学習させて、Chatwork上で24時間質問に答えてくれる「AI相談室」の仕組みを作ります。

こんな課題を解決できます🌱
✓ バラバラに存在する社内ナレッジを一元化
✓ 新入社員の基本的な質問に24時間対応
✓ ベテラン社員の知見を効率的に共有・継承

以下の様なイメージ✨


01. データの準備

社内マニュアル(PDF/Word)や過去の会話履歴など、AIに学習させたいテキストデータを準備。

02. 【Dify】セットアップ

Difyにログイン
Difyのウェブサイトにアクセスし、「始める」

Difyのダッシュボードから上部バーにある【ナッレジ】【ナレッジを作成】を選択し、

先ほど01で準備したテキストファイルを学習データとしてインポートします。【テキストファイルからインポート】を選択。

準備した社内ナレッジデータをアップロードします。

アップロードが完了したら、「次へ」ボタンをクリック。

次にテキストの前処理とチャンク分割の設定を行います。
(アップロードしたデータは、FAQボットが効率的に処理できるよう、テキストの前処理とクリーニングが行われます。)

チャンクとは.....大量のデータを扱う際に、効率よく処理するためにデータを小さな単位(塊)に分割したものです。これにより、データの管理や分析がしやすくなります。

ファイルのインポートが完了したら、以下の設定を選択してください:

チャンク設定: 「自動」
インデックスモード: 「高品質」
検索設定: 「ハイブリッド検索」

これらを設定した後、【保存して処理】をクリック。

補足:これらの設定項目は、データの内容や特性に合わせて最適な値を選択してください。

Q&Aボットの作成
次はDifyのダッシュボード画面に戻り、【スタジオ】を選択し、「アプリを作成する」の【最初から作成】をクリック。

【チャットボット】を選択し、【Chatflow】を選択。
ボットの名前と説明を入力し、最後に【作成】ボタンをクリックします。

すると以下の様なワークフローの設定画面が表示されます。

【開始】【LLM】をつなぐ線の上にカーソルを当てると ⊕ ボタンが出てくるのでクリックして、

【知識取得】を選択します。

+ボタンをクリックし、先ほど01で準備し、インポートしたPDFデータを呼び出します。

【追加】を押せばナレッジが追加されます。

続いてはLLMの設定を行います。
API連携をするので、【Difyのダッシュボード】へ移動し【設定】をクリック。

【モデルプロバイダー】を選択。

次に、【セットアップ】から、任意のLLMモデルを選択して、OpenAIであればGPTの{APIキー}を貼り付けて設定完了です。


先ほどの【Dify】チャットボットの構成(設定画面)に戻ります。
LLMモデルの選択をしてください。

次にコンテキストに、【知識取得/result Array】を選択します。

続いて、コンテキストの下にあるスペースに任意のプロンプトを設定してください。

プロンプト例

あなたは公務員の職員向けクレーム対応AIアシスタントです。
提供されたクレーム対応マニュアルに基づいて質問に答えてください。

{{#context#}}
以下の原則に従って回答してください:
1. マニュアルに記載されている内容に基づいて回答する
2. マニュアルに記載のない内容については「申し訳ありませんが、その内容についてはマニュアルに記載がないため、お答えできません」と回答する
3. 具体的な対応例や手順がある場合は、それらを引用して回答する
4. 状況に応じて、上司への報告や警察への通報など、適切なエスカレーションを提案する

{context}の部分には、RAGの検索結果が反映されます。
※contextは、/ または { 入力すると設定できます。

続いてメモリをONに設定します。

設定が完了したら【プレビュー】タブで質問を入力し、【送信】ボタンをクリック。実際に質問してテストしてみましょう。

正常に動作することが確認できたら、
【公開する】タブから【公開】【アプリを実行】をクリックすることで、ブラウザ上でボットを使用できるようになります。

★1:APIキーの取得
左側メニューの【APIアクセス】を選択し、【APIシークレットキー】を取得します。※このシークレットキーは、後のステップで使用するため保存しておいてください。

03. Chatwork 設定

Chatworkside での設定を行います。

① APIトークンの取得

Chatwork画面右上の【利用者名】をクリックして表示されるメニューの【サービス連携】を選択。
サービス連携画面が開きますので、左側のメニューから【APIトークン】をクリックしてください。
★2:後のステップで使用するため保存しておいてください。

Chatwork APIの利用には組織管理者への申請が必要です。APIを利用したいアカウントでログインの上、申請してください。

②Bot用アカウントIDを確認する
チャッとボット用のChatworkアカウントを作成します。
そのアカウントIDを確認します。チャット画面の右上にある 【利用者名】のクリックで表示されるメニューの 【環境設定】を開きます。

【Chatworkについて】タブをクリックし、アカウントIDに表示されている数字を確認します。
★3:後のステップで使用するため保存しておいてください。

04. GAS(Google Apps Script)でDifyとChatworkを連携させる

①スクリプトの作成
Google スプレッドシートを開いて、「拡張機能」 > 「AppsScript」を選択します。

次に、Google Apps Script(GAS)を使用して、DifyとCWの連携を設定します。以下のコードをGoogle Apps Scriptに貼り付けてください。

// 定数定義
const DIFY_API_URL = 'https://api.dify.ai/v1/chat-messages';
const CHATWORK_API_URL = 'https://api.chatwork.com/v2';

// テスト用関数
function testConnection() {
  Logger.log('Testing connections...');
  const scriptProperties = PropertiesService.getScriptProperties();
  
  // APIキー取得
  const DIFY_API_KEY = scriptProperties.getProperty('DIFY_API_KEY');
  const CHATWORK_API_TOKEN = scriptProperties.getProperty('CHATWORK_API_TOKEN');
  const BOT_ACCOUNT_ID = scriptProperties.getProperty('BOT_ACCOUNT_ID');
  
  Logger.log('Checking properties:');
  Logger.log('BOT_ACCOUNT_ID exists: ' + !!BOT_ACCOUNT_ID);
  Logger.log('CHATWORK_API_TOKEN exists: ' + !!CHATWORK_API_TOKEN);
  Logger.log('DIFY_API_KEY exists: ' + !!DIFY_API_KEY);
  
  // Difyテスト
  try {
    const testResponse = callDifyAPI('テストメッセージ', DIFY_API_KEY);
    Logger.log('Dify test response: ' + testResponse);
  } catch (error) {
    Logger.log('Dify test failed: ' + error);
  }
  
  // Chatworkテスト
  try {
    const response = UrlFetchApp.fetch(`${CHATWORK_API_URL}/me`, {
      headers: {
        'X-ChatWorkToken': CHATWORK_API_TOKEN
      }
    });
    Logger.log('Chatwork test successful: ' + response.getContentText());
  } catch (error) {
    Logger.log('Chatwork test failed: ' + error);
  }
}

function doPost(e) {
  Logger.log('Webhook received');
  Logger.log('Payload: ' + JSON.stringify(e.postData.contents));
  
  const scriptProperties = PropertiesService.getScriptProperties();
  const DIFY_API_KEY = scriptProperties.getProperty('DIFY_API_KEY');
  const CHATWORK_API_TOKEN = scriptProperties.getProperty('CHATWORK_API_TOKEN');
  const BOT_ACCOUNT_ID = scriptProperties.getProperty('BOT_ACCOUNT_ID');
  
  try {
    const payload = JSON.parse(e.postData.contents);
    
    // メッセージ情報を取得
    const messageBody = payload.webhook_event.body;
    const roomId = payload.webhook_event.room_id;
    const senderId = payload.webhook_event.account_id;
    
    Logger.log('Message received: ' + messageBody);
    Logger.log('Room ID: ' + roomId);
    Logger.log('Sender ID: ' + senderId);
    Logger.log('BOT_ACCOUNT_ID: ' + BOT_ACCOUNT_ID);
    
    // ボットからのメッセージは無視
    if (senderId.toString() === BOT_ACCOUNT_ID.toString()) {
      Logger.log('Ignoring bot message');
      return ContentService.createTextOutput('OK');
    }
    
    // メンションパターンの確認
    const mentionPattern = `[To:${BOT_ACCOUNT_ID}]`;
    Logger.log('Checking mention pattern: ' + mentionPattern);
    Logger.log('Message contains mention: ' + messageBody.includes(mentionPattern));
    
    if (messageBody.includes(mentionPattern)) {
      Logger.log('Bot mention found');
      
      // メッセージからメンション部分を削除
      const cleanMessage = messageBody
        .replace(new RegExp(`\\[To:${BOT_ACCOUNT_ID}\\].*?(?=\\s|$)`), '')
        .trim();
      
      Logger.log('Clean message: ' + cleanMessage);
      
      if (!cleanMessage) {
        Logger.log('Empty message after cleaning');
        postToChatwork(roomId, 'メッセージ内容を入力してください。', CHATWORK_API_TOKEN);
        return ContentService.createTextOutput('OK');
      }
      
      // Dify APIに送信
      const difyResponse = callDifyAPI(cleanMessage, DIFY_API_KEY);
      Logger.log('Dify response: ' + difyResponse);
      
      if (difyResponse) {
        // Chatworkに返信
        postToChatwork(roomId, difyResponse, CHATWORK_API_TOKEN);
      }
    } else {
      Logger.log('No bot mention found');
    }
    
    return ContentService.createTextOutput('OK');
  } catch (error) {
    Logger.log('Error in doPost: ' + error.toString());
    Logger.log('Error stack: ' + error.stack);
    return ContentService.createTextOutput('Error occurred');
  }
}

// Dify APIにメッセージを送信
function callDifyAPI(message, apiKey) {
  const headers = {
    'Authorization': 'Bearer ' + apiKey,
    'Content-Type': 'application/json'
  };
  
  const payload = {
    'inputs': {},
    'query': message,
    'response_mode': 'blocking',
    'conversation_id': '',
    'user': 'chatwork-user-' + Math.random().toString(36).substr(2, 9)
  };
  
  const options = {
    'method': 'post',
    'headers': headers,
    'payload': JSON.stringify(payload),
    'muteHttpExceptions': true
  };
  
  try {
    Logger.log('Calling Dify API...');
    const response = UrlFetchApp.fetch(DIFY_API_URL, options);
    const responseText = response.getContentText();
    Logger.log('Dify response: ' + responseText);
    
    if (response.getResponseCode() === 200) {
      const responseBody = JSON.parse(responseText);
      return responseBody.answer || 'No response from Dify';
    }
    return 'Error calling Dify API';
  } catch (error) {
    Logger.log('Dify API error: ' + error);
    return 'API Error occurred';
  }
}

// Chatworkにメッセージを送信
function postToChatwork(roomId, message, apiToken) {
  const url = `${CHATWORK_API_URL}/rooms/${roomId}/messages`;
  
  const options = {
    'method': 'post',
    'headers': {
      'X-ChatWorkToken': apiToken
    },
    'payload': {
      'body': message
    }
  };
  
  try {
    Logger.log('Sending message to Chatwork...');
    const response = UrlFetchApp.fetch(url, options);
    Logger.log('Chatwork response: ' + response.getContentText());
    return response;
  } catch (error) {
    Logger.log('Chatwork API error: ' + error);
    throw error;
  }
}

②GASのデプロイ
Google Apps Scriptの上部メニューから【デプロイ】をクリックし、【新しいデプロイ】を選択。

③ウェブアプリの設定
デプロイ形式として【ウェブアプリ】を選択し、以下の項目を設定します:

新しい説明文:(例)クレーム対応マニュアルAIアシスタント
次のユーザとして実行:自分
アクセスできるユーザー:全員

最後に【デプロイ】を選択。

④アクセスを承認
デプロイ完了後、初めてそのスクリプトを実行する場合は、Googleから権限を求めるポップアップが表示されます。指示に従って必要な権限を承認します。
【続行】を選択

使用中のGoogleアカウントを選択します。

以下の様な画面が表示されたら、【詳細】または【詳細を表示(Advanced)】をクリック。

【プロジェクト名(安全ではないページ)に移動】をクリックして遷移してください。

このような画面が表示されるので、下までスクロールして【許可(Allow)】をクリックしてください。

⑤ウェブアプリのURL取得
デプロイが完了すると、生成された【WebアプリケーションのURL】が表示されます。

★4: ↓【ウェブアプリ】のURLをコピーしておいてください。(※後に使用します)

05. ChatworkにてWebhookの新規作成

GASのウェブアプリURLをChatworkに設定し、イベントがトリガーされた際に正しく応答できるようにします。

CW設定画面→【Webhook】から→【新規作成】

以下の項目を設定します:
Webhook名:
任意
Webhook URL:先ほど★4で取得した「GASのウェブアプリURL」を入力します。CWがこのURLにリクエストを送信してイベントを処理します。
イベント:ルームイベントを選択
メッセージを作成にチェック
ルームIDを指定:ルームIDはパーマリンクのid以降の数字になります
https://www.chatwork.com/#!rid{ここの数字}

最後に作成ボタンを押すと以下の様に情報が発行されます。★5【トークン】を後のステップで使用するため保存しておいてください。

06. GAS スクリプトプロパティの設定

※APIキーやトークンなどの重要な情報はコードに直接書かずに、スクリプトプロパティで管理する必要があります。そのためプロパティ設定していきます。

GASの左メニューバーにある【プロジェクトの設定】をクリック。

【スクリプトプロパティ】タブから以下のプロパティを追加してください。

★1  DIFY_API_KEY: Difyで取得したAPIキー
★2  CHATWORK_API_TOKEN: Chatworkで取得したAPIトークン
★3  BOT_ACCOUNT_ID: ボットとして使用するChatworkアカウントD
★4  WEBHOOK_TOKEN: Chatworkのwebhookトークン

最後に【スクリプトプロパティを保存】

これで設定は完了です!
実際にチャットワークのボットアカウントに@メンション形式で質問してみてください。回答が返ってきたら実装は完了です◎

まとめ

今回は、Dify・Chatwork・GPTを連携させたシンプルな例を記録しました。より詳細設定として、プロンプトとモデル・ パラメータを調整したり、「複数のモデルとしてデバッグ」機能を利用して、モデルの応答の有効性をバッチテストしたり、と用途に応じたカスタマイズが可能です。
必要に応じて柔軟に設定を変更し、業務や作業に役立つツールに仕上げてみてください。

急なトラブルが発生した場合や、Web開発・AI連携についてのご相談があれば、ぜひお気軽にお声掛けください。「もっとこうすれば?」など、アイデアや意見交換も大歓迎です。

最後まで読んでくださり、ありがとうございました🌱少しでも参考になる箇所があればそーっと♡で教えてください✨大変励みになります!


いいなと思ったら応援しよう!