📖

re:Invent 2024: AWSが解説するGenerative AI向けデータ活用戦略

2024/01/01に公開

はじめに

海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!

📖 AWS re:Invent 2024 - A practitioner’s guide to data for generative AI (DAT319)

この動画では、Generative AIアプリケーションにおけるデータの活用方法について、自動車保険の見積もりを例に詳しく解説しています。Retrieval Augmented Generation (RAG)の基本的な手法であるNaive RAGから、より高度なAdvanced RAG、Modular RAGまでの進化を説明し、それぞれのトレードオフについて触れています。また、Vector検索やChunking戦略、データパイプラインの構築方法など、実装に必要な技術的な選択肢を網羅的に紹介しています。特に、Amazon Bedrock Knowledge BasesやAmazon OpenSearch Service、Amazon Neptuneなど、AWSの各サービスを活用したデータ統合の具体的な方法にも言及しており、実践的なデータ活用の全体像を把握できる内容となっています。
https://www.youtube.com/watch?v=o1F2yJu2nDw
※ 動画から自動生成した記事になります。誤字脱字や誤った内容が記載される可能性がありますので、正確な情報は動画本編をご覧ください。
※ 画像をクリックすると、動画中の該当シーンに遷移します。

re:Invent 2024関連の書き起こし記事については、こちらのSpreadsheet に情報をまとめています。合わせてご確認ください!

本編

Generative AIのためのデータ活用:イントロダクション

Thumbnail 0

こんにちは、ようこそ。まず始める前に、Expo Hallが開場していますので、皆様とExpo Hallでのパーティーの間に私たちが立っているような状況です。時間内に収めるよう努めます。「Generative AIのためのデータに関する実践ガイド」へようこそ。私はJonathan Katzです。こちらは2009年からAWSに在籍しているSiva Raghupathyです。彼は長年にわたってデータに関する多くの経験を積んでおり、プレゼンテーションの最後に、私たちが話す内容すべてをまとめていただきます。ステージに briefly 登場していただき、ありがとうございます。

Thumbnail 40

このトークの文脈をお話しすると、すべてはデータフローに関するものです。Vector Databaseやベクトル検索、Generative AIについて、皆様も多く耳にされていることでしょう。しかし、Generative AIの真髄は、長年かけて構築してきた独自のデータソースをすべて Foundation Modelに取り込み、非常に豊かなパーソナライズされた応答を生成することにあります。これはLevel 300のトークですので、可能な限り技術的な詳細に踏み込んでいきます。ただし、これは非常に広範なトピックであり、目標としては、Generative AIアプリケーションを構築する際に、十分な情報に基づいた判断ができるよう、できるだけ多くの戦略をご紹介することです。

自動車保険の例を用いたRAGの概要説明

Thumbnail 90

Thumbnail 110

それを説明するのに、例を挙げるのが一番良いでしょう。さっそく、Patという人物の例を見ていきましょう。Patは自動車保険に加入する必要があります。これは皆さんもよくご存じのことだと思います。自動車保険に加入したことがある方はいらっしゃいますか? 運転履歴、事故記録、支払い履歴、過去の支払額、以前利用していた保険会社など、複雑になる可能性があります。そのパーソナライズされた体験を提供するためには、多くの異なるデータソースから情報を取得する必要があります。また、Patが「自動車保険に興味があります」というような発言をした際の、言葉のニュアンスも理解する必要があります。「興味がある」という言葉には多くの意味が含まれる可能性があります - Patは自動車保険について調べているのか、それとも購入する準備ができているのか?これによって最終的なワークフローが決まってきます。

Thumbnail 140

Thumbnail 170

その応答を提供しようとする際、私たちは持っているすべてのデータをどのように活用して、豊かでパーソナライズされた体験を提供するかを理解する必要があります。これを実現するために確立された手法が、Retrieval Augmented Generation(RAG)と呼ばれるものです。RAGについて聞いたことがある方はいらっしゃいますか?これから素晴らしい内容をお聞きいただけます。というのも、このトーク全体がほぼRAGについてだからです。 私たちの異なるデータベースをRAGに統合する方法を理解するために、まずRAGの仕組みを理解する必要があります。これから、出現している様々なRAG技術のワークフローと、そこでデータがどのように関わってくるのかについて、詳しく見ていきます。

Thumbnail 180

Thumbnail 190

「自動車保険に興味があります」というこの質問について考えてみましょう。もし公開情報だけで学習したFoundation Modelに問いかけた場合、価値のある応答は得られないでしょう。 しかし、運転履歴、支払い履歴、事故記録といった独自のデータソースを取り入れることで、詳細な見積もりを提供できる可能性があります。 このトークの最初のパートでは、この最初の問いかけと応答がどのようなものになるかを見ていきます。その後、より多くのデータソースとテクニックを組み込んで、このアプリケーションを豊かにしていくワークロードの構築を始めていきます。

RAGにおけるコンテキストの重要性と拡張プロンプトの構築

Thumbnail 200

Thumbnail 210

Thumbnail 220

Thumbnail 230

ユーザーの質問から拡張プロンプトを生成するためには、データの出所を理解することが重要です。考慮すべきコンテキストには2種類あります。 まず、状況的コンテキストがあります。これは、その人物に関する情報や、現在の状況、現在のセッションの内容などを指します。 Patの例で言えば、場所、運転履歴、車両の仕様などです。これらは質問している人物について既に把握している事実です。 次に、意味的コンテキストがあります。これは事実に意味を与えるもので、自動車関連の規制、写真、提出された保険金請求などが該当します。

Thumbnail 240

Thumbnail 250

Thumbnail 260

状況的コンテキストは、従来型のエンタープライズデータストア、つまりRelational Databaseやその他の運用データベースなどに、既に存在している可能性が高いでしょう。 意味的コンテキストは、多くの場合、変換されたデータを扱います。これは、検索可能な形式に変換する必要のある、異なるフォーマットのデータです。ここで Vector Databaseや Vector Search Engineと出会うことになるでしょう。 拡張プロンプトを構築する際には、以下の4つのステップを考慮する必要があります:まず、Foundation Modelへの指示(「自動車保険の見積もりを作成している」「情報を作り出さない」など)。次に状況的コンテキスト(ログインしているユーザーの情報など)。そして意味的コンテキスト(例えば、Nevadaの自動車保険販売規制がNew Yorkとは異なる可能性があるため、その確認)。最後にユーザー入力(Foundation Modelによって追加が必要な場合もあります)。

Thumbnail 310

まず理解すべきなのはプロンプトの指示内容です。この場合、フレンドリーな保険代理店として情報を提供することを目指します。 プロンプトの指示は、データベースとは無関係な場合もあります。アプリケーションにハードコードされているか、プロンプトデータベースから取得する必要があるかもしれません。アプリケーションを設計する際には、このフローを理解することが重要です。

Thumbnail 330

Thumbnail 340

Thumbnail 350

次に状況的コンテキストですが、これはほぼ間違いなくデータベースから取得することになります。 これは基本的に事実情報を埋め込むもので、文字列置換のように情報を挿入できるプロンプトを使用するかもしれません。 そして、規則や規制、価格などが含まれるドキュメントコレクションに対して検索を実行する必要がある場合は、意味的情報を追加します。

