kintoneにDifyによるLLMワークフローを組み込む〜クラウドデータベースをAI化しよう!〜

ジェネラティブエージェンツの西見です。

この記事はkintoneアドベントカレンダー2024の12月9日の記事です。

qiita.com

去年は「AIエージェントにkintoneへのデータ登録を代行してもらうCopilotの可能性」ということで、kintoneとAIエージェントを接続する話を書いていました。AIエージェントという言葉がそんなに広まっていない中で、なかなか早まった記事を書いたと思っております。。

note.com

qiita.com

今年は逆にもう少し落ち着いて、kintoneにDifyを繋ぐとかなり便利ですよ!という話をしようと思います。

そもそもDify、皆さまご存知でしょうか。Difyとは、ノーコードで大規模言語モデル(LLM)による処理を繋げたワークフローを作成できるツールです。

このツールを使うと、こんな感じでWebページの情報をまとめたり、

企業調査をしたり、

X向けのポストを生成したりといった仕組みが作れちゃう訳です。

こんな感じで便利ではあるんですが、Webページの情報をまとめたり、企業調査をして欲しいときに、いちいちDifyを開くのは面倒くさいんですよね・・・。

例えば企業調査をして欲しいときって、お問い合わせを受け取ったときに自動でして欲しいものだったりするじゃないですか。

そう、kintoneのお問い合わせ管理アプリでレコードが新規追加されたら、勝手にやって欲しい。

つまりkintoneとDifyを繋げたら、めっちゃ便利になるよ!というのが今回の記事の提案です。

というわけで、ハンズオン形式で、具体的な設定について紹介していきます。

ハンズオン

全体像

今回はkintoneプリセットの「お問い合わせ」アプリを改造する形で、Difyによる処理を仕込んでいきます。

お問い合わせがあったらスパム判定&返信ドラフトを書かせるというシナリオのもと、以下のようなフローを実現するkintoneアプリを作成していきます。

  1. kintoneお問い合せアプリの準備:お問い合せが登録されるたびにWebhookを発火させます。

  2. Difyワークフローでの処理:お問い合せ内容(顧客名、担当者名、問い合わせ種別、詳細)をDifyへ渡し、スパム判定や返信ドラフト生成などのLLMワークフローを実行します。

  3. Webhookアプリ(中継サーバ):kintone Webhook → Webhookアプリ → Difyワークフロー → Webhookアプリ → kintone というデータの流れを担います。Webhookアプリは今回提示したFastAPI + Python実装を利用します。

  4. 結果反映:Difyの結果(返信ドラフト、スパム判定結果・理由)をkintoneレコードに書き戻します。

kintoneアプリの準備

(1)お問い合せアプリ作成

kintoneにはプリセットで「お問い合せ管理」アプリが存在します。それを元に新たなアプリを作成し、以下のフィールドを追加・変更してください。

既存フィールドの確認・変更:

  • 顧客名:text_customer_name
  • 担当者名:text_customer_person_name
  • 問い合わせ種別:radio_inquiry_type
  • 問い合わせ詳細:text_detail

新規フィールドの追加:

  • 返信ドラフト(文字列フィールド):text_reply_draft
  • スパム判定(ラジオボタン):radio_spam
  • スパム判定理由(文字列フィールド):text_spam_reason
(2)APIトークンの発行

kintoneアプリの「設定」画面から、レコード追加・更新が可能なAPIトークンを発行します。 発行したAPIトークンはconfig.yamlに記載します。

Difyワークフローの準備

次にDifyワークフローを準備しましょう。このワークフローはkintoneから受け取ったお問い合わせ内容をもとに、以下の処理を行います。

  1. ユーザー(顧客)からの問い合わせ詳細を受け取る(開始ノード)
  2. 受け取ったテキストからスパム判定とスパム理由を抽出(パラメータ抽出ノード)
  3. スパムかどうかをIF/ELSEノードで分岐(分岐ノード)
  4. スパムであれば、そのまま終了ノードでスパム結果を返す(終了ノード)
  5. スパムでなければ、LLM(大規模言語モデル)を用いてメール返信文のドラフトを生成(LLMノード)
  6. 返信ドラフトとスパム判定結果を出力(終了ノード)

ポイントは開始ノードにはkintoneから受け取りたい値、終了ノードにはkintoneに設定したい値を設定することです。

今回は以下の変数を入力値として受けられるようにしています。

  • text_detail: 問い合わせ詳細
  • text_customer_name: 顧客名
  • text_customer_person_name: 顧客担当者名
  • radio_inquiry_type: 問い合わせ種別

