AppSync の Bedrock 統合 (Bedrock 専用リゾルバーを利用した統合) を試してみる
こんにちは。クラウド事業本部の枡川です。
昨年末に AppSync が Amazon Bedrock 統合をサポートしました。
「AppSync から Bedrock を呼び出すなんて大分前からやってますよ?どこが新しいの??」と思う方もいるかもしれません。
ここで Bedrock 統合と呼ばれているのは HTTP リゾルバーや、Lambda リゾルバーを経由しない、Bedrock 専用の連携方法になります。
10 秒以内の同期呼び出しという条件はつきますが、HTTP リゾルバーより簡単な、より統一化されたやり方で Bedrock の呼び出しを行うことができます。
実行時間が長い呼び出しの場合、お客様は引き続き AWS Lambda 関数をイベントモードで使用して Bedrock モデルとやり取りし、サブスクリプションを介してクライアントに段階的な更新を送信できます。
Whats'n New にも記載されてますが、Lambda などを非同期で呼び出して、ストリーム API の結果を段階的にサブスクリプション経由で返すようなユースケースの代わりにはならないので、注意が必要です。
やってみる
ではさっそく試してみます。
今回は AppSync から Bedrock 統合を利用して Claude 3.5 Sonnet を呼び出してみます。
まず、GraphQL API を作成します。
「Design from scratch」を選択します。
Private API を有効化しても良いですが、今回はやりません。
諸々後から設定するので、とりあえず作成しちゃいます。
続いて、データソースを作成します。
データソースタイプとして、AMAZON_BEDROCK_RUNTIME
が選択できるので、こちらを選択します。
IAM ロールを新規作成でき、ここで選択したモデルへの InvokeModel
アクセスを許可した IAM ロールが作成され、アタッチされます。
今回はこんな感じで作れられました。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["bedrock:InvokeModel"],
"Resource": [
"arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0"
]
}
]
}
スキーマは下記のようにしました。
type SentimentResult {
sentiment: String!
score: Float!
summary: String
}
type Query {
analyzeSentiment(text: String!): SentimentResult
}
文章を投げるとサマリつつ、positive な文章か negative な文章かを判定してくれる感じです。
Amazon Comprehend で似たようなことができそうですが、あくまで検証用なので多めに見て下さい。
リゾルバーの設定に移ります。
ユニットリゾルバーで、リゾルバーランタイムは APPSYNC_JS
とします。
リゾルバーコードを書いていきます。
InvokeModel API と Converse API が使えるようですが、とりあえず InvokeModel API を利用します。
モデル ID を指定しつつ、各モデル特有の形式で body に情報を渡します。
type BedrockInvokeModelRequest = {
operation: 'InvokeModel';
modelId: string;
body: any;
guardrailIdentifier?: string;
guardrailVersion?: string;
guardrailTrace?: string;
}
今回作成したリゾルバーコードは下記です。
Bedrock 側の Usage を見れば、サクッと書けますね。
import { util } from '@aws-appsync/utils';
import { invokeModel } from '@aws-appsync/utils/ai';
export function request(ctx) {
return invokeModel({
modelId: 'anthropic.claude-3-5-sonnet-20240620-v1:0',
body: {
anthropic_version: "bedrock-2023-05-31",
max_tokens: 200,
messages: [
{
role: "user",
content: [
{
type: "text",
text: `このテキストの感情分析を行い、JSONで回答してください。JSONにはsentiment(POSITIVE、NEGATIVE、またはNEUTRAL)、score(確度を0〜1の範囲で指定)、summary(テキストの要約)を含めて下さい: "${ctx.args.text}"`
}
]
}
]
}
});
}
export function response(ctx) {
const responseText = ctx.result.content[0].text;
const parsed = JSON.parse(responseText);
return {
sentiment: parsed.sentiment,
score: parsed.score,
summary: parsed.summary
};
}
では、クエリを投げてみます。
query {
analyzeSentiment(text: "今日気分が最高じゃないやついねぇよな!?") {
sentiment
score
summary
}
}
ちゃんと POSITIVE で返ってきました!
最後に
AppSync の Bedrock 統合を試してみました。
同期呼び出しでサクッと回答が返ってくるようなユースケースで、Cognito 認証を簡単につけたりできて良さそうです!