どうもこんにちは。
今回はRailsアプリケーションからAmazon BedrockをAPIで接続してみたので紹介します。
Amazon Bedrockって何?
公式ページから引用すると、、、
Amazon Bedrockは、主要なAIスタートアップとAmazonが提供するFMをAPI経由で利用可能にするフルマネージドサービスであるため、幅広いFMから自分のユースケースに最適なモデルを選ぶことができる。Bedrockのサーバーレス・エクスペリエンスを利用すれば、インフラを管理することなく、AWSツールを使ってFMをアプリケーションに簡単に統合し、デプロイすることができます。
ものすごく簡単にいうと、「すでに存在している基盤モデルを使用して生成系AIアプリケーションを構築できるサービス」です。
使用方法
使用方法は、RailsサーバーからAPIを叩くだけです。
ただ、AWSコンソール上で言語モデルを使用するための設定をする必要があるので、以下のサイトを参考に設定をしてみてください。
今回使用したモデルは「Amazon Titan Embeddings G1 - Text」というモデルです。
このモデルは、チャットGPTのような会話はできないが、入力された文字列を数値化してくれるモデルのようです。公式の説明によると、数値ひとつひとつに意味が設定されているとかされていないとか。。。(私は実際に動かしてみるまで数値化ってどういうこと?と思ってやってました。)
実装
0. AWSコンソール上で必要な設定を行う
この時に、自分のアカウントのアクセスキーとシークレットアクセスキーを入手しておいてください。
1. Gemで必要なライブラリを追加する
Gemfileに以下を記述します。
gem 'aws-sdk-bedrockruntime'
aws-sdk-bedrock
というGemを入れると、モデルとのやり取りというよりもモデルのチューニングなどを行うことができるようになるようです。
2. bundle install
みなさんお馴染みのbundle install
をします。
$ bundle install
3. 処理を書く
処理は自分の入れたいところに入れてもらってOKです。
自分は、Railsアプリケーション内のコメント機能でコメントが入力された時に言語モデルにリクエストを投げたいので、コメントが作成される処理に入れ込みます。
先に自分が実装したコードを示します。
comment = 'これはテストコメントです。'
access_key = 'XXXXXXXXXXXXX' # アクセスキー
secret_access_key = 'YYYYYYYYYYYYYYYYYY' # シークレットアクセスキー
begin
credentials = Aws::Credentials.new(access_key, secret_access_key)
bedrock_client = Aws::BedrockRuntime::Client.new(region: 'ap-northeast-1', credentials: credentials)
data = {
"inputText": "次の文章を英語に翻訳してください。「#{comment}」"
}
body = data.to_json
response = bedrock_client.invoke_model({
accept: "*/*",
content_type: "application/json",
body: body,
model_id: "amazon.titan-embed-text-v1",
})
string_io_object = response.body
string_io_object.rewind
string_io_object.each_line do |line|
puts line
end
rescue => e
p e.class
p e.message
p e.backtrace
end
まず、Aws::BedrockRuntime::Client.new
でBedrockのインスタンスを作成します。
次に、以下の形式でリクエストを投げられるようにコードを書きます。
{
accept: "*/*",
content_type: "application/json",
body: {
"inputText": "テキスト"
},
model_id: "amazon.titan-embed-text-v1",
}
ただ、このまま「テキスト」のところに文字列を入力すると、「"expected params[:body] to be a String or IO like object that supports read, rewind, and size, got class Hash instead."
」とエラーが出て怒られてしまうので、bodyの値はString
型に直してからリクエストを投げるようにした方が良いと思います。
次に、invoke_model
メソッドでリクエストを投げます。response変数でBedrockから返ってきたデータを格納します。
response = bedrock_client.invoke_model({
accept: "*/*",
content_type: "application/json",
body: body,
model_id: "amazon.titan-embed-text-v1",
})
次にレスポンスを見たいわけですが、response.bodyの中身はStringIO
クラスになっているのでちょっと工夫が必要です。
string_io_object = response.body
string_io_object.rewind
string_io_object.each_line do |line|
puts line
end
上記コードのように、StringIOクラスのメソッドを使用して中身を出力します。
4. 処理結果
そうすると以下のような結果が出ました。
{"embedding":[0.8203125,-0.11425781,-0.10498047,-0.036376953,-0.390625,0.1953125,-0.11621094,1.2207031E-4,0.25,-0.18554688,-0.095214844,-0.35742188,0.3046875,0.4765625,-0.58203125,-0.3515625,0.30273438,0.15917969,-0.41992188,0.1015625,-0.37109375,0.4765625,-0.515625,0.55859375,0.43359375,0.7421875,0.36914062,-1.0390625,-0.016845703,0.27929688,-0.5859375,1.1328125,0.24414062,-0.65234375,0.28125,-0.16503906,-0.203125,0.19335938,0.052001953,0.20996094,-0.39257812,0.24023438,0.04321289,0.095214844,0.31640625,0.123046875,0.49609375,-0.24804688,0.6640625,0.57421875,0.28515625,0.80859375,-0.3359375,-0.011413574,0.23632812,0.671875,-0.3828125,-0.46289062,0.5859375,-0.037109375,-0.50390625,-0.025390625,-0.33007812,0.045166016,0.029785156,0.18652344,0.19042969,-0.43945312,-0.4375,0.3984375,-0.2578125,-0.26171875,0.625,0.118652344,-0.107910156,0.34570312,-0.44921875,-0.24609375,-0.075683594,0.031982422,-0.43945312,0.092285156,-0.43359375,-0.12451172,-0.59375,-0.1796875,-0.34179688,0.30664062,......]}
これが、「Amazon Titan Embeddings G1 - Text」というモデルで出力される結果のようです。
まとめ
今回はrailsでAmazon Bedrockを使用する方法をまとめました。
他のモデルでも実装してより良いアプリになると良い〜
Embeddingsモデルでも何か使い道がないか考えてみようと思います。
以上