Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

DifyとKnowledge bases for Amazon Bedrockを連携させてRAGを構築する

こんにちは。ベランダで育てていたバジルが虫に食べられてしまいました。ハヤトです。
しかし植物の生命力というのはすごいもので、残った茎から再び葉っぱが成長してきています。次はぜひ私が食べたいものです。

さて、成長著しいといえば生成AIアプリ開発の分野はまさに日進月歩ですが、
なかでも「Dify」は、LLMワークフローが特に便利で、注目度が急上昇中です。
今回はそんなDifyとKnowledge bases for Amazon Bedrockを連携させてRAGを構築してみます。

Difyとは?

Difyは、生成AIアプリを手軽に構築できるオープンソースのLLMアプリ開発プラットフォームです。
簡易的なチャットボットであれば、プログラミング知識がなくてもノーコードで作成できてしまいます。

dify.ai

Knowledge bases for Amazon Bedrockとは?

Amazon Bedrockで検索拡張生成(RAG)を簡単に構築するためのサービスです。
RAGは、生成AIにモデルが学習していない外部情報を組み合わせることで回答の精度を高める手法です。

aws.amazon.com

今回作成するチャットボットについて

DifyにもRAGで使用するナレッジを作成する機能は組み込まれていますが、2024年7月現在では選択できるデータソースは以下に限られています。

  1. テキストファイルからインポート
  2. Notionから同期
  3. ウェブサイトから同期

そのため今回は、データソースとしてより多くの社内データなどを扱う実際的なユースケースを想定して、
Knowledge bases for Amazon BedrockをDifyのナレッジとして使用するRAGチャットボットの構築手順を説明していきます。

構成イメージ:

AWS側の設定手順

AWS側では、Knowledge bases for Amazon Bedrockを使ってナレッジベースを作成し、
そこから知識取得を行うAPIをLambda + API Gatewayで構築します。

ナレッジベースの作成

今回はサンプルとして、IPAが公開している以下の資料を情報として持つナレッジベースを作成します。

デジタルスキル標準 Ver.1.1
https://www.ipa.go.jp/jinzai/skill-standard/dss/ps6vr700000083ki-att/000106872.pdf

安全なウェブサイト運営にむけて
https://www.ipa.go.jp/security/todokede/vuln/ug65p90000019gda-att/000089537.pdf

作成手順については、以下の記事で詳細を説明しているのでこちらに従います。
acro-engineer.hatenablog.com

ナレッジベースが作成できたら次のステップで使用する「ナレッジベース ID」をメモしておきます。

APIの作成

Knowledge base for Amazon Bedrockには、クエリに対してナレッジベースに基づいた回答を生成する
「RetrieveAndGenerate API」が用意されています。
docs.aws.amazon.com

今回はこれを使用して、先ほど作成したナレッジベースから回答を取得するAPIを作成します。

Lambdaの作成

RetrieveAndGenerate APIを実行するLmbdaを作成します。

今回は最小限の内容で、以下のような形式のリクエストを受け取ってqueryに対する回答を取得する実装になります。

{
  "query": "安全なウェブサイトの作り方を教えてください。"
}

コードから「lambda_function.py」を以下の内容に編集します。
※{作成したナレッジベースのID}は先ほどメモしたナレッジベース IDに置き換えてください。

import boto3
import json

KNOWLEDGE_BASE_ID = '{作成したナレッジベースのID}'

print('Loading function')
client = boto3.client('bedrock-agent-runtime')


def lambda_handler(event, context):
    response = client.retrieve_and_generate(
        input={
            'text': event['query']
        },
        retrieveAndGenerateConfiguration={
            'knowledgeBaseConfiguration': {
                'knowledgeBaseId': KNOWLEDGE_BASE_ID,
                'modelArn': 'anthropic.claude-v2:1'
            },
            'type': 'KNOWLEDGE_BASE'
        }
    )

    return response

参考ドキュメント:
boto3.amazonaws.com

注意点としては、AmazonBedrockへのアクセス権限の付与が必要となります。今回は「AmazonBedrockFullAccess」を付与しました。
(今回は簡単のため上記の設定としていますが、本来は必要最小限の権限だけに限定するのが適切です)
また、RetrieveAndGenerate APIの応答には時間がかかるのでLambdaのタイムアウトは30秒に変更しました。

設定ができたら作成したLambdaをテストしてみましょう。

