Amazon Bedrockに接続して生成AIのユースケースを実現する
Amazon Bedrockは、生成AI開発のための基盤モデル(FM)の使用の複雑さを排除する完全に管理されたサービスです。Anthropic、AI21 Labs、Cohere、Amazonなどの大手AI企業から厳選された高性能なFMを提供する、中央集約的なハブとして機能します。
Amazon Bedrockは、以下を提供することで生成AI開発を簡素化します:
-
選択肢と柔軟性: さまざまなFMを試験・評価して、ユースケースに最適なものを見つけます。
-
統合の簡素化: 単一の統一されたAPIを通じてFMにアクセスして使用でき、開発時間を短縮します。
-
セキュリティとプライバシーの強化: データを保護し、悪用を防ぐための組み込みセーフガードの恩恵を受けます。
-
責任あるAI機能: 出力を制御し、バイアスを軽減するためのガードレールを実装します。
以下のセクションでは、Amazon BedrockをデータソースとしてAPIに追加し、Amplifyアプリから接続するためのステップを説明します:
- Amazon Bedrockをデータソースとして追加する
- カスタムクエリを定義する
- カスタムビジネスロジックハンドラーコードを構成する
- カスタムクエリを呼び出して生成AIモデルにプロンプトを送る
ステップ1 - Amazon Bedrockをデータソースとして追加する
Amazon Bedrockにデータソースとして接続するには、Lambda関数またはAppSync JavaScriptリゾルバーを使用したカスタムリゾルバーの2つの方法から選択できます。以下のステップは両方の方法を示しています:
amplify/backend.tsファイルで、以下のコードでコンテンツを置き換えて、バックエンドにLambda関数を追加し、Amazon Bedrockの生成AIモデルを呼び出す権限を付与します。generateHaikuFunction Lambda関数は、次のステップでamplify/data/resource.tsファイルで定義・エクスポートされます:
import { defineBackend } from "@aws-amplify/backend";import { auth } from "./auth/resource";import { data, MODEL_ID, generateHaikuFunction } from "./data/resource";import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
export const backend = defineBackend({ auth, data, generateHaikuFunction,});
backend.generateHaikuFunction.resources.lambda.addToRolePolicy( new PolicyStatement({ effect: Effect.ALLOW, actions: ["bedrock:InvokeModel"], resources: [ `arn:aws:bedrock:*::foundation-model/${MODEL_ID}`, ], }));amplify/backend.tsファイルで、以下のコードでコンテンツを置き換えて、APIにAmazon Bedrockの HTTPデータソースを追加し、生成AIモデルを呼び出す権限を付与します:
import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";import { defineBackend } from "@aws-amplify/backend";import { auth } from "./auth/resource";import { data } from "./data/resource";
export const backend = defineBackend({ auth, data,});
const MODEL_ID = "anthropic.claude-3-haiku-20240307-v1:0";
const bedrockDataSource = backend.data.addHttpDataSource( "BedrockDataSource", "https://bedrock-runtime.us-east-1.amazonaws.com", { authorizationConfig: { signingRegion: backend.data.stack.region, signingServiceName: "bedrock", }, });
bedrockDataSource.grantPrincipal.addToPrincipalPolicy( new PolicyStatement({ effect: Effect.ALLOW, actions: ["bedrock:InvokeModel"], resources: [ `arn:aws:bedrock:${backend.data.stack.region}::foundation-model/${MODEL_ID}`, ], }));
backend.data.resources.cfnResources.cfnGraphqlApi.environmentVariables = { MODEL_ID}このガイドの目的上、Anthropicの Claude 3 Haikuを使用してコンテンツを生成します。異なるモデルを使用する場合は、Amazon BedrockドキュメントのモデルIDのリストまたはAmazon Bedrockコンソールで選択したモデルのIDを見つけ、MODEL_IDの値を置き換えることができます。
ステップ2 - カスタムクエリを定義する
次に、amplify/data/resource.tsファイルの内容を以下のコードで置き換えます。これにより、前のステップでAmazon Bedrockの生成AIモデルを呼び出す権限が付与されたLambda関数を定義・エクスポートします。a.handler.function()モディファイアを使用して、generateHaikuFunctionをハンドラーとして、generateHaikuという名前のカスタムクエリがスキーマに追加されます:
import { type ClientSchema, a, defineData, defineFunction,} from "@aws-amplify/backend";
export const MODEL_ID = "anthropic.claude-3-haiku-20240307-v1:0";
export const generateHaikuFunction = defineFunction({ entry: "./generateHaiku.ts", environment: { MODEL_ID, },});
const schema = a.schema({ generateHaiku: a .query() .arguments({ prompt: a.string().required() }) .returns(a.string()) .authorization((allow) => [allow.publicApiKey()]) .handler(a.handler.function(generateHaikuFunction)),});
export type Schema = ClientSchema<typeof schema>;
export const data = defineData({ schema, authorizationModes: { defaultAuthorizationMode: "apiKey", apiKeyAuthorizationMode: { expiresInDays: 30, }, },});Amazon Bedrockがデータソースとして追加されたため、データソースの名前とリゾルバーのエントリーポイントを受け入れるa.handler.custom()モディファイアを使用して、カスタムクエリでそれを参照できます。amplify/data/resource.tsファイルの内容を以下のコードで置き換えて、スキーマでgenerateHaikuという名前のカスタムクエリを定義します:
import { type ClientSchema, a, defineData } from "@aws-amplify/backend";
const schema = a.schema({ generateHaiku: a .query() .arguments({ prompt: a.string().required() }) .returns(a.string()) .authorization((allow) => [allow.publicApiKey()]) .handler( a.handler.custom({ dataSource: "BedrockDataSource", entry: "./generateHaiku.js", }) ),});
export type Schema = ClientSchema<typeof schema>;
export const data = defineData({ schema, authorizationModes: { defaultAuthorizationMode: "apiKey", apiKeyAuthorizationMode: { expiresInDays: 30, }, },});ステップ3 - カスタムビジネスロジックハンドラーコードを構成する
次に、amplify/dataフォルダにgenerateHaiku.tsファイルを作成し、以下のコードを使用して、前のステップでスキーマに追加されたカスタムクエリのカスタムリゾルバーを定義します:
以下のコードは、@aws-sdk/client-bedrock-runtimeパッケージのBedrockRuntimeClientを使用して、Amazon Bedrockの生成AIモデルを呼び出します。handler関数はユーザープロンプトを引数として受け取り、モデルを呼び出し、生成された俳句を返します。
import type { Schema } from "./resource";import { BedrockRuntimeClient, InvokeModelCommand, InvokeModelCommandInput,} from "@aws-sdk/client-bedrock-runtime";
// initialize bedrock runtime clientconst client = new BedrockRuntimeClient();
export const handler: Schema["generateHaiku"]["functionHandler"] = async ( event, context) => { // User prompt const prompt = event.arguments.prompt;
// Invoke model const input = { modelId: process.env.MODEL_ID, contentType: "application/json", accept: "application/json", body: JSON.stringify({ anthropic_version: "bedrock-2023-05-31", system: "You are a an expert at crafting a haiku. You are able to craft a haiku out of anything and therefore answer only in haiku.", messages: [ { role: "user", content: [ { type: "text", text: prompt, }, ], }, ], max_tokens: 1000, temperature: 0.5, }), } as InvokeModelCommandInput;
const command = new InvokeModelCommand(input);
const response = await client.send(command);
// Parse the response and return the generated haiku const data = JSON.parse(Buffer.from(response.body).toString());
return data.content[0].text;};次に、amplify/dataフォルダにgenerateHaiku.jsファイルを作成し、以下のコードを使用して、前のステップでスキーマに追加されたカスタムクエリのカスタムリゾルバーを定義します:
以下のコードは、Amazon Bedrockの生成AIモデルを呼び出すためのHTTPリクエストを構成するrequest関数を定義します。response関数は応答を解析し、生成された俳句を返します。
export function request(ctx) {
// Define a system prompt to give the model a persona const system = "You are a an expert at crafting a haiku. You are able to craft a haiku out of anything and therefore answer only in haiku.";
const prompt = ctx.args.prompt
// Construct the HTTP request to invoke the generative AI model return { resourcePath: `/model/${ctx.env.MODEL_ID}/invoke`, method: "POST", params: { headers: { "Content-Type": "application/json", }, body: { anthropic_version: "bedrock-2023-05-31", system, messages: [ { role: "user", content: [ { type: "text", text: prompt, }, ], }, ], max_tokens: 1000, temperature: 0.5, }, }, };}
// Parse the response and return the generated haikuexport function response(ctx) { const res = JSON.parse(ctx.result.body); const haiku = res.content[0].text;
return haiku;}上記のコードは、Anthropicの Claude 3 HaikuなどのチャットモデルでサポートされているMessages APIを使用しています。
systemプロンプトは、モデルにペルソナや従うべき指示を与えるために使用され、messages配列はメッセージの履歴を含むことができます。max_tokensパラメーターはモデルが生成できるトークンの最大数を制御し、temperatureパラメーターは生成されたレスポンスのランダム性(創造性)を決定します。
ステップ4 - カスタムクエリを呼び出して生成AIモデルにプロンプトを送る
生成されたDataクライアントから、client.queriesおよびclient.mutations API下ですべてのカスタムクエリとミューテーションを見つけることができます。
以下のカスタムクエリは、与えられたプロンプトに基づいて俳句を作成するよう生成AIモデルにプロンプトを送ります。prompt値を希望するプロンプトテキストまたはユーザー入力で置き換え、以下のようにクエリを呼び出します:
const { data, errors } = await client.queries.generateHaiku({ prompt: "Frank Herbert's Dune",});ユーザー入力に基づいて生成AIモデルに俳句を作成するよう促す簡単なUIの例です:
import type { Schema } from '../../../amplify/data/resource';import { Component } from '@angular/core';import { FormsModule } from '@angular/forms';import { Amplify } from 'aws-amplify';import { generateClient } from 'aws-amplify/api';import outputs from '../../../amplify_outputs.json';
Amplify.configure(outputs);
const client = generateClient<Schema>();
@Component({ selector: 'app-haiku', standalone: true, imports: [FormsModule], template: ` <main class="flex min-h-screen flex-col items-center justify-center p-24 dark:text-white" > <div> <h1 class="text-3xl font-bold text-center mb-4">Haiku Generator</h1> <form class="mb-4 self-center max-w-[500px]" (ngSubmit)="sendPrompt()"> <input class="text-black p-2 w-full" placeholder="Enter a prompt..." name="prompt" [(ngModel)]="prompt" /> </form> <div class="text-center"> <pre>{{ answer }}</pre> </div> </div> </main> `,})export class HaikuComponent { prompt: string = ''; answer: string | null = null;
async sendPrompt() { const { data, errors } = await client.queries.generateHaiku({ prompt: this.prompt, });
if (!errors) { this.answer = data; this.prompt = ''; } else { console.log(errors); } }}まとめ
このガイドでは、AmplifyアプリからAmazon Bedrockに接続する方法を学びました。Bedrockをデータソースとして追加し、カスタムクエリを定義し、カスタムビジネスロジックハンドラーコードを構成し、カスタムクエリを呼び出すことで、アプリケーションで生成AIモデルのパワーを活用できます。
クリーンアップするには、ターミナルでサンドボックスプロセスを終了する際に表示されるプロンプトを受け入れることで、サンドボックスを削除できます。あるいは、AWS Amplifyコンソールを使用してサンドボックス環境を管理・削除することもできます。