RAGワークフローの進化:Naive RAGからAdvanced RAGへ

Thumbnail 360

Thumbnail 370

Thumbnail 380

では、この具体的なソリューションをどのように構築するか見ていきましょう。ユーザーがアクセスしてきたとき、 質問はアプリケーションに送られます。最初に行われるのは、質問に基づいてプロンプトリポジトリにアクセスすることです。これは先ほど述べたように、アプリケーションにハードコードされている場合もあります。 Git Repositoryやデータベースに格納されている可能性もあります。それらを取得した後、状況的コンテキストを取得します。これは従来のトランザクショナルアプリケーションで行ってきたことと同様で、単純なデータベースクエリで済むかもしれません。

Thumbnail 390

Thumbnail 400

一方で、ユーザー入力に対してVector Embeddingを生成することになります。 このVector Embeddingは、ユーザー入力の内容を効果的に変換し、最適な応答を見つけるために、他の意味的に関連する要素と比較できる形式に変換します。 Vectorは単なる変換と考えてください。テキスト、画像、動画などのコンテンツを数学的な構造に変換することで、他のコンテンツと比較でき、効果的な共通言語として機能するのです。

Thumbnail 420

Thumbnail 430

Thumbnail 440

最後に、これらすべてを組み合わせて、Generative AIモデル、つまりFoundation Modelに送信して応答を得ます。状況コンテキストについて見てみると、この場合はおそらく皆さんもよくご存知のSQLクエリがあり、意味的コンテキストについては、 OpenSearchデータベースを作成するため、APIコールになります。これも特に目新しいものではありません。私たちは長年これを行ってきました。ただ、すべてを一つにまとめて、 Promptを作成し、回答を得るというわけです。

Thumbnail 460

先ほどのPromptに基づいて、まずPatの情報を検証してから先に進むという回答が得られます。その情報を自然言語で出力し、続行するかどうかを確認します。Patが「はい、その通りです」と答えると、 その地域での自動車保険料が25,000ドルの範囲内であることを伝え、さらに詳しい情報が必要かどうかを尋ねる応答が返ってきます。これだけ幅広い範囲なので、Patはおそらく「はい」と答えるでしょう。意味的には正しいものの、まだ十分な応答とは言えません。

Thumbnail 500

これが、Generative AIにデータソースを組み込む際の重要なポイントとなります。最も適切な応答を提供するために、いかに意味的なコンテンツを充実させるかが課題です。なぜなら、やり取りを何度も繰り返す必要があると、コストがかかってしまうからです。ここまでで、状況コンテキストと意味的コンテキストについて定義してきました。これは、 広範なデータアーキテクチャを構築する際に非常に重要になります。なぜなら、データのクエリ方法や取り込み方に影響を与えるからです。

Thumbnail 520

パフォーマンスやタイミング、そして最終的にユーザーとのやり取りを最小限に抑える方法を考える必要があります。ここにはコストが発生します。Foundation Modelへのクエリのコストだけでなく、 大量に生成する場合、入力トークンと出力トークンの生成にかかるコストもかなり大きくなる可能性があります。従来のアプリケーション開発でユーザーのクリック数が多いほど取引完了率が下がるのと同様に、仮想AI体験でユーザーが質問や回答を多く求められるほど、取引完了率は低下します。

Thumbnail 550

このトークの残りの部分では、これらのインタラクションをどのように最適化し、このデータにできるだけ多くのセマンティックな意味を持たせるかについて説明します。私たちは様々なRAGテクニックを活用し、RAGの基盤を構築していきます。そして、必要に応じてより複雑なテクニックを追加していく過程を見ていきます。さらに、これが私たちのデータ基盤全体にどのように適合するのか、特にデータソースの理解とAI利用のためのデータ準備について見ていきます。最後に、データの分散や様々なプライベートデータソースを含め、それらをすべて接続して豊かなGenerative AIアプリケーションを実現する方法を見ていきます。

RAGの実装:データの準備からVector検索まで

Thumbnail 580

Thumbnail 590

Thumbnail 600

では、これまでのRAGの進展とその発展について、楽しく見ていきましょう。セマンティックデータを構築しようとする場合、PDFドキュメントをEmbeddingモデルで使用できる適切なサイズのチャンクに変換する必要があります。なぜなら、Embeddingモデルは文書全体を一度に読み込むことができないからです。

Thumbnail 610

Thumbnail 630

Thumbnail 640

Embeddingモデルは、これらのテキストチャンクをベクトルに変換し、Vector databaseに保存します。これがアプリケーションにセマンティックコンテキストを追加する第一段階、つまりインジェストパイプラインです。次の段階は、お客様が実際に目にする部分です。例えば、お客様が「自動車保険について知りたい」という質問をする際の対話型ワークフローです。これがGenerative AIアプリケーションに送られ、その質問がEmbeddingに変換され、Vector database内で類似性検索が実行され、回答が返されます。そしてプロンプトを補強してユーザーに回答を提供することができます。

Thumbnail 650

Thumbnail 660

これが対話型ワークフローです。そしてこれら2つのプロセスは連携して機能します。なぜなら、セマンティックコンテキストの検索のためにデータを常に新鮮で最新の状態に保ち、効果的にクエリを実行できる必要があるからです。これが最終的な目標です。RAGで使用できる手法は、Naive RAGから始まります。これは少し誤解を招く名前かもしれません。後で見る手法と比べると「素朴」ですが、実際には基本となる手法です。つまり、先ほど見たワークフローで、質問が入力され、データベースに対してクエリを実行し、応答を返して終了するというものです。多くの場合、これで十分かもしれませんが、Patの保険の例で見たように、特定のアプリケーションに対して必ずしも最適な応答が得られるとは限りません。

Thumbnail 690

Thumbnail 710

ここで登場するのがAdvanced RAGです。データにアクセスしてより多くのコンテキストを提供するために、さまざまな検索テクニックを使用できます。例えば、Patの運転履歴に関する情報があれば、実際の見積もりを絞り込むのに役立ちます。最後にModular RAGがあります。Advanced RAGでは、複数のデータソースから情報を取得し、複数のKnowledge baseを設定することが多いため、最も正確な応答を提供するために異なるKnowledge base間で選択する方法が必要になります。さらに、応答を生成するために複数のリソースに同時にクエリを実行する必要がある多段階のワークフローが必要になることもあり、このプロセスを自動化することで大幅な時間の節約になります。

Thumbnail 730

Thumbnail 740

Thumbnail 760

Naive RAGとは実際どのようなものなのでしょうか?これは基礎的なRAGと呼ぶべきものです。なぜなら、これは初期設計と技術選定を行う基本的なワークフローだからです。 データの準備や検索技術に関する意思決定を行いますが、本質的には技術選定が重要です。つまり、どのようなフレームワークを使用するか、どのFoundation ModelやEmbedding Modelを採用するか、どのようなデータストレージを導入するか、どのデータベースを使用するか、そしてどのような追加技術をスタックに加えるかということです。 シンプルで素朴なワークフローではありますが、基盤を築くことが目的です。最終的には、高度なRAG技術を追加し、さらなるデータやコンテキストを取り入れながら、反復的に改善していくものなのです。

Thumbnail 780

Thumbnail 820

