コマンドラインからTypeScriptでBedrockを実行する
前提
この記事では、以下の技術を使ってコマンドからBedrockを実行する方法を記述していきます。
- Yarn
- TypeScript
- AWS SDK for JavaScript v3
- AWS Bedrock(Anthropic Claude 3.5 Sonnet v2)
- AWS IAMユーザー(SDK認証用)
なお、この記事ではローカルで挙動確認することを目的としているため、簡易的にIAMユーザーかつBedrockフルアクセスポリシーを用いています。実運用時には適切な権限の設定を推奨します。
またBedrockの利用には基盤モデルへの事前リクエストが必要ですが、本記事では省略します。公式ドキュメントなどをご参照ください。
IAM
今回は既存のIAMユーザに実行権限を追加していきます。
ユーザー更新
- 左メニューで
ユーザー
を押下 - 対象のユーザー名を押下
-
許可
タブの許可を追加
を押下し、展開されたメニューから許可を追加
を押下 - 以下のとおりに設定
- 許可のオプション:
ポリシーを直接アタッチする
- 許可ポリシー:
AmazonBedrockFullAccess
- 許可のオプション:
-
次へ
を押下 -
許可を追加
を押下
アクセスキー発行
IAMユーザのアクセスキーが未発行の場合のみ対応します。
- 左メニューで
ユーザー
を押下 - 対象のユーザー名を押下
-
セキュリティ認証情報
タブ内のアクセスキーを作成
を押下 - 以下のとおりに設定
- ユースケース:
ローカルコード
- 上記のレコメンデーションを理解し、アクセスキーを作成します。:ON
- ユースケース:
-
次へ
を押下 -
アクセスキーを作成
を押下 - 画面上に
アクセスキー
とシークレットアクセスキー
が表示されるので、コピーして控えておく
プロジェクト作成
以降の手順はローカルで実行していきます。
初期設定
まずは空のディレクトリにて、パッケージマネージャとTypeScriptを設定します。今回はyarnを使用しています。
yarn init -y
yarn add typescript ts-node @aws-sdk/client-bedrock-runtime @aws-sdk/client-bedrock dotenv
yarn add --dev @types/node
npx tsc --init
環境変数設定
AWSの接続情報を環境変数から読み込むため、.env
を作成します。
AWS_REGION={AWSリージョン}
IAM_ACCESS_KEY={IAMユーザのアクセスキー}
IAM_SECRET_ACCESS_KEY={IAMユーザのシークレットアクセスキー}
実装上の環境変数呼び出しは、初期設定コマンドで追加したdotenvで行います。
実装
src/index.ts
を作成し、次のように実装していきます。
import {
BedrockRuntimeClient,
InvokeModelCommand,
} from "@aws-sdk/client-bedrock-runtime";
import * as dotenv from "dotenv";
dotenv.config();
const client = new BedrockRuntimeClient({
region: process.env.AWS_REGION,
credentials: {
accessKeyId: process.env.IAM_ACCESS_KEY!,
secretAccessKey: process.env.IAM_SECRET_ACCESS_KEY!,
},
});
const executeScript = async () => {
try {
const command = new InvokeModelCommand({
modelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
body: JSON.stringify({
anthropic_version: "bedrock-2023-05-31",
max_tokens: 1000,
messages: [
{
role: "user",
content: [{ type: "text", text: "こんにちは。" }],
},
],
}),
accept: "application/json",
contentType: "application/json",
});
const res = await client.send(command);
const body = JSON.parse(Buffer.from(res.body).toString("utf-8"));
const outputText = body.content[0].text;
console.log(outputText);
} catch (error) {
console.error("Error executing script:", error);
}
};
executeScript();
Bedrock用のクライアントを作成し、InvokeModel
実行の結果テキストをコンソールに出力して終了します。
基盤モデルによる変更点
InvokeModel
実行時に指定するbody
の構造は、modelId
で指定する基盤モデルによって異なります。
例えば、Titan Text modelsの場合は次のように設定します。レスポンスでテキストが格納されている項目も変更となります。
const command = new InvokeModelCommand({
modelId: "Amazon.titan-text-express-v1",
body: JSON.stringify({
inputText: "こんにちは。",
textGenerationConfig: {
maxTokenCount: 1000,
},
}),
accept: "application/json",
contentType: "application/json",
});
const res = await client.send(command);
const body = JSON.parse(Buffer.from(res.body).toString("utf-8"));
const outputText = body.results[0].outputText;
Claudeの指定形式についてはText Completions APIとMessages APIという2種類があり、v3系が対応しているのはMessages APIのみです。
Text Completions APIを利用する場合、promptに固定文字列が必要となります。
const command = new InvokeModelCommand({
modelId: "anthropic.claude-v2:1",
body: JSON.stringify({
prompt: `Human:こんにちは。 Assistant:`,
max_tokens_to_sample: 1000,
}),
accept: "application/json",
contentType: "application/json",
});
const res = await client.send(command);
const body = JSON.parse(Buffer.from(res.body).toString("utf-8"));
const outputText = body.completion;
コマンド実行
次のコマンドで処理が実行されます。
yarn ts-node src/index.ts
正常終了した場合、以下のような結果が出力されます。
こんにちは!お手伝いできることがありましたらお気軽にお申し付けください。
✨ Done in 3.27s.
NCDC株式会社( ncdc.co.jp/ )のエンジニアチームです。 募集中のエンジニアのポジションや、採用している技術スタックの紹介などはこちら( github.com/ncdcdev/recruitment )をご覧ください! ※エンジニア以外も記事を投稿することがあります
Discussion