🙆
RustでBedrock Modelをたたいてみた。
Amazon Bedrock Advent Calendar 2024 の14日目の記事になります。
なぜ、Rust。Rustのメリットを
実行するための前準備
Cargo.toml
[package]
name = "bedrock-sample"
version = "0.1.0"
edition = "2021"
[dependencies]
aws-config = { version = "1.1.7" ,features = ["behavior-version-latest"]}
aws-sdk-bedrockruntime = "1.21.0"
tokio = { version = "1", features = ["full"] }
serde_json = "1.0.64"
serde = { version = "1.0", features = ["derive"]}
axum = "0.6.0"
Cargo パッケージマネージャー、cargo updateで依存モジュールも含めて更新してくれて便利でした。
HTTP Server
3,000ポートで待ち受けする設定
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
println!("Listening on http://{}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
Routing
async fn app() -> Router {
Router::new()
.route("/", get(handler))
.route("/users", post(get_users))
}
/usersパスでPOSTリクエストされた場合、get_users呼び出されます
BedrockModel リクエストカプセル化
#[derive(Serialize, Deserialize, Debug)]
struct Content {
r#type: String,
text: String
}
#[derive(Serialize, Deserialize, Debug)]
struct Message {
role: String,
content: Vec<Content>
}
#[derive(Serialize, Deserialize, Debug)]
struct Payload {
anthropic_version: String,
max_tokens: u32,
messages: Vec<Message>
}
Contentにcache_controlを付与すれば、Prompt Cachingにもいけると思われます。(申請とおってないので確認できず
Bedrock Request Message
Fundation Modelにリクエストするメッセージを生成します。
async fn create_blob(prompt: &str) -> Blob {
// async fn create_blob(prompt: String) -> Blob {
let payload = Payload {
anthropic_version: "bedrock-2023-05-31".to_string(),
max_tokens: 500,
messages: vec![Message {
role: "user".to_string(),
content: vec![Content {
r#type: "text".to_string(),
text: prompt.to_string()
}]
}]
};
Blob::new(serde_json::to_vec(&payload).unwrap())
}
invoke Model
POSTによる、下記jsonをdataとしてリクエストする実装になります。
{
"user_prompt": "Amazon BedrockとAzureOpenAIのメリットデメリットは?"
}
let user_prompt = match body_json.0.get("user_prompt"){
Some(user_prompt) => user_prompt.as_str().expect("user_prompt should be a string"),
None => panic!("error")
};
println!("{}", user_prompt);
let config = aws_config::load_from_env().await;
let client = aws_sdk_bedrockruntime::Client::new(&config);
let builder = client.invoke_model();
let prompt: &str = user_prompt;
let blob = create_blob(prompt).await;
let output = builder
.model_id("anthropic.claude-3-5-sonnet-20240620-v1:0")
.body(blob)
.content_type("application/json")
.send()
.await;
load_from_envは環境変数のAWS_REGIONをみるようです。
Response
Bedrock Modelからのレスポンスが入っている outputからJSONとしてクライアントに返す。
match output {
Ok(output) => {
let body=String::from_utf8_lossy(&output.body.as_ref());
println!("Success: {:?}", body);
return (
StatusCode::OK,
Json(Body {
Body: body.to_string()
})
)
}
Err(e) => {
println!("Error: {:?}", e);
return (
StatusCode::OK,
Json(Body {
Body: "error".to_string()
})
)
}
動作確認
curl -X POST http://127.0.0.1:3000/users -H "Content-Type: application/json" -d '{"user_prompt": "AWSとAzureの活用ユースケースを教えて"}'
{"Body":"{\"id\":\"msg_bdrk_012zNnvpSBqbbRR2PFoJAHGb\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-3-5-sonnet-20240620\",\"content\":[{\"type\":\"text\",\"text\":\"AWSとAzureは、どちらも幅広いクラウドサービスを提供していますが、それぞれに特徴があり、様々なユースケースで活用されています。以下に、AWSとAzureの一般的な活用ユースケースをいくつか紹介します。\\n\\nAWS (Amazon Web Services) の活用ユースケース:\\n\\n1. ウェブホスティングとコンテンツ配信:\\n - Amazon S3とCloudFrontを使用して、静的ウェブサイトをホストし、コンテンツを高速配信。\\n\\n2. ビッグデータ分析:\\n - Amazon EMR、Redshift、Athenaを使用して大規模なデータ分析を実行。\\n\\n3. サーバーレスアプリケーション:\\n - AWS Lambdaを使用して、イベント駆動型のサーバーレスアプリケーションを構築。\\n\\n4. 機械学習と人工知能:\\n - Amazon SageMakerを使用して、機械学習モデルの開発、トレーニング、デプロイを行う。\\n\\n5. IoTソリューション:\\n - AWS IoT Coreを使用して、IoTデバイスの接続と管理を行う。\\n\\nAzure (Microsoft Azure) の活用ユースケース:\\n\\n1. エンタープライズアプリケーション:\\n - Azure Active DirectoryとAzure ADFSを使用して、企業のID管理とシングルサインオンを実現。\\n\\n2. ハイブリッドクラウド:\\n - Azure Stack HCIを使用して、オンプレミスとクラウドのハイブリッド環境を構築。\\n\\n3. DevOpsとCI/CD:\\n - Azure DevOpsを使用して、ソフ\"}],\"stop_reason\":\"max_tokens\",\"stop_sequence\":null,\"usage\":{\"input_tokens\":25,\"output_tokens\":499}}"}⏎
索引
aws_sdk_bedrockruntime
RustのTokio製WEBフレームワークaxum version 0.5.6 を使ってみた
Discussion