そして返却値として以下の値を設定しています。

  • text_reply_draft: 返信ドラフト
  • radio_spam: スパム判定
  • text_spam_reason: スパム判定理由

ワークフローそのものの内容は図の通りなので割愛します! 詳しく聞きたい方はイベントに呼んでください!

Webhookアプリのセットアップ

いよいよkintoneとDifyを繋ぐためのwebhookアプリのセットアップです。

ただ、当社で使っているwebhookアプリはまだ公開していないので・・・代わりに機能を実現した最小限のコードをGithubで公開しました。このコードでも十分に動くので、お手元で試したい方はぜひ立ち上げてみて下さい。

github.com

なお、ローカルで試せるようにngrokというツールで実行するようにしているため、事前にngrokのセットアップが必要です。

ngrok.com

セットアップ方法

(1)リポジトリのクローン

git clone https://github.com/mahm/kintone-dify-sample.git
cd kintone-dify-sample

(2)環境構築

uvを使っているので事前にuvのセットアップをしてください。

github.com

セットアップ後は以下のコマンドで環境構築(パッケージのインストール&仮想環境の設定)が完了します。

uv sync

(3)config.yamlの編集

config.yamlを開き、以下のような形で設定してください。

kintone:
  base_url: "https://[あなたのドメイン].cybozu.com"

pairs:
  - name: "inquiry-processing"
    kintone_app_id: [実在のものに置き換えてね]
    kintone_token: [実在のものに置き換えてね]
    dify_api_key: [実在のものに置き換えてね]

    # kintone→Dify
    kintone_to_dify:
      text_customer_name: "text_customer_name"
      text_customer_person_name: "text_customer_person_name"
      radio_inquiry_type: "radio_inquiry_type"
      text_detail: "text_detail"

    # Dify→kintone
    dify_to_kintone:
      text_reply_draft: "text_reply_draft"
      radio_spam: "radio_spam"
      text_spam_reason: "text_spam_reason"

kintoneのAPIトークンやDify APIキーは本物の値を入れてください。本記事ではセキュリティ上伏字にしています。

(4)サーバ起動

./run_local.sh

このスクリプトでuvicornによるFastAPIサーバー起動とngrokによる外部公開が同時に実行されます。 ngrokによって割り当てられたURLが表示されるので、これをコピーします。

(5)kintone Webhook設定

kintoneアプリの設定画面でWebhookを設定し、先ほど取得したngrokのURLを登録します。

https://[ngrokによって出力されたURL]/webhook

例:こんな感じのURLになります↓

https://xxxx-xxxx-xx-xxxx-x-xxxx-xxxx-xxxx-xxx.ngrok-free.app/webhook

「レコード追加時」または「レコード更新時」をトリガーとして設定します。

疎通テスト

それではいよいよkintoneアプリにアクセスし、新規にお問い合わせレコードを追加してみます。

  • 顧客名や問い合わせ詳細を適当に入力し保存
  • すると、Webhookが発火し、中継アプリ→Difyワークフロー→中継アプリ→kintone、という順で処理が走ります。
  • 数秒後、レコードを見直すと、「返信ドラフト」が自動生成され、「スパム判定」や「スパム判定理由」がDify側のロジックに応じて更新されているはずです。

というわけで、早速こんな感じに新規レコードを追加してみましょう。

無事スパム判定されました!・・・まぁ、普通こんなノリでお問い合わせ送ってこないですよね。

それではちゃんと製品自体のお問い合わせを送ってみたら、どうでしょうか。

無事返信内容の下書きが作成されましたね!

こんな感じでkintoneにDifyを使ってAI機能を埋め込むことができました。

まとめ

この仕組みを応用すると、単純にOpenAIのGPTによる応答やAnthropicのClaudeによる応答をさせるだけでなく、Difyのワークフローを用いてインターネットの情報を用いて応答をさせたり、独自のナレッジDBの情報を踏まえた応答をさせることができるようになります。

AIチャットをベースとして「なかなかAI活用が進まない!」という声が聞かれたりしますが、そもそもAIのために人間が何かを入力するということ自体が不便だと思います。kintoneのように、データが集まる仕組みがあるのであれば、そのデータを入力としてAI活用をしていけると、どんどんAI活用が進むのではないでしょうか。

今回ご紹介したサンプルコードをリモートサーバにデプロイすれば、まずはコストゼロで連携を試すことが可能です。ぜひ試してみてください!

現場からは以上です。