さて、堂々と恥ずかしげもなくAWSのサンプルコードをパクります宣言をしたInfrabbitです。
いいんです、別にプロダクトコードにするわけじゃないし、そもそもただの勉強コラムです。そういうもののためにAWSさんが用意しているコードだと思います。
さて、長ったらしいので元コードはリンク先で見てもらうとして。
ちょっといじります。まあ定型応答じゃ面白くないから、コンソールでチャットしようぜ、というだけの話ですね。で、注意事項ですが、converseのAPIが利用できるのはいくつか限られたFMとなります。
例えばClaude3系列とか、Amazon TitanだとPremiumということになり、ここまででモデルアクセス許可をしたTitan Expressでは実行できません。ついでに言えば、Titan Premiumは東京リージョンにはありません。Claude 3 sonnetもあるんですが、こちらはクロスリージョンインターフェース、というものになります。
適当な説明をすると、クロスリージョンインターフェースは第一のリージョンでの推論に失敗したら別のリージョンで推論実行しますよ、というやつらしいです。推論失敗ってなにかはよくわかりません。リソース不足とかかな。
とりあえず東京リージョンでパラメータ数の少ないClaude 3 haikuで済ませます。Titanとかいろいろ試したい人は北米リージョンでやってください。
Claude 3は最初のモデルアクセス時に会社名とか使用目的とか聞かれますのでまじめに答えましょう。めんどくさい人は北米いってTitan Premiumでも使えばいいと思います。モデルアクセスの許可出しは先の通りなので割愛。
で、コードはこんな感じに。適当にCloud Shell立ち上げて実行しました。
import boto3
from botocore.exceptions import ClientError
def generate_conversation(bedrock_client,
model_id,
system_prompts,
messages):
temperature = 0.5
top_k = 200
inference_config = {"temperature": temperature}
additional_model_fields = {"top_k": top_k}
response = bedrock_client.converse(
modelId=model_id,
messages=messages,
system=system_prompts,
inferenceConfig=inference_config,
additionalModelRequestFields=additional_model_fields
)
token_usage = response['usage']
return response
def main():
model_id = "anthropic.claude-3-haiku-20240307-v1:0"
system_prompts = [{"text": "# あなたはインフラエンジニアです。\n"
"質問者の質問に対して必要であればWebを検索し、回答してください\n"
}]
print(f"system prompt: {system_prompts[0]['text']}")
messages=[]
try:
bedrock_client = boto3.client(service_name='bedrock-runtime')
c = ""
while c != "bye":
c = input("put prompt >>")
prompt = {
"role": "user",
"content": [{"text": c }]
}
messages.append(prompt)
response = generate_conversation(bedrock_client, model_id, system_prompts, messages)
output_message = response['output']['message']
messages.append(output_message)
print(output_message['content'][0]['text'])
except ClientError as err:
message = err.response['Error']['Message']
print(f"A client error occured: {message}")
else:
print(f"Finished generating text with model {model_id}.")
if __name__ == "__main__":
main()
と、ほぼサンプルコードのままですね。コメントとloggingをごっそりそぎ落とし、コンソール上でのチャットが出来る、という感じです。
まあ利便性なんかないので、遊びです。
さて、軽く説明しておくと、system_promptに人格プロンプトとかなんや言われているやつを放り込みます。これはもう毎回送信されます。初期設定がtemperature=0.5なので回答は結構ブレるはずです。
で、入力されたプロンプトをmessageに整形して放り込み、bedrock-runtime apiにconverseで送り付け、帰ってきた応答がoutput_messageに入ってますね。それぞれ、messagesに追記していくことで、履歴情報として残し、messagesも毎回bedrockに送り付けることで、いわゆるメモリ機能、履歴の参照をさせています。
byeでループ抜ける。以上。ほかに言うことなんか何もないですね。
あのクソめんどくさいLLMの組み込みが、たった一つのAWSのAPI投げれれば完結している、というのがわかるかと思います。やろうと思えばAmazon Titan PremiumとClaude 3を口喧嘩させることも容易、というのはコード読めれば想像つくんじゃないでしょうか。generate_conversation呼び出す際にmodel_id入れ替えていけばいいだけですからね。
まあ本当に適当に書いただけなので、Pythonのプロの人たちからは叱られるのが目に見えてはいるんですが、そもそも僕らはLambdaが動けばいい、というレベルの世界で生きているので勘弁してください。へたすりゃめんどくせぇって言ってTry Catchすら省くんですからwww
じゃあ、残りはかるーくBedrockのエージェントやワークフロー、ナレッジベースなんかを見ていきましょうか。