正しく設定できていれば、作成したナレッジベースに基づく質問に対する回答が得られます。

API Gatewayの作成

次に、作成したLambdaを実行するAPIAPI Gatewayで作成します。

POSTメソッドとして先ほど作成したLambdaを実行するメソッドを作成します。

リクエストボディの形式を指定するために、以下の内容でモデルを作成します。

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title" : "Query Schema",
  "type" : "object",
  "properties" : {
    "query" : {
      "type" : "string"
    }
  }
}

メソッドリクエストの編集からリクエスト本文として作成したモデルを設定します。
あわせてAPIキー認証を有効にしておきます。

ここまでの設定ができたらAPIをデプロイします。
APIキー認証のために、デプロイしたステージとAPIキーの紐づけが必要なので、以下を参考に設定を行います。
docs.aws.amazon.com

認証の設定ができたのでAPIを呼び出してみましょう。
APIのURLをコピーします。

今回はPostmanでAPIを呼び出してみました。
Headersで「x-api-key」に作成したAPIキーを設定する必要があります。

無事、Lambdaの実行時と同等のレスポンスを得られました。
作成したAPIのOpenAPIスキーマをこのあと使用するので、
API Gatewayの「ステージ>ステージアクション>エクスポート」を選択しておきます。

AWS側の準備はこれで以上になります。

Dify側の設定手順

Dify側では、AWS側で構築した知識取得のAPIを実行するカスタムツールと、
そのレスポンスを元にユーザへの回答を行うチャットボットを構築します。

DifyはOSS版を自分でデプロイして使うことも出来ますが、
今回はブラウザから手軽に利用できるSaaS版を使いました。

カスタムツールの作成

Difyで「ツール>カスタム>カスタムツールを作成する」を選択します。
先ほどエクスポートしたOpenAPIスキーマを一部編集して設定します。

  1. servers.urlが変数を含む形になっているので実際のパスに置き換える。
  2. paths.postに以下の設定を追加する(「利用可能なツール」の表示に必要)。
summary: Retrieve And Generate
operationId: retrieveAndGenerate

「認証方法」からリクエストに使用するAPIキーを設定します。

「利用可能なツール>テスト」でAPIを呼び出せたら設定OKです。

チャットボットの作成

いよいよ最後のステップです。「スタジオ>最初から作成」でチャットボットを作成します。
はじめからノードベースで構築したいので、「チャットボットのオーケストレーション方法」はChatflowを選択します。

開始ブロックの後ろに先ほど作成したカスタムツールを追加し、ユーザが入力したクエリを受け取るようにします。

次に後続のLLMブロックがカスタムツールで取得した情報を元に回答をするように設定します。
※カスタムツールのレスポンス内にBedrock側で生成した回答も含まれていますが、
レスポンスのパース処理を書くよりLLMに解釈させる方が楽なので今回はそのようにしています。

以下の設定を行いました。

  1. モデルをgpt-4o-2024-05-13に変更
  2. コンテキストにカスタムツールの出力内容を設定
  3. SYSTEM、USERプロンプトに以下を設定

SYSTEM

あなたはユーザの言語に合わせて回答を行うQAチャットボットです。
質問に対する回答は、事前知識ではなく取得した以下のコンテキストに基づいて行ってください。
---
{{#context#}}
---

USER

コンテキストに基づいて、以下のユーザからに質問に答えてください。
---
{{#sys.query#}}
---

以上で設定は完了です。

デバッグとプレビューで会話を試してみましょう。

質問文:

DX推進スキル標準で定義されている人材類型について教えてください。

質問文:

IPAがウェブサイトの脆弱性に関する届出を受けた場合の、脆弱性対策の流れを教えてください。

それぞれカスタムツールで取得したナレッジベースの情報を元に回答してくれていることがわかりますね。

まとめ

今回は手軽に生成AIアプリを開発できるDifyと、企業レベルのユースケースにも対応したナレッジベースを構築できる
Knowledge bases for Amazon Bedrockを連携させたRAGチャットボットを作成しました。
Difyのカスタムツールを使用すれば、今回使用したナレッジベースに限らず様々なサービスと連携させられそうで夢が広がりますね。

Acroquest Technologyでは、キャリア採用を行っています。

  • Azure OpenAI/Amazon Bedrock等を使った生成AIソリューションの開発
  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • マイクロサービス、DevOps、最新のOSSクラウドサービスを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

www.wantedly.com