簡単な例を見てみましょう。 完全なコード例は作成しませんが、RAGワークフローを実装するための多くのプリミティブを提供するオープンソースフレームワークのLangChainを見てみましょう。これは他のアプリケーションのプログラミングと同じように見えるはずです。ただし、Generative AIのために構築するという点が異なります。特に状況コンテキストに注目してほしいのですが、LangChainの呼び出しに加えて、Postgresを使用している方々にはお馴染みのPython Postgresライブラリの呼び出しがあることにお気づきでしょう。これは状況コンテキストを確立する一部であり、これまで使用してきたデータソースからSQLクエリを実行して状況情報を取得する部分です。

Thumbnail 830

興味深い側面の1つは、Semanticコンテキストの取り込みです。ユーザーが利用できるようにSemantic コンテキストを構築する際の重要な部分は、取り込みワークフローであり、これにはパイプラインが必要になります。私がアプリ開発者だった頃、最初のパイプラインをメール管理アプリケーションで構築したことを思い出します。当時は未熟で、すべてをトランザクション的に処理しようとしていました。つまり、何かが入力されたら、メールを送信して終了という具合でした。これはウェブリクエストの一部でした。しかし、一度に100通のメールを送信することになると、ウェブリクエストが非常に遅くなりました。これは良くないと気づき、リクエストを非同期で処理するためにキューに入れるパイプラインを構築しました。それは素晴らしいと思いましたが、すぐにこの非同期メールパイプラインの監視やその他の側面の管理が必要だということに気づきました。現在ではこれらの実装ははるかに簡単になっていますが、パイプライン管理には依然として課題があるということです。

Thumbnail 900

ドキュメントがアップロードされる例を見てみましょう。ドキュメントを取得し、チャンクに分割し、ベクトル化して、OpenSearchデータベースに保存します。 最終的には類似性検索を実行できますが、最初の2つのステップは非同期で実行される可能性が高いです。そのため、このプロセスを効果的に管理する必要があります。

Thumbnail 910

このプロセスを効果的に管理するには、常に管理できる場所にそのコードを配置する必要があります。 ここで、Amazon Bedrock Knowledge Basesのような機能が役立ちます。Knowledge Basesはその部分を自動化し、基本的にパイプラインの取り込みを代行してくれます。独自のパイプラインを管理するコードを書く代わりに、Bedrock Knowledge Basesを使用して、Amazon S3バケット内のすべてのドキュメントを管理できます。ドキュメントが追加されたり削除されたりすることがありますが、Knowledge Basesがそれを検知し、ベクトルデータベースを更新して自動的に行を追加または削除し、すべてのデータを最新の状態に保ちます。

Thumbnail 940

Thumbnail 950

データを管理するライブラリを置き換えるだけで、コードがはるかにシンプルになります。パイプライン管理のコードをすべて書く必要はなく、管理コンソールでチャンクサイズやデータの送信先、データベースに格納されているデータのソースを指定するだけです。そのような心配は不要で、Similarity Searchの側面に集中できます。データ基盤を確立する際に注目すべき点の1つは、パイプライン管理のような作業をどこで自動化できるかということです。パイプラインは必ずしも差別化要因ではありません。アプリケーションこそが差別化要因なのです。データソースの準備とアプリケーションへの取り込みに集中できることで、全体的な管理時間を節約することができます。

Advanced RAGテクニック:Hybrid SearchとGraphRAGの活用

Thumbnail 990

では、Naive RAGのトレードオフとは何でしょうか?基礎的なRAGだと言い続けているにもかかわらず、「Naive」という言葉を使い続けているのには理由があります。非常にシンプルであり、シンプルであることは良いことです。シンプルであれば始めやすく、多くの異なるワークフローに対応できるかもしれません。しかし、必ずしもセマンティックデータのニュアンスを完全に捉えられるわけではありません。先ほどの自動車保険の例に戻ると、自動車保険が25,000ドルかかる可能性があるという回答は、適切にカスタマイズされた回答とは言えません。必要なすべてのガードレールを設定できない可能性があります。より個別化された回答を得るためには、複数の検索方法を組み合わせる必要があるかもしれません。そこで登場するのがAdvanced RAGです。

Thumbnail 1040

Thumbnail 1060

この例に戻ってみましょう。Patは3台の車を所有していて、そのうちの1台が事故を起こしましたが、その時点でPatはその車を所有していなかったと言いました。しかし、このNaive RAGの手法だけを使用すると、エージェントが「2台目の車が事故を起こしているため、超お得なプレミアム割引レートは適用できません」と判断してしまい、その状況を正しく理解できない可能性があります。Patは「待ってください、何の話ですか?その車は何年も前に売却しましたよ」と反論するでしょう。しかし、基本的なSimilarity Searchだけを使用している場合、エージェントはその要求に対応するための十分な情報を持っていない可能性があります。この時点で、Patは自分の運転記録を理解していない保険会社からは車の保険を購入したくないと考えて、フラストレーションを感じているでしょう。

Thumbnail 1080

Thumbnail 1110

Advanced RAGで文脈をより多く取り入れるのに役立ついくつかの手法を見てみましょう。まず、Advanced RAGのワークフローを理解するために、Pre-retrieval Tasksがあります。質問が入ってきたとき、質問をカスタマイズするための追加作業を行うことができます。例えば、エージェントのワークフローでトランザクションを完了しないようにしたり、人間のエージェントが対応する必要がある場合を示したりするようなガードレールを追加できます。探索するデータを前処理するための他の手法もあります。次に、より高度な検索を行うための複数の手法を見ることになるContext Retrievalがあります。最後に、Post-retrieval Tasksがあり、ここではデータをフィルタリングするための追加のガードレールを設定したり、再ランク付けや要約を行ったりする必要があるかもしれません。

Thumbnail 1120

Thumbnail 1130

Thumbnail 1160

最初の手法はHybrid Searchです。Hybrid Searchは、質問の文脈に基づいてより多くのセマンティックな意味を引き出す方法の1つです。先ほど話した例では、「interested」という言葉がありました。「interested」は単に自動車保険の購入を検討しているという意味なのか、それとも「購入する準備ができている、さあ始めましょう」という意味なのか。Hybrid Searchを使用することで、Full Text Search技術を使用してテキストの意味をより深く理解し、Vector Searchと組み合わせ、最終的にそれらを再ランク付けすることができます。これにより、Embedding Modelで確立したセマンティックな関係と、確立した一般的なテキストコーパスの両方の意味を取り入れることができます。

Thumbnail 1170

Thumbnail 1180

Thumbnail 1200

Hybrid searchはさまざまな方法で活用されています。コンテンツ生成、要約、感情分析など、多岐にわたります。ある意味では、データの品質が本当に最高のものであることを確認するための追加のチェックとしても機能します。例を見てみましょう:「自動車保険に興味があります」。これは、Patが提案している内容が違法でない、不適切でないことを確認することで、ガードレールを追加できる場面の一つです。また、この文脈における「興味がある」という言葉の意味をさらに深く理解することもできます。これは「購入」を意味しているのでしょうか?そのため、「購入」と書き換えた場合、異なる検索をしてみましょう。所有するすべてのドキュメントに対してVector searchを実行して、この言葉が本当に何を意味するのかを確認します。

Thumbnail 1220

