🛏️

AWS Bedrockに入門するーチャットログから過去の問題対処をいい感じにまとめたい

2024/10/02に公開

背景

  • 業務で「これ過去にも対応したけどどうやったっけ」みたいな作業がちょくちょくある
  • チャットにログがあるはずだが、探すのも面倒
  • 過去ログを抽出して要約させ、Wikiみたいな形式でいい感じに過去事例がまとめられたらいいなと思う
  • ちょうどAWSのAI系サービスに入門したかったので、Bedrockを試してみる

将来的にやりたいこと

以下のことがやりたいが、出来るのか?というのを順に試していく

  • チャットアプリから過去ログをエクスポートする
  • 過去ログを適切なトークンサイズに分割する
  • 分割したデータをS3に置く
  • AWS ComprehendでPII(個人識別用情報)をマスキングする
    • この辺はBedrock側で配慮済みとのことで、不要かもしれない?
  • LambdaからBedrockを呼び出し、要約させる
  • 結果をS3に置く
  • Wikiなどのナレッジベースにまとめる

今回試すこと

以下の部分を試す

  • 分割したデータをS3に置く
  • LambdaからBedrockを呼び出し、要約させる
  • 結果をS3に置く

架空のチャットログを作り、手動でS3に置いて検証してみる。

AWS Bedrockとは

https://aws.amazon.com/jp/bedrock/

  • 事前トレーニング済みのモデルを色々選べる
  • RAGのためのナレッジベースを簡単に作れる(今回は使わない)
  • 会議のダイアログを渡して要約するというユースケースがサンプルにあり、今回のと近い

Bedrockを準備

利用したい基盤モデルを選ぶ。今回はAmazon Titan Text G1を選択
最初は無効化されているのでモデルアクセスから有効化する
(AnthropicはClaude3.5 Sonnetが使えなかったのと、有効化しようとすると所属企業の情報を求められて面倒そうだった)

これだけでAPI利用はできるが、プレイグラウンドでコンソールから直接テキストを渡して試すことも可能

S3バケットを作成

以下を作成する

  • 会話ログ用バケット
    • 要約対象のテキストファイルを置く場所
    • イベント通知をオンにし、ファイルがPutされたタイミングで通知する。後で作成するLambdaをターゲットとする
  • 要約結果ファイル用バケット
    • 要約結果のテキストファイルが置かれる場所

Lambdaを作成

会話ログ用バケットからファイルを取得し、Bedrockをinvokeして結果を要約結果ファイル用バケットに置く

ChatGPTに聞きつつ以下を参考に作成
https://docs.aws.amazon.com/ja_jp/code-library/latest/ug/python_3_bedrock-runtime_code_examples.html#amazon_titan_text

会話ログをbodyに入れつつ、前に要約形式を指定するプロンプトをつける

import boto3
import json
import os

s3_client = boto3.client('s3')
bedrock_client = boto3.client('bedrock-runtime', region_name='ap-northeast-1')

def lambda_handler(event, context):
    # S3イベントからバケット名とファイル名を取得
    bucket_name = event['Records'][0]['s3']['bucket']['name']
    file_key = event['Records'][0]['s3']['object']['key']
    
    # S3から会話ログファイルを取得
    s3_response = s3_client.get_object(Bucket=bucket_name, Key=file_key)
    text_data = s3_response['Body'].read().decode('utf-8')
    prompt = '以下のテキストを、「問題:~、対処:~」のような形式で要約してください。'
    
    # Bedrockにテキストを送信して要約を生成
    bedrock_response = bedrock_client.invoke_model(
        modelId='amazon.titan-text-express-v1',
        body=json.dumps({
            'inputText':  prompt + text_data,
            'textGenerationConfig': {
                'maxTokenCount': 500
            }
        })
    )
    
    # Bedrockのレスポンスから要約結果を取得
    response_body = json.loads(bedrock_response.get('body').read())
    output_text = response_body['results'][0]['outputText']
    
    # 要約結果をS3に保存
    output_bucket = 'bedrock-sample-output'
    output_key = f"summaries/{file_key.split('/')[-1].replace('.txt', '_summary.txt')}"
    s3_client.put_object(Bucket=output_bucket, Key=output_key, Body=output_text)
    
    return {
        'statusCode': 200,
        'body': json.dumps('Summary successfully generated and stored.')
    }

Lambdaに付与するRoleに以下権限をつける

  • 会話ログ用バケットに対するGetObject、ListBucket
  • 要約結果ファイル用バケットに対するPutObject
  • BedRockに対するInvokeModel

S3にチャットログを置く

以下の架空の体重管理アプリに障害が発生して対応するチャットログを置いてみる(実際のログを取得できていないので、想像でいいねなどのリアクション部分を入れてある)

山田 12:15
@suzuki
ユーザから問い合わせが来ていて、ユーザ画面から体重推移画面を表示しようとするとエラーになるようです。
ユーザIDは12345です。
調査をお願いできますか?

鈴木 12:17
@yamada
確認します。
1 いいね

山田 12:17
よろしくお願いします。

鈴木 13:22
@suzuki
こちらの件ですが、BACKEND-SYSTEM-1のログを確認したところ
最初のプロフィール設定時に身長をcmで入力する部分が1.75と入力されており、BMIが大きすぎてエラーになるようです。
user-profileテーブルのデータを直接修正する必要があります。
1 いいね

山田13:25
ありがとうございます。175に修正する必要がありますね。修正はDBチームに依頼します。
1 いいね

ここから
「体重推移画面に問題が起きた」
「BACKEND-SYSTEM-1のログを見た」
「user-profileテーブルのデータを直接修正した」
みたいな部分が抜き出せていれば良さそう。

ファイルを置いて10秒経たないぐらいで、以下の結果ファイルが置かれた

問題:ユーザ画面から体重推移画面を表示しようとするとエラーになる。
対処:BACKEND-SYSTEM-1のログを確認したところ最初のプロフィール設定時に身長をcmで入力する部分が1.75と入力されており、BMIが大きすぎてエラーになる。user-profileテーブルのデータを直接修正する必要があります。修正はDBチームに依頼します。

重要な情報が少ないので普通に要約すればこうなるだろう、という感じではあるが、とりあえずそれらしい結果を得ることが出来た。

感想

実データに使えるかはまだ全然わからないが、作るのが簡単だったのと、プレイグラウンドでとりあえず要約だけ試すことも出来るので入門が手軽で良かった。
他のモデルに変更するのも、ちょっとしたLambdaの変更で済みそう。
次は実データを入手してそもそもリクエストの最大長以下に分割できるのか、他のモデルはどうか、みたいなところからスタートしたい。

Discussion