Ruby × Amazon Bedrock  × Claude 3 Sonnet

# はじめに
Bedrockを利用した機能の検証を行う必要があったため、備忘録として残しておこうと思い書いています。
とある個人間中古車プラットフォームでユーザーの投稿内容が規約に違反していないかをチェックしたいという要件をビジネス部門から受けました。
そのため、生成AIを利用し、チェックを行う、あわよくばマスキングしてもらおうと思い検証しました。
Bedrockを利用する理由は以下のとおりです。
- すでにAWSを利用しているため、すぐに使えること
- 使った分だけの費用であること （会社でOpenAIなどの個別の契約がなく、新規で固定費をかけたくなかった）
- Claude3の評判が良い

チェックしたい情報は以下です。
- 電話番号やメールアドレスなどの直接コンタクトが取れるような情報
- コンプライアンス上望ましくない言葉

# まずは、BedrockをRubyから呼び出す
モデルの呼び出しまでについては以下を参考にしました。
https://www.xmisao.com/2024/04/27/invoke-claude3-opus-from-ruby-aws-sdk.html

なお、利用するモデルは `Claude 3 Sonnet` のため、`model_id`は`anthropic.claude-3-sonnet-20240229-v1:0`です。

# コード
コードは下記を用意しました。
```
def replace_incorrect_strings(comment)
      payload = {
        system: PROMPT_AGAINST_RULE,
        messages: [
          {
            role: "user",
            content: [
              {
                type: "text",
                text: comment
              }
            ]
          }
        ],
        max_tokens: 1000,
        anthropic_version: "bedrock-2023-05-31"
      }
      body = payload.to_json
      resp = bedrock_client.invoke_model({
                                           model_id: CLAUDE3_SONNET,
                                           content_type: "application/json",
                                           body: body
                                         })
      resp_body = resp.body.read
      resp_json = JSON.parse(resp_body)
      resp_json["content"][0]["text"]
    end
```

システムプロンプトは以下です
```
あたなのタスクは入力されたに対して、電話番号やメールアドレスなどの個人情報、値段の交渉に関すること、日にちや時間の情報、コンプライアンス上望ましくない言葉、ECサイト名の情報が含まれているかチェックし、条件に合致する部分はマスク文字「〇〇〇」に置き換え返すことです。
な「値段の交渉」の例は「XX円にできないでしょうか、値下げできないでしょうか、価格交渉可能でしょうか、金額の交渉可能です、相談可能です、値引きします、べんきょう」などです。
「ECサイト名」の例は「ジモティ、メルカリ、ヤフオク、カババ、ガリバーフリマ、楽天、オークション」です。
返信する文章には余計な文章を追加しないでください。
```
ユーザープロンプトにはマスク処理を行いたい文章を渡します。
以下はユーザープロンプトの例です。
```
ご覧いただきありがとうございます。
平成30年式スズキワゴンRの出品になります。
目立つ傷や凹みはございません。エンジン音ですが静かで異音などもございません。内装も綺麗です。暖房エアコンも問題なく動きます。その他質問がございましたら気軽にコメントください。

◎ 車名　　　　スズキワゴンR
◎ 駆動式　　　二駆
◎ グレード　　FX
◎ 走行距離　　100000キロ
◎ 車検　　　　なし
◎ 年式　　　　平成30年式
◎ 色　　　　　黒

設備⇩

◎ AC
◎ CD
◎ ラジオ
◎ 暖房
◎ タイミングチェーン
◎ パワーステアリング　
◎ パワーウィンドウ
◎ サイドミラー自動収納

注意事項

全国陸送可です。
中古車ですので現車確認必ずお願いします。また購入後トラブル防止のため免許証のコピーをいただきます。名義変更までに3万円を預かります。名義変更次第お返しします。

電話番号：080-1111-2222

メールアドレス：example@example.com
```
結果
```
ご覧いただきありがとうございます。
平成30年式スズキワゴンRの出品になります。
目立つ傷や凹みはございません。エンジン音ですが静かで異音などもございません。内装も綺麗です。暖房エアコンも問題なく動きます。その他質問がございましたら気軽にコメントください。
◎ 車名　　　　スズキワゴンR
◎ 駆動式　　　二駆
◎ グレード　　FX
◎ 走行距離　　100000キロ
◎ 車検　　　　なし
◎ 年式　　　　平成30年式
◎ 色　　　　　黒
設備⇩
◎ AC
◎ CD
◎ ラジオ
◎ 暖房
◎ タイミングチェーン
◎ パワーステアリング　
◎ パワーウィンドウ
◎ サイドミラー自動収納
注意事項⇩
全国陸送可です。
中古車ですので現車確認必ずお願いします。また購入後トラブル防止のため免許証のコピーをいただきます。名義変更までに3万円を預かります。名義変更次第お返しします。
電話番号：〇〇〇-〇〇〇〇-〇〇〇〇
メールアドレス：〇〇〇〇〇〇〇@〇〇〇〇〇〇〇.〇〇〇
```

す、すごい。。。

# （詰まったこと） x-rayを利用しているとBedrockがnewできない？
動作確認をしようと思って `rails c` 'Aws::BedrockRuntime::Client.new' をしようとした時、
```
irb(main):007:0> Aws::BedrockRuntime::Client.new
Traceback (most recent call last):
        1: from (irb):7:in `<main>'
ArgumentError (invalid configuration option `:xray_recorder')
```
というエラーが発生しました。確かに、x-rayは有効にしており、x-rayを無効に（`aws_xray.rb`をコメントアウトすると）エラーは起きませんでした。ただ、 rails s では問題は起きず、Fargate上で動かしても動作していました。理由までは追えてませんが、分かり次第追記しようと思います。

# まとめ
色々試してみた結果、いくつか問題もありましたが概ね良い結果になりました。
実際にプロダクションに入れるかはまだ様子を見る予定ですが、有用であることが分かったのはよかったです。


# 参考
https://www.xmisao.com/2024/04/27/invoke-claude3-opus-from-ruby-aws-sdk.html