また、長年行ってきた従来のテキストベースの検索も実行します。すべてのドキュメントとその意味を確認し、それらをすべて集めて結果を得ます。これにより、検索結果の関連性を高めることができます。Vector searchを、期待される結果がどれだけ返されるかを測定するRecallの観点で考えると、これはRecallを向上させるのに役立つテクニックと言えます。

しかし、良いものには必ずトレードオフがあります。このケースでは、2つの異なるレイテンシーを持つ検索を実行し、最終的に再ランク付けを行う必要があるため、検索速度が若干遅くなる可能性があります。再ランク付け自体は通常高速ですが、より質の高い結果が得られれば、自動車保険を購入するPatにより個人化された体験を提供できます。これらのテクニックを検討する際の主要な課題となります。どこかでコストを支払う必要がありますが、理想的には、データベースの応答時間が少し遅くなるというコストよりも、ユーザー体験やユーザーの最終目標に対するリターンの方が大きくなるようにしたいものです。

Thumbnail 1280

Thumbnail 1300

Thumbnail 1310

Thumbnail 1320

次に、GraphRAGは、データ間のより多くの関係性を見つけることができるため、RAGワークフローにおける情報を強化できる別のRAGテクニックです。先ほどの「自動車保険に興味があります」という例を再び取り上げてみましょう。このケースでは、言葉の意味よりも、Patの車の所有履歴を理解することに重点を置いています。なぜなら、通常、車の事故を起こすと自動車保険料が上がるからです。Patの2台目の車が事故を起こしたことは事実ですが、その時点でPatはその車を所有していませんでした。データのグラフや関係性のマッピングがあれば、系統を確認して、Patがその車を所有していなかったことがわかります。別の人がその車を所有していて、その時に事故を起こしたということがわかります。これは良いことです。なぜなら、Patは低リスクドライバーであり、最も優遇された保険料を提示できるからです。

GraphRAGを使用すると、特にデータの系統を作成した場合、データの背後にある意味をより深く理解できます。ただし、コストがかかり、クエリの生成にも時間がかかる可能性があります。グラフの検索に特化して設計されたAmazon Neptune AnalyticsやAmazon Neptuneを使用して検索を実行し、応答を強化することができます。しかし最終的には、そのようなデータの検索に最も適したテクニックを使用することが重要です。

Thumbnail 1370

Thumbnail 1380

Advanced RAGには、コンテキストの要約など、他の要素も取り入れることができます。Naive RAGや一般的なRAGの課題の1つは、入力トークンにコストがかかることです。多くの入力トークンがあり、実質的にトークンごとに料金が発生しますが、それらのトークンの中には意味を持たないものもあるかもしれません。例えば、ネバダ州の自動車保険規制について考えてみましょう。私は実際には読んだことがありませんが、きっと非常に詳細な情報が含まれているはずです。情報が多すぎる場合、Foundation Modelには「lost in the middle」と呼ばれる課題があり、適切な回答にまとめることができない可能性があります。

Thumbnail 1400

Thumbnail 1410

Thumbnail 1430

しかし、この問題に対処するための要約というテクニックがあります。保険規制を取り上げ、大規模なFoundation Modelに送る前に、より小規模なLarge Language Modelに送ります。小規模なLarge Language Modelは迅速な応答を返すことができますが、保険規制の要点を要約することができます。その要約をプロンプトに入れ、そのプロンプトを大規模なFoundation Modelに送ります。これは、コストを節約しつつ、より良い応答を得るための効果的なテクニックです。特に、元の情報が多すぎて、顧客への最終的な応答で意味のある内容を得ることが難しい場合に有効です。

Modular RAGとSemantic Caching:RAGの更なる進化

Thumbnail 1450

Thumbnail 1470

他のAdvanced RAGテクニックにはどのようなものがあるでしょうか?私のお気に入りの1つは自然言語クエリです。SQLを書くのが大好きなので、自然言語クエリがこれほど強力になってきているのは少し寂しい気もしますが、少なくともSQLがなくなることはないと分かっています。重要なのは、Generative AIアプリケーションに入ってくる質問のすべてが、必ずしもベクトルに変換する必要があるわけではないということです。例えば、Patが昨年の自動車保険料を知りたい場合、それは「select * from payment_history where user = 'Pat'」のようなものです。この場合、質問が入ってきたときに、その情報がすべてAmazon Redshiftクラスターにあれば、そのスキーマを取得し、そのスキーマを拡張プロンプトに入れて理解することができます。

Thumbnail 1520

データ間の関係を理解し、最終的にSQLクエリを出力します。SQLクエリは自然言語クエリを表現し、それをデータベースに対して実行して応答を返すことができます。これが非常に強力な理由は、データを変換する必要がない点です。質問を受け取り、クエリに変換し、既存のデータに対して実行して答えを得ることができれば、それは非常に効果的です。このようなデータをデータウェアハウスに保存し、最終的にベクトルに変換する場合、いくつかの潜在的な問題があります。まず、ベクトル表現が元のデータよりも大きくなり、データが膨張する可能性があります。さらに、別のパイプラインを管理する必要があります。プレゼンテーションの前半で説明したように、パイプラインを管理するたびに、構築しているアプリケーションにとって最終的に差別化されない作業が増えることになります。データをその場で照会できるのであれば、そうすべきですし、それをGenerative AIの形で組み込むこともできます。

Thumbnail 1570

Thumbnail 1610

Naive RAGとAdvanced RAGについてかなり説明してきましたが、それぞれをいつ使用すべきでしょうか?実は、Naive RAGは常に使用しています。これは基本となるRAGだからです。これは少しトリッキーな質問でしたね。では、いつNaive RAGを使い続けるべきでしょうか?基本的に、ロジックが関係ない場合です。もちろんコンピューターを使用していますが、プライベートデータソースとの非常にシンプルなQ&Aであれば、Naive RAGを使用できます。質問について考える必要がなく、基本的にセマンティックな情報を持つデータベース内の事実であれば、それを返すことができます。しかし、自動車保険料に関する意味のある情報を持ち、その回答への道筋を提供できるようにしたいなど、よりパーソナライズされた対応を望み始めた時点で、おそらくAdvanced RAGが必要になるでしょう。このような場合のパーソナライゼーションは良いものですが、コストとそのトレードオフを理解することが重要です。データベース部分のクエリでより多くのコストを支払いたいのか、それともFoundation Modelでより多くのコストを支払いたいのか。最終的に、アプリケーションが成熟するにつれて、より良い応答を提供するためにAdvanced RAGへと進化していく可能性が高いでしょう。

Thumbnail 1650

Thumbnail 1680

さて、ここからが面白い部分です。様々な情報を含む複数のKnowledge Baseを構築してきましたが、特定のKnowledge Baseをいつ使用すべきかをどのように判断すればよいのでしょうか?アプリケーションにそのロジックを組み込むことはできますが、それは困難な作業となります。なぜなら、様々な異なるデータソースがあり、それらをいつ使用すべきか分からない状況では、いわばエージェントのためのエージェントが必要になってしまうからです。ここでModular RAGの出番となります。私たちは適切なタイミングで適切なデータソースを選択したいのです。この手法は現在も進化を続けていますが、急速に普及しつつある事前検索クエリルーティングです。これにより、入力される質問に基づいて、異なるKnowledge Baseや検索手法の中から適切なものを選択することができます。

