📖

DifyとAWSで作る!RAGを活用したSlack Botの構築ガイド

2024/12/08に公開

はじめに

筆者は e-dash でバックエンドエンジニアをしている ikeda です。
こちらはe-dash advent calendar 2024の 8 日目の記事にあたります。

昨今、ChatGPTをはじめとする生成AIを利用する方が増えています。その後、生成AIをさらに活用する技術として「RAG(Retrieval Augmented Generation)」が注目されるようになりました。
RAGとは、生成AIに質問と共に特定の情報を提供し、回答を生成する技術です。
膨大な情報が蓄積される中、必要な情報を効率的に取得する手段として注目されています。

また、生成AIを簡単に扱えるOSSであるLangChainや、ノーコードで利用できるDifyも登場し、生成AIを活用する技術には多様な選択肢が広がっています。
本記事では、社内コミュニケーションツールとして全社員が利用しているSlackをインターフェースに、RAGを活用した社内情報を回答するBotの作成方法を紹介します。RAGを試してみたい方に、実装のイメージを掴んでいただければと思います。

RAGを作る動機

筆者がRAGを作ろうと思った背景には、日々の業務で感じていた課題がありました。

「あの仕様、SlackかNotionで見た気がするけど、どこだっけ…Google Driveだったかな?探す時間がもったいない…」
「同じことを何度も聞くのは気が引ける…でも、自力で探すのも限界がある…」
このような悩みを解消するため、RAGに挑戦しました。

RAG作成の流れ

RAGの基本的な作成プロセスは以下の通りです。

  1. 文書をベクトル化してデータベースに保存
    テキストをAIモデルを使って数値データ(ベクトル)に変換します。
    例: [0.0107, 0.0024, 0.0093, ...]

  2. 質問に対して近い文章を検索
    質問文をベクトル化し、データベース内の類似する文書を検索します。

  3. 生成AIで回答を生成
    検索結果をもとに、ChatGPTのようなAIで回答を生成します。

  4. 回答をSlackに投稿
    生成された回答をSlackに投稿して完了です。

RAGを作成するための技術

RAGを実現するためには、各工程を実装する必要があります。以下では、筆者が試したツールを紹介し、それぞれの特徴と難易度を評価します。

OpenAI API(RAG実装難易度⭐️⭐️⭐️)

OpenAIのAPIを使えば、ベクトル作成や質問への回答取得が可能です。ただし、データベースの設計やベクトル検索の実装には専門的な知識が必要です。

以下は質問と回答を受けるプログラムの例
from openai import OpenAI
import os
from dotenv import load_dotenv

load_dotenv()

client = OpenAI(
api_key=os.getenv('OPENAI_API_KEY'),
)

response = client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[
        {"role": "system", "content": "あなたは、Go言語に詳しいエンジニアです。Goに関する質問に回答してください。"},
        {"role": "user", "content": "Go言語の特徴はなんですか?"}
    ]
)

print(response)

LangChain(RAG実装難易度⭐️⭐️)

LangChainは、OpenAIを含むさまざまなLLMを扱えるOSSです。高い自由度が魅力ですが、設定やカスタマイズに手間がかかるため、やや実装難易度が高めです。

以下はLangChainを使ったプログラムの例
import os
from dotenv import load_dotenv
from langchain_openai import OpenAI

load_dotenv()

llm = OpenAI(temperature=0)

result = llm.invoke("自己紹介してください")
print(result.strip())

Dify(RAG実装難易度⭐️)

以下のGithubドキュメント
記事執筆時点で53kスターを獲得している非常に勢いのあるOSSです。

オープンソースとなっており、商用利用も可(利用規約は要確認)。
自前でサーバーを立てれば、そこで使える。もちろんローカルも可。(docker compose up -dだけですぐ使えた)

ノーコードで扱うことができ、生成AIの知識やプログラムの知識が浅くても扱いやすく、初期検討には最適。

