育休を4ヶ月取っていた吉川@広島です。9月に復帰しました。
Amazon Bedrock が一般利用可能に – 基盤モデルを利用した生成系 AI アプリケーションの構築とスケール | Amazon Web Services ブログ
GAされたAmazon BedrockをAWS SDK for JS v3+TypeScriptから使ってみました。
環境
- node 20.5.1
- typescript 5.2.2
- @aws-sdk/client-bedrock-runtime 3.422.1
- esbuild 0.19.4
- esbuild-register" 3.5.0
AI21 Labs
早速ですが、まずAI21 Labsを試してみます。こちらはイスラエルのAI企業みたいです。テキスト生成ができるようなので言葉を投げてみます。
コード
// main.ts
import { BedrockRuntime } from "@aws-sdk/client-bedrock-runtime";
const client = new BedrockRuntime({ region: "us-east-1" });
const main = async () => {
const res = await client.invokeModel({
// Model IDsを参照 https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids-arns.html
modelId: "ai21.j2-ultra-v1",
body: JSON.stringify({
prompt: "Knock, knock!",
maxTokens: 200,
temperature: 0.7,
topP: 1,
}),
accept: "application/json",
contentType: "application/json",
});
const body = JSON.parse(Buffer.from(res.body).toString("utf-8"));
console.log(body.completions[0].data.text.trim());
};
main();
const res = await client.invokeModel({
// Model IDsを参照 https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids-arns.html
modelId: "ai21.j2-ultra-v1",
body: JSON.stringify({
prompt: "Knock, knock!",
maxTokens: 200,
temperature: 0.7,
topP: 1,
}),
accept: "application/json",
contentType: "application/json",
});
v2互換スタイルで書いてみました(v3スタイルはバンドルサイズの優位性があるんでしょうが、どうしてもこっちを使う癖が抜けず)。v3スタイルの場合は
import { BedrockRuntimeClient, InvokeModelCommand } from "@aws-sdk/client-bedrock-runtime";
const client = new BedrockRuntimeClient({ region: "us-east-1" });
const main = async () => {
const res = await client.send(new InvokeModelCommand({/* 省略... */}))
// 省略...
のようになるでしょう。
実行
esbuild-registerでビルド+実行します。
node -r esbuild-register main.ts
# 以下出力:
# Who's there?
# Boo
# Boo who?
# Don't cry, it's just a joke!
Stability AI
続いてStability AIを試してみます。こちらは画像生成ができます。
コード
// main.ts
import { BedrockRuntime } from "@aws-sdk/client-bedrock-runtime";
import { writeFileSync } from "fs";
const client = new BedrockRuntime({ region: "us-east-1" });
const main = async () => {
const res = await client.invokeModel({
// Model IDsを参照 https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids-arns.html
modelId: "stability.stable-diffusion-xl-v0",
body: JSON.stringify({
text_prompts: [
{
// プロンプト
text: "crazy mad gorilla",
},
],
cfg_scale: 10,
seed: 20,
steps: 50,
}),
accept: "application/json",
contentType: "application/json",
});
const body = JSON.parse(Buffer.from(res.body).toString("utf-8"));
if (body.result !== "success") {
throw new Error("Failed to invoke model");
}
writeFileSync("./out.png", body.artifacts[0].base64, { encoding: "base64" });
};
実行
同じように実行します。
node -r esbuild-register main.ts
./out.png
に画像が出力されます。
今回はこんな出力でした。
なかなかイケてますね(?)
感想
ということで楽しく遊べそうな雰囲気でした。AWSアカウントが1つあれば色々な会社のAI製品のAPIを叩けるのが良いですね。
少し気になったのは、SDKなのに .invokeModel()
に渡す引数がfetch APIやAxiosを使う場合と同じ程度の型安全性しかないように見える点です。accept
や contentType
まで指定するので通信処理を隠蔽できていない感があります。
これはおそらく使いたいAI製品によって入出力のフォーマットが全く違うからだと思いますが、ユニオンやジェネリクスを活用したり、使うAIによってメソッドを変えるなどで型付けできそうな気はします。このあたりをより良くするために @aws-sdk/client-bedrock-runtime
をラップするOSSとか作ってみると面白いかもしれませんね。もしくは公式からラッパーが出るかも?
以上、参考になれば幸いです。