Thumbnail 1690

Thumbnail 1710

こちらは、LlamaIndexのコードを使用して複数のストレージシステムに対してクエリを実行する例です。ご覧の通り、これはすぐに非常に複雑になってしまい、何をすべきかを判断するためのAIモデルを構築しているような感覚になります。ここで、Amazon Bedrockのエージェント機能が役立ちます。Bedrockエージェントは、回答を作成するために複数のソースにアクセスしたり、回答に情報を追加するために複数の異なるサービスを呼び出したりする必要がある、複数ステップのワークフローのオーケストレーションを支援してくれます。オーケストレーションを自動化できれば、差別化されていない重労働を削減できます。これは、自動化すればするほど、必要なアプリケーション固有のロジックを追加しやすくなるため、このプレゼンテーションを通じて私のお気に入りのフレーズとなりました。

Thumbnail 1740

Thumbnail 1750

Thumbnail 1770

Patの自動車保険の事例を見てみましょう。「自動車保険に興味があります」という質問が入ってきた時、ワークフローの最初の部分では、様々なコンテキストを取り込むことになります。多くのコンテキストはデータベースにありますが、まだ更新されていないDMVの記録を直接照会する必要があるかもしれませんし、Patの請求履歴やクレジットレポートを取得する必要があるかもしれません。エージェントは、与えられたコンテキストに基づいて、そのデータを自動的に作成することができます。そして、コンテキストを理解した後、追加のステップが必要になるかもしれません。例えば、Patの自動車保険が事前承認される場合、保険料の見積もりを取得し、特定の日付にPatに提示した保険料見積もりを記録するためにデータベースを更新するなど、様々なタスクを実行することができます。

Thumbnail 1790

これは非常に素晴らしい機能です。なぜなら、このような複数ステップのエージェントワークフローを設定した後は、単なるAPI呼び出しで済むからです。APIを呼び出してこのワークフローを開始すると、Amazon Bedrockエージェントがこれらの異なるステップを実行する複雑な作業を行い、最終的にPatに自動車保険の見積もりを提供する回答を届けてくれます。

Thumbnail 1810

Thumbnail 1820

最後に、Semantic cachingについて説明する必要があります。Foundation Modelに対してどの程度のクエリを実行するかについて何度か言及してきましたが、Semantic cachingは、Foundation Modelに対して類似の質問や類似のプロンプトがある場合に、Foundation Modelの呼び出しをショートサーキットできる手法です。キャッシングは複数のレベルで行うことができます:質問のみ、拡張されたコンテキストを含む質問、あるいは質問、コンテキスト、回答のすべてを含むものなどです。

Thumbnail 1840

Semantic cachingの課題は、すべてのキャッシングと同様にスコープの問題です。 シンプルなパブリックのQ&Aチャットボットであれば、おそらくすべてをキャッシュすることになります。しかし、テナント指向やユーザー指向の場合、特定のモデルがどの程度使用されているかによって、Semantic cachingが適切かどうかが変わってきます。例えば自動車保険の場合、非常にユーザー指向であり、個別のやり取りになる可能性が高いため、キャッシング技術を使用することは必ずしも適切ではないかもしれません。しかし、米国全体の自動車保険とその規則について一般的に話すチャットボットであれば、Semantic cacheを活用できる可能性があります。

RAGのためのデータ準備:構造化から非構造化データまで

Thumbnail 1870

仕組みについて説明しましょう。これは私たちがよく目にする一般的なエージェントのワークフローです。質問が入力されたとき、あるいはコンテキストを含む質問が入力されたとき、まずAmazon MemoryDBなどでその内容を確認します。Vector検索を実行して、その内容が存在するかどうかを確認できます。存在しない場合は、Foundation modelに問い合わせて回答を取得し、それをAmazon MemoryDBインスタンスに保存します。しかし、Semantic cachingでキャッシュヒットした場合は、ワークフローの下半分全体をスキップできます。これには2つの利点があります:誰もが好む高速な回答が得られること、そしてFoundation modelへの呼び出しが不要になることでコスト削減につながることです。

Thumbnail 1920

Thumbnail 1950

では、データの準備方法を見ていきましょう。これまで様々なRAGワークフローと、そこにデータを取り込む方法について見てきました。 まず、構造化データですが、これは定義されたスキーマを持っています。意味とパターンがあります。用途によっては、自然言語クエリを直接実行できるため、準備が不要な場合もあります。これは状況的なコンテキストが存在する可能性が高い場所です。

Thumbnail 1980

次に半構造化データですが、これはユニークな特徴を持っています。依然として構造化データですが、構造の定義がより緩やかです。例えば、JSONは構造を持っていますが時間とともに進化する可能性があります。また、データレイクに存在するデータでも、スキーマが時間とともに進化する可能性があります。このデータは状況的コンテキストにもセマンティックコンテキストにもなり得るため、何らかの準備が必要かもしれません。 最後に非構造化データですが、これは意味を把握できていないデータです。ここでEmbedding modelが重要になります。なぜなら、これらのEmbedding modelがデータに意味を与えるからです。この場合、何らかの変換が必要になります。

Thumbnail 1990

RAGアプリケーションのための非構造化データの準備方法から始めましょう。ソース情報(この場合はドキュメント)があり、まずこれをチャンク分割する必要があります。Chunkingとは、ドキュメントを適切なサイズに分割し、Embedding modelに投入する方法です。Embedding modelはこれらのチャンクをベクトルに変換します。チャンク分割が必要な理由は、Embedding modelが文書全体を処理できない場合があることや、コストが高くなりすぎる可能性があるためです。たとえコンテキストウィンドウが十分に大きくても、それが必ずしも適切とは限らず、適切な意味を捉えられない可能性があります。

Thumbnail 2040

では、Chunkingの戦略をどのように選べばよいのでしょうか?最も手軽なアプローチは、Fixed Chunkingと呼ばれる方法です。これは、256トークンのような標準的な数値で、一定のトークン数でChunkingを行う方法です。実装が非常に簡単である一方で、解決しようとしている特定の問題に必要なコンテキストを十分に捉えきれない可能性があります。例えば、Nevadaの保険規制を見る場合、単純にチャンクに分割すると、特定の規制の意味を見落としてしまう可能性があります。法規制の場合、そのようなコンテキストの欠落は問題になりかねません。

Thumbnail 2080

次に、定義されたスキーマがある場合のSchematic ChunkingまたはStructural Chunkingがあります。これは、HTMLのような擬似構造化または半構造化されたドキュメントを解析する場合に特に有効です。定義されたスキーマがある場合は素晴らしい方法ですが、ない場合は推測に頼らざるを得ません。例えば、段落でChunkingを行う場合、その中に意味が含まれているかもしれません。私の場合、各段落が独立した意味を持つように心がけていますが、それが常に可能とは限りません。

Thumbnail 2110

Hierarchical Chunkingは、グループや階層を定義してChunkingを行うもう一つのアプローチです。これはStructural Chunkingに似ていますが、必ずしも構造が分かっているわけではないため、ルールを設定する必要があります。このアプローチの利点は、ルールを定義できれば、Nevadaの保険規制の各セクションのように、特定のポイントの周りのコンテキストをすべて定義できるため、意味のあるChunkを得られることです。ただし、ドメインの理解が必要で、さまざまなソースから多数のドキュメントが入ってくる場合、このChunking戦略が必ずしも機能するとは限りません。