上記のようにRAGを作る方法はいくつかあるのですが、まずはRAGを実際に触ってみた感触を掴むため、スピーディにプロトタイプを作りたいと思い、Difyを使うことにしました。
なお、Difyは自身でサーバーを立てずに、Webアプリとして利用することができます。また、無料プランでも試すには十分な機能が提供されています。

Difyを使ってRAGを活用したSlack Botを作成する

今回はWebアプリ版を利用して、Slack Botを作成します。

AWSの構成

API GatewayとLambdaを使って、Slackからのリクエストを受け取り、Difyを使って回答を生成し、Slackに返すBotを作成します。
学習素材として、公開されている情報(e-dash本社オフィス移転記事)を使って試してみました。
以下の手順で実装しました。

各工程の詳細はすでに多くの方が情報共有してくださっていますので、ここでは手順のみを記載します。

1. 下準備

  • SlackAPIにアクセスして、アプリを作成します。
  • OpenAIにアクセスして、APIキーを取得します。
  • DifyにOpenAIのAPIキーを登録します。

2. 学習用のナレッジを作成

Difyのコンソール画面からナレッジを作成します。

e-dashのオフィス移転に関する記事のページの文字をブラウザから単純にコピーしただけの情報を利用しました。

3. DifyのRAGアプリを作成

画面上部のスタジオのメニューからチャットボットを作成します。
以下のような画面となるのですが、チャットボットを選択していただきます。

手順、変数、コンテキストを設定していきます。
手順は、質問に対してどのような回答を返すかを設定します。
変数は、質問文を受け取るための変数を設定します。
コンテキストは、作成したナレッジを設定します。

右上の公開するボタンをクリックするとチャットボット作成が完了します。(とても簡単)
また、APIリファレンスにアクセスの画面からAPIキーを発行します。

4. Slack Botの作成

Slackのアプリを作成し、Botを作成します。
作成したBotに、API Gatewayのエンドポイントを設定します。

今回の構成では、APIGatewayのあとのLambdaはすぐに次のQueueに渡すだけの処理を行っています。
これは、Slackの仕様で3秒以内にSlackへのレスポンスがないと再度Slackからリクエストが送信され、何度も処理を行ってしまうことから、エラーハンドリングは受け取った後に自身で行うようにしています。

作ったBotを使ってみる

SlackでBotに質問をしてみます。

期待通りに回答が返ってきました!
感動するとともに、「これさっきのナレッジをもとに本当に回答しているの?」という疑問が湧いてきます。
試しにスタジオの設定からナレッジを削除してみます。

そして、再度実行すると。。。

ナレッジを削除したことにより、回答が返ってこなくなりました。弊社オフィス移転は2024年5月であり、その情報はChatGPTは持っていません。
地味に重要なのが、わからないと回答していることですね。生成AIのハルシネーションが問題となるため、プロンプトやナレッジの設定が重要です。

所感

RAGを使うためのツールとしていくつかの選択肢があるのですが、Difyはノーコードで扱えるため、初めてRAGを使う方にはおすすめです。
多くの場面ではこれで十分な機能を提供してくれると思います。
RAGをより高度に扱うには、UX、利用するモデル、プロンプト、ナレッジの作成、文書検索アルゴリズム、不適切な入出力の制御など本当にたくさんの検討パラメータがあります。
それらのパラメータに対して手軽に勘所を掴むには非常に有用なツールだと感じました。
一方で、Difyの現状のバージョンではLangGraphのようにできない機能もあるため、LangChainを利用することや必要な機能を実装することも検討の余地はあると思いました。

次回(e-dash advent calendar 2024 18日目)は以下の内容で執筆したいと思います。
RAGを実際に社内で使ってもらうために以下のようなバージョンアップやその結果についてご紹介します。

  • DifyをAWSサーバにデプロイ
  • ナレッジの作り込み
  • 回答の信頼性を高めるための工夫
  • RAGを作る動機に対して目的は達成されたのか?

Discussion