re:Invent 2024: AWS AppSyncでAmazon Bedrockの AI Gateway構築
はじめに
海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!
📖 AWS re:Invent 2024 - Build an AI gateway for Amazon Bedrock with AWS AppSync (FWM310)
この動画では、AWS AppSyncをAI Gatewayとして活用し、Amazon Bedrockと接続する方法について解説しています。AWS AppSyncの認証機能やリアルタイム更新機能を活用することで、Generative AIバックエンドとの安全な接続や長時間実行されるワークロードの処理が可能になります。また、AnthropicのClaude 3.5 SonnetやHaikuなど、目的に応じた最適なLLMの選択方法や、Chain of Thoughtを活用したプロンプト設計のテクニック、レイテンシー改善のためのPrompt Cachingの活用など、LLMを実用的に活用するための具体的な手法が紹介されています。さらに、Amazon Connectと組み合わせたコンタクトセンターでの活用事例など、実践的なユースケースも示されています。
※ 画像をクリックすると、動画中の該当シーンに遷移します。
re:Invent 2024関連の書き起こし記事については、こちらのSpreadsheet に情報をまとめています。合わせてご確認ください!
本編
AWS AppSyncを活用したAI Gatewayの構築:概要と課題
本日はご参加いただき、ありがとうございます。このセッションへようこそ。FWM 310「AWS AppSyncを使用してAmazon Bedrock用のAI Gatewayを構築する方法」についてご説明させていただきます。会場の皆様にとっては意外ではないかもしれませんが、現在、Generative AIは至るところに存在しています。多くのお客様がこの技術を採用し、活用しようとしているのを目にします。お客様がGenerative AIを導入する際、特にアプリケーションをGenerative AIバックエンドに接続する際に、多くの課題に直面しています。そこで本プレゼンテーションでは、AI Gatewayについて、そしてAI GatewayがアプリケーションとGenerative AIバックエンド、そしてAWS Bedrockモデルを接続する際にどのように役立つのかについてお話しします。
私はAWS AppSyncのPrincipal Product ManagerのBrice Pelléです。本日は、AWSのPrincipal ConsultantのSalman Moghalと、AnthropicのApplied AIのCal Ruebにも参加していただいています。 本日のアジェンダでは、主に3つの分野をカバーします。まず、AI GatewayとしてのAWS AppSyncについて、そしてAmazon Bedrockとの接続方法についてお話しします。次に、AWS AppSyncを実際のエンタープライズ統合でAI Gatewayとして活用する方法について詳しく見ていきます。最後に、LLMを活用したアプリケーションを構築する際に直面する一般的な課題について深く掘り下げていきます。
Generative AIの導入における課題とAI Gatewayの必要性
先ほど申し上げたように、状況は急速に変化しており、Generative AIはあらゆる場所に存在しています。しかし、まだ初期段階であり、お客様には多くの疑問があります。お客様は始めたいと考えていますが、AWSに対して「どのモデルを使うべきか?」「どうすれば迅速に進められるか?」「モデルのテストはどうすればいいのか?」「セキュリティはどう扱うべきか?」「データをどう安全に保つか?」といった質問をされています。これらの質問に応えるため、AWSはAmazon Bedrockを構築しました。 Amazon Bedrockは、モデルへの接続方法に関して真のゲームチェンジャーです。モデルへの接続、テスト、アプリケーションの構築、プロンプトのテスト、RAGの構築、そしてAgentへの接続において、最も迅速かつシンプルな方法を提供します。これは、LLMとの接続や対話方法を根本的に変えるものです。
しかし、特にアプリケーションをGenerative AIバックエンドに接続する際には、まだいくつかの課題が残っています。まず一つ目は、バックエンドへの接続そのものです。お客様は、アプリケーションをバックエンドに接続するための柔軟なセキュリティとアクセス制御を必要としています。認証されたユーザーがモデルと対話できるように、必要な認証モードを提供するAPIソリューションが必要です。モデルが知的財産である場合、そのモデルへのアクセスを制御したいと考えます。プロンプトへのアクセスを制御し、確認されたユーザーのみがこれらにアクセスできるようにしたいのです。
また、フロントエンドのアクセスパターンとバックエンドのアクセスパターンを切り離すことも重要です。Generative AIバックエンドへのアクセスに使用する秘密の認証情報をフロントエンドで公開しないようにする必要があります。そして、特定のAPIや特定のアプリケーションに適した認証モードを使用できるようにする必要があります。アプリケーションによって要件が異なる場合があり、それに対応できる必要があります。
2番目に重要なのは、柔軟なリクエスト処理です。Generative AIでは、リクエストは短いものもあれば、長時間実行されるものもあります。モデルに対して同期的なアクセスや同期的な呼び出しを可能にし、さらに長時間実行される処理もサポートできるAPIソリューションが必要です。これらの処理は30秒から5分ほどかかることがあり、それに対応できるAPIが必要です。また、アプリケーションが継続的にデータをポーリングする必要なく、リアルタイムで段階的な更新をアプリケーションに送信できるAPIも必要です。そして、モバイルアプリケーション、Webアプリケーション、IOアプリケーションなど、さまざまなアプリケーションで動作するソリューションが必要です。
最後に、モデル選択に関して柔軟性を持たせることができるソリューションが必要です。アプリケーションを接続できるAPIを提供しながら、同時にモデル、プロンプト、知的財産、ビジネスロジックを保護できるようにする必要があります。そして、APIを変更することなくモデルを入れ替えることができるようにする必要があります。つまり、開発者はGenerativeなバックエンドに接続するための柔軟なAPIソリューションを必要としているのです。
AWS AppSyncのAI Gateway機能と実装方法
ここで、AIゲートウェイとしてのAWS AppSyncの出番です。これらの課題すべてを考慮して、ここ数ヶ月で多くのお客様にとってAppSyncがAIゲートウェイとして進化してきました。その理由はいくつかあります:AppSyncはAmazon Bedrockバックエンドと安全に会話することができ、Subscriptionを通じたネイティブWebSocketによって長時間実行されるワークロードのリアルタイムソリューションを提供し、ユーザーとモデルアクセスを個別に制御でき、GraphQLの組み込み型機能を使用して必要なデータを取得するオブジェクトを作成でき、フロントエンドアプリケーション開発者が自身のペースを保ちながら、モデルを独自のペースで成長させることができるよう、アプリケーションとモデルを分離することができます。
ここで手を挙げていただきたいのですが、GraphQLをご存知の方はどのくらいいらっしゃいますか?素晴らしい、私たちは長い道のりを歩んできました。会場の多くの方がGraphQLをご存知のようです。しかし、GraphQLにあまり詳しくない方のために、少し基本に立ち返らせていただきます。GraphQLはAPIのためのクエリ言語です。APIがどのように動作すべきかを示す、完全に型付けされたドキュメントを指定することができます。クライアントは、REST APIを使用する際に通常見られる複数のリクエストを行うことなく、複数のデータソースにアクセスするリクエストをAPIに対して行うことができます。ここでの重要なポイントは、クライアントが必要なものを正確に指定でき、バックエンドが必要なデータを取得するために必要なデータソースに接続するため、過剰なフェッチを避けることができるということです。
GraphQLは非常に強力で、AppSyncが提供する機能の1つに、Subscriptionによるリアルタイム機能があります。AppSyncでは、GraphQLのSubscription機能を使用して、管理されたWebSocket経由でリアルタイムイベントをアプリケーションに転送することができます。これにより、バックエンドに接続し、回答を得るまでに数分かかる長時間実行アプリケーションを構築する際に、多くの可能性が開かれます。 AppSyncでは、すぐに使える認証タイプが用意されています。複数の認証タイプを使用でき、アプリケーションに適した認証タイプを使用することができます。これらはすべてAppSyncに含まれており、これを実現するために何かを構築する必要はありません。個々のユーザーを認証し、リクエスト全体で彼らのアイデンティティを追跡したい場合はAmazon Cognitoを使用できますし、APIの半公開アクセスパターンには開発時にAPI keyを使用できます。また、多くのお客様が独自のカスタム認証を構築するためにLambda authorizerを選択しています。
バックエンド側では、AppSyncはデータソースを通じてモデルと直接やり取りすることで、Generative AIバックエンドと連携します。AppSyncではAmazon Bedrockと統合データソースを介して連携することができます。Amazon Bedrock runtimeデータソースを作成するか、AWS Lambda関数をオーケストレーターとして使用してモデルを呼び出すことができます。これは特に、応答に時間がかかるオーケストレーションを必要とするアプリケーションを作成する場合に便利です。また、ネイティブのHTTPリゾルバーやHTTPデータソースも使用できます。あまり知られていないかもしれませんが、HTTPデータソースを使用して任意のAWSサービスAPIに接続することができ、これらのデータソースにはそれぞれ独自の認証設定があります。
AppSyncを有効にして、特定のモデルとの対話、特定のプロンプトとのやり取り、特定のガードレールへのアクセスを許可することができます。データソースを設定する際、このようにしてアクセスに関するセキュリティを構築します。AppSyncがBedrockバックエンドとどのように連携するかを指定し、さらにAPI管理者として、ユーザーがAPIとどのように連携できるかを設定できます。これら2つを組み合わせることで、実装しようとしているアプリケーションやユースケースに特化した目的別APIを作成することができます。 AppSyncのもう一つの素晴らしい点は、エンタープライズグレードのセキュリティ機能を提供することです。プライベートAPIなどの機能を使用できます。
現在、多くのお客様が社内のスタッフやユーザー向けのGenerative AIソリューションをプライベートAPIで構築しています。内部VPCからのみアクセス可能なAPIを作成できます。また、 クロスアカウントのGraphQL API機能を使用することで、1つのAWSアカウントでAPIを作成し、組織内の任意のAWSアカウントと共有することができるようになりました。これは、複数のアカウントを使用して責任分離を行う組織にとって非常に便利です。つまり、1つの中央ネットワークアカウントでAPIを作成し、それを組織全体で共有することができます。
AWS AppSyncとAmazon Bedrockの連携:具体的な実装例
先ほど述べたように、AWS AppSyncでAmazon Bedrockバックエンドに接続するのは簡単です。HTTPリゾルバーを使用することも、マイクロ呼び出しのためにAmazon Bedrock runtimeとの新しい統合を使用することもできます。 これは、10秒以下で完了する呼び出しが必要な場合に使用します。Invoke ModelやConverse APIを使用できます。 ここでは、アシスタントクエリを作成するAPIの例を示しています。このアシスタントクエリは、自然言語のクエリを受け取り、Converse APIにリクエストを送信して、その質問に相当するSQLクエリを取得します。そして、タイプをJSONスキーマにマッピングすることができます。
リゾルバーからConverse APIを呼び出す際、これはAWS SDKsで見つかるのと全く同じAPIで、リゾルバーから直接呼び出すことができます。Amazon Bedrockについて知っているすべてを活用できます。これについて私が特に気に入っているのは、ガードレール設定を使用して呼び出しをさらに保護できることです。プロンプトインジェクションから保護したい場合や、Amazon Bedrockが機密情報を返すのを防ぎたい場合は、ガードレールを使用することができます。
私のAssistantにクエリを投げて、Las Vegasに出荷された商品の中で最も売れた商品を教えてもらい、その回答の説明も求めました。ここに表示されているようなシステム構成とデータベーススキーマを与えた場合、このような形式のクエリが返ってきます。返されるクエリが特定の形式になっていることにお気づきでしょう。これは非常に便利で、クライアントに返す際に、クライアント側が何を期待でき、どのように応答を処理すべきかが分かります。すべてのロジックをAPI内に保持できるため、クライアント側で行う作業はほとんどありません。
また、例えばAmazon Titanを呼び出したい場合、Invoke Model APIを使用して要約やキーポイントのリストを作成することができます。 Amazon Titan Embed Textを使用して埋め込みを作成することもできます。これは類似性検索を行うAPIを作成する場合に非常に便利です。例えば、 Pipeline Resolverと組み合わせて使用することができます。最初のステップでAmazon Bedrockを使用して埋め込みを作成し、その埋め込みの結果を使用してAmazon Aurora PostgreSQLデータベース内のデータを検索します。これは非常に簡単で、追加の計算リソースを設定する必要はなく、プロンプトやモデルをクライアントに公開することなく、AWS AppSyncだけで実現できます。
最後に重要なのが非同期のユースケースで、これは長時間実行される処理に使用するケースです。AWS AppSyncをAI Gatewayとして使用する場合、AWS AppSyncのSubscription機能を使って実現できます。この例では、Lambda関数を呼び出しています。ここでのLambda関数は、Amazon Bedrockバックエンドを呼び出すオーケストレーターとして機能します。LambdaがAmazon Bedrockから更新を受け取ると、Mutationを使用してその更新をAWS AppSync APIに送信でき、AWS AppSyncは自動的にそれらの通知を接続されたクライアントに転送します。これにより、通知を受け取るたびにクライアントに段階的な更新を送信することができ、現在、多くのお客様がこのようなパターンを実装しています。
エンタープライズ統合におけるAWS AppSync AI Gatewayの活用事例
この詳細について、私のパートナーであるSalmanをステージにお招きして、AWS AppSync AI Gatewayを使用したエンタープライズ統合についてお話ししてもらいます。皆さん、こんにちは。聞こえていますでしょうか。素晴らしい。私は、エンタープライズのお客様が直面している2つのユースケースについてお話ししたいと思います。1つは大規模言語モデルを使用したコンテンツ分析と、それらのモデルにアクセスするためのゲートウェイとしてのAWS AppSyncの活用についてです。2つ目のユースケースは、Amazon Connectを使用したコンタクトセンターについてです。私はSalman Moghalで、AWS Professional Services Canadaのプリンシパルコンサルタントを務めています。
まず、手を挙げていただきたいのですが、Amazon Connectをご存知の方は何人いらっしゃいますか?素晴らしいですね。このユースケースは皆さんにとって非常に興味深いものになると思います。Amazon Connectには固有の課題があり、8秒の制限を突破するために長時間実行ワークフローをどのように使用したかについてお話しします。昨年からGenerative AIブームが始まって以来、私はエンタープライズのお客様のためにこれらのユースケースの解決に専念してきました。
まず、現代のアプリケーションにおいて、フロントエンドにリアルタイム更新をプッシュする必要がある場合に、非同期パターンが非常に有用な場面についてご説明します。非同期処理は通知機能に最適で、長時間実行されるタスクを処理するベストな方法です。特に生成系AIの機能を使用する場合には、さらに重要性を増します。皆さんもBedrockやチャットのプレイグラウンドを使用した際に、トークンがストリーミングされるのを目にしたことがあると思いますが、その裏側ではBedrock APIが呼び出されているのです。特に興味深い2つのユースケースは、コラボレーティブアプリケーションに関するものです。企業では従業員やドキュメント、バックエンドとのやり取りにこうしたコラボレーティブアプリケーションを使用しており、AWS AppSyncを活用してリアルタイム更新を効率化しています。そして最後に、最も興味深いケースの1つとして最近遭遇したのが、Amazon Connectの活用です。Amazon Connectには様々なペルソナがありますが、カスタマーペルソナで利用できる機能は限られています。このカスタマーペルソナに生成系AI機能をどのように導入したのかについてお話しします。
この特定のスライドについて数分お時間をいただきます。矢印は見えないかもしれませんが、数字に沿ってご説明します。これは非同期アーキテクチャの基本的な側面です。リアルタイム更新を開始する際には、まず一意のセッションIDを使用してサブスクライブする必要があります。セッションIDはフロントエンドで生成することも、重複を管理したい場合はミドルティアで生成することもできます。今回のデモでは、フロントエンドでの生成を選択しました。サブスクライブする際、例えば「モニターの解像度をリセットする方法を教えてください」といったIT関連の質問を入力すると、それがバックエンドに流れ、フロントエンドがクエリを呼び出します。このクエリ操作は同期的で、メッセージをSNSに送信します。これはEventBridgeやデータベース、次の一連の操作をトリガーできる中間的なプレースホルダーであれば何でも構いません。
クエリはすぐにフロントエンドに応答を返し、その時点でUIをどのように表現するかは自由です。デモでどのように実装したかご覧いただけます。トークン生成が始まるまでの間、数秒間、3点ドットのアニメーションを表示することもできます。その後、完全に非同期のバックエンドワークフローが始まり、通常のRAG(Retrieve Augment Generation)ワークフローやエージェントワークフローが実行されます。Amazon Connectのケースでは、プレゼンテーションの後半で、このエージェントワークフローを非同期処理でどのように使用できるかを見ていきます。Bedrockでトークンが生成され始めると、Lambdaは通常のinvoke model APIではなく、response stream APIを使用してモデルを呼び出します。トークンが生成され始めるとすぐに、Lambdaは非同期サブスクリプションに対してサーバーサイドのミューテーションを呼び出し始めます。クロストークを避けるため、トークンの送信先を特定する必要があるので、その一意のセッションIDを使用してサブスクリプションを呼び出す必要があります。ここでこの一意のセッションIDが重要な役割を果たすのです。
次に、最初のユースケースについてお話しします。これは興味深い例で、大企業であれば皆さんも経験したことがある、あるいは今後経験するであろうケースです。通常、企業には顧客とのコミュニケーション方法、従業員とのコミュニケーション方法、そしてメッセージを送信する前の適切なトーン分析を含むコンテンツ生成に関する具体的なガイドラインがあります。
私たちが支援していた顧客が直面していた課題は、これらのコンテンツの編集に多大な時間を費やし、サードパーティのライセンスアプリケーションに多額の費用を支払っていたことでした。BedrockとClaudeモデル(これについては次の講演者が詳しく説明します)を使用して実験を行い、このコンテンツ生成とトーンガイダンス全体を大規模言語モデルで自動化することができました。多くの指示を与える必要があり、プロンプトはより大きくなる可能性がありますが、それが私たちが考案したソリューションです。
コンテンツ分析だけでなく、裏側でRESTとGraphQLの両方を簡単に組み合わせることができました。プロンプト管理システムがあり、これをあらゆるビジネスニーズに対応できるように拡張できます。これが付加価値となり、お客様は大幅なコスト削減を実現できます。しかし、本当の価値は言語の自動分析にありました。言語スコアリングやブランドボイス分析が可能です。コミュニケーションを発信する前に特定のガイドラインに従いたいマーケティング担当者にとって、これは素晴らしいものです。これらはすべて実現可能です。
Amazon ConnectとAI Gatewayの統合:長時間実行ワークフローの実現
Microsoftの生産性アプリケーションを導入しました。GraphQLとAppSyncは非常に汎用性が高く、基本的にどのようなフロントエンドでもAppSyncと組み合わせることができます。ここでのコンセプトは、バックエンドインフラストラクチャは同じで、Bedrockモデルも同じですが、データがMicrosoftアプリケーション、つまり生産性アプリケーションに流れ込むということです。それらが何かについて説明します。Add-inというコンセプトを追加しました。このAdd-inは企業内部でホストされます。セキュリティは独自のセキュリティガードレールを使用し、AppSyncには独自のIdentity Providerを使用して認証と認可を行う機能があります。これについては次のスライドで見ていきます。このAdd-inの素晴らしい点は、すべてのMicrosoft生産性アプリで動作することです。
これを実現する方法について少し説明します。Manifestファイルと呼ばれるものがあり、これはAdd-inのパッケージング構造のようなもので、実際のアプリケーションの場所が裏側のどこにあるかを指定します。シングルページアプリケーションですが、ドキュメントと対話できるように特定のSDKでアプリケーションを作成する必要があります。スプレッドシートやメールと対話でき、ビルトインアシスタントのような役割を果たします。
GraphQLスキーマについて、いくつか説明します。スキーマは非常に基本的なもので、深く掘り下げることはしません。質問がある場合は、後ほど私たちに声をかけてください。核となるのは、Mutation、Query、Subscriptionです。QueryとSubscriptionは、基本アーキテクチャで説明したように、クライアントによって使用されます。Mutationはバックエンドで使用されます。フロントエンドが典型的なフロントエンドではなくOfficeスイートであっても、AppSyncをゲートウェイとして使用してMutationをフロントエンドにプッシュします。ここで強調していない重要な点は、Resolverです。Resolverは特殊なフィルターを使用して、渡されたセッションIDを捕捉し、正しいクライアントにMutationを送信します。クロスワイヤーは避けたいからです。セキュリティの観点から、Resolver内に追加のSubscriptionフィルターを追加できます。これは、ユーザーコンテキストが本人であることを確認したい場合に、誰もが使用する典型的な方法です。通常、これを別のSubscriptionとして追加します。
では、デモに移りましょう。
これはかなり見やすいと思います。 ここにマーケティングチームが作業している典型的なドキュメント、あるいは他の種類のコンテンツがあります。リボンの下には通常このAdd-onがあり、独自のAdd-inを起動することができます。RUTHと呼ばれる理由については、後ほどお話できればと思います。レンダリングされると、要約や言語スコア、ドキュメント分類などができるインターフェースが表示されます。これらはマーケティング特有の、あるいは部門特有の要件で、必要に応じて変更することができます。このように、コンテンツ分析は簡単に行えます。
まず、同期呼び出しのクイックデモをお見せします。これは、ドキュメントの内容を取得し、AppSyncにQueryオペレーションを通じて送信するバックグラウンドでの処理です。ブランドガイドラインに基づいてこのコンテンツをスコアリングする方法を指定するPromptが裏側で拡張されます。Queryオペレーションが実行され、クラウド上の大規模言語モデルが動作して応答を返します。これはServerless環境なので、現時点ではすべてがコールドな状態です。分析結果がリアルタイムで返ってくるのをご覧いただけました。Promptに含まれていたガイドラインによると、このドキュメントには長い文章が多く含まれています。これは要件に応じて変更可能です。また、受動態の使用も見られますが、これも同様に変更可能です。このデモの要点は、AppSyncをゲートウェイとしてコンテンツ分析を行い、さまざまなフロントエンドで利用できることを示すことです。
ここで、できることをいくつか手短にお見せします。先ほど同期呼び出しを見ていただきましたが、今度はSubscriptionのユースケースをお見せして、ドキュメント内でリアルタイム更新がどのように行われるかをご覧いただきます。言語翻訳をやってみましょう。クラウドには複数の言語に翻訳する機能があり、異なる言語間を行き来することもできます。私は中国語を話せませんが、ドキュメント内でハイライトされた部分だけを翻訳してみましょう。 かなり大きなドキュメントですが、翻訳は可能で、ドキュメント内の言語と英語の間を行き来することができます。時間の都合上、他にも多くの機能がありますが、機能デモはここまでとさせていただきます。
これで2番目の、より興味深いケースに移ります。私にとって特に興味深いのは、この特定の課題の分析に多くの時間を費やしたからです。課題は、Amazon Connectに8秒のタイムアウトという変更不可能な厳格な制限があることでした。これには正当な理由があります:電話で待っているお客様を長時間待たせたくないのです。そのため、リアルタイム更新はできるだけ早くユーザーに届く必要があります。Connectで作業する際、Amazon LexやLambdaでタイムアウトが発生することがありました。従来のバックエンドAPIコールは実行に時間がかかりすぎます。課題は、発信者が待機している間にパスワードのリセットやチケットステータスの確認をどのように処理するか、つまり、接続を維持しながら、エンドユーザーにリアルタイムで更新をプッシュする方法でした。
この課題に対する解決策は非常に興味深いものです。リアルタイム更新を利用し、これらのバックエンドワークフローを処理するための再利用可能なSDKを作成しました。この解決策は現在も顧客環境内でクローズドベータ段階にあります。テスターの限定グループ内で平均解決時間が大幅に短縮されました。この解決策により、24時間365日のサポート機能が実現しました。
Amazon Connectは、クラウド上に仮想コンタクトセンターを実装するためのAmazonのソリューションです。エージェントインターフェースにAmazon Qによる生成AIの機能が組み込まれており、エージェント向けに豊富な機能が用意されています。エージェントダッシュボード内では、感情分析やコール分析を実行でき、さらにAmazon Qを使用したRetrieval Augmented Generationも実行できます。管理者はシステムを広範に設定できる一方、スーパーバイザーはQ Insightsなどの機能を通じて分析を行うことができます。
この設計について少し説明させていただきます。一見複雑に見えるかもしれませんが、基本的には先ほど説明した基本設計と同じ考え方に基づいています。図を見ると、ユーザーがサブスクリプションとクエリで対話を開始する際、SNSにメッセージを送る代わりにAmazon Connectに送信しています。Amazon Connectでチャットを開始すると、リアルタイムの更新をSNSトピックを通じて送信するオプションがあります。Connectでデータが利用可能になると、それをSNSトピックにプッシュし、そこからフロントエンドのMutationを呼び出すことができる下部のLambdaに送られます。
興味深い違いは、右上のAmazon Connectフロー内にあります。フローをトリガーすると、Amazon Lexを使用してユーザーの発話や意図を取得するオプションがあります。私たちはLexを、ユーザーの質問や発話の取得のみに使用することにしました。それ以外の目的では使用していません。これが完了すると、Lexを終了し、バックエンドワークフローをトリガーするLambda関数を呼び出します。例えば、誰かがモニターの解像度のリセット方法を尋ねた場合、ナレッジベースから回答を検索したいと考えます。
そのワークフローをトリガーする際、Lambdaはバックエンドワークフローをトリガーするための中間層として、セッションストレージまたは永続的なストレージを必要とします。バックエンドの実行中、このデータベースに更新を送信し、ワークフローからさらに更新が利用可能かどうかを常にチェックするLambda関数があります。これにより、応答を待っている人にリアルタイムでステータス更新を送信することができます。
この実装では、Lambdaがツールを使用して質問やクエリをトリガーするためにAgentic Workflowsを使用してワークフローを実行します。次の講演者が詳しく説明する思考の連鎖ワークフローについて、私たちはモデルに一連のツールを装備しています。このお客様の場合、これらのツールにはパスワードのリセット、ServiceNowチケットの確認、ナレッジベースの検索が含まれます。舞台裏では、お客様独自のナレッジベースにアクセスできる機能をモデルに装備しています。つまり、モデルにそのような機能を持たせているのです。
Claudeの印象的な点は、後ほどご紹介しますが、非常に複雑なクエリを理解できることです。複数の質問を組み合わせることができ、Claudeはバックグラウンドで必要なツールを自動的に判断します。これは実際にはAmazon Bedrock上では実行されておらず、バックグラウンドでLangChainを使用しています。ただし、基本的な考え方はBedrockと同じです。
ここでは多くの時間を割きません。元のものと同じです。ここでは示していない主な違いは、Amazon Connectから返される複雑な構造が若干異なることです。バックグラウンドでは、クエリがあり、フロントエンドで使用されるサブスクリプションがあり、そしてAmazon Connectからレスポンスを取得する際にLambdaが実行するミューテーションがあります。
Connectのフローをご覧になったことがない方もいるかもしれませんが、かなり複雑になることがあります。これが典型的なフローの例です。Amazon Lexを使用してユーザーのインテントを捉えます。そして、フローの中でバックエンドからレスポンスを得るまで、フローは行ったり来たりを繰り返します。バックエンドのレスポンスは、呼び出されたステータスLambdaから来ています。これは常にデータベースをチェックしています:更新はあるか?更新があれば、ユーザーにプッシュバックします。これをスクリーンショットに撮って自分で試してみることもできますが、私たちのデモパブリックに素早く切り替えてみましょう。
これを先ほど見ましたが、これが私たちのインターフェースです。Webアプリケーションを使用していて、現在起きているのは、チャットボットがAmazon Connectとハンドシェイクを行っているところです。そこから返ってくるのは、フローが開始され、「今日はどのようなご用件でしょうか?」という応答です。「パスワードをリセットしてください。私のユーザー名はSM110です」と言ってみましょう。会話履歴を追加して本当の意味で会話的にすることもできますが、私は質問に全てのデータを含めています。もしユーザー名を省略すると、「ユーザー名を教えてください」と聞き返してきます。
現時点では会話履歴は主な焦点ではありません。主な目的は、Amazon Connectと長時間実行ワークフローをどのように接続するかを示すことでした。これらの実行更新は、Connectから直接返されています。ボットが適切なツールを選択する際のバックグラウンドでの思考プロセスも、フロントエンドにストリーミングされます。より興味深い質問をしてみましょう:「パスワードをリセットしてチケットのステータスも確認してください。私のユーザー名はSM20で、チケット番号はABC123です。」すると、Claudeはこの発話を複数ステップのプロセスとして識別し、まずパスワードをリセットし、その後長時間実行ワークフローが進行している間に - もし長時間実行ワークフローがなければ、タイムアウトが発生するところです。
ご覧の通り、Claudeはチケットのステータスを次に確認する必要があると判断し、このツールを使用して、最終的にパスワードのリセットを完了します。そして出力を適切に組み合わせています。ぜひ皆さんも自由に試してみてください。そのスライドに戻って写真を撮っていただきたいのですが、音声デモの電話番号も用意してあります。お気軽にダイヤルしていただければ、バックエンドで動作している生成AIの音声システムと対話することができます。
LLMを活用したシステム構築の課題:モデル選択とプロンプト設計
それでは、これらのAIプロンプトについてより深く掘り下げていきたいと思います。Anthropicのサポートを借りてご説明させていただきます。BriceとSalmanと知り合い、彼らのユースケースについて話し合い、どのように協力できるか検討している中で、これらのシステムを構築する裏側について詳しく聞いていくと、他のお客様でもよく見られる共通のテーマや課題が多くあることに気づきました。そこで、このプレゼンテーションの最後に、LLMを活用したシステムを構築する際に直面する可能性のある5つの一般的な課題についてお話ししたいと思います。私はCal Ruebと申しまして、AnthropicのApplied AIチームのメンバーとして、プレシードのスタートアップからFortune 500の企業まで、Claudeを活用して素晴らしい製品や機能を構築されるお客様のサポートを行っています。
最初に直面する可能性があり、考慮しなければならないのは、世の中には多くのLLMが存在し、毎月新しいものが登場しているということです。自社の製品に使用するLLMをどのように選べばよいのでしょうか?現在、Amazon Bedrockには30以上のテキスト生成LLMが提供されており、Bedrock以外にも検討対象となるLLMが存在します。この選択肢を絞り込むために、パブリックなリーダーボードやベンチマークを参照して、現状を把握することができます。これに関連して一つ事例を共有させていただきたいのですが、現在AnthropicにはClaude 3.5 Sonnetというモデルがあり、多くの人々から世界最高のコーディングモデルと評価されています。しかし、コーディング能力を測定するこれらのベンチマークやリーダーボードの中には、Sonnetが必ずしも上位に位置していないものもあります。そのため、単純にこれらのベンチマークやリーダーボードを見て、上位のものを選択するだけでは、重要な機会を逃す可能性があります。
時として、これらのベンチマークには、皆さんの特定のタスクやデータに関連する微妙なニュアンスが欠けている場合があります。これらを使って選択肢を絞り込むことはできますが、他の方法も併せて検討できます。最初の段階で、価格や応答時間に関して譲れない明確な要件がある場合は、独自にモデル化してベンチマークを行い、いくつかのモデルを候補から除外することができます。そうでない場合は、特に新しい実験的なものを構築し、顧客やステークホルダーに価値を証明したい場合には、利用可能な最高のモデルを使用することをお勧めします。まずは製品市場フィットを確認し、その後、より高速で安価な小規模モデルへの移行は最適化の一環として考えるとよいでしょう。
Anthropicの現状について簡単にご紹介させていただきます。Claudeを活用してシステムを構築する場合に検討すべきモデルとして、まず注目していただきたいのがClaude 3.5 Sonnetです。このモデルには、今年の初夏にリリースされたバージョンと、最近10月にリリースされたバージョンの2つがあります。全体的に性能が向上している10月版をお勧めします。これは現在、私たちが提供している最も知的なモデルで、特にソフトウェアエンジニアリングの分野で優れた性能を発揮します。また、画像を認識して解析する優れた視覚能力も備えています。文章作成などの基本的なLLMタスクもこなせますし、このモデルは私たちが初めてコンピュータの操作機能を実装したもので、人間と同じようにコンピュータを操作することができます。
もう1つ注目すべきモデルはClaude 3 Opusです。このモデルは今年の春にリリースされ、当時は最も強力なモデルでしたが、モデルファミリーを3.5にリフレッシュし始めた今、Claude 3 Opusはまだリフレッシュされていません。そのため、代わりに3.5 Sonnetを使用することをお勧めします。Opusを本番環境で使用しているお客様もいますが、比較的まれなケースです。また、Claude 3.5 Haikuもあります。Haikuのコンセプトは、より大きく強力なモデルの優れた特徴(コーディング能力など)を、より小さく、安価で、高速なモデルにパッケージ化することです。スピードが重要な場合は、Haikuを検討することになります。コーディングは依然として優れていますが、特にリアルタイム性が求められるタスクでは、Haikuが非常に適しています。
次の課題は、モデルまたはモデルセットを手に入れた後、プロンプトも必要になるということです。2025年に向けてのプロンプトについて、私の考えをお話しします。まず第一に、新しいモデルがリリースされるにつれて、モデルはより制御しやすくなる傾向にあり、つまりプロンプトがより直感的でアクセスしやすくなっています。私がAnthropicに入社したとき、Claude 2を使って多くの時間を費やしましたが、プロンプトを何度も調整して有用な結果を得るのに丸一日かかることもありました。今日では、5分程度プロンプトを書くだけで、新しいモデルからかなり良い出力が得られるようになっています。
2025年でも恐らく重要であり続けるであろう、いくつかの「タイムレス」なプロンプト技術があります。私の考えでは、より多くのプロンプトがメタプロンプティングツールと呼ばれるものの助けを借りて作成されるようになるでしょう。今年の初め、Claudeは実際にプロンプトエンジニアリング自体が得意であることに気付き、プロンプトを作成・改善できるシステムを構築しました。もちろん、現在では多くの他の企業も同様のものを作成しています。
依然として重要なプロンプト技術についてお話ししましょう。1つ目は、明確で直接的であるべきということです。お客様との主な作業の1つは、プロンプトを見せていただくことです。私の仕事は通常、プロンプトを読んで、曖昧で分かりにくい、または意味が通じない部分を見つけることです。そして、お客様に「これはどういう意味ですか?」と確認することができます。私に理解できないものは、おそらくモデルにも理解できないでしょう。これを私たちは明確なプロンプトの黄金律と呼んでいます:プロンプトを書くとき、そのプロンプトを、あなたが取り組んでいることを正確に知らない同僚に見せて、「もしこの指示を与えられたら、このタスクを実行できますか?」と尋ねてみてください。もし「はい」と言えば、おそらくモデルもそれを実行できるでしょう。「いいえ」と言われたら、プロンプトをもう少し改善する必要があるかもしれません。
明確で直接的であることに加えて、プロンプトに構造を持たせることも役立ちます。右側に示されているのは少し小さいですが、これは私たちのメタプロンプターから出力された旅行日程に関する簡単な例のプロンプトです。メタプロンプターから出力される構造には、いくつかの特徴があります。まず、冒頭の1〜2文で、非常に高レベルな役割とタスクを示します:「Hey Claude、あなたはAI旅行アシスタントです。あなたのタスクは、ユーザー入力に基づいて、以下の指示に従って旅行日程を出力することです。」次に、動的なコンテンツがある場合、RAGを使用している場合、ヘルプセンターの記事を多数取得している場合は、それを次に配置し、その後に指示を続けます。メタプロンプターは番号付きリストを選択しました。そして、例やChain of Thoughtを使用する場合は、最後にそれらを配置します。私が好むプロンプトのコツの1つは、Claudeが何かを忘れている場合、その指示を最後にもう一度繰り返すことです。これは、Claudeが扱いにくい場合に非常に効果的です。
例の使い方についてお話ししましょう。例を使用することは、おそらくClaudeに望む動作をさせるための最も強力なプロンプト技術です。その理由は、多くのタスクにおいて、良い出力がどのようなものかをClaudeに説明しようとすると多くの指示が必要になりますが、時にはClaudeに直接示す方が簡単だからです。特にスタイルやトーンに関することであれば、本当に良い出力の例を10個ほどClaudeに見せて、Claudeの一般化や推論能力に任せた方が、すべてを書き出そうとするよりもずっと簡単です。プロンプトに例を追加すると、プロンプトのサイズが大きくなり、入力トークンが増えるため、レイテンシーやコストに影響が出ます。ただし、入力トークンは出力トークンよりもかなり安価なので、多くの例を追加してプロンプトを長くしても、レイテンシーやコストへの影響は限定的です。
もう一つお話ししたいプロンプト技術は、Claudeに最終的な回答の前にトークンを出力させる方法、つまりChain of Thoughtと呼ばれるものです。基本的に、Claudeに「最終的な考えはこれです」と言う前に、考えを声に出したり作業をしたりさせるのです。そして、それらの初期のトークンはすべて破棄し、エンドユーザーには見せず、最終的な出力だけを使用します。通常、これは回答の質を向上させる傾向があります。ただし、先ほど触れたように、出力トークンの方がコストが高く、また少し遅くなるというより大きなトレードオフがあります。そのため、一部のユースケースでは適していないかもしれませんが、非常に強力な技術です。
LLMアプリケーション開発における性能最適化と評価方法
デバッグにも活用できて面白いです。Chain of Thoughtのトレースを実際に読んで、モデルの思考を理解し、なぜClaudeが特定の動作をしているのかを把握することができます。Chain of Thoughtを読んでデバッグし、プロンプトを修正することができます。
レイテンシーについて少し触れましたが、もちろんLLMの上に構築する場合、これらのAPIは通常より高いレイテンシーを持っています。アプリケーションを構築する際に、100ミリ秒のレスポンスに慣れているのに、突然LLMを使用することで2秒、10秒、あるいは40秒のレスポンスになると、それは課題となり、製品に実際の影響を与える可能性があります。この問題を解決するための最も良い方法の1つは、APIが全出力を一度に返すのを待つのではなく、出力をストリーミングすることです。素晴らしいのは、製品がそれをサポートしていて意味がある場合、エンドユーザーはすぐにコンテンツを見始めることができ、実際のレスポンスは多くの人が読むよりも速くストリーミングされるということです。
レイテンシーについて他に何ができるでしょうか?もちろん、最も良い方法の1つは、より高速なモデルを使用することです。より高速なモデルは、通常より単純なモデルを意味します。そのため、Claudeを使用して精度を維持しながらレスポンス時間を短縮しようとする場合、プロンプトエンジニアリングにより多くの時間を費やす必要があるかもしれません。エンドツーエンドのレイテンシーについて考えると、出力トークンの数が非常に重要になります。そのため、元々機能していたChain of Thoughtを削除し、代わりに例を使用する必要があるかもしれません。Claudeが冗長すぎる場合は、より簡潔になるように依頼できないでしょうか?エンドツーエンドのレイテンシーを改善するために、出力から削除できるものはないでしょうか?
私たちは現在、推論周りのモデルを補完するための他の機能にも取り組んでいます。その1つが、まもなくAmazon Bedrockに導入されるPrompt Cachingです。これは、形状が似たプロンプトを最適化し、入力トークンを前処理して結果をキャッシュすることでレイテンシーを改善するものです。最後に検討できるのは、入力トークン数を減らすか、プロンプトを短くすることです。これは、大量の入力トークンがあり、プロンプトから数千トークンを削減できる場合にのみ有効です。例えば、RAGを使用してヘルプセンターの記事を取り込む場合、20個から10個に減らすのは大きな違いがあります。ただし、プロンプトから1文だけを削除しようとしても、Claudeは入力トークンを非常に速く処理するため、レイテンシーにはほとんど影響がないでしょう。
多くのチームから「Claude は素晴らしいけれど、JSONモードがないから使えない。私たちのLLMはバックエンドプロセスの一部で、ClaudeにJSONを出力させる必要があるんだ」という相談を受けます。私はこのような多くのチームと協力していますが、正式なJSONモードがまだなくても、Claudeから一貫性の高い、質の良い構造化データを取得する技術があることを確信しています。私たちは、求めるものを明確で詳細な指示としてClaudeに提供する必要があります。Claude 3以降は、JSONを出力することが得意になるように訓練されています。Claudeは通常、JSONの周りに会話的な要素を追加する傾向があるため、「前置きや後置きを含めないでください」といった指示を追加する必要があるかもしれません。
また、Claudeに良い出力例を示すことで、望むJSONを確実に得ることもできます。これら2つのアプローチで上手くいかない場合(通常は上手くいきますが)、いくつかの高度なテクニックを実装することができます。Tool Useを試すことができます。これはJSONの出力をツールに適合させることで、Claudeから構造化データを取得する優れた方法です。また、Prefillやプロンプトの中で答えの一部を示すといったテクニックでも良い結果が得られます。
最後に、LLM機能の評価方法についてお話ししたいと思います。これは誰もが直面する一般的な問題です。LLMは確率的なものであり、プロンプトを変更したりモデルを変更したりした時に、それが改善されたのか、悪化したのか、あるいは同じくらいなのかを知る方法が問題になります。LLMの評価方法によって、LLMを活用した製品の改善をどれだけ迅速に、自信を持って行えるかが決まります。私は評価の5つのカテゴリーと、それらに関する一般的な考えについてお話しします。最初の評価方法は、冗談めかして「Evaluation by Vibes(雰囲気での評価)」と呼ばれているものです。これは、プロンプトの作業中に、5個、10個、あるいは20個程度のテストケースを試してみて、良い進展があるかどうかを頭の中でメモしながら進めていく方法です。これは素晴らしい方法で、多くのプロジェクトがVibesから始まります。セットアップは不要で、非常に速く、タイトな反復サイクルが可能です。ただし、明確な欠点もあります。1つは、定量的な厳密さが欠けていることです - 雰囲気の良さを数値化することができません。また、チームメイトに上手く伝わらない可能性があります。彼らは異なる雰囲気を感じたり、異なるテストケースを持っていたりするかもしれず、いわば手探り状態です。しかし、多くのプロジェクトがここから始まり、社内でのバグバッシュの開催などは、規模を拡大したVibesと言えるかもしれません。
では他に何ができるでしょうか?どのような選択肢があるのでしょうか?人間を活用した方法がいくつかあります。 一つの方法として、レベルアップを図ってテストケースをしっかりと定義することができます。さらに一歩進んで、テストケースを用意するだけでなく、明確な評価基準(Rubric)を作成することもできます。Promptを更新する際には、テストケースを実行し、その出力を評価基準に照らして採点します。これにより、人間が介在する信頼性の高い定量的な評価が可能になります。ただし、欠点として、特に法律家による評価が必要な信頼性重視の分野では、評価プロセスが遅くなり、コストがかかる可能性があります。
もう一つの方法は、感覚的にPromptを改善し、実際のプロダクション環境に投入してエンドユーザーの反応を見ることです。私が関わっているチームの多くは、評価戦略の一環としてA/B Testingを活用しています。A/B Testingの素晴らしい点は、最終的に変更したい指標を直接測定できることです - 新しいPromptを導入することで、デイリーアクティブユーザーが増加したり、購入数が増えたりといった効果が分かります。ただし、A/B Testingで私が感じる問題点は、イテレーションサイクルが非常に遅いことです。テストを実施し、結果が出るまで1週間ほどかかり、それを解釈して、場合によっては一から見直す必要があります。また、Promptの変更がダウンストリームの指標にどのように影響するのかを解釈するのが難しい場合もあります。
では他に何ができるでしょうか?コンピューターによる評価も可能です。 決定論的チェックまたはプログラムによるチェックと呼べるものです。これはコードによる評価を行う方法です。テストセットを作成し、出力を評価するコードを書きます。完全一致の文字列マッチング、正規表現、理想的な出力との意味的類似度など、非常に速く緊密なイテレーションサイクルが可能になります。新しいPromptを書いて、チェックを実行し、改善しているか悪化しているかのスコアを得ることができます。これは分類タスクなどには効果的ですが、チャットボットの構築やクリエイティブな文章作成が必要なタスクには難しい場合があります。そのようなタスクのニュアンスをコードで捉えるのは困難かもしれません。
現在、チームが検討している最後の選択肢は、LLM as Judgeというアイデアです。人間が評価基準を使って出力を評価する代わりに、同様の評価基準を含むPromptを作成し、LLMに評価させる方法です。これにより、すべてがプログラム的に処理できるため、高速なイテレーションサイクルを維持でき、より広範なタスクに適用できます。ただし、これはLLMの判断と人間の判断を一致させることができた場合にのみ機能するため、かなり難しい面があります - LLMが全く異なる判断をしている場合、信頼できる指標とはなりません。
私の経験では、評価方法の選択はビジネス目標に応じて決定され、通常、先ほど説明した5つのカテゴリーを組み合わせて使用することが効果的です。Prompt EngineeringやLLMの機能・プロダクトの開発は反復的なプロセスなので、評価を考える際には、素早く反復できる何かしらの方法やプロセスを持つことで、より速くプロダクトを本番環境にリリースすることができます。さて、時間となりましたので、 ご来場いただき、ありがとうございました。この後、あちらで待機していますので、お気軽にお立ち寄りいただき、質問などございましたらお声がけください。ありがとうございました。
※ こちらの記事は Amazon Bedrock を利用することで全て自動で作成しています。
※ 生成AI記事によるインターネット汚染の懸念を踏まえ、本記事ではセッション動画を情報量をほぼ変化させずに文字と画像に変換することで、できるだけオリジナルコンテンツそのものの価値を維持しつつ、多言語でのAccessibilityやGooglabilityを高められればと考えています。
Discussion