検索拡張生成
アドバイザー
Spring AI は、Advisor
API を使用して一般的な RAG フローをすぐにサポートします。
QuestionAnswerAdvisor
ベクトルデータベースには、AI モデルが認識していないデータが格納されます。ユーザーの質問が AI モデルに送信されると、QuestionAnswerAdvisor
はベクトルデータベースに対してユーザーの質問に関連するドキュメントを照会します。
ベクトルデータベースからのレスポンスはユーザーテキストに追加され、AI モデルがレスポンスを生成するためのコンテキストを提供します。
すでに VectorStore
にデータをロードしていると仮定すると、QuestionAnswerAdvisor
のインスタンスを ChatClient
に提供することで、検索拡張生成 (RAG) を実行できます。
ChatResponse response = ChatClient.builder(chatModel)
.build().prompt()
.advisors(new QuestionAnswerAdvisor(vectorStore))
.user(userText)
.call()
.chatResponse();
この例では、QuestionAnswerAdvisor
は ベクトルデータベース内のすべてのドキュメントに対して類似性検索を実行します。検索するドキュメントの種類を制限するために、SearchRequest
はすべての VectorStores
間で移植可能な SQL のようなフィルター式を使用します。
このフィルター式は、QuestionAnswerAdvisor
の作成時に構成できるため、すべての ChatClient
リクエストに常に適用されます。また、実行時にリクエストごとに提供することもできます。
しきい値が 0.8
である QuestionAnswerAdvisor
のインスタンスを作成し、上位の 6
結果を返す方法を次に示します。
var qaAdvisor = new QuestionAnswerAdvisor(this.vectorStore,
SearchRequest.builder().similarityThreshold(0.8d).topK(6).build());
動的フィルター式
FILTER_EXPRESSION
アドバイザーコンテキストパラメーターを使用して、実行時に SearchRequest
フィルター式を更新します。
ChatClient chatClient = ChatClient.builder(chatModel)
.defaultAdvisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.builder().build()))
.build();
// Update filter expression at runtime
String content = this.chatClient.prompt()
.user("Please answer my question XYZ")
.advisors(a -> a.param(QuestionAnswerAdvisor.FILTER_EXPRESSION, "type == 'Spring'"))
.call()
.content();
FILTER_EXPRESSION
パラメーターを使用すると、指定された式に基づいて検索結果を動的にフィルタリングできます。
RetrievalAugmentationAdvisor (インキュベーション)
Spring AI には、独自の RAG フローを構築するために使用できる RAG モジュールのライブラリが含まれています。RetrievalAugmentationAdvisor
は、モジュラーアーキテクチャに基づいて、最も一般的な RAG フローのすぐに使用できる実装を提供する実験的な Advisor
です。
RetrievalAugmentationAdvisor は実験的な機能であり、将来のリリースで変更される可能性があります。 |
シーケンシャル RAG フロー
ナイーブ RAG
Advisor retrievalAugmentationAdvisor = RetrievalAugmentationAdvisor.builder()
.documentRetriever(VectorStoreDocumentRetriever.builder()
.similarityThreshold(0.50)
.vectorStore(vectorStore)
.build())
.build();
String answer = chatClient.prompt()
.advisors(retrievalAugmentationAdvisor)
.user(question)
.call()
.content();
デフォルトでは、RetrievalAugmentationAdvisor
は取得したコンテキストが空であることを許可しません。その場合、モデルはユーザークエリに応答しないように指示します。次のようにして空のコンテキストを許可できます。
Advisor retrievalAugmentationAdvisor = RetrievalAugmentationAdvisor.builder()
.documentRetriever(VectorStoreDocumentRetriever.builder()
.similarityThreshold(0.50)
.vectorStore(vectorStore)
.build())
.queryAugmenter(ContextualQueryAugmenter.builder()
.allowEmptyContext(true)
.build())
.build();
String answer = chatClient.prompt()
.advisors(retrievalAugmentationAdvisor)
.user(question)
.call()
.content();
高度な RAG
Advisor retrievalAugmentationAdvisor = RetrievalAugmentationAdvisor.builder()
.queryTransformer(RewriteQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder.build().mutate())
.build())
.documentRetriever(VectorStoreDocumentRetriever.builder()
.similarityThreshold(0.50)
.vectorStore(vectorStore)
.build())
.build();
String answer = chatClient.prompt()
.advisors(retrievalAugmentationAdvisor)
.user(question)
.call()
.content();
モジュール
Spring AI は、論文 "モジュラー RAG: RAG システムをレゴのような再構成可能な フレームワークに変換する (英語) " で詳述されているモジュール性の概念に触発されたモジュラー RAG アーキテクチャを実装します。
- WARNING
モジュラー RAG は実験的な機能であり、将来のリリースで変更される可能性があります。
事前取得
事前取得モジュールは、ユーザークエリを処理して、可能な限り最良の検索結果を実現するロールを担います。
クエリ変換
入力クエリを変換して検索タスクの効率を高め、不完全なクエリ、あいまいな用語、複雑な語彙、サポートされていない言語などの課題に対処するコンポーネント。
CompressionQueryTransformer
CompressionQueryTransformer
は、大規模な言語モデルを使用して、会話履歴とフォローアップクエリを、会話の本質を捉えるスタンドアロンクエリに圧縮します。
このトランスフォーマーは、会話履歴が長く、フォローアップクエリが会話のコンテキストに関連している場合に役立ちます。
Query query = Query.builder()
.text("And what is its second largest city?")
.history(new UserMessage("What is the capital of Denmark?"),
new AssistantMessage("Copenhagen is the capital of Denmark."))
.build();
QueryTransformer queryTransformer = CompressionQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder)
.build();
Query transformedQuery = queryTransformer.transform(query);
このコンポーネントで使用されるプロンプトは、ビルダーで使用可能な promptTemplate()
メソッドを使用してカスタマイズできます。
RewriteQueryTransformer
RewriteQueryTransformer
は、大規模な言語モデルを使用してユーザークエリを書き換え、ベクトルストアや Web 検索エンジンなどのターゲットシステムを照会するときに、より良い結果を提供します。
このトランスフォーマーは、ユーザークエリが冗長、曖昧、検索結果の品質に影響を与える可能性のある無関係な情報が含まれている場合に役立ちます。
Query query = new Query("I'm studying machine learning. What is an LLM?");
QueryTransformer queryTransformer = RewriteQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder)
.build();
Query transformedQuery = queryTransformer.transform(query);
このコンポーネントで使用されるプロンプトは、ビルダーで使用可能な promptTemplate()
メソッドを使用してカスタマイズできます。
TranslationQueryTransformer
TranslationQueryTransformer
は、大規模な言語モデルを使用して、ドキュメントの埋め込みを生成するために使用される埋め込みモデルでサポートされているターゲット言語にクエリを変換します。クエリがすでにターゲット言語である場合は、変更されずに返されます。クエリの言語が不明な場合も、変更されずに返されます。
このトランスフォーマーは、埋め込みモデルが特定の言語でトレーニングされ、ユーザークエリが別の言語である場合に役立ちます。
Query query = new Query("Hvad er Danmarks hovedstad?");
QueryTransformer queryTransformer = TranslationQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder)
.targetLanguage("english")
.build();
Query transformedQuery = queryTransformer.transform(query);
このコンポーネントで使用されるプロンプトは、ビルダーで使用可能な promptTemplate()
メソッドを使用してカスタマイズできます。
クエリ拡張
入力クエリをクエリのリストに拡張し、代替クエリ形式を提供したり、複雑な問題をより単純なサブクエリに分解したりすることで、クエリの形式が不適切などの課題に対処するコンポーネントです。
MultiQueryExpander
MultiQueryExpander
は、大規模な言語モデルを使用してクエリを複数の意味的に多様なバリエーションに拡張し、さまざまな視点を捉えます。これは、追加のコンテキスト情報を取得したり、関連する結果を見つける可能性を高めたりできます。
MultiQueryExpander queryExpander = MultiQueryExpander.builder()
.chatClientBuilder(chatClientBuilder)
.numberOfQueries(3)
.build();
List<Query> queries = expander.expand(new Query("How to run a Spring Boot app?"));
デフォルトでは、MultiQueryExpander
は拡張クエリのリストに元のクエリを含めます。ビルダーの includeOriginal
メソッドを使用してこの動作を無効にすることができます。
MultiQueryExpander queryExpander = MultiQueryExpander.builder()
.chatClientBuilder(chatClientBuilder)
.includeOriginal(false)
.build();
このコンポーネントで使用されるプロンプトは、ビルダーで使用可能な promptTemplate()
メソッドを使用してカスタマイズできます。
検索
検索モジュールは、ベクトルストアなどのデータシステムを照会し、最も関連性の高いドキュメントを取得するロールを担います。
ドキュメント検索
検索エンジン、ベクトルストア、データベース、ナレッジグラフなどの基盤となるデータソースから Documents
を取得するコンポーネント。
VectorStoreDocumentRetriever
VectorStoreDocumentRetriever
は、入力クエリと意味的に類似するドキュメントをベクトルストアから取得します。メタデータ、類似度しきい値、上位 k の結果に基づくフィルタリングをサポートします。
DocumentRetriever retriever = VectorStoreDocumentRetriever.builder()
.vectorStore(vectorStore)
.similarityThreshold(0.73)
.topK(5)
.filterExpression(new FilterExpressionBuilder()
.eq("genre", "fairytale")
.build())
.build();
List<Document> documents = retriever.retrieve(new Query("What is the main character of the story?"));
フィルター式は静的または動的にすることができます。動的フィルター式の場合は、Supplier
を渡すことができます。
DocumentRetriever retriever = VectorStoreDocumentRetriever.builder()
.vectorStore(vectorStore)
.filterExpression(() -> new FilterExpressionBuilder()
.eq("tenant", TenantContextHolder.getTenantIdentifier())
.build())
.build();
List<Document> documents = retriever.retrieve(new Query("What are the KPIs for the next semester?"));
ドキュメント結合
複数のクエリに基づいて複数のデータソースから取得したドキュメントを 1 つのドキュメントコレクションに結合するコンポーネントです。結合プロセスの一環として、重複するドキュメントや相互ランキング戦略も処理できます。
ConcatenationDocumentJoiner
ConcatenationDocumentJoiner
は、複数のクエリに基づいて複数のデータソースから取得されたドキュメントを連結して、単一のドキュメントコレクションにまとめます。重複するドキュメントがある場合は、最初に出現したものが保持されます。各ドキュメントのスコアはそのまま保持されます。
Map<Query, List<List<Document>>> documentsForQuery = ...
DocumentJoiner documentJoiner = new ConcatenationDocumentJoiner();
List<Document> documents = documentJoiner.join(documentsForQuery);
回収後
取得後モジュールは、取得したドキュメントを処理して、可能な限り最良の生成結果を実現するロールを担います。
ドキュメントランキング
クエリとの関連性に基づいてドキュメントを順序付けおよびランク付けし、最も関連性の高いドキュメントをリストの先頭に表示して、途中で失われるなどの課題に対処するコンポーネント。
DocumentSelector
とは異なり、このコンポーネントはリストからドキュメント全体を削除するのではなく、リスト内のドキュメントの順序 / スコアを変更します。DocumentCompressor
とは異なり、このコンポーネントはドキュメントの内容を変更しません。
世代
生成モジュールは、ユーザーのクエリと取得したドキュメントに基づいて最終的なレスポンスを生成するロールを担います。
クエリ拡張
入力クエリを追加データで拡張するためのコンポーネント。ユーザークエリに回答するために必要なコンテキストを大規模な言語モデルに提供できます。
ContextualQueryAugmenter
ContextualQueryAugmenter
は、提供されたドキュメントのコンテンツからのコンテキストデータを使用してユーザークエリを拡張します。
QueryAugmenter queryAugmenter = ContextualQueryAugmenter.builder().build();
デフォルトでは、ContextualQueryAugmenter
は取得されたコンテキストが空になることを許可しません。その場合、モデルはユーザークエリに応答しないように指示されます。
allowEmptyContext
オプションを有効にすると、取得したコンテキストが空の場合でもモデルがレスポンスを生成できるようになります。
QueryAugmenter queryAugmenter = ContextualQueryAugmenter.builder()
.allowEmptyContext(true)
.build();
このコンポーネントで使用されるプロンプトは、ビルダーで使用可能な promptTemplate()
および emptyContextPromptTemplate()
メソッドを使用してカスタマイズできます。