Thumbnail 2150

Semantic Chunkingは最も強力な戦略となるでしょう。なぜなら、Embeddingモデルを効果的に使用して、異なるChunk間の意味を見つけ出すからです。ドキュメント全体を分析し、Semantic検索を行う際に最も関連性の高い結果が得られるようにChunkに分割します。より多くの時間とリソースが必要で、追加のコストがかかりますが、手法が進化するにつれて、特に成熟したアプリケーションでは、最終的にHierarchical ChunkingかSemantic Chunkingのいずれかを採用することになるでしょう。これらのChunking手法にはそれぞれトレードオフがあります。何かが機能することを示す簡単なProof of Conceptを構築したい場合は、Fixed Chunkingが適していますが、最終的にはより意味のある方法を選択する必要があります。

Thumbnail 2190

構造化データと半構造化データについては、すでに自然言語クエリを使用してデータを照会できることを紹介しました。データの中には、変換によって引き出す必要のある意味的な意味が存在する可能性があり、これは実際に本番環境でお客様が行っていることです。リレーショナルデータベースやData Warehouse内のデータを取り出し、データベース内のテキストBlobやJSONドキュメントなどの形式に変換し、それをVectorに変換します。その後、アプリケーションで意味的な意味を別の方法で引き出す必要がある場合は、Semantic検索の一部として使用できます。ただし、これは継続的に最新の状態を保つ必要のあるパイプライン管理の問題であることを覚えておいてください。

Thumbnail 2250

チャンクサイズを決定する際、セマンティックチャンキングを使用してある程度自動的に判断される場合を除き、バランスを取る必要があります。一般的に、意味があまり重要でない単純な質疑応答などのアプリケーションでは、小さなチャンクが適しています。一方、非常に具体的な情報や、大きなコードブロック、テキスト、保険規制などを扱う場合は、そのコンテキストを捉えるために大きなチャンクが必要になることがあります。アプリケーションに最適なサイズは、実験を重ねて見つけていく必要があります。階層的チャンキングを採用する場合は、その多くが自動的に決定されますが、Embeddingモデルやデータベースの保存コストに基づいて、チャンクサイズに上限を設ける必要があるかもしれません。

さて、私の好きなトピックの1つであるVector検索について説明しましょう。本日早い時間帯に、PostgreSQLに関するこのトピックを深く掘り下げたブレイクアウトセッション「DAT423」を行いました。講演の約3分の2が経過した今になってVector検索の選択について触れているのは、意図的なものです。なぜなら、Retrieval Augmented Generation(RAG)において、Vector検索は単なる構成要素の1つに過ぎないからです。アプリケーションの意味づけの多くは、従来型のエンタープライズトランザクション運用分析ストアや、場合によってはVectorに変換された非構造化データなど、様々なソースから得られます。

Thumbnail 2330

Thumbnail 2350

Vector検索ソリューションを選ぶ際は、まず馴染みのあるものから始めましょう。 実際の用途に応じて、多くのパフォーマンス特性は非常に似通っています。実装のしやすさを考慮して、最も使い慣れたソリューションを選択することをお勧めします。パーソナライゼーションの実現は、選択するRAGテクニックに依存することを忘れないでください。Naive RAGから始める必要がありますが、最終的にはAdvanced RAGへと進化していくため、スタック全体を通じて快適に統合できるVector検索ソリューションを選ぶことが重要です。

Thumbnail 2370

スケールビルディングのパフォーマンスは重要かもしれませんが、それはデータセットのサイズによります。扱うVectorの数が「大規模」という定義は、人によって異なります。私にとっては最近では数十億規模を指しますが、数十万のVectorを扱う場合でも「多い」と表現する人もいます。これらのソリューションはいずれもそうした規模を迅速に処理できるため、馴染みやすさと実装のしやすさが重要になってきます。なぜなら、生成AIアプリケーションでパーソナライズされたレスポンスを提供するために、何度も繰り返し改善を重ねることになるからです。

Thumbnail 2400

私たちはVector検索を組み込んだ様々なデータベースを提供しています。

Vector検索を組み込んだデータベースは数多く存在し、それぞれが性能、速度、スケールに関して様々なクエリ技術と共に類似した機能を提供しています。使い慣れているかどうか以外の観点で特定のデータベースを選ぶ際には、自分の特定のドメイン課題を解決できるものを選ぶことが重要です。例えば、GraphRAGを活用して情報グラフを検索する必要がある場合は、その用途に特化して構築されているAmazon Neptune Analyticsを選ぶことになるでしょう。全文検索が必要な場合は、その用途のために作られたAmazon OpenSearch Serviceを使用することになります。最終的には、まずは最も使いやすいソリューションを選び、より深いユースケースのアーキテクチャを検討していく中で、自分に合ったソリューションを見つけていくことができます。

Thumbnail 2460

Vectorのインデックス化において、近似最近傍検索を行っているということを理解することが重要です。つまり、必ずしもベストな結果をすべて返すわけではないということです。検索の関連性は再現率(Recall)で測定する必要があります。100%の再現率、つまり検索対象の中から常に最適な候補を確実に見つける必要がある場合は、Vectorインデックスは使用しません。選択性が高い場合は、リレーショナルデータベースのB-treeを使用すれば非常に高速な検索が可能です。しかし、常に最高品質の結果を確実に得たい場合は、近似最近傍技術は使用しません。

Thumbnail 2500

利用可能なさまざまなVectorインデックスの中で、HNSW(Hierarchical Navigable Small Worlds)が最も人気のあるものとして台頭しています。HNSWは多くのユースケースで機能し、開発者にとって非常に扱いやすいものです。なぜなら、データの追加や削除が可能な従来のインデックスと同様の動作をするからです。インデックスが自動更新と削除機能を許可している限り、自動的に更新されます。HNSWではそれを実現するのは少し難しいのですが、可能です。開発者の立場からすれば、その技術的な詳細を気にする必要はありません。簡単で、うまく動作し、高品質な結果を良好なパフォーマンスで提供してくれるからです。

Thumbnail 2540

Thumbnail 2580

HNSWインデックスは非常に大きくなる傾向があることに気付くかもしれません。これは容量を多く必要とするインデックスだからです。Quantizationは、Vectorのサイズを縮小することでストレージを削減する技術ですが、再現率に影響を与えます。これにはトレードオフが生じます:データベースのストレージを削減し、潜在的に応答を高速化できますが、望ましい関連性が得られない可能性があります。コストの大部分を占めるのはFoundation Modelの方なので、ストレージ削減によるコスト削減がFoundation Modelのコストに見合うかどうかを検討する必要があります。Quantizationはすべてのアプリケーションに適しているわけではないので、データサイエンスチームと協力して最適なアプローチを決定すべきです。最後に、選択性が高い(非常に少ない結果を返す)場合は、他のインデックスタイプの方が適している可能性があります。そのような場合は、代替のインデックス方式を検討することをお勧めします。

RAGのためのデータアーキテクチャ設計:ベストプラクティスと実装例

Thumbnail 2620

Thumbnail 2650

Thumbnail 2670

Thumbnail 2680

