1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Chatbot on Mattermost using Bedrock

Last updated at Posted at 2024-09-28

0. はじまり

AWS Chatbotは2024年9月28日現在,Mattermostに対応していません。ちょっと残念です。
とはいえAWS Lambda以外はコーディングなしで,MattermostでもAmazon Bedrockを使用したChatbotが作れます。

1. 構成要素

  • IAM Role
  • Mattermost
    • region: ap-northeast-1
  • Amazon Bedrock
    • region: us-east-1
  • AWS Lambda
    • region: us-east-1
  • API Gateway

Bedrockの使用リージョンは注意が必要です。北米でしか利用できないベースモデルがあるからです。

2.1 IAM Role

AWS Lambdaが使用するロールを作成しておきます。以下の許可ポリシーを設定します。

  • AmazonBedrockFullAccess
    • Bedrockにアクセスする上で必要
  • AWSLambdaBasicExecutionRole
    • CloudWatchログを使用する上で必要

image.png

2.2 Setting up Amazon Bedrock

「Bedrock configurations / モデルアクセス」から,使用したいモデルに対してのリクエストを行います。
今回は「Claude 3 Sonnet」を使用しましたが,これでないといけない理由はありません。使いたいものを選択すれば良いです。
リクエストするには,「リクエスト可能」の文字を右クリックして,「モデルアクセスをリクエスト」します。

image.png

アクセスが付与されたら,「基盤モデル / ベースモデル」から,使用したいモデルを探し,「Model ID」を控えておきます。後ほど,Lambdaのコード中に埋め込みます。

image.png

2.3 Mattermost : Add user account for Chatbot

Chatbotは特定のアカウント上で動作します。ですので,Chatbotにしたいアカウントを作ります。普通にinviteして,新しいユーザを作るだけです。

2.4 Mattermost : Incoming Webhook

一旦Adminアカウントで作業します。

2.4.1 Chatbot用チャネル作成

まず,Chatbotを使用するチャネルを作ります。普通に新しくチャネルを作ればよいです。

2.4.2 ChatbotアカウントにAdmin権限を付与する

ChatbotのユーザでWebhookを作成するため,ChatbotアカウントにAdmin権限を与えます。これを行うことで,Chatbotアカウントで「Integrations」メニューを使用できます。
「System Console / Users」でユーザを表示し,Chatbotで発言させたいユーザの「System Admin」から「Manage Roles」を選択します。

image.png

「System Admin」を選択して「Save」します。
image.png

2.4.3 Create an Incoming Webhook

ChatbotアカウントでMattermostにアクセスします。

「Integrations / Incoming Webhook」を選択します。

image.png

「Title」「Description」「Channel」「Lock to this channel」を適切に設定します。
「Save」を押します。
image.png

ここで出てきたURLが「Incoming Webhook」のURLです。控えておきましょう。
「Done」を押したら,Incoming Webhookの取得作業は終わりです。
なお,このURLは「Incoming Webhooks」の画面で後ほど確認することもできます。
image.png

2.5 AWS Lambda

「Lambda / 関数」から右上「関数の作成」をクリックします。
image.png

「一から作成」
「関数名」は適切に。
「ランタイム」は「Python 3.12」にしておきます。
「アーキテクチャ」は「arm64」。
「実行ロール」は「既存のロールを使用する」。
「既存のロール」として以前に作成した「LambdaToBedrockAccessRole」を指定します。
「関数の作成」をクリックします。
image.png

関数のタイムアウト時間を1分にしておきましょう。Bedrockからの応答に10秒以上かかるからです。
「設定」タブを選択し,左の列から「一般設定」を選択。一般設定の右側の「編集」をクリックします。
image.png

タイムアウトを1分に変更して,「保存」。
image.png

AWS Lambdaのコードは以下の通り。

  • IMCOMING_WEBHOOK
  • MODEL_ID
  • SYSTEM_PROMPT

の3つは適切に置き換えてください。Incoming WebhookとModelIDは以前に控えたものを使用します。
SYSTEM_PROMPTは,このChatbotがどういう応答を返すのか,いわゆるプロンプトを記述します。日本語が解釈できるModelであれば,日本語で記述できます。

import json
import urllib.request
import ssl
import boto3
import base64

