re:Invent 2024: AWSサーバーレスとGenerative AIで実現する5つのユースケース
はじめに
海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!
📖 AWS re:Invent 2024 - Unlock the power of generative AI with AWS Serverless (SVS319)
この動画では、AWS ServerlessとGenerative AIを組み合わせたアプリケーション構築について、5つの主要なユースケースを通じて解説しています。Amazon Bedrock、AWS Lambda、Amazon SQS、AWS Step Functionsなどを活用した基本的なChatbotの実装から、RAG(Retrieval Augmented Generation)によるナレッジベース構築、Function CallingによるVirtual Assistant実装、大規模ドキュメント処理、コンテンツ生成までをカバーしています。特に、Parameta Solutionsの事例では、規制文書の自動評価システムをServerlessアーキテクチャで実装し、Amazon Bedrockを活用してコンプライアンス違反を検出する具体的な成功例が示されています。Serverlessの特徴である進化的な性質とGenerative AIの組み合わせにより、新しいモデルへの置き換えが容易で、スケーラブルなアプリケーション構築が可能になることを説明しています。
※ 画像をクリックすると、動画中の該当シーンに遷移します。
re:Invent 2024関連の書き起こし記事については、こちらのSpreadsheet に情報をまとめています。合わせてご確認ください!
本編
Serverlessで解き放つGenerative AIのパワー:セッション概要
re:Inventの2日目へようこそ。皆様の中には、これが最後のセッションとなる方もいらっしゃるかもしれませんが、素晴らしいセッションにしたいと思います。SVS 309:AWS ServerlessでGenerative AIのパワーを解き放つ、へようこそ。内容が盛りだくさんですので、まず自己紹介から始めさせていただきます。私はUma Ramadossと申します。Serverlessを専門とするPrincipal Specialist Solutions Architectです。こちらがPatrickです。はい、私はPatrick O'Connorと申します。AWSのPrototyping Engineerで、実は今日は私のお客様と一緒にプレゼンテーションをさせていただきます。
ありがとうございます。私はMartin O'Gormanと申します。ロンドンを拠点とするParameta SolutionsのHead of Data Scienceを務めております。皆様、こんにちは。私はDhiraj Mahapatroと申します。Bedrockを専門とするPrincipal Specialist SAです。本日はこのような機会をいただき、ありがとうございます。Uma、Patrick、Martinの皆様、ご紹介ありがとうございます。そして、皆様、本日はご参加いただき、ありがとうございます。これまで多くのセッションに参加されてきた中で、ServerlessとGenerative AIについて学ぶために、このセッションを選んでいただき、大変うれしく思います。
それでは早速ですが、今日は豊富なコンテンツをご用意しており、これからお話しする内容について順を追って見ていきたいと思います。本日は、Generative AIモデルを使用したアプリケーションの構築方法について説明します。モデル推論のユースケースとパターンについても見ていきます。先ほどMartinが申し上げたように、お客様としてMartinをお招きし、Parameta SolutionsでのAWSとGenerative AIの活用についてお話しいただきます。最後に、本日お話しした内容を実際に試していただけるリソースをご紹介し、ServerlessがGenerative AIといかに相性が良いかをご理解いただきたいと思います。
AWSのGenerative AIスタックとServerless統合パターン
同様に、今回カバーしないトピックとしては、Foundation Modelの基礎、事前学習や微調整の方法、モデル評価戦略があります。これらのトピックについては、他のセッションで詳しく取り上げられています。 しかし、ユースケースやパターンの説明に入る前に、まずAWSにおける現在のGenerative AIスタックがどのようになっているかを見ていきましょう。
最下層には、Foundation Modelのトレーニングと推論のためのインフラストラクチャがあります。多数のGPU、AWS Trainium、AWS Inferentia、Nitro Systems、AWS Neuronなどがあります。これらはすべて、Foundation Modelの実行、トレーニング、推論を可能にするインフラストラクチャの基盤となっています。 その上に、Foundation Modelに関する機能を提供するServerlessサービスとしてAmazon Bedrockがあります。Bedrockを中心にアプリケーションを構築するためのAgent機能やGuardrailを提供します。Bedrock Studioでは、Large Language Modelを試して、どれが最適かを確認することができます。また、カスタムモデルをインポートしてBedrockで動作させることも可能です。
Bedrockの上には、Amazon Qという最も抽象度の高い層があります。ここには、Amazon Q for Business、コーディング用のQ Developer、そしてQuickSightやConnectなどがあります。しかし、この1時間では、InfrastructureとBedrockという2つのスタックにおいて、Serverlessを使用してInferencingを行う方法に焦点を当てていきます。 簡単に言えば、Foundation Modelsにアクセスするためには、何らかのインターフェースが必要です。AWSでServerlessな方法でインターフェースを構築したい場合、APIが必要になります。そのために、サービス向けのAmazon API GatewayやGraphQLインターフェース用のAWS AppSyncといったサービスがあります。これらはどちらもマネージドサービスでServerlessな性質を持っているため、基盤となるインフラストラクチャを管理する必要がありません。組み込みのセキュリティを備えた高度にスケーラブルなサービスを利用でき、使用量に応じた料金体系となっています。
AWSにおけるServerlessの統合について考えると、最も基本的な統合パターンは、API GatewayとLambda関数を組み合わせたものです。これは、マイクロサービスと完全なServerlessスタックを構築する基礎となります。さらに、Lambda関数がAmazon SQSからメッセージを取得して処理を行うパターンも見られます。また、Amazon EventBridgeがStep Functionsなどのターゲットにイベントをプッシュしたり、Step Functionsが次の状態に移行して作業を実行する前に人間の介入を待機したりするパターンもあります。今日の議論では、これらのパターンをさまざまな形で見ていきます。 Serverlessの統合の観点からは、Lambda関数がFoundation Modelsを呼び出すパターンや、Step FunctionsがAmazon BedrockのFoundation Modelsを直接呼び出すパターンが見られます。使用するFoundation ModelやLanguage Modelに関係なく、レスポンスは選択したコンピューティングサービス(この場合はLambda関数)にストリーミングで返されます。
統合とAPIについて議論する理由は、次のことを示すためです:ServerlessのスピードとGenerative AIのパワーを組み合わせることで、 アプリケーションの迅速な提供や市場投入までの時間短縮といった成果を達成できます。下部に示されているAWS Lambda、Amazon EventBridge、Amazon SQS、そしてAmazon BedrockやSageMakerといった一連のサービスを使用することで、Generative AIを活用した多くのアプリケーションを構築・強化し、市場投入までの時間を短縮することができます。このセッションの主な目的は、皆さんの業務で実装できるこれらのアイデアを提供することです。
チャットボットの進化:シンプルな実装からスケーラブルな設計へ
Generative AIアプリケーションについて顧客と話をする際、 通常、カスタマーエクスペリエンスの向上、従業員の生産性と創造性の向上、既存のビジネスプロセスの最適化という3つの主要な柱に焦点が当てられます。ここではそのようなユースケースの一部をご紹介します。このセッションでは、これら5つの広範なユースケースをカバーし、それらがどのようにさまざまなシナリオに適用できるかを検討します。これらのパターンが、Generative AIが価値を提供できるあらゆる場面でどのように適用できるかをご理解いただけると確信しています。
最も単純なユースケースであるチャットボットから始めましょう。今日、Generative AIを試してみたい場合、おそらくブラウザで言語モデルやFoundation Modelとチャットすることから始めるでしょう。AWSでGenerative AIやFoundation Modelの機能を持つチャットボットを構築する場合、次のような構成になります:ユーザーは、先ほど説明したAPI Gatewayと IAMを使用してAPIと対話し、これがLambda関数と通信します。このLambda関数は、Foundation Modelが理解できるプロンプトを作成し、Foundation Modelを呼び出して応答を得ます。この単純なアプローチは、Amazon BedrockやSageMaker JumpStartで動作します。API GatewayとIAMは、リクエストの認証、レート制限、使用量プランの管理機能を提供します。
しかし、これは実証実験では上手く機能しますが、ユーザー数が増加した場合はどうなるでしょうか?最終的にAPIレイヤーで問題が発生します。適切なレート制限がないと、処理する必要のある同時リクエストによってLambdaに影響を与え、最終的にFoundation Modelのパフォーマンスにも影響を及ぼします。API Gatewayでレート制限を実装することはできますが、ユーザー体験を損なうことは避けたいものです。リクエストを拒否したりスロットリングレスポンスを送信したりするのではなく、すべてのユーザーリクエストを効果的に処理したいと考えます。
この課題に対処するため、同期型アプローチから非同期型アプローチに移行し、制御フローを導入します。その仕組みは次のとおりです:同じシナリオで、ユーザーがAPI Gatewayを呼び出しますが、直接Lambda関数を呼び出す代わりに、すべての着信リクエストをバッファとして機能するSQSキューに集めます。サーバーレス統合に関するスライドを思い出すと、最初のパターンではLambdaがSQSからポーリングしていました。これにより、リクエストレートが増加した場合でも、Lambdaが自身のペースでキューから取り出すことができるため、Lambda関数やダウンストリームのFoundation Modelに負荷をかけることなく、バッファとして機能します。AWS Lambdaはキューからリクエストを取り出し、最終的にそのリクエストをAmazon Bedrockに送信します。
レスポンスを受け取ったら、システム全体の同期性を分断したため、API Gateway WebSocket、Amazon API Gateway、またはクライアントに非同期で応答を送り返すことができる他の仕組みを通じて、クライアントにレスポンスを返す方法が必要になります。これにより得られるのは、高いスケーラビリティを持つ分離されたアーキテクチャです。Amazon SQSとAWS Lambda Event Source Mappingには、Lambdaのスケーリング方法を定義するための多くの有用な属性があり、これについては後ほど詳しく見ていきます。
RAGの実装:ナレッジベース構築とドキュメント処理の最適化
この基礎を踏まえて、このチャットボットや大規模言語モデルを組織のデータと連携させる方法を見ていきましょう。静的な応答を返すチャットボットも便利ですが、エンタープライズ規模の本番環境では、この機能を自社のデータと連携させる必要があります。データこそが他社との差別化要因となるため、適切な場所で適切な形式でデータにアクセスできるようにする必要があります。重要なのは、強固なデータ基盤を持つエンド・ツー・エンドのデータ戦略を構築することです。AWSは、データ基盤の構築に使用できる幅広いサービスを提供しています。データ統合時に必要となる主要なサービスをいくつかハイライトしてお示ししました。
データをData Foundationに格納したら、それを他のユーザーがアクセスできるようにし、ガードレールを実装し、Continued Pre-training、Fine-tuning、Retrieval Augmented Generation(RAG)といった高度なGenerative AIテクニックに活用することができます。では、Large Language Modelをあなたのデータと連携させる方法についてお話ししましょう。これらのテクニックはすべてLarge Language Modelをコンテキストに対応させるのに効果的ですが、特にRAGは強力でコスト効率が良いのです。RAGを例に取り上げて、実装のメリットをご紹介したいと思います。
RAGについて簡単におさらいしましょう。Generative AIに質問をしたい場合、Large Language Modelに直接質問するのではなく、まずその質問をナレッジベースで検索し、その質問に関連する情報を取得して、質問を補強してからLarge Language Modelに問い合わせます。入力に追加された詳細情報により、Large Language Modelはより正確な回答を提供できるようになります。このRAGプロセスが機能するためには、ナレッジベースが極めて重要です。なぜなら、そこにベクトルと呼ばれる特定のフォーマットで入力データが格納されており、そのベクトルデータを生成するためには、Embedding Modelと呼ばれる特別なモデルが必要だからです。
ベクトルデータを生成してこのナレッジベースを構築するプロセスは、一筋縄ではいきません。Amazon Bedrockを使用する場合、Bedrock Knowledge Basesを利用すれば、RAGを最も素早く始められます。様々なデータソースにアクセスでき、データを取得し、様々なチャンキング戦略を適用し、エンベッディングを作成して、複数の異なるベクトルデータベースにそのベクトルデータを格納できます。ただし、これらのナレッジベースの構築と管理方法についてより細かな制御と柔軟性が必要な場合や、Bedrockが選択肢として使えない場合もあります。
そのような場合のために、ナレッジベースを構築するプロセスをドキュメント処理の一例として取り上げました。この例を選んだのは、RAGが人気があるからというだけでなく、分散処理で実行するのが最適だからです。LambdaやECSでLangChainやLlamaIndexを実行すれば、このプロセスを完了できるのではないかと思われるかもしれません。ドキュメント処理は一般的に非構造化データの処理を含みます - 音声・動画の録音・録画、メールのやり取り、チャットメッセージ、ソーシャルメディアのフィードなどを考えてみてください。このデータの一部は分類や変換が必要で、一部は機密情報のチェックが必要で、一部はマスキングが必要で、エンベッディングやデータの保存を進める前にデータ品質の検証が必要です。これは正確なオーケストレーションが必要であることを示しており、AWS Step Functionsのようなサービスがこのユースケースに最適となります。
さらに、処理するのは少数のドキュメントだけではなく、何万ものドキュメントを処理することになります。開発者として、forループやイテレーターライブラリを使ってドキュメントのコレクションを反復処理することを考えるかもしれません。しかし、スケーリング時に課題が生じます:何万ものドキュメントを効果的かつ効率的に処理するにはどうすればよいでしょうか?垂直スケーリングを行うのでしょうか?どれだけのCPUとメモリを割り当てるべきでしょうか?スレッドを追加するのでしょうか?何個のスレッドを追加すべきでしょうか?処理の途中で失敗した場合、1万件すべてのドキュメントを最初からやり直すのでしょうか?
ここで Step Functions Distributed Map の出番です。私の考えでは、RAG のユースケースのように、大規模データを処理する上で Distributed Map は画期的な機能です。Distributed Map をご存知ない方のために説明すると、これは Amazon S3 内のオブジェクトのコレクションに対して反復処理を行うことができる Step Functions のステートです。必要な反復回数を指定する必要はありません。オブジェクトの場所と反復処理の内容を指定するだけで、自動的に処理を行い、大規模データの処理をより細かくコントロールすることができます。
例えば、並列実行する反復処理の数を1回、10回、40,000回など、自由に設定できます。なぜこれが重要かというと、大規模言語モデルに対して過剰な呼び出しを行いたくないからです。 また、ドキュメントのバッチ処理も可能です。1回の反復処理で1つのドキュメントではなく、10個のドキュメントを送信することができます。 さらに重要なのは、失敗した時点から再試行できることです。10,000個のドキュメントを処理中に失敗した場合でも、最初からやり直す必要はなく、失敗したドキュメントから再開できます。何より、反復処理の数を完全に把握できるため、 処理しているドキュメント数、現在の反復回数、成功した反復回数、入力と出力の内容など、すべての情報をその場で確認することができます。
Step Functions とこれらのサービスを使って RAG パイプラインを構築すると、まさに相乗効果を生み出すことができます。変換や大規模ドキュメントのチャンク分割には AWS Lambda で LangChain や LlamaIndex ライブラリを実行し、Amazon Bedrock の埋め込みモデルを使用して埋め込みを作成し、それを Amazon OpenSearch Serverless に保存し、Amazon EventBridge Scheduler を使用してパイプライン全体をスケジューリングします。これらのサーバーレスで目的に特化したサービスが非常にうまく連携します。
今見てきたように、目的特化型イテレーターである Distributed Map は、大規模データの処理を簡素化することができます。データは複雑で予測不可能なことが多いため、失敗時点からの再試行機能は非常に重要です。10個であれ10,000個であれ、大規模なデータを扱う際の変動性にうまく対応できるため、最も重要なビジネス価値の創出に集中することができます。今見てきたのは、RAG のような大規模データ処理のユースケースを実装する方法です。RAG を使用することで、大規模言語モデルが入力データを認識できるようになり、一歩前進することができます。
バーチャルアシスタントの実現:Function CallingとStep Functionsの活用
では、全体的な API の質問にどのように当てはまるのか見てみましょう。ありがとうございます、Uma さん。ここで学んだことと、その活用方法をまとめてみましょう。上部のセクションは Uma が説明した内容で、Step Functions を使用してベクトル埋め込みを作成する方法です。下部は私が説明したチャットボットと非同期処理の方法です。しかし今の疑問は、組織のデータを使用できるように、これらをどのように組み合わせて実装するかということです。チャットボットのシナリオではほとんどすべてが同じままですが、新しく追加されるのは、Lambda 関数がベクトル埋め込みを参照するか、類似性検索を行うためのベクトルを取得する必要があるという点です。
私たちは類似性検索にVectorを使用し、その類似性検索によって関連するコンテキストをLambda関数に提供します。このような追加のコンテキストと、先ほど尋ねられた質問を使って、Lambdaは言語モデルを呼び出すことができます。言語モデルは応答を返送します。このような追加コンテキストにより、ハルシネーションの発生率が低下し、言語モデルからより確実で焦点を絞った情報を得ることができるようになります。モデルから回答が返されると、先ほど説明したのと同じ方法でレスポンスが配信されます。
このプロセス全体が、Retrieval Augmented Generation(RAG)と呼ばれるもので、Embeddingの作成方法とそれをアプリケーションでどのように使用するかについて説明してきました。現在、静的なデータを扱っており、Large Language Modelが組織のデータに基づいて応答を返しているため、うまく機能しています。しかし、これが限界なのでしょうか?それとも、さらに先に進むことができるのでしょうか?Large Language Modelが私たちに代わってアクションを起こすことはできるのでしょうか?そこで注目されるのが、バーチャルアシスタントのようなユースケースです。
私たちが以前から経験してきた古いユースケースの1つと、どのように関連付けられるか見てみましょう。インターネットで予約ができるようになる前、予約担当者とどのようにやり取りしていたかを思い出してください。フライト、ホテル、レンタカーを予約する際のやり取りは、このような感じでした。まず、ユーザーとして「オーランドに旅行するので、フライト、ホテル、レンタカーが必要です」と伝えます。すると、担当者から追加の質問が続きます。出発空港はどこですか?出発日はいつですか?そして、このような会話が予約担当者が予約に必要なすべての情報を得るまで続きます。
この例えを念頭に置いて、Large Language Modelでどのようにこれを実現できるか見てみましょう。Large Language Modelは、私たちに代わって働いていた予約担当者のような役割を果たすことができるでしょうか?その仕組みを見てみましょう。先ほど説明したServerlessアプリケーションがあり、右側に言語モデルがあり、ユーザーが「ディズニーワールドへの旅行の予約をして」といった質問をしています。旅行代理店のように、このような質問をすると、LLMは即座にアクションを起こすことができないため、そのようなことはできないと応答します。
そこで重要になってくるのがAgentのような機能です。LangChain AgentやAmazon Bedrock Agentについて聞いたことがあるかもしれません。これらのAgentはLarge Language Modelと連携して作業を調整し、予約をどのように完了できるかを判断します。Agentは、APIコールを実行したり、検索を実行したり、ナレッジベースを呼び出したりすることができます。その目標は、実際にユーザーの代わりに予約を行うことです。Amazon Bedrock Agentは、これを実現する1つの方法です。
今日私たちが注目するのは、Amazon Bedrock Agentのようなエージェントオーケストレーターを使用せず、これまで紹介してきたServerlessやLambda関数の機能を活用して同じ目的を達成する別のアプローチです。予約の依頼について同じ質問がされた場合、このServerlessアプリケーションは、あなたはAIトラベルアシスタントであり、これらのツールを使って予約を行う必要があるというシステムプロンプトを送信します。この機能はFunction CallingまたはTool Useと呼ばれています。
前回のアプローチとの違いは、エージェントがあなたに代わってオーケストレーションを行っていたのに対し、今回の場合、言語モデルは単にどのツールを呼び出すべきかのヒントを提供するだけで、実際にそのツールを呼び出すのはあなたの責任となります。ここで「あなた」とは、Serverlessアプリケーションのことを指しています。この場合、get_owner_info、get_passenger、get_reservationというツールがあり、最初のリクエストについて言語モデルに尋ねると、NLPを使用してどのツールを使用するかを判断します。get_owner_infoを使用する必要があることを通知します。そこでServerlessアプリケーションがAPIまたはLambda関数を呼び出し、レスポンスを取得して、そのレスポンスを言語モデルに送り返し、次に使用すべきツールを判断します。これが会話の進め方です。
大規模ドキュメント処理:バッチ要約とコスト最適化の戦略
会話の進め方が理解できたところで、システムプロンプトでツールをどのように定義するか見てみましょう。先ほど述べたように、この例で使用するモデルIDはAnthropic Claude 3 Sonnetです。ツールの定義方法はこのようになります。get_owner_infoがあり、get_owner_infoの機能を説明し、スキーマを提供します。次にget_passenger_informationがあり、ツールとしての機能を説明します。予約のBookingと同様にスキーマを提供します。この例では、これらのビジネスロジックを返す3つのLambda関数をツールとして使用しています。
owner IDを送信すると、オーナー情報を取得します。再度owner IDを送信すると、パッセンジャー情報を取得します。最後に、予約をするためのJSONを送信します。では、Step Functionsワークフロー内でどのように見えるか確認してみましょう。これはすでに構築済みで、サンプルは利用可能です。リソースセクションで公開される予定です。これが予約エージェントのための仮想アシスタントシナリオを実現できる完全な機能です。
ステップバイステップで見ていきましょう。最初の質問は、このowner IDを持つJohn Doeさんがサプライズ旅行を計画していて、5時間以内にこの旅行を計画する必要があるというものです。Step Functionsはリクエストを受け取り、青色で示されているBedrockモデルに渡します。そしてBedrockモデルが判断します。先に進むためには、このツールを使用する必要があると。このツールとは何か?それはget_owner_infoで、入力テキストからowner IDも渡します。スキーマで定義したように、どのツールを使用すべきか、そのツールにどのような入力が必要かを伝えます。そして停止理由は「tool use」となります。ツールを使用して、次に何をすべきか教えてもらうために戻ってくる必要があります。この場合、出力トークンは入力トークンよりも比較的少なくなっています。予約を取得するために次に進むための十分なコンテキストだけを送信すればよいため、これが有用であることを覚えておいてください。
その後はどうなるのでしょうか? ここから実際の会話が始まります。ユーザーがこのように質問を投げかけ、そしてAssistant(この場合はモデル)が、このツールを使用する必要があるという回答を返します。 そして、アプリケーション開発者またはユーザーである私たちが、このツールの結果をJSONストリングとして提供します。これらの情報がすべて新しいコンテキストとしてモデルにフィードバックされます。
モデルは、オーナー情報を取得できたので、次は乗客情報が必要だと返答します。このオーナーIDを使って乗客情報を取得するようにツールを使用してください、という具合です。乗客情報を受け取ると、すべての乗客情報が揃います。最終的に、BedrockモデルのStep Functionsは予約に必要なすべての情報を持つことになります。モデルは「すべての情報が揃いました。これが予約のための入力ペイロードです」と伝えてきます。ここを確認すると、オーナーID、名前、姓、出発空港、到着空港、すべての乗客情報などが含まれていることがわかります。これで予約の準備が整い、この情報を予約APIやLambda関数に渡して実際の予約処理を行うことができます。
このように、Bedrockモデルが「もう使用するツールはありません」と判断するまで、再帰的なプロセスが続きます。そして停止理由が返されたら、Step Functionから「すべての処理が完了しました。予約が完了しました。これが要約です。追加情報が必要な場合は、お知らせください」というように終了することができます。これらの応答はLarge Language Modelによって提供されます。このシナリオのメリットは何でしょうか?トークンサイズが小さいため、ツールの使用により決定論的な応答が得られ、既存のビジネスロジックを実行できます。例えば、企業内で3つのツールの動作がAPIとして既に定義されている場合、それらをツールとしてプラグインして動作させることができます。また、Step Functionsがネイティブにこの機能を提供しているため、より良いエラーハンドリングが可能です。パフォーマンスも向上します。なぜなら、毎回数千のトークンを返すのではなく、使用するツールの情報だけという形で、出力トークン数が大幅に少なくなるためです。これによって、より効率的な仮想アシスタントを実現できます。
ここまでの説明は以上です。次は、Large Language Modelsが大量のドキュメントを処理する際にどのように役立つかというシナリオに移りましょう。このユースケースについては、特に説明は必要ないでしょう。
Generative AIは、長い会話から簡潔な要約を作成したり、製品レビューから重要な洞察を抽出したり、住宅ローン書類のような大量の文書を簡素化したりする際に、ゲームチェンジャーとなっています。文書要約におけるGenerative AIの応用可能性は、実質的に無限です。このセッションのこのパートでは、要約を実装するいくつかの方法と、バッチ要約を費用対効果の高い方法で実装する方法についてお話ししたいと思います。
リアルタイムでサマリーを作成したい場合があります。Amazon API Gatewayを通じてユーザーがドキュメントをAmazon S3にアップロードできるようにすることができます。 そして、S3のイベント通知機能を活用できます。S3は、ファイルのアップロード時に複数の宛先にイベント通知を送信できるからです。その宛先の1つがAmazon SQSです。その後、AWS LambdaでSQSからメッセージを処理し、要約を実行します。大きなドキュメントの変換やチャンク分割には、目的に特化したライブラリを使用することができます。
このように複数のユーザーがドキュメントをアップロードする場合、S3からイベントが集中的に発生するのを目にすることになります。Lambdaはこの急増に対応できますが、AI/MLサービスがすぐに過負荷になってしまう可能性があります。そのため、S3とLambdaの間に中間層を導入して、S3からAI/MLサービスへのメッセージの流れを制御できるようにしています。これは、先ほど説明した非同期パターンです。 LambdaでSQSからメッセージを処理する際、MaxConcurrencyという設定があります。MaxConcurrencyを設定すると、Lambdaは設定された数の実行環境のみを起動してSQSからのメッセージを処理することを保証します。このように、接続先のサービスが異なる制限でスケーリングされている場合でも、メッセージを確実に処理する、つまりこの場合はドキュメントを確実に要約することができます。
大量のドキュメントがあり、イベント駆動で実行したくない場合、バッチでドキュメントを処理したいことがあります。 これらを実行する最適な方法は、Amazon EventBridge Schedulerを使用してスケジュールに従って実行することです。先ほどのナレッジベース構築のユースケースで見たように、大量のドキュメントがある場合は、AWS Step Functions Distributed Mapを使用できます。このユースケースでは、Step Functions Distributed Mapでドキュメントの場所を指定すると、自動的に反復処理して要約を行ってくれます。先ほどの同時実行性について説明したスライドと同様に、Distributed Mapでも同時実行数を設定できるため、バッチ要約時にAI/MLサービスが大量の入力で過負荷になることを防げます。要約は保存する必要があり、Amazon DynamoDBのようなデータベースを選択することになります。
モデルプロバイダーを使用せず、Amazon EKSやAmazon SageMakerで独自のカスタムモデルを実行し、バッチ要約に使用する場合、コスト効率が悪いため、モデルを24時間365日実行したくはありません。 例えば、モデルがSageMakerにデプロイされており、Step Functionsでバッチ要約に使用している場合、前処理と後処理のステップを追加するだけです。前処理では、SageMakerモデルのエンドポイントが起動し、そのエンドポイントが稼働するまで待機することを確認します。Step Functionsは、間にコンピュートを必要とせずにSageMaker APIを直接呼び出すことができ、APIを呼び出して待機できます。
要約が完了したら、後処理でエンドポイントを削除します。このエンドポイントを効率的に管理することで、必要な時だけモデルを実行してコストを削減できます。Amazon Bedrockを使用している場合は、バッチ推論APIがあり、複数のプロンプトをバッチとして送信できるため、これもバッチ要約時のコスト削減の方法の1つとなります。
コンテンツ作成の効率化:Prompt ChainingとHuman-in-the-loop
さて、ここからは視点を変えていきましょう。バッチの要約については、実装方法についてある程度理解できたと思います。次は別の興味深いユースケース、コンテンツ作成について見ていきましょう。このセッションでは、Prompt ChainingとHuman-in-the-loopという2つのテクニックを取り上げ、これらがGenerative AIアプリケーションの精度とパフォーマンスをどのように向上させるのか、そしてその実装方法について説明します。
Prompt Chaining は、モデルの精度とパフォーマンスを向上させる優れた方法の1つです。例えば、Generative AIを使用して技術ブログを書く場合を考えてみましょう。一般的なブログには、概要、課題、解決策などの複数のセクションがあります。ブログ全体を1つのプロンプトで生成するのは良いアイデアでしょうか?おそらくそうではありません。なぜなら、多くの編集が必要になり、結局ブログを自分で書き直すことになってしまうからです。包括的なプロンプトには他にもデメリットがあります。プロンプトの一部を変更すると、他の部分に影響が及ぶ可能性があります。より高度な大規模モデルが必要になるため、コストが高くなり、全体的に処理が遅くなる可能性があります。また、大規模なプロンプトの保守、チューニング、テストは非常に困難です。
プログラミングと同様に、明確で焦点を絞った単一目的のプロンプトを考えるべきです。その方法は、大きなプロンプトを小さなプロンプトに分解し、ユースケースに合わせて適切に連携させることです。この手法がPrompt Chainingです。Prompt Chainingを実行する優れた方法として、AWS Step Functionsがあります。複数のプロンプトをチェーンで連携させる場合、順次実行、並列実行、反復実行などが必要になることがありますが、Step Functionsはこれらの異なるフローを簡単に構築できる機能を提供しています。
目的に特化したプロンプトを使用することで、目的に特化したモデルも使用できます。例えば、ブログのコードを生成する場合、コード生成用に訓練されたモデルを使用できます。目的特化型のモデルを使用する場合、モデルはAWS内部でも外部でも構いません。プライベートAPIを使用することもできます。Step FunctionsのHTTP API統合を使用してモデルを直接呼び出すことができ、追加のコンピュートリソースは必要ありません。つまり、アーキテクチャがシンプルになります。さらに重要なのは、すべてのプロンプトがどのように連携し、実行され、ブログを改善するためにどこを変更する必要があるかが完全に可視化されることです。Step Functionsの可観測性により、プロンプトの最適化も可能になります。
Generative AIアプリケーションの精度を向上させるもう1つのテクニックとして、Human Reviewerを組み込む方法があります。もちろん、Generative AIを使用する目的は全てを自動化することですが、アプリケーションの安全性や精度、顧客に表示するレスポンスの正確性がより重要なユースケースも存在します。自動評価を行い、その評価が失敗した場合にHuman Reviewerが必要になることがあります。
Step Functionsを使用してHuman Reviewerを実装することは、一般的なパターンの1つです。人間のレビュアーとの連携が必要なステップがある場合、コールバックパターンと呼ばれる方式を使用します。これを使用すると、トークンが生成され、統合されたサービスを通じてレビュアーに送信され、そのステップは一時停止状態となり、トークンが返されるまで待機します。Human Reviewerがレビューを行い、承認または否認を行うと、レビュアーは自身の回答とともにトークンを返送します。これが行われると、そのステップはトークンを受け取り、Human Reviewerからの回答に基づいて下流のサービスに進みます。このように、状態の依存関係やトークンの管理を意識することなく、Step Functionsを使ってHuman Reviewerのプロセスを簡単に統合できることがお分かりいただけると思います。
この具体例を超えて、私たちが今見てきたのは、Generative AIアプリケーションの精度とパフォーマンスを向上させるために、より目的に特化したモデルを使用することになるということ、そして当面はモデルを切り替えながら使用していくということです。これにより、モデルを簡単に組み替えることができます。Step Functionsを使用することで、Human-in-the-loopを簡単に統合し、Promptトレーニングを実装できることを確認しました。そして、Promptトレーニングと組み合わせた可観測性により、より良いコントロールが可能になり、Promptの最適化に役立つことを見てきました。
Parameta Solutionsの事例:規制評価の自動化とGenerative AIの実践
ここからは、お客様のGenerative AIの取り組みについて直接お話を伺います。その前に、少し背景をお話しさせていただきます。私はAWSのPrototyping Engineerを務めるPatrick O'Connorです。私の仕事は、特にGenerative AIのような新しいテクノロジーについて、4〜6週間という短期間で革新的な取り組みを行うことです。
ありがとうございます、Patrick。私はParameta Solutionsのデータサイエンス部門長を務めるMartin O'Gormanです。背景として、ParametaはTP ICAP Groupのデータ部門です。TP ICAP Groupは世界最大のインターディーラーブローカーで、主要な金融、エネルギー、商品市場における機関投資家の売り手と買い手を結び付けています。これにより、年間数兆ドルの取引を促進し、毎日何百万もの金融データポイントを生成しています。Parametaでは、革新的なデータ製品とデータ配信ソリューションを通じて、このデータをクライアントが利用できるようにしています。
私たちのGenerative AIの取り組みは、18ヶ月前にAWSでのイマージョンデーから始まりました。私たちはGenerative AIで解決できそうな課題についてのアイデアを持ち寄り、その中から1つを選んで前に進むことにしました。これがPrototyping Engagementのきっかけとなり、Patrickもエンジニアの一人として参加しました。このPrototyping Engagementの結果、4週間にわたって密接に協力し、動作するプロトタイプを完成させることができました。その後の18ヶ月間で、プレゼンテーションで説明されたすべてのカテゴリーにわたる多くの異なるユースケースに取り組んできました。
この規制評価のユースケースに焦点を当てたいと思います。私たちにはBenchmarkやIndexを構築するプロダクトチームがあります。Benchmarkに関しては、2種類の文書が関係してきます。1つは金融市場で何が許可され、何が禁止されているかを定める法的文書である規制です。もう1つは、規制がどのように作成されるのか、どの通貨が関係するのか、その他の定義パラメータなどを説明する一般公開用のMethodology文書です。Methodologyに関して重要なのは、すべての規制ルールをカバーしていなければならないということです。このプロトタイプの目的は、Generative AIを使用してこのプロセスを自動化しながら、正確性を維持することでした。
では、Patrickが実際のアーキテクチャについて説明します。
問題設定を理解しましょう。つまり、規制当局が定める規制と、企業が規制で定められた内容を解釈・理解するために作成するMethodologyがあるということです。アーキテクチャを見ていきましょう。このプロトタイプはこれら2つの文書に焦点を当てています。アーキテクチャ的には、まず規制を取り込み、遵守すべき各ルールをデジタル化することから始めます。その後、Methodologyと規制を相互参照する必要があります。
最初に行ったのは、フロントエンドをホストできるAWSのサービス群であるAmplifyの活用です。Parameta Solutionsが簡単に規制をアップロードできるように、React TypeScriptのフロントエンドを構築しました。下部に表示されているOkta IDPを使用していますが、これはAmplifyにネイティブに統合されており、サイトにログインする人を安全に認証できます。また、 バックエンドAPIシステムとしてAWS AppSyncを活用し、サービスバックエンドへの安全な接続を実現しています。ユーザーが規制やMethodologyを送信またはアップロードすると、入力用のS3 Bucketにアップロードされ、Step Functionがトリガーされます。
このStep Functionで重要な処理が行われます。Step Functionの最初のプロセスは、 規制とMethodologyを区別することです。規制については、個々のルールを解析して取り出します。例えば、Great Britain Marketでは、ポンドで取引しなければならない、特定の地域内の特定の市場に従わなければならないといったルールがあります。これらのルールを抽出して保存します。Methodologyの場合は異なるプロセスとなります。文書全体を規制に照らしてスキャンするためです。
この情報を解析した後、一連のGenerative AIによる処理を実行します。要約にはAmazon Bedrockを使用しています。最初の実験では、規制への準拠を確認するために、手法に含まれるキーワード検索を行いました。そして最後の、本当に魔法が起こるステップでは、Bedrock上のLarge Language Modelを使用して文書全体をスキャンし、違反箇所、違反理由、そしてそれらの違反を改善するための提案をラベル付けします。これらの結果はNoSQLデータベースのAmazon DynamoDBに保存します。
このプロトタイプの注目すべき機能の1つ、最後のChatbotについてお話ししたいと思います。参考までに、これは昨年8月にプロトタイピングチームと行った最初のGenerative AIプロジェクトでしたが、お客様は非常に刺激を受けられ、さらに一歩進んでBedrockを使用して独自のChatbotを導入されました。
このStep Functionで実際に何が起きているのか見てみましょう。画面からわかるように、先ほど説明した様々な反復的なアクションが複雑に組み合わさっています。まず上部にある決定木であるの最初の項目を見てみましょう。このStep Function内では、規制と手法を組み込みメカニズムを使用して処理し、関連するパスを選択しています。その後、反復パターンなどの他の機能を使用しています。
右側の反復パターンは、規制をルールごとに保存して、Step Function内でルールごとにループ処理を行う方法を示しています。例えば、最初のルールが「イギリスの取引ではポンドを使用しなければならない」という場合、文書がこのルールに準拠しているかチェックします。ユーロが使用されている箇所や、イギリス以外の通貨についての文脈的な説明が言及されている箇所をスキャンして見つけ出します。そしてこの情報を抽出し、違反内容とその理由を表形式で保存します。この反復パターンを使用してすべてのルールを処理します。
ここで使用している重要な機能の1つが、完全にServerlessなAmazon BedrockによるLarge Language Modelの呼び出しです。関連セクションでは、AWS Lambdaを使用してPrompt ChainingとPrompt Curationを処理し、左側で効果的に要約を行っています。より重要なのは、右側でAmazon Bedrockを活用したコンプライアンスチェックを行っていることです。関連する部分では、エラー処理も実装しています。Hallucinationが発生した場合や他の側面が捕捉されなかった場合、そのエラーを捕捉し、フロントエンドまたはバックエンドシステムを通じて何が問題だったかを通知できます。最後のコンポーネントはLambdaタスクです。これらすべてが連携して動作し、コンプライアンス違反を解析して検出する完全なServerlessワークフローを作り出しています。
このスライドでは、Martinに話を戻して、のプロトタイプ以降にどのようなプロジェクトを手がけてきたのかをお聞きしたいと思います。ここで注目したいのは、チームがServerlessテクノロジーをどのように活用してアプリケーションを構築してきたかということです。ここに示されているのは、クライアントのサポートチケットの分類を自動化するワークフローです。私たちは、さまざまなGenerative AIのユースケースで活用できるマクロレベルの設計パターンが見えてきています。最初に、2つのGenerative AIコンポーネントを含むメッセージ処理があります:1つはサポートチケットの分類、そして分類結果に応じて意味のあるエンティティを抽出するエンティティ抽出です。これは通常、AWS Step Functionsでオーケストレーションされ、様々なコンポーネントを含むアクションにつながります。
例えば、エンティティ抽出ステップで抽出されたエンティティを使用して、Text-to-SQLモデルでSQLクエリを構築し、この場合はSnowflakeという外部データウェアハウスに対してクエリを実行しています。また、このサポートチケットの解決に役立つ可能性のあるクライアント情報を検索するために使用できるナレッジベースも持っています。サポートチケットは非構造化データであることを忘れてはいけません。現在、私たちのGenerative AIモデル全体で見られるもう一つのパターンは、モデル評価です。ここでは、テストデータセットを構築し、それを使用して新しいモデルとプロンプトの組み合わせを評価し、現在のベストなものと比較することができます。
私たちが発見しているのは、ServerlessとGenerative AIがイノベーションを促進し、ワークフローの自動化を支援し、サイロ化されたデータストアのロックを解除するのに役立っているということです。これにより、よりクリーンなデータ、より良いデータガバナンス、そして結果として新しい収益源が生まれています。Parameta Solutionsの戦略の2本柱は、デジタルトランスフォーメーションとコスト最適化です。ワークフローをクラウドに移行することで、これらの目標達成を支援しています。一般的に、この新しいテクノロジーを使用することで、データサイエンスチームはより幸せで生産性が高くなり、もちろん、お客様にも満足していただいています。
セッションまとめと今後の学習リソース
今日取り上げた内容を振り返ってみましょう。最も単純なChatbotから始まり、それをどのようにスケールで実行できるかという複数のユースケースを取り上げました。次に、ドキュメント処理に深く踏み込み、Retrieval Augmented Generationの構築方法、モデルの作成方法、そしてVector Embeddingを作成するための関数の使用方法を見てきました。ChatbotとRAG特有のアプリケーションを組み合わせて構築できる方法を示しながら、これら2つのアプローチを調和させました。次に、Virtual Assistantに進み、Amazon Bedrock Agentsを考える際に非常に強力な概念である予約機能を実現するためのStep Functionsにおけるツールの使用やFunction Callingについて説明しました。最後に、スケールでのドキュメント要約に移り、Amazon Bedrockが選択肢とならない場合の関数を使用したドキュメント要約方法や、Amazon Bedrockを使用したバッチ処理の方法を実演しました。これは、様々な顧客に共通する産業用途のユースケースです。
そして、マーケティングチームにとって非常に重要なコンテンツ作成について説明しました。承認プロセスにおいてHuman-in-the-loopを取り入れながら、より速いペースでコンテンツを作成したい場合、AWS Step Functionsを使用する方法も見てきました。最後にParameta Solutionsと確認したプロセスでは、彼らがどのようにプロセスを最適化したかを示し、これらのシナリオの多くをカバーしました。
Generative AIとServerlessがどのように連携するのかをまとめると、アプリケーションをより迅速に構築し生成できるようになります。アプリケーションは進化的な性質を持ち、既存のコンポーネントを壊すことなく新しいコンポーネントを組み込むことができます。ServerlessアーキテクチャとGenerative AIモデルを使い始める際、明日により精度の高いモデルや、より良いスコアを持つモデルが登場しても、古いものを新しいものに単純に置き換えれば、期待通りに動作するはずです。
Amazon SQSのようなサービスがバッファとして機能するため、AWS Lambda関数やバックエンドのFoundation Modelに関して、きめ細かなスケーリングコンポーネントを実現できます。Serverlessアーキテクチャを使って小さなコンポーネントで構築する際に、この力を発揮します。進化的な性質を活かして、複数のモデルで推論を簡単に行うことができ、新しいモデルをテストし、ビジネスユースケースに適したものを見つけ、素早く失敗し、より速く構築することができます。AWS Step Functionsとの豊富な統合も提供され、220以上のAPIが標準で統合されています。Step FunctionからLambda関数を書くことなく、Amazon Bedrockを直接呼び出すことができます。
最後に重要な点として、私たちは全てを自動化したいと考えていますが、Large Language Modelsを使用する場合はまだ非決定的な要素があるため、このプロセスに人間による承認も必要としています。コンテンツを公開する際や、対象となる読者に適切なコンテンツであることを確認する際には、人間の目で確認し承認することが望ましいのです。以上のリソースにアクセスできます。このQRコードをスキャンしていただければ、複数のブログ、ワークショップ教材、そしてプライベート航空予約に関するツール使用シナリオを実演するサンプルアプリケーションを入手できます。また、そのサンプルアプリケーションに関連するブログも用意されています。
他のセッションをお探しの方は、re:Inventでこれらの追加セッションをチェックしてください。ServerlessリアルタイムAPI、AIパワードチャットボット、ツール使用エージェント、Prompt Engineeringの戦略についてより詳しい情報を得ることができます。Serverlessについてさらに学びたい場合は、これらの方法があります。このQRコードをスキャンすると、Serverlessラーニングにアクセスでき、Serverlessテクノロジー、イベント、ワークフローに関するバッジを獲得できます。ServerlessとStep Functions、イベント、ワークフローについて学び始めると、Generative AIアプリケーションであれ通常のアプリケーションであれ、よりマネージドでServerlessな方法で考えられるようになります。Generative AIは急速に進化している分野なので、素早くプラグアンドプレイできる仕組みが必要で、Serverlessがそのメカニズムを提供してくれます。
ご参加いただき、ありがとうございました。こちらが登壇チームです。セッションについてレビューをお願いします。私たちのパフォーマンスについてフィードバックをいただければ幸いです。このフィードバックを参考にさせていただき、来年またはお会いする機会に、さらに興味深い新しいトピックについて掘り下げていきたいと思います。皆様、本当にありがとうございました。
※ こちらの記事は Amazon Bedrock を利用することで全て自動で作成しています。
※ 生成AI記事によるインターネット汚染の懸念を踏まえ、本記事ではセッション動画を情報量をほぼ変化させずに文字と画像に変換することで、できるだけオリジナルコンテンツそのものの価値を維持しつつ、多言語でのAccessibilityやGooglabilityを高められればと考えています。
Discussion