これまでデータをパーソナライズするための様々なRAG技術と、そのデータの準備方法について説明してきましたが、ここでこのデータフローをどのように組み合わせるかを見ていきましょう。 RAGアプリケーションでは、常にコンテキストが重要です。コンテキストは、運用データベース、データウェアハウス、データレイク、ストリーミングデータストアから得られます。保険の例で考えてみましょう: 顧客プロファイルはリレーショナルデータベースに保存され、裁判記録、保険契約情報、請求データなどの履歴は、データウェアハウスやデータレイクに保存されているかもしれません。Jonathanが言及した州固有の規制などのルールは、おそらくS3などのファイルストアやデータレイクにPDFドキュメントとして保存されています。一部の保険会社では、運転特性に関するデータを送信する装置やアプリを車に設置する使用量ベースの保険を提供しており、これによって割引につながる可能性のあるストリーミングデータが生成されます。

Thumbnail 2700

DMVは運転免許情報や車両記録を管理しています。この情報は、車両販売や事故報告を含む様々なプロセスにおいて重要な役割を果たします。

Thumbnail 2720

例えば、以前お話ししたように、車の販売データがシステムに反映されていないという問題により、2台目の車が事故に遭う可能性があるというケースがありました。これらのデータは全て、企業のデータシステムに集約されることになります。 これには多くの課題があります。データは様々なデータサイロに存在しており、そのデータの系統(つまり、データの出所)を追跡できる必要があります。データ品質の問題については、2つのソースからデータを取得している場合、それを更新して同期を保つ必要があります。また、入力されるデータの品質を理解し、評価する必要があります。

PIIデータについても考慮が必要です。例えば、顧客のクレジット履歴や社会保障番号を取得する場合があります。DMVからドライバー情報を取得する場合、通常は機密情報である運転免許証ID、氏名、住所などの情報も含まれます。パイプラインはこれらのデータを扱い、管理し、場合によってはトークン化する必要があります。さらに、Identity Resolutionという課題もあります。DMVは運転免許証IDで、信用情報機関は社会保障番号で、そして組織内では顧客IDで個人を識別します。これら3つは同一人物を表すものなので、これらを照合して同一の顧客であることを特定するシステムが必要です。アクセス制御については、Chatbotアプリケーションを作成する場合、適切な権限で関連データにアクセスする必要があります。

Thumbnail 2820

私はAWSで多くのBig Dataパイプラインを構築してきましたが、新しいサービスのローンチやその他の変更に関係なく、時間の試練に耐えた5つのルールを体系化しています。それらをご紹介したいと思います。まず、Big Dataアプリケーションやアーキテクチャを構築する際は、 常にパイプラインのように感じます。一方からデータが入り、もう一方から答えが出てくるというものです。その間にあるのが、扱うデータの種類です。デカップルされたシステムを構築する場合は、処理ステージを設けて構築します。システムを挟んで2つの処理状況があり、これをストレージサブシステムでデカップルします。

Thumbnail 2870

例えば、ストリーム処理を行う場合、データストリーム(車両に設置したデバイスから得られる運転に関する全ての情報)を取得し、それをAmazon Kinesisに格納します。データを格納したら、処理ステージでApache Spark StreamingやApache Flinkを使用することになるでしょう。このデータに対してGraph RAGを実行したい場合は、そのデータをグラフデータベースに格納する必要があります。 パイプラインの各ステージで使用するテクノロジーやツールは、扱うデータの構造、データの格納先、そして要求されるレイテンシーに基づいて選択します。つまり、適切な場所にデータを格納するためには、アクセスパターンを理解する必要があるのです。

Thumbnail 2890

Thumbnail 2910

ベストプラクティスとしては、このようなクラスター管理の問題全体に対処するマネージドサービスがある場合、そのマネージドサービスやサーバーレスサービスを利用することをお勧めします。そうすることで、クラスターの管理ではなく、アプリケーションの改善に時間を費やすことができます。 ストリーミングデータに関しては、Amazon S3にデータのコピーを保存することが常にベストプラクティスです - これを私はLog-centricデザインパターンと呼んでいます。私は長年データビジネスに携わってきましたが、データベースでさえ、まず最初にトランザクションログに書き込み、その後でページバックアップなど様々なシステムにデータを具現化しています。

Thumbnail 2940

この同様のパラダイムを使用して、Amazon S3にデータのコピーを保持します。アプリケーションにはバグが発生することもあるので、オリジナルのデータに戻れるようにしておくことは常に良いアイデアです。Materialized Viewを作成することも非常に重要になってきます。 最後に重要なのは、ビッグデータが大きなコストを意味するべきではないということです。顧客向けのデザインレビューを行う際は、いつも20〜30分経過後に一度中断して、エンドツーエンドのソリューションのコストを確認します。多くの場合、コストのバランスが取れていません。これは、適切なツールを使用していないか、顧客のニーズに合わせてデザインを変更する必要があることを意味します。AWSでデータサービスを構築する際は、低コストで機能を極めて効率的に実行できるように設計しています。大きなコストが発生している場合、おそらく適切なサービスを使用していない可能性があります。

Thumbnail 2990

では、これはRAGにどう関連するのでしょうか?RAGパイプライン、つまりRAGに適切なデータアーキテクチャを選択することは、常にサービングレイヤーの作成を伴います。私にはETLのように感じます - サービングレイヤーを構築するのです。 例えば、Graphデータベースにデータを具現化したい場合は、Graphデータベースにデータを配置する必要があります。実際の要件として、一部のRAGシステムでは、検索しようとしている内容のセマンティックな意味を具現化するために、数十回、あるいは数百回のリクエストを行う必要があるかもしれません。

一部のRAGシステムでは、探そうとしている内容のセマンティックな意味を具現化するために数百回のリクエストが必要で、ミリ秒単位のレスポンスが求められる場合があります。100ミリ秒ごとに100回の呼び出しを行う場合、顧客の待ち時間は許容範囲かもしれません。しかし、応答に数秒かかるシステムを呼び出す場合、文字通り時間が足りません。パイプラインのレイテンシー要件によって、データをどこに配置するかが決まります。例えば、運用データベースは通常、応答を得るのにミリ秒単位の時間しかかかりません。Data Lakeアーキテクチャを検討している場合、Data Lakeにデータを配置すると、応答時間は長くなります。

Thumbnail 3040

2番目の決定は、バックエンドパイプラインとデータの鮮度に関するものです。ミリ秒単位でデータを表示したいバックエンドパイプラインを構築している場合は、データを直接データベースにストリーミングすることを検討するかもしれません。2つ目のオプションは、Amazon Redshiftなどのデータウェアハウスにデータをストリーミングすることです。Amazon KinesisやAmazon MSKのストリーミングデータを取り込んでRedshiftに具現化できるコネクターがあります。オープンテーブルフォーマットが人気を集めており、数分以内のアクセスを想定してデータを配置する場合は、ICEBERGのようなオープンテーブルフォーマットにストリーミングデータを配置することが、顧客にとって適切なパターンとなります。5分以上のレイテンシーが許容される場合は、バッチジョブを実行してオープンテーブルフォーマットにデータを具現化するアプローチが適切です。

Thumbnail 3110

Thumbnail 3140