# Incoming Webhook
WEBHOOK_URL = "INCOMING_WEBHOOK"

def lambda_handler(event, context):
    bedrock_runtime = boto3.client(service_name='bedrock-runtime', region_name='us-east-1')

    model_id = 'MODEL_ID'
    system_prompt = "SYSTEM_PROMPT"
    max_tokens = 1000

    body = event['body']
    message_text = base64.b64decode(body).decode()

    user_message = {"role": "user", "content": message_text}
    messages = [user_message]
    
    body = json.dumps(
        {
            "anthropic_version": "bedrock-2023-05-31",
            "max_tokens": max_tokens,
            "system": system_prompt,
            "messages": messages
        }  
    )  

    response = bedrock_runtime.invoke_model(body=body, modelId=model_id)
    response_body = json.loads(response.get('body').read())

    req_headers = {
        "Content-Type": "application/json",
    }

    req_json = {
        "text":json.dumps(response_body['content'][0]['text']).encode().decode('unicode-escape'),
    }

    req = urllib.request.Request(WEBHOOK_URL, json.dumps(req_json).encode(), req_headers)
    urllib.request.urlopen(req)

コードソースにコードを貼り付けたら,「Deploy」です。
image.png

ここでテストをしたい場合は,

    body = event['body']
    message_text = base64.b64decode(body).decode()

    # body = event['body']
    message_text = "私はJavaの初心者です。何から始めればいいですか?"

といった形に書き換えて,「Deploy」したあと「Test」します。1
Testを押すとテストイベントの設定を求められますが,テスト用に修正した都合上,eventを使用していないので,イベント名だけ入力すれば実行できます。
image.png

message_textに対するBedrockの回答が,Mattermostのchannelに出力されれば,ここまでは動作しています。
image.png

テストした後は,修正した2行を戻して,「Deploy」し直しておきます。

2.6 API Gateway

API GatewayでAPIを作成します。この作成結果をOutgoing Webhookの指定に使用します。
「APIを作成」をクリック。
image.png

APIタイプは「HTTP API」にします。
image.png

「統合」を押して,「Lambda」を選択。
作成したLambda関数を指定します。
「API名」は適切に設定しておきます。
image.png

「メソッド」はPOSTにします。ここでリソースパスを指定した場合は,後ほどCallback URLを指定するときにリソースパスをURLに追加することになります。
image.png

「ステージ名」は$defaultのままで「次へ」。
image.png

確認して作成します。
image.png

表示されているルートの「POST」を選択して,「統合」の「設定」を押します。
image.png

作成したLambda関数が設定されていることを確認。
image.png

左側ペインから,「Deploy / Stages」を選択し,APIを選択すると,「ステージの詳細」に「URLを呼び出す」という項目があります。このURLを控えておきます。Mattermost側でOutgoing Webhookのパラメータ(Callback URLs)として使用します。
image.png

2.7 Mattermost : Outgoing Webhook

Chatbotのアカウントに戻ります。
「Outgoing Webhook」の「Add Outgoing Webhook」をクリック。
image.png

必要な項目を設定していきます。
「Channel」に加えて,「Trigger Words」も設定しておくといいでしょう。
image.png
「Callback URLs」に,API Gatewayから取得したURLを貼り付けます。このとき,パスつきのURLでAPIを設定している場合は,そのパスをURLの後ろに追記しておきましょう。

image.png

「Save」を押すと,「Setup Successful」と表示されます。「Done」を押せば終了です。
image.png

2.8 最終動作確認

Chatbot以外のMattermostアカウントで,Chatbotを有効にしたchannelに入り,Trigger Wordsの後ろに質問を書きます。
10数秒して,結果が返ってくれば完成。
お疲れ様でした。
image.png

まとめ

Amazon Bedrockを使用して,Mattermost上で動作するChatbotを作成しました。
ここまでできれば,あとはAmazon Bedrockの機能を使ってさらに高度な応用に挑戦することができます。

参考

  1. 「イベントJSONにbody書けばコード修正しなくてもいいのでは?」という疑問が沸きますが,Mattermostが送信するリクエストのbodyはBase64encodingされているので,AWS LambdaのイベントJSONに分かりやすく書けません。要調査です。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?