🌊

社内のDify市民開発人口を増やすために取り組んだこと(技術編)

2024/12/06に公開

本記事はQiita Dify Advent Calendar 2024の6日目の記事です。

About

自分の所属している会社では、2024年9月からAWS上にDifyを構築して運用しています。

運用を始めた狙いとしては、

AIネイティブな組織へ

つまり、AIにたくさん働いてもらおう

そのために、現場起点でノウハウがAIアプリとして量産できる体制が必要

そのために、AIアプリの市民開発ムーブを社内に作ろう

というものです。

開始からおおよそ3ヶ月経過し、次のような変化をもたらすことが出来ました。

  • Difyアプリ開発者人数: 1人 -> 5人 (エンジニアではない開発者)
  • 開発されたDifyアプリ数: 1個 -> 約10個 (うち5個は運用中、残りは検証中)

運用開始直後の課題感

AIアプリ(AIエージェント)の構築フレームワークに関しては、抽象化されすぎて使う人を選ぶものも多く、カオスな乱立状況ではありますが、Difyは使いやすさと拡張性が絶妙なバランスで設計された良いツールだと思います。

一方で、Dify単体では越えられない壁もあるなー、と感じていました。

その課題の1つが、入出力に関する課題です。

便利なDifyアプリが出来上がったとしても、

  • Difyの画面を開かないと使えない (普段遣いのSlackからサクッと呼べたらなぁ...)
  • AIへのデータ入力が面倒 (データを取るためにまた別のシステム開いて...)

あたりがラストワンマイルのネックになり、なかなか活用が進まずでした。

開発人口を増やすという面では社内勉強会の開催など実施していましたが、技術的にこれらの入出力に関する課題を解決しない限り、市民開発ムーブは訪れない気がして、エンジニアとして技術的な策を打つことにしました。

策の内容

外部との入出力にまつわる課題を解決すべく、Bridgeとというサービスを構築することにしました。

概念的には下記のようなもので、Difyと外部システムとの間を滑らかに接続することで、AI(Dify)アプリの呼び出しを簡単にし、入力作業を効率化することを意図した仕組みになります。

ユーザー的には、普段使いのSlackから気軽にAI(Dify)アプリを呼び出せて、AIへのデータ入力も非常に楽ちん、というベネフィットが得られるものです。

現在、大きく3つの機能があります。

1. Slack/Dify 間のメッセージ転送

1つ目は、Slack/Dify間のメッセージ転送機能です。SlackからすぐにAI(Dify)アプリを呼び出すことができます。

仕組みとしてはシンプルで、Slack Botにメンションを投げると、Slack Botと関連付けられたDifyアプリ(Chatbot)にAPI経由でメッセージが転送され、Difyアプリからの応答が最終的にSlackのスレッドに返信として届く仕組みです。

↑は、SlackのメッセージをDify経由でgpt-4oに入力した結果です。微妙にコンテキストにキャラ設定を追加しているので、文体がアレなのはご愛嬌...

LLMがMarkdown形式で出力するケースが多く、必要に応じてmrkdwn(Slackの形式)に自動変換するなど、実は細かいところでチューニングはしています。

Slack BotとDifyアプリの対応関係はデータベース(DynamoDB)で管理されており、Difyアプリ開発者自身で管理画面から対応関係を登録することが可能になっています。

ファイル転送にも対応しています。今のところ画像とPDF(主にClaudeに読ませる)のみですが、最近Difyのファイル関連の機能が強化されつつあるので、今後拡張する予定です。

開始ノードに必須の入力項目を持つアプリへの対応も可能です。

例えば、上のように2つの入力必須項目持つアプリをSlackから呼び出すと、、、

下のようにSlackスレッドにBlock Kitで入力項目を返し、ユーザーに必須項目の入力を強制させることが出来ます。

これは、メッセージ転送前にDifyのアプリパラメータ取得API GET /v1/parameters をコールし、入力項目(UserInputForm)の定義を確認することで実現しています。

2. スレッドと会話を対応付けてコンテキストを同期

表題では分かりづらいので実行例を示します。Botに話しかける前の会話履歴を考慮した回答をしている例です。

メッセージ転送機能は、Botへのメンションが発生した場合のみ、当該メッセージを転送するものですが、メンション前にスレッド上で発生していた会話履歴や、メンションとメンションの間に繰り広げられた会話履歴を考慮した回答が出来ないと不便だと感じ、その対策として追加した機能になります。

この機能は非常に強力で、たとえば人間同士で会話している長いスレッド上に、途中にBotを割り込ませることで論点を整理したりまとめさせたりすることが可能になります。

実現にために、Slack側のスレッド識別子(channel_id + thread_ts)とDify側の会話識別子(ConversationID)の対応関係を中継サービスのDB上で管理しています。
(実装としてはAWSのDynamoDBを利用しました)

その上で、メッセージ転送時に次の制御を行っています。

  • 保存されたConversationIDをDifyアプリ実行APIに入力
  • 最終転送時のmessage_tsと今回のmessage_tsの差分を考慮し、抜けている未転送のメッセージを抽出し、Difyアプリ実行APIに追加入力

要するに、同じSlackスレッドへのメッセージは同じDify会話スペースに転送し、さらにはメンション外の未転送のメッセージ履歴も適宜入力に加えていく、みたいなことをしています。

3. Tool(OpenAPI/Swagger)経由で外部連携

3つ目は、外部システムとのAPI連携です。一例ですが、SalesforceのレポートのURLを渡すだけで、AI(Difyアプリ)はレポートの内容を踏まえた処理を行うことができます。

SlackからすぐにAI(Difyアプリ)を呼び出すことが出来るようにはなりましたが、結局AIへの指示に多くの入力データを含める必要があり、入力データを取得するために個別にシステムを開いて、、、といった作業を繰り返すことになり、非常に非効率です。

その解決のため、社内システムへのAPIアクセス環境をBridgeの一部として整備しています。

APIはOpenAPI準拠仕様でSwaggerドキュメント(JSON)化されており、Difyでドキュメンt(JSON)を読み込ませることでツールとして使えるようになっています。

これは愚直に整備していくしかないですね。。

まとめ

SlackとDifyの連携を強化していった結果、わざわざDifyを開かなくてもすぐにアクセスできるAIアプリ、という形で社内ユーザーの利用ハードルも下がり、使われやすくなりました。

結果として、開発者のモチベーションも向上→開発人口増→アプリ増、という最初の流れを作ることが出来ました。

そしてMCPの登場

ところで、Bridgeの今後の方向性を考えていた先週、AnthropicさんがMCP(Model Context Protocol)なるものを発表しました。

Bridgeの仕組みを抽象化していくと、きっとMCP的な規格に落ち着くのだと思います。

ということで、MCPもしくは今後乱立するであろう類似規格に寄り添いながらの開発が必要になりそうなので、色々と考察をしています。それについてはまた別のアドベントカレンダーにて記事化出来れば...

Discussion