Jonathanが説明したフロントエンドパターンについて、まとめさせていただきます。会話履歴を保持するアプリケーションでは、多くのお客様がAmazon DynamoDBを使用しています。これは、親子関係を表現するためのハッシュキー(パーティションキー)とレンジキーを持っています。すべての会話を保持するために、ハッシュキーにCustomer ID、レンジキーにタイムスタンプを設定し、ペイロードはAmazon S3内のオブジェクトへのポインターの一部として保存します。 状況コンテキストは、SQL、NoSQL、グラフ、あるいはユースケースに適したどのようなデータベースでも、運用データベースから取得できます。分析コンテキストは分析システムから取得でき、通常はAmazon AthenaやAmazon Redshiftを通じてアクセスするオープンテーブル形式のデータから1秒程度で取得できます。意味的コンテキストは、Jonathanが説明したように、ベクトルデータストアを活用します。

Thumbnail 3180

コンテキストを更新するバックエンドアーキテクチャについては、中央にサービングレイヤーがあります。分析データストアを通じて状況コンテキストを導出する場合、Amazon S3内のデータを3層で保持します。最下層はS3で、オープンテーブル形式を使用してParquet形式でファイルを保存します。その上にはデータカタログがあり、スムーズなデータ取得を可能にし、すべてのメタデータをAWS Glue Data Catalogに保持します。これは特に、Jonathanが言及したText-to-SQLのようなシナリオで役立ちます。SQLクエリを具体化する前にスキーマを取得できるからです。

Thumbnail 3230

Thumbnail 3240

Thumbnail 3260

ストリーミングデータソースについては、標準的なストリーム処理を実行し、データをAmazon MSKに格納し、AWS Glue Streaming、Amazon EMR、またはAmazon Managed Streaming for Apache Flinkを使用してデータを管理し、オープンテーブル形式で保存します。 これには、Jonathanが説明したChunkingの部分も含まれており、データレイク内のすべてのデータやAmazon MSKのようなソースからのデータをフロントエンドのサービングレイヤーに格納するツールを使用します。これは従来のストリーム処理やバッチ処理に似ているため、馴染みやすいはずです。 主な違いは、これをRAGアプリケーションのサービングレイヤーにおけるコンテキストの表面化に結びつけている点です。

データガバナンスとRAGの統合:品質管理からLineageまで

Thumbnail 3280

データガバナンスに関して、 データ共有アーキテクチャやデータマーケットプレイスについてお話しします。保険会社を例に取ると、営業部門がデータレイクを持っているケースを考えてみましょう。一つのアプローチとしては、Chatbotビルダーが全てのデータレイクを構築し、すべてのデータを自身で調達する方法があります。

より良いパターンは、営業部門が独自のデータレイクを持ち、保険金請求部門も独自のデータレイクを持つという形です。そこからデータプロダクトを作成することができます。データプロダクトは通常、S3ファイルや様々なテーブルなど、複数のアーティファクトで構成されます。これをDataZoneに登録すると、Chatbot構築チームが各チームの構築しているデータプロダクトをサブスクライブできるデータフローが生まれます。Chatbotチームが特定のデータプロダクトの共有許可を申請すると、そのワークフロー全体が管理されます。プロダクトの作成者が承認すると、必要な権限がすべて付与される仕組みになっています。

Thumbnail 3380

データの品質とLineageについてお話ししましょう。データ品質を確保するためのビジネスルールの例として、保険金請求日は保険の開始日と終了日の間でなければならないというものがあります。ネバダ州で保険を引き受ける場合、最低限の賠償責任保険が必要といったルールもあるでしょう。これらはすべて、パイプラインが対応すべきビジネスルールです。電話番号のフォーマットや、保険IDが一意であることを確認するといったフォーマット要件もあります。データ品質の観点から、これらを追跡するシステムが必要になります。

Thumbnail 3410

例えば、AWS Glueパイプラインを使用している場合、私たちが開発したData Quality Definition Language(DQDL)というものがあります。これは宣言的に指定できる様々なルールで構成されています。ジョブを実行すると、これらのルールが満たされているかを検証し、データ品質スコアを算出できます。10個のルールがあり、ジョブ実行時に9個のルールしか満たされていない場合、データ品質スコアは90%となります。このデータプロダクトを構築するチームは、公開する特定のアーティファクトが特定のデータ品質ルールを満たしていることを確認できます。

Thumbnail 3460

データLineageも重要です。例えば、この場合、データプロデューサーはUnderwritingチームです。営業部門が見積もりを提供する際、顧客に見積もりIDと保険料を提示します。Underwritingチームは、顧客向けに作成する様々な保険を決定し、保険IDを作成し、通常はその保険料をテーブルに保存します。アプリケーションのシナリオでEmbeddingを作成する際、UnderwritingチームがPDFドキュメントとして作成した保険をチャンク分割してVector Storeに保存します。その保険ドキュメントには、Vector EmbeddingとともにPremium(保険料)の情報を含むテーブルがあるかもしれません。保険料が間違っていることが判明した場合、そのLineageを追跡できる必要があります。

Thumbnail 3540

これらのアセットの管理にDataZoneを使用している場合、Open LineageはLineageを維持するためのオープンスタンダードです。SparkやDBTなど、Open Lineageと互換性のある技術であれば、このLineageを保持できます。チャットボット開発チームとして、データLineageを理解することは重要です。 ここで、私が考えるRAGのエンドツーエンドアーキテクチャをまとめたいと思います。ここでの重要なポイントは、Generativeアプリケーションに提供できる形でデータを具現化できるServingレイヤーを構築することです。

Thumbnail 3580

ここでJonathanに話をまとめてもらいましょう。時間内に収めるために急いで進めましたが、皆さんが定時に退出できるようにしました。 今日は何を学んだでしょうか?これはL300のトークで、技術的な内容を扱い、多くの異なるコンセプトをカバーする必要がありました。ワークフローから逆算して考える必要があります - どのようにデータを取り込み、どのRAGテクニックを使用してGenerative AIアプリケーションを強化するのか?これらのデータソースが最終的にそれを支え、データソースの選択がデータターゲットの選択につながることになります。

Thumbnail 3600

Thumbnail 3630

そこに向かって段階的に進めていけばいいのです。そして可能な限り自動化を活用してください。既存のデータを活用できるというのが重要なポイントです。すべてをベクトル化しなければならないという話を耳にするかもしれませんが、Vector検索が大好きな私でさえ、今日お話しした内容のほとんどはベクトルではありませんでした。皆さんが持っているオリジナルのソースデータを、そのままGenerative AIアプリケーションに活用できるのです。 最後に自動化についてですが、できる限り自動化してください。アプリ開発者として私が犯した最大の過ちは、十分な自動化を行わなかったことです。運用タスクにかかる時間を大幅に節約できたはずでした。

Thumbnail 3640

以上で終わりです。プレゼンテーションについてフィードバックをいただけますと幸いです。本日はご参加いただき、ありがとうございました。ありがとうございました。感謝いたします。


※ こちらの記事は Amazon Bedrock を利用することで全て自動で作成しています。
※ 生成AI記事によるインターネット汚染の懸念を踏まえ、本記事ではセッション動画を情報量をほぼ変化させずに文字と画像に変換することで、できるだけオリジナルコンテンツそのものの価値を維持しつつ、多言語でのAccessibilityやGooglabilityを高められればと考えています。

Discussion