AgentforceとRAG: AIエージェントを向上させるベストプラクティス
非構造化データと長い自由テキストフィールドでAgentforceを強化するためのベストプラクティスガイド
非構造化データと長い自由テキストフィールドでAgentforceを強化するためのベストプラクティスガイド
Reinier van Leuken、Agentforce部門製品管理シニアディレクター
このガイドでは、非構造化データと長い自由テキストフィールドを活用して、Agentforce 360 Platform上で検索拡張生成(RAG)によってAgentforceを強化するためのベストプラクティスを提供します。 RAGは、ファイル、メール、記事、ドキュメント、通話メモ、目的の説明、構造化されたテーブルのフィールドなどを含む企業のエンタープライズナレッジを活用して、AIエージェントの応答をより正確で最新のものにし、関連性を高めることで、その質を高めます。 RAGツールの中には、シンプルでそのまま使用できるものもあれば、詳細な設定オプションを提供しているものもあります。 本ガイドは、Salesforceシステム管理者および開発者が、情報にもとづいて設計に関する選択を行いソリューションを最適化する上で役立ちます。
このコンテンツは実際の導入シナリオにもとづいており、一般公開中、またはオープンベータ版のテクノロジーを対象としています。 ロードマップの項目について審議される場合があり、これらは#ロードマップと記されており、可能な場合にはリリースのタイムラインが提供されています。これは、付録内の将来予想に関する記述の対象となります。
このドキュメントは、help.salesforce.comおよびTrailheadドキュメントを補完し、高性能AIエージェントを実現するための実践的なガイダンスを提供します。
本ガイドの「はじめに」では、Agentforce 360 Platform上のRAGの概要をご紹介します。 ただし、本ガイドは完全な初心者向けではありません。 この章の最後には、本ガイドの残りの部分を理解するための前提条件が記載されています。
Data 360のRAGは、大規模言語モデル(LLM)のプロンプトをグラウンディングするためのフレームワークです。 正確かつ最新で関連性の高い情報を追加することで、RAGはユーザーへのLLMの応答の関連性と価値を高めます。 プロンプトにデータを取り込むには、差し込み項目やデータグラフなど、さまざまな方法があります。 本ガイドでRAGについて言及する場合、クエリとの意味的な類似性にもとづいて取得された長文テキストコンテンツでプロンプトを拡張することを指します。
LLMプロンプトを送信すると、Data 360のRAGは以下のように動作します。
多くのLLMは、インターネット上で一般公開されている静的なコンテンツをもとに学習しています。 RAGは、企業の非公開データなど、LLMの学習データに含まれていない、正確な最新情報をプロンプトに追加し、ナレッジストアからの関連情報によってLLMの機能を補完します。 RAGを使用すると、ユーザーはモデルの再学習や微調整を行うことなく、独自のデータをLLMに提供できます。 その結果、ユーザーのコンテキストやユースケースにより適したLLMの応答を得ることができます。
RAGのユースケースの例は以下のとおりです。
オフライン準備とオンライン利用の2つの主要な部分で分けて考えると、RAGを理解しやすくなります。
リトリーバーを含むプロンプトテンプレートが実行されるたびに、上記の図に示されているようなシーケンスが発生します。
クエリはプロンプトにおける重要な要素です。 これには、ユーザーのインテントを反映した検索文字列が含まれています。 RAGプロセスは、この検索文字列を使用して、意味的な類似性にもとづいて関連するデータを検索します。このプロセスでは、正確な単語ではなく、意味に重点が置かれます。 ハイブリッド検索は、セマンティック検索にキーワードの類似性を追加することで、LLMの応答品質を向上させることができます。 RAGは、識別子や単一のキーワードを使った単なるデータ検索とは異なります。 RAGには必ず、複数のキーワードを含む検索文字列との意味的な類似性にもとづいて、より長い自由記述形式のテキストデータを特定することが伴います。
Agentforce Builderまたは設定でAgentforceデータライブラリ(ADL)を追加する ことが、RAGソリューションを設定する最短の方法です。 ADLを作成すると、RAGを活用したソリューションの動作に必要なすべてのコンポーネントが自動的に設定されます。 これらのコンポーネントには、データストリーム、オブジェクトとマッピング、ベクトルデータストア、検索インデックス、リトリーバー、プロンプトテンプレート、およびエージェントアクションが含まれます。 Salesforceは、これらのコンポーネントにデフォルト設定を使用します。 作成したコンポーネントをベースとして、さらに設定や改良を行うこともできます。 たとえば、カスタムテンプレートでデフォルトのリトリーバーを使用したり、検索インデックス用にカスタムリトリーバーを作成したりできます。
Data 360でRAGを手動で実装するには、まず、LLMプロンプトのグラウンディングのために、RAGが関連情報を取得する構造化データおよび非構造化データを接続します。Data 360は、検索インデックスを使用して、構造化および非構造化コンテンツを検索に最適化された方法で管理します。 サポートされているファイルタイプのコンテンツは、さまざまなソースから取り込むことができます。 RAGで使用される非構造化コンテンツには、サービス返信、ケース、RFPの回答、ナレッジ記事、よくある質問、メール、会議メモなどがあります。
Data 360でのオフライン準備の手順は以下のとおりです。
詳細については、AI、自動化、分析の検索 をご確認ください。
リトリーバーは、検索インデックスとプロンプトテンプレートの間の橋渡し役として機能します。 検索インデックスを作成すると、Data 360は自動的にデフォルトのリトリーバーを作成します。これは、エージェントスタジオで表示されます。 さまざまなユースケースに対応するために、エージェントスタジオ でカスタムリトリーバーを作成できます。 プロンプトを拡張するために、カスタムリトリーバーは検索条件を改善し、フィルターを追加したり、追加の返信フィールドを含めたりするなどして、コンテキストとの関連性がもっとも高い情報を取得します。 詳細については、リトリーバーの管理 をご確認ください。
RAG実装の最後の要素となるのが、プロンプトテンプレートにリトリーバーへの呼び出しを追加することです。 特定のプロンプトテンプレートに対して、プロンプトデザイナーは、リトリーバークエリおよび結果設定をカスタマイズすることができます。これにより、プロンプトとの関連性がもっとも高い情報が入力されます。 詳細については、Data 360における検索拡張生成(RAG)によるグラウンディング をご確認ください。
これまで、検索インデックスのオフライン準備と、プロンプトテンプレート内でのオンライン使用について説明してきました。 RAGをAgentforceで実装するには、このプロンプトテンプレートを呼び出すエージェントアクションが必要です。 以下の図は、RAGを活用したAIエージェントのランタイムフロー全体を示しています。
RAGを活用したAIエージェントのフロー
上のフローは、Agentforceが適切なモデルとリトリーバーを選択し、構造化データと半構造化データを組み合わせた非構造化データにもとづいて適切なアクションを実行する方法を示しています。
本ガイドの内容への理解を深めるために、以下のコンテンツをご確認ください。
構造化コンテンツには、数値や関係性を備えた意味のある構造に従ったオブジェクトやデータテーブルが含まれます。 これらには、カテゴリ型(ピックリスト、識別子)、数値型、参照型などのフィールドがあります 一部の構造化コンテンツには、説明、会話、記事などの長文テキストフィールドがあります。 これらのフィールドのうち、意味的に有益なファクトイドを表す完全な文がテキストに最低1つ含まれているもののみ、RAGに使用できます。 機密レベル、閲覧数、商品の種類など、インデックス化可能なテキストに関連するカテゴリ型および数値型のフィールドは、セクション5.1で説明されているように、インデックスを充実させる目的で使用できます。
構造化コンテンツの例には、ナレッジ記事用のSalesforceオブジェクト(記事本文、説明などを含む)、ケース(ケース詳細、解決結果、まとめなどを含む)、アクティビティ(アクティビティメモを含む)があります。
ドキュメント、記事、メール、メモなどの長文テキストのファイルは、非構造化コンテンツと呼ばれます。 これには、RAGプロセス向けにテキスト化された音声ファイルや動画ファイルが含まれる場合もあります。 音声ファイルと動画ファイルは、元の場所(ゼロコピー・ファイルストア)に保持されます。 これらは、音声をテキストに変換する文字起こしサービスに送信されます。 次に、文字起こしされたデータはチャンク化およびベクトル化され、分割要素とベクトルのみがData 360に保存されます。
当然ながら、すべてのファイルが非構造化に該当するわけではありません。 ファイルにJSON、CSV、XML形式などのフィールドと値を持つ固有の構造が含まれている場合、まず構造化データとして読み込む必要があります。 長文テキストのみがチャンク化およびベクトル化に使用できます。 その他のフィールドは、セクション5.1で説明されているように、インデックスおよび検索の強化に使用できます。
LLMのプロンプトや応答を向上させるために、ソースコンテンツを調整して、情報検索を最適化します。 特定の製品の機能は、インデックス化の強化(セクション5.4)やフィールドのプリペンド(セクション5.1)など、不適切に作成されたコンテンツの問題に対応しています。 しかし、ソースコンテンツにコンテンツキュレーションの手法を適用すれば、検索を強化し、結果を向上させることができます。
Data 360で手動作成された検索インデックスでは、以下のような追加のコンテンツソースに対応しています。
*注: ファイルはData 360にコピーされません。 その代わりに、必要なメタデータとインデックス化されたコンテンツのみを処理して保存するゼロコピーアプローチを使用します。
以下の推奨事項は、ナレッジ記事やその他の長文テキストを含むオブジェクトなど、長文テキストフィールドに保存されたドキュメントや長文テキストに適用されます。 AIによって生成された記事の場合、これらの推奨事項をプロンプト内の指示として提供できます。
従来のRAGのベストプラクティスでは、長いテーブルを分割したり、PDFをJSONに変換してから取り込んだりなど、複雑なドキュメントをフォーマットする多大な手作業が必要でした。 Data 360のインテリジェントコンテキストや高度な解析オプションの導入により、この手作業によるキュレーションを行う必要がなくなりました。 AIを活用して、コンテンツを自動的にキュレーション、解析、構造化し、最適な検索を実現できるようになっています。
インテリジェントコンテキストは、Data 360内のAIを活用したワークスペースです。完全な検索インデックスを構築する前に、非構造化データの処理方法を対話的にテストおよび調整できます。 「ブラックボックス」的な取り込みプロセスの代わりに、チャンク化および抽出論理を最適化できる実践的な環境を実現できます。
主な機能
インテリジェントコンテキストのワークフロー
インデックス戦略を設定する際は、インテリジェントコンテキスト内または標準の高度な検索インデックス設定のいずれかで、解析方法を選択する必要があります。 この選択によって、特にテーブルやレイアウトのような複雑な要素に対して、ドキュメント構造をシステムが読み取る方法を決定します。
LLMベースの解析
LLMベースの解析は、マルチモーダル大規模言語モデル(例:GPT-4o)を使用して、ドキュメントを視覚的に「読み取り」ます。 ここでは意味的な理解もとづいてコンテンツの解釈が行われます。
Docling解析の違い
Docling(IBM製)は、ドキュメントのレイアウト分析向けに最適化されたコンピュータビジョンとOCRモデルを使用しています。 これは、ドキュメントの構造的完全性の復元に重点を置いています。
| 機能 | LLMベースの解析 | Docling解析の違い |
| 主なアプローチ | セマンティック分析とビジュアル推論 | コンピュータビジョンとレイアウト分析 |
| 最適なデータソース | 不規則で乱雑、またはスキャンされたドキュメント | 構造化された、デジタル作成されたPDF |
| テーブル処理 | コンテンツの意味を解釈 | 構造レイアウトを再構築 |
| パフォーマンス | 遅い(推論が多い) | 高速/最適化 |
これらの自動キュレーション機能は、実装パスに応じてプラットフォームの複数の領域で利用できます。
セクション5.5に詳細が記載されている多言語埋め込みモデルによって、検索インデックスは多くの言語のコンテンツに対応しています。 数十種類の異なる言語に対応し、言語間で意味的な類似性を保持します。 これは、ある言語のクエリに対して、別の言語で書かれたコンテンツから意味的に関連する結果を取得できるということを意味します。 埋め込みモデルの学習データセットにその言語が含まれているかどうかによって、結果は異なる場合があります。 詳細については、セクション5.5をご確認ください。
言語は事前フィルターとしても使用できます(セクション5.1を参照)。 コンテンツを複数の言語で使用すべきでない場合や、クエリと同じ言語のコンテンツを使用して応答を生成する必要がある場合に役立ちます。
Agentforceでの言語サポートは、広範なトピックであることにご注意ください。 以下は、機能ごとの言語サポートの内訳です。
Intelligent Document Processing(IDP)とデータ前処理は、Agentforceで効果的にRAGが機能するための基礎となります。 IDPは、PDFや画像などの非構造化ドキュメントから構造化データを自動的に抽出し、このデータをデータレイクオブジェクト(DLO)でアクセスできるようにします。 RAGシステムは、適切に準備された関連性の高いデータによって最大限に機能するため、これは重要なプロセスとなります。 データ前処理は、広い意味で、Agentforceエージェントによって使用される前にコンテンツを調整し、クリーンアップするために必要なすべての作業を含みます。これにより、最適なパフォーマンスを確保できます。
IDPの主なユースケースには、自動請求書処理、カスタマーサービス文書の処理、契約書分析、自動オンボーディングがあります。 抽出された値をData 360に入力し、Agentforceがそれらを活用して実践的なインサイトを提供します。
RAGのシナリオでは、IDPは大量のドキュメント処理において特に有用です。 これにより、大量の非構造化ファイルからのデータのストリーミングおよび抽出が可能になります。 これらのインサイトはAgentforceに保存されます。 このプロセスにより、RAG、セグメンテーション、分析などのダウンストリームアプリケーションを有効化できます。
効果的な前処理には、特定の見出しをインデックス化から除外したり、Agentforceへの引き渡し前にコンテンツをクリーンアップしたりすることも含まれます。これにより、高品質な情報のみが使用されることを保証できます。
Agentforceデータライブラリ(ADL)を設定することで、RAGを活用したAIエージェントを最短でセットアップすることができます。 ユーザーは、ADLにファイルをアップロードするか、設定またはAgentforce Builderインターフェースを通じてナレッジ記事を選択できます。 ただし、ADLに他の形式のコンテンツを追加することはできません。 たとえば、ナレッジ記事以外のSalesforceオブジェクトからコンテンツを取得する必要がある場合は、RAGパイプラインを手動で設定する必要があります。 ADLのオープンWeb検索は2025年5月時点で利用可能ですが、この機能はデータの取り込みや検索インデックスの構築を行わないため、本ガイドでは取り扱っていません。
ファイルは手動でADLにアップロードされ、Salesforceが管理するファイルストレージに保存されます。 ファイルのコンテンツはRAGに使用されます。 そのストレージからファイルをダウンロードすることはできません。また、ユーザーがそのファイルに戻るためのクリック可能なリンクもありません。 ユーザーによって削除されるまで、ファイルは保存されたままになります。
ADLを設定した後、RAGパイプラインの構成要素はすべて、以下に記載されているデフォルト設定を使用して自動的に作成されます。
SELECT
v.Hybrid_score__c AS Score,
c.Chunk__c AS Chunk,
c.SourceRecordId__c AS SourceRecordId,
c.DataSource__c AS DataSource,
c.DataSourceObject__c AS DataSourceObject
FROM hybrid_search(
TABLE(KA_Agentforce_Default_Library_index__dlm),
'{!$_SEARCH_STRING}',
'Language__c=''{!$_LANGUAGE}''
AND KnowledgePublicationStatus__c=''Online''
AND DataSource__c IN (''FAQ_Internal_Comments_c__c'', ''AssignmentNote__c'')',
30
) v
INNER JOIN KA_Agentforce_Default_Library_chunk__dlm c
ON c.RecordId__c = v.RecordId__c
INNER JOIN ssot__KnowledgeArticleVersion__dlm kav
ON c.SourceRecordId__c = kav.ssot__Id__c
ORDER BY Score DESC
LIMIT 10
リトリーバーには、Data 360オブジェクトへの2つのパス(ファイルとナレッジ記事)が存在します。 RAGソリューションスタックの残りのプロセスでは、これらのパスがプロンプトテンプレートとエージェントアクションで収束します。
AIエージェントがSalesforce管理ファイルストア内のファイルやSalesforceナレッジ記事のコンテンツにグラウンディングして質問に回答する必要がある場合、ADLが推奨されます。 その他のデータソースについては、手動での設定が必要です。
次のシナリオにおいては、RAGの構成要素を手動で設定する必要があります。
1つの検索インデックスは、1つのデータソースにのみマッピングできます。 検索インデックスは単一のDMO/UDMOに対してのみ構築できるため、複数のデータソースがある場合、異なるデータソースは単一のDMO/UDMOにマッピングする必要があります。 「ファイル」は、ファイルの数やファイル拡張子の種類に関係なく、1つのデータソースとしてカウントされることにご注意ください。
以下は、RAGグラウンディング用のデータソースのコレクションの例です。
この例では、4つの個別の検索インデックスが必要であり、それぞれに少なくとも1つのリトリーバーが必要です。
特定のソリューション内でRAG関連コンポーネントを整理および分配する最適な方法は何でしょうか?4つのリトリーバーすべてを含む1つのプロンプトテンプレート(および対応するエージェントアクション)を作成すべきでしょうか?リトリーバーごとに個別のプロンプトテンプレートを作成すべきでしょうか?あるいは、2つのプロンプトテンプレートを構築し、それぞれに2つのリトリーバーを備えるべきでしょうか?それとも、リトリーバーを3つ備えたプロンプトテンプレートと、リトリーバーを1つ備えたプロンプトテンプレートの2つを作成すべきでしょうか?このような設計上の選択を行う理由とトレードオフについて説明していきます。
アプローチ 1: アンサンブルリトリーバーを使用して、すべてのリトリーバーで1つのプロンプトテンプレートと対応するエージェントアクションを作成
このアプローチでは、以下のコンポーネントを使用します。
以前は、Agentforce推論エンジンのエージェントアクションが呼び出されると、プロンプト解決時にすべてのリトリーバーが必ず実行され、それぞれの結果ですべてのプロンプトが拡張されていました。 これによってプロンプトの肥大化が生じ、LLMのコンテキストウィンドウを超えて失敗の原因になるリスクがありました。
現在、アンサンブルリトリーバーの利用が可能になったことで、このアプローチは複数のデータソースを扱うために大幅に最適化されています。 アンサンブルリトリーバーは、さまざまなデータソースからの結果を統合し、再ランク付けして、もっとも関連性の高い情報が上位に表示されるようにします。 これは、複数の個別リトリーバーを呼び出す代わりに、1つのアンサンブルリトリーバーを使用してプロンプトをグラウンディングできることを意味します。
このアプローチは、以下の場合に最適です。
このアプローチにおけるアンサンブルリトリーバーの使用には、以下のようなメリットがあります。
以前の「アプローチ1」を使用していた既存のソリューションでは、プロンプトテンプレート内で複数のリトリーバーを呼び出していた部分を、ただアンサンブルリトリーバーの呼び出しに置き換えるだけで済みます。 残りのエージェントソリューション設計は、これ以上変更することなく維持できます。 現在、アンサンブルリトリーバーはADLおよびその他の標準機能で利用可能であり、今後、任意のリトリーバーを手動でバンドルできるツールの公開も計画されています。
このアプローチでは、以下のコンポーネントを使用します。
このアプローチでは、Agentforce推論エンジンが複数の対応するエージェントアクションを呼び出す必要があります。
このアプローチは、以下の場合に最適です。
たとえば、「欠陥」という名前のデータソースに、商品の欠陥に関するナレッジが含まれているとします。 このリソースに対応する指示または分類の説明は、次のようなものになる可能性があります。 「お客様が不良品について質問した場合は、必ず『既知の欠陥で回答』アクションを使用してください。」 これは、Agentforce推論エンジンが実行時にこのアクションを呼び出すタイミングを判断するためのガイドとなります。 他のすべてのアクションについても、同様に明確かつ正確な説明と手順を必ず提供してください。
注意: 前述の最初のアプローチの代替として、個別のアクションを個別のプロンプトテンプレートと一緒に使用しないでください。 Agentforce推論エンジンに、次のような複数のアクションを連続して実行するような指示は使用しないでください。 「常に4つのアクションを使用してユーザーの質問に回答してください。 まず、ファイル用にアクション1を呼び出します。 次に、ナレッジ記事用にアクション2を呼び出します」など。 このアプローチを避けるべき理由は以下のとおりです。
ユースケースに該当する場合、同じソリューション内で両方のアプローチを使用することは可能です。 たとえば、あるソリューションでは「欠陥」専用の個別アクション(アプローチ2)を用意し、その他の3つのグラウンディングソース(「ファイル」、「ナレッジ記事」、「ケース」)を1つのプロンプトテンプレート(アプローチ1)で組み合わせることができます。
RAGを活用したAIエージェント内のトピックおよびアクションには、説明、手順、範囲の明確化が必要です。 すべての一般的なベストプラクティスは、トピックはこちらのヘルプページ 、アクションはこちらのヘルプページ に記載されているとおりに適用されます。 RAGのトピックおよびアクションの指示と範囲の説明は、検索インデックスが回答できる範囲内の質問に対してのみ選択され、呼び出されるように作成します。
RAGアクションが呼び出されると、プロンプトテンプレートのリトリーバーは必ず検索インデックスから結果を取得し、LLMが応答を生成します。 検索インデックスに関連するコンテンツが見つからない場合、プロンプトテンプレート内の適切な指示によって、LLMがハルシネーションを避けるよう促すことができます(セクション7を参照)。 ただし、最初から範囲外の質問に対してRAGアクションが呼び出されれないようにすることが望ましいです。 これにより、ハルシネーションのリスクがさらに低減され、AIエージェントのコストと遅延も削減されます。
RAGソリューションでは、検索インデックスビルダーを使用して検索インデックスを設定すると、ハイブリッド検索に対応できます。 ハイブリッド検索は、ベクトル検索とキーワード検索の強みを1つの検索呼び出しに統合します。 単一のデータソースから2つの異なる検索操作を行い、その結果を統合して再ランク付けするものと考えてください。 これはアンサンブルリトリーバー(セクション3)に類似していますが、ハイブリッド検索は単一のデータソースから結果を導き出すのに対し、アンサンブルリトリーバーは複数のデータソースから結果を導き出す点において異なります。
ハイブリッド検索は、ベクトル検索とキーワード検索の結果を組み合わせてランク付けし、もっともランクが高いチャンクが、意味的および語彙的に類似しているものとなります。
ベクトル検索は、それ自体で意味的な類似性に優れていますが、キーワードが重要な場合にそれを認識できないことがあります。 たとえば、ベクトル検索は「自分のアカウントにログインする方法は?」と「どのようにサインオンすればいいですか?」が類似したクエリであることを理解します。 しかし、「レーザープリンターTX 400」と「レーザープリンターTX 440」を探している場合、類似していることを理解できない場合があります。 キーワード検索とは異なり、ベクトル検索は数値をうまく一致させることができず、また特定のドメイン用語(レーザープリンターなど)を適切に一致することも困難です。
しかし、ベクトル検索とキーワード検索を組み合わせることで、互いに補完し合い、「レーザープリンターTX 400で紙詰まりが発生した場合はどうすればよいですか?」のような質問に対して最適な回答を返すことができます。
ハイブリッド検索を使用することで、意味的な類似性とキーワードの類似性の両方を利用してコンテキストを取得できます。 たとえば、商品名、ブランド、特定の用語、専門用語などのキーワードが検索品質の鍵となる場合、ハイブリッド検索が推奨されます。 ユーザーの質問および取得可能なすべてのコンテンツが、特定の用語やセマンティック、キーワードを含まない自然言語である場合、ハイブリッド検索の付加価値は小さく、ベクトル検索のみで対応することが可能です。
ただし、カテゴリのキーワード検索エンジンとしてハイブリッド検索を使用しないでください。
RAGソリューションの場合、ベクトル検索は単独で使用できますが、キーワード検索はできません。 キーワード検索はベクトル検索結果を強化できますが、辞書式順序検索の単独利用には使用できません。 検索インデックスの場合、カテゴリのみを含むフィールド(Salesforceのピックリストなど)をインデックスフィールドとして選択することは推奨されません。
カテゴリは、非常に短いチャンク(1つの単語または数単語)になってしまいます。 これらのマイクロチャンクもユーザーのクエリに対して意味的な類似性で一致されますが、単語単位のチャンクによるセマンティック検索は、これらのチャンクが意味的なコンテキストを欠いているため、適切には機能しません。 その結果、ハイブリッド検索のベクトル検索部分が不安定になり、最終的なランキングが不正確になってしまいます。 代わりに、カテゴリはセクション5.1で説明しているように、プリペンドするフィールドとして使用する方が適しています。
ハイブリッド検索は、実行時の遅延やData 360クレジット消費の増加というトレードオフと引き換えに、検索結果の精度を向上させます。
ハイブリッド検索機能は、ベクトルとキーワードインデックスの両方でクエリを処理し、結果を再ランク付けするため、Data 360サービスクレジットを約2倍消費します。
再ランク付け中に、ハイブリッド検索はベクトルスコアとキーワードスコアを組み合わせてハイブリッドスコアを生成します。そのハイブリッドスコアにもとづいて最終的なランキングが決定されます。
検索インデックスビルダーには、人気度と最新度という2つの追加のランク付け要素が存在し、最終的なランキングに影響を与える可能性があります。 検索インデックスビルダーでは、ユーザーはこれらのドキュメント特性を定義する(関連する)DMO上の2つのフィールドを選択できます。 最終ランキングでは、これらの特性を取り入れて、人気が高く、最新のコンテンツが上位にランク付けされます。
詳細および例については、help.salesforce.com の記事をご確認ください。
検索インデックスを設定する際、Data 360はデータをベクトル化する前にチャンク化を実行します。 チャンク化は情報をより小さな要素に細分化します。 すべてのチャンク(およびベクトル)は、有意義なファクトイドまたはファクトイドの集合を表します。 1つのベクトルがドキュメント内のすべてのコンテンツの意味的な表現にはなり得ないため、1つのベクトルで冗長なドキュメント全体を表現することは現実的ではありません。
RAGソリューションにおいてフィールドが担う、以下の4つのロールを検討しましょう。
以下の例は、これら4つのフィールドがどのような役割を担っているのかを示しています。 このユースケースでは、ケースオブジェクトがユーザーの質問に回答するために使用されます。 プロンプトは、説明がユーザーの質問と一致する、完了したケースの解決結果の内容で拡張されます。 これを達成するには以下を必要とします。
ユースケースの図: 過去のケースの解決結果を使用した顧客への返信。
検索インデックスを構築する際は、ステップ2のチャンク化でインデックスフィールドを選択します。 「フィールドを管理」ボタンをクリックします。 検索インデックスの作成時に、インデックスフィールドはチャンク化およびベクトル化されてから、検索プロセス中にクエリとの意味的な類似性を評価するために使用されます。
インデックスフィールドとして選択できるのはテキストフィールドのみです。 カテゴリやカテゴリデータではなく、長い自由テキストコンテンツのあるテキストフィールドのみを選択してください。 カテゴリフィールドは選択しないでください。 複数のフィールドをインデックス化のために選択できます。 たとえば、「説明」、「要約」、「コンテンツ」、「解決結果」が選択されている場合、すべての対応するベクトルは同じ検索インデックスにまとめて保存されます。 ベクトルのDMO上のDataSource__c というフィールドにもとづいて、ベクトルを分離することが可能です。 DataSource__c には元のフィールド名が含まれています。 このフィールドはインデックスDMOにあるため、リトリーバーの事前フィルターで使用することが可能です。 たとえば、リトリーバーは特定のフィールド(「解決結果」ではなく「説明」など)に対してのみクエリの意味的な類似性を評価できます。
注意: カテゴリ列をインデックスフィールドとして選択しないでください。 カテゴリデータは、Salesforceのピックリストにマッピングされる1語または2語の記述子です。 優れた結果を得るためには、セマンティック検索には長いテキスト範囲と多くのコンテキストが必要です。 ハイブリッド検索は、キーワード検索によってセマンティック検索を補完することを思い出してください。 検索インデックスはキーワード検索エンジンではありません。 カテゴリフィールドのみをインデックス化するのではなく、それらを、長い自由テキストコンテンツを含むテキスト列にプリペンドする必要があります。
注意: 類似したフィールドを選択しすぎないようにしてください。 選択項目は少ない方が効果的です。 すべてのテキストフィールドを選択しないように注意し、「要約」、「タイトル」、「説明」などの重複する可能性のあるフィールドを選択しないようにします。 こうすることで、DataSource__cに事前フィルタリングを使用せずに検索インデックスを利用した場合、再呼び出し率が低下する可能性があります。 これらのフィールドは、すべて同じ、または非常に類似した情報を含んでいる可能性が高いため、特定のクエリに対して、同じドキュメントから少なくとも3つのチャンクがランクの上位に表示されることがあります(フィールドごとに1つずつ)。 これらは同じ情報をLLMにもたらします。たとえば、リトリーバーが9件の結果を取得するように設定されている場合でも、結果リストには3つのドキュメントのみが表示されます。 これによりばらつきが減少する一方、ドキュメントが見逃される場合があります。
2つ以上のフィールドが同じ内容を異なる形式で表している場合、前述の例の「説明」のように、もっとも圧縮されていない形式のフィールドを選択することが推奨されます。 このフィールド(セクション5.3を参照)には、前の例の「タイトル」のような、短くて簡潔なバージョンをプリペンドすることを検討してください。
検索エンジンビルダーでは、インデックス化するフィールドを選択する際(DMOケース)や、インデックスに含めるファイルタイプを選択する際(UDMOケース)に、ユーザーはチャンク化戦略を構成できます。詳細はhelp.salesforce.comのこのトピックをご参照ください。
フィールドのプリペンドを使用して、チャンクにコンテキストを追加し、識別しやすくします。 たとえば、トラブルシューティング手順のシーケンスを含むチャンクがあるとします。 そのチャンクの前に「デバイス123が動作xyzを示す場合の対処方法」というテキストを付け加えることで、そのコンテンツがユーザーの質問に関連していることを識別しやすくなります。
注: フィールドのプリペンドは、DMOベースのインデックスでは利用可能ですが、UDMOベースのインデックスでは利用できません。
RAG実装をデザインする際には、フィールドのプリペンドが環境内のメタデータからどのようなメリットを得られるかを慎重に検討してください。
検索インデックスビルダーのチャンク化戦略で、フィールドのプリペンドを設定します。 インデックス化するフィールドを選択した後、チャンク化設定のダイアログを開き、「フィールドをプリペンドする」のトグルをオンにします。
チャンク化を最適化するもう一つの方法として、検索インデックス設定でソリューションに合わせてチャンクサイズを調整することがあります。
検索インデックスの作成中、プラットフォームは、ヘルプで説明されている意味ベースの文章抽出マーカーを使用して、可能な限りコンテンツを分割し始めます。 その後、プラットフォームは指定されたチャンクサイズに達するまで、細かく分割されたチャンクを再びまとめます。 現在設定可能な最大のチャンクサイズは512トークンであり、これはラテン系言語で約400~500語に相当します。
最適なチャンクサイズはソリューションごとに異なります。 これは、特定のソリューションの目標にもっとも適した最適化戦略に一部依存します。
検索向けにチャンクサイズを最適化する際は、コンテンツの情報密度と組織構造を考慮します。 1つのチャンクが1つのベクトルになることを忘れないようにしてください。 このチャンク全体のコンテンツは、この1つのベクトルで表されます。 チャンクの意味を十分に理解するには、いくつの単語が必要でしょうか?400~500語でしょうか?少ない語数でもフィールドのプリペンドやチャンク強化によって補強された場合に、自己完結型で識別可能なファクトイド情報を十分に表現できるでしょうか?
拡張の観点からチャンク化を検討します。 LLMが十分に実践的な応答を生成するためには何が必要でしょうか?小さな個々のファクトイドだけで十分でしょうか、それとも、さらなるコンテキストが必要でしょうか?
インデックス化の強化(近日公開)は、検索のリコールと精度を向上させるために、インデックス化の際に追加の(または強化された)チャンクが生成されるプロセスを指します。
インデックス化の強化が有効になっている場合、元のチャンクに対して、「PLAIN」「QUESTION」「METADATA」の3種類のチャンクが生成されます。
| チャンクの種類 | 説明 |
|---|---|
| PLAIN | 元のチャンクテキストを含みます。元のドキュメントからの未加工のコンテンツチャンクです。 |
| QUESTION | チャンクが回答できる質問が含まれています。 LLM生成の質問のセットを含みます。 関連する元のチャンクは、これらの質問への回答を提供します。 すべての生成された質問は、ベクトル化の前に1つのチャンクにまとめられます。 これは、会話からのユーザーの意図(質問として表現)と、元のチャンクに保存されたコンテキスト(回答として表現)との間で発生し得る意味的な不一致を最小限に抑えます。 質問チャンクは、特にQ&A関連のAIエージェントシナリオにおいて、検索のリコールと精度を向上させます。 質問チャンクに属するベクトルは取得されますが、プロンプト拡張は対応する元のチャンクを使用して自動的に行われます。 したがって、質問自体がプロンプトに拡張されることは決してありません。 |
| METADATA | 元のチャンクにもとづいてLLMが生成したメタデータのセットを含みます。 以下は、インデックス化中に生成されるメタデータです。 - キーワード(最大10件) - エンティティ(チャンクのコンテンツに出現する主要なエンティティ) - トピック(最大5つの主要なトピック) - センチメント(ポジティブ/ネガティブ/ニュートラルをチャンクで指定済み) - タイトル(簡潔で情報量の多いタイトル) - 概要(通常100~250語の概要) |
インデックス化の強化 は、特にフィールドのプリペンドができないケース(UDMOパス)や、Q&Aエージェントアクションにおいて、検索の精度を大幅に向上させます。 チャンクの強化は、LLM生成コンテンツが適切なチャンクの特定を向上させるため、集中的なコンテンツキュレーションの代替手段を提供します。 トレードオフとして、チャンクの強化により、取得処理に含まれるチャンク数が増えるため、コストと遅延が増加します。
プラットフォームは3つの埋め込みモデルをサポートしています。
コンテンツが英語以外の言語である場合は、この埋め込みモデルを使用してください。 このモデルは、言語間での意味的な類似性をも保持します。 たとえば、フランス語でのクエリがドイツ語で書かれた関連記事を取得できます。 この埋め込みモデルは100の言語に対応しています。 次の表は、対応しているすべての言語と、モデルが各言語で学習したトークン数を示しています。 5億トークン未満で学習された言語については、結果の品質を十分に評価する必要があるため、慎重に扱うことを推奨します。
出典: Unsupervised Cross-Lingual Representation Learning at Scale(英語)
コンテンツが英語以外の言語である場合は、この埋め込みモデルを使用してください。 このモデルは、言語間での意味的な類似性をも保持します。 たとえば、フランス語でのクエリがドイツ語で書かれた関連記事を取得できます。 この埋め込みモデルは100の言語に対応しています。 次の表は、対応しているすべての言語と、モデルが各言語で学習したトークン数を示しています。 5億トークン未満で学習された言語については、結果の品質を十分に評価する必要があるため、慎重に扱うことを推奨します。
出典: Unsupervised Cross-Lingual Representation Learning at Scale(英語)
この埋め込みモデルは、チャンクの強化が有効になっている場合にデフォルトで使用されます。 E5モデルと組み合わせてチャンクの強化を実行することはできません。 チャンクの強化が有効になっていない場合、このモデルを使用できます。 Ada 002も多言語に対応していますが、本ガイド執筆時点では、OpenAIは対応言語の確定リストを公開していません。 一般的でない言語については、追加のテストおよびモニタリングが推奨されます。
多くの場合、RAGは特定のレコードのコンテキスト内で実行される必要があります。 例として、特定のケースのタスク内を検索することや、特定のアカウントの契約内を検索することが挙げられます。 これは、ドキュメントをSalesforceレコードに関連ファイルとしてアップロードすることで可能です。 このアカウントの例を用いて、このような(ノーコード)ソリューションを設定するには、以下の手順が必要です。
リトリーバーは、検索インデックスと、それにコンテキストを追加するプロンプトの橋渡し役として機能します。 ADLを設定する際、リトリーバーは自動的に作成されます。 取得および拡張プロセスをより詳細に制御するために、エージェントスタジオでは、リトリーバーを手動で作成およびカスタマイズできます。これには、ADLを使用して作成された検索インデックス用のリトリーバーも含まれます。
リトリーバーは、取得したチャンクに追加のフィールドを返すことができます。 これらは、チャンクDMOまたは元のDMOから来る場合があります。 検索インデックスがUDMO(ファイルなどの非構造化データ)に対して作成されている場合、通常は関連するメタデータをほとんど利用できません。 これは、非構造化ファイルを関連ファイルとしてSalesforceのレコードにアップロードすることで解決できます。 ContentDocumentコネクターを使用することで、これらを添付ファイルとして検索インデックスに取り込むことができます。 検索インデックスには、これらの添付ファイルおよび選択されたインデックスフィールドから生成されたチャンクが含まれるようになります。 この検索インデックスに対して、ソースDMOから任意のフィールドを返すようにリトリーバーを設定できます。
カスタムリトリーバーの場合、すべての取得結果に特定の条件(特定の言語で書かれていることや、特定のカテゴリに属していることなど)を適用するために、事前検索フィルター(または単に事前フィルター)を設定できます。 事前フィルタリングにより、要求した件数の結果が返され、すべての結果がフィルターの条件を満たすことが保証されます。 フィルターは、検索インデックス作成時に検索インデックスビルダーで定義されたフィールドにもとづき、リトリーバーの設定エクスペリエンスで定義されます。 これらのフィールドは、インデックスDMO(ベクトルを含む)のスキーマの一部となります。
注: 現在、既存の検索インデックスに事前フィルタリング項目を追加することはできません。
事前フィルターによって、結果セットのサイズを制限し、クエリに関連しない余分なコンテンツを除外することで、関連性に結果の重点を置くことができます。 リトリーバーが10件の結果を返すように設定されている場合、検索インデックスで見つかった最大10件の結果を返します。 結果には、フィルター条件が「True」と評価されたコンテンツのみが含まれます。
対照的に、事後検索フィルタリングは最初に10件の結果を取得して、それからフィルターを適用します。 これにより、結果セットのサイズが縮小される可能性が高く、フィルター条件を満たす結果がない場合は、結果セットが0になることもあります。 現在、事後フィルターはリトリーバーに対応していません。 ただし、Apexを使用したプロコードソリューションで定式化することができます(セクション9を参照)。 事後検索フィルターを使用するメリットは、あらゆるアクセス可能な関連フィールドを使用できる点です。一方、事前フィルターはフィルタリングのために検索インデックスに追加されたフィールドを必要とします。
動的事前フィルターでは、フィルター条件の値が実行時に提供されます。 フィルター条件は、プロンプト解決時に設定される値のプレースホルダー構文を使用して、設計時にリトリーバーに指定されます。 たとえば、Account = $placeholderのようにフィルターを設定できます。 次に、プロンプトビルダーのプロンプトエンジニアによって、プロンプトテンプレートの入力から$placeholderが適切な値にマッピングされます。 たとえば、アカウントフィールドのフィールド補完テンプレートや、アカウントを入力フィールドとするフレックステンプレートでは、プロンプトエンジニアはそのプレースホルダーをアカウント名やID、または検索インデックスの識別用事前フィルターとして追加された任意のフィールドにマッピングできます。 この方法により、リトリーバーはその特定のアカウントでタグ付けされた結果のみを返却します。
(デモリンク 、現在はSalesforce内部のみ)
#ロードマップ
詳細検索モードは、クエリの書き換えと反復的な検索を組み合わせたリトリーバー機能です。 詳細検索モードを使用すると、特にユーザーのクエリが適切に構成されていない場合や、ユーザーが質問を把握していない場合、または、検索インデックスが何に応答できるかを把握していない場合に、検索の品質を最適化できます。 具体的なステップは以下のとおりです。
RAGは通常通り実行されます。 ステップ4の結果でプロンプトを拡張し、解決したプロンプトを選択したLLMに送信して、最終的な応答を生成します。
プロンプトテンプレートの指示は、LLM生成結果の成功に不可欠です。
基本的なプロンプトテンプレートの例
please answer this question:
{!$Input:question}
using this information:
{!$EinsteinSearch:ArticleRetriever_1Cx_Q8Qa1857028.results}
上記の例には、2つの差し込み項目があります。
過度に単純化された指示は、さまざまな理由によりLLMのハルシネーションを引き起こすリスクがあります。
これは、12歳の子供に地理の本を渡して、「試験のために勉強しましょう」と言うようなものです。 一部の生徒は試験準備を進められますが、生徒の多くはどのように勉強すればよいか、また、本をどのように活用すればよいかについてのさらなる指導を必要とします。
「ナレッジで質問に答える」という標準の、すぐに使えるプロンプトテンプレートは、一般的なプロンプト設計の原則に従って、より詳細な指示を提供します。 前述の基本プロンプトテンプレートで指定されている内容に加えて、このテンプレートは以下を提供します。
以下は、既製のプロンプトテンプレート内の指示です。これは標準アクションに属します。 動的リトリーバーを使用します。
###
指示
1. クエリを分析する: 質問セクションからユーザーの質問や問題を注意深く読み、理解してください。
2. ナレッジを検索する: 提供された会社のナレッジを確認して、関連情報を見つけてください。
3. 情報を評価する: ナレッジセクションにある利用可能な情報が質問に答えるのに十分かどうかを判断してください。
4. 応答を作成する: ユーザーへの返信 <generated_response> を生成するには、これらのルールに従う必要があります
a.
ユーザーの問い合わせにもっとも関連性の高い記事チャンクを見つけ、その記事のIDをそのまま抽出して、レスポンスJSONの<source_id>フィールドに設定します。
該当する記事が見つからない場合は、<source_id> を「なし」に設定してください。
b. 関連する記事チャンクを使用して、ユーザーの質問に正確に回答する応答を生成し、<generated response>フィールドに設定します。
c. ユーザーのリクエストが提供されたナレッジで回答できない場合、<source_id> を 「なし」に設定し、<generated_response> を「申し訳ありませんが、利用可能な記事にもとづいて回答を見つけることができません」に設定してください。
5. 改善し、提供する: 回答が丁寧かつ専門的、簡潔で、{language}のみであることを徹底してください。
6. 返信を見直す: 上記のすべての指示に従っていることを確認し、希望する出力形式で回答し、ナレッジのみに厳密にもとづいて回答を作成してください。
###
ナレッジ:
{!$EinsteinSearch:sfdc_ai__DynamicRetriever.results}
###
質問:
{!$Input:Query}
ユーザーはこのテンプレートの精度が高いと報告しています。 特定のシナリオにおいて、追加の指示を加えることで応答の品質を向上させることができます。
たとえば、次のプロンプトテンプレートは以下の点において異なる構造になっています。
提供されたコンテキストについて深く考え、質問を複数の視点から検討するように促す指示に留意してください。
以下のコンテキストから論理的に導き出される根拠のみにもとづき、ユーザーのクエリに対して明確かつ直接的に回答してください。
その後、ユーザーのクエリに対して、コンテキストにもとづき異なる視点を強調しつつ、詳細で慎重な推論をもって、論理的かつ体系的、思慮深く、多角的な視点から綿密に応答してください。
回答には、整理された構成で詳細を提供してください。 現在の推論の道筋に異議を唱える可能性のある別の視点やアプローチを検討してください。
質問に回答するための十分な情報が見つからない場合、または質問への回答方法がわからない場合は、「申し訳ありませんが、ご質問にお答えするための十分な情報が見つかりませんでした」と回答してください。
推論を裏付ける証拠やデータを評価し、不足や矛盾がないか特定してください。
最後に、ユーザーのインテントを明確にするために質問をしつつ、ユーザーのクエリについて批判的思考と自己発見を促してください。
事実と、意見または信念の違いを、詳細を交えて明確に説明してください。
答えがわからない場合は、ユーザーのインテントを明確にするために質問してください。
ユーザーのクエリで言及されているエンティティに注意し、そのエンティティに関する情報がコンテキストに含まれていることを確認してください。
コンテキスト:
{!$EinsteinSearch:ArticleRetriever_1Cx_Q8Qa1857028.results}
クエリ:
{!$Input:question}
指示の形式を設定する:
以下のマークダウン構造で回答の形式を設定してください。
トピックの概要から始めてください。
主なポイントをリスト形式で挙げ、重要な用語は太字で強調してください。
以降のセクションでは、サブクエリを暗黙的に組み込んだ見出しおよび小見出しを作成してください。
手順や連続したデータがある場合は、順序付きリストで提示してください。
結論で締めくくってください。
信頼こそがAI導入における基盤です。 AIエージェントが応答を生成する際、ユーザーはその情報が正確であり、現実にグラウンディングされていて、ハルシネーションではないことを知る必要があります。 引用は、AIが生成した応答をその作成元となったグラウンディングソースへ直接リンクすることで、この信頼の基盤を提供します。
Agentforce導入において、引用は以下の3つの主要な戦略的目的を果たします。
Agentforceで引用を実装するには、以下の2つの異なるアーキテクチャアプローチがあります。 適切なアプローチを選択するには、求められる制御のレベルと、すぐに使える一貫性を重視するかどうかを比較検討する必要があります。
プラットフォーム管理型の引用(推奨)
これは、引用の形式設定、表示、リンクを自動的に行う専用プラットフォームサービスです。 複雑なプロンプトエンジニアリングを必要とせず、エージェントインターフェース全体で一貫したユーザー体験を実現します。
指示ベースの引用
このアプローチは、プロンプトエンジニアがプロンプトテンプレート内でカスタム指示を提供し、引用を生成することに依存しています(例:「常に出典タイトルの形式で出典を引用してください」)。
プラットフォーム管理型の引用が機能するためには、データはソースであるリトリーバー側で準備されている必要があります。 エージェントスタジオで引用機能を有効にすると、リトリーバーがメタデータをプロンプトテンプレートやAIエージェントなどのダウンストリームコンポーネントに引き渡すことができます。
エージェントスタジオでリトリーバーを設定する際、引用の構築方法を定義するために、以下の2つのオプションがあります。
標準引用
システムは、基盤となるデータモデルオブジェクト(DMO)のデフォルトのソースURLと見出しテキストフィールドを使用して、自動的に引用を生成します。 これは標準ナレッジ実装向けの最短の設定方法です。
カスタム引用
より複雑なデータモデルの場合、特定のフィールドを手動でマッピングして引用を構築できます。 以下の内容を定義します(agentforce.comは例として使用されているドメインです。ここにご自身のドメインを指定してください)。
ベストプラクティス: https://www.agentforce.com/search?q=URLs に選択されたフィールドに、エンドユーザーが確実にアクセスできるようにします。 引用リンクは、ユーザーが対象ドキュメントを表示する権限を持っている場合にのみ有用です。
引用をサポートするようにリトリーバーを設定したら、そのリトリーバーを呼び出すプロンプトテンプレート内でこの機能を有効化する必要があります。
プロンプトビルダーで、{!$EinsteinSearch...} リソースを設定する場合は、以下の手順に従ってください。
このプロンプトテンプレートが呼び出されると、LLMの応答には、使用されたドキュメントのクリック可能なリストを含む「出典」セクションが表示されます。
カスタムアクションに関する注意: プロンプトテンプレートにもとづくカスタムアクションは、応答の下部にある「出典」リストには対応していますが、標準の「ナレッジで質問に回答する」アクションと同様に、インライン引用(例:「保証期間は2年間です [1]」)には現在対応していません。
引用はテキストに限定されません。Agentforceは、ドキュメント内に含まれるチャート、グラフ、図などのビジュアルデータにグラウンディングして応答を生成できるようになりました。
ユースケース: ファイナンシャルプランニング
ファイナンシャルプランナーがAIエージェントに顧客のポートフォリオ配分について質問する場面を想像してみてください。 ソースドキュメントにポートフォリオの円グラフが含まれている場合、RAGプロセスは、その画像の構造化された説明を取得できます。
実装の手順は以下のとおりです。
エージェントインターフェースでは、これらは外部リンクとして表示され、ユーザーは回答をグラウンディングした特定のチャートやグラフをポップアップ画面で開くことができます。
リトリーバーは、プロンプトテンプレートと検索インデックスを結びつけます。 これにより、ユーザーは、指定された検索文字列(ユーザーのクエリまたは質問)に、もとづいて検索インデックスから取得するコンテンツを指定する、再利用可能かつバージョン管理可能な、ノーコードのクエリテンプレートを設定できるようになります。 リトリーバーを使用すると、ユーザーは以下を指定できます。
ノーコードリトリーバーは以下をサポートします。
一部のユースケースでは、クエリが検索インデックスに対してより複雑な表現を必要とします。 以下のような追加の制御が必要となります。
リトリーバーは、RAGの実装用に迅速かつ簡単(ノーコード)なアプローチを提供します。 リトリーバーは、検索インデックスクエリに加えて、アンサンブルリトリーバーや(#ロードマップ)詳細検索モードなどの追加機能を提供します。 Agentforce 360 Platform上のすべてのノーコードアーキテクチャと同様に、一部のユースケースはプロコードを使って解決する方が最適です
実行時に、リトリーバーはユーザー設定をData 360 SQLクエリに変換し、ベクトル検索またはハイブリッド検索関数を呼び出すために使用します。 これらの関数は、Apexクラス内からData 360 Connect APIを使用して呼び出すこともできます。 Apexユーザーは、クエリの表現を直接記述する柔軟性と能力を持ち合わせています。
このハイブリッド検索に関するヘルプトピック を参照して、クエリの表現の例や、ノーコードリトリーバーが対応していない事前フィルター表現の例をご確認ください。 事前フィルター(このページには記載されていません)は、SQL式のWHERE句によってサポートされています。
ユーザーは、Apexクラスを使用してプロンプトをグラウンディングでき、ノーコードリトリーバーが現在利用できないケースにおいてプロコードの代替手段を提供します。
注: Apexクラスまたはフローがコンテンツウィンドウを超えるコンテンツを返した場合、そのコンテンツは自動的に要約されます。 その場合、元のレコード/チャンクデータは返却されず、要約バージョンが提供されます。
Apexクラスとプロンプトテンプレートの使用方法については、Salesforceヘルプの「Apex差し込み項目をフレックスプロンプトテンプレートに追加する 」を参照してください。 そのページの例では、public static Listメソッドには、Data 360 Connect APIへの呼び出しは含まれていません。 ただし、このページではApexクラスの構造が示されています。
次の例では、Connect APIへの接続とクエリ表現を作成します。 このコードでは、取得したコンテンツへのユーザーアクセスのためにプロシージャルフィルター(クエリ表現の外側)を適用しますが、これは現在ノーコードリトリーバーでは利用できません。
public static List<Response> searchSimilarCases(List<Request> requests) {
List<Response> responses = new List<Response>();
Response response = new Response();
String caseDescription = requests[0].RelatedEntity.Description;
ConnectApi.CdpQueryInput input = new ConnectApi.CdpQueryInput();
input.sql = 'SELECT DISTINCT v.score__cScore__c, c.ssot__Id__cId__c, c.ssot__Subject__c
Subject__c"+
'FROM vector_search(\case_chunk_vector__dlm\;\" + caseDescription + '\', \'\', 200) v ' +
'JOIN Case_Chunks__dlm cc ON v.chunk_id__c = cc.chunkid__c ' +
'JOIN ssot__Case__dlm c ON cc.parentid__c = c.ssot__Id__c ' +
WHERE cc.column__c != \'ssot__Subject__c\' AND c.ssot__DataSourceId__c = \'CRM\' ' +
'LIMIT 10';
ConnectApi.CdpQueryOutput output = ConnectApi.CdpQuery.queryANSISql(input);
List Object> data = output.data;
String scs = '';
for (Object searchRecord : data) {
Map<String, Object>myMap = (Map<String, Object>) JSON.deserializeUntyped(JSON.serialize(searchRecord)); // check for access of case record for the current user if (SimilarCasesSearch.getUserRecordAccess((String) myMap.get('Id__c'))) { Map<String, String>sc = new Map
<String, String>();
sc.put('Id', (String) myMap.get('Id__c'));
sc.put('Similar_Case__c', (String) myMap.get('Id__c'));
sc.put('Name', (String) myMap.get('Subject__c'));
sc.put('Score__c', String.valueOf(myMap.get('Score__c')));
scs = scs + JSON.serialize(sc);
}
}
response.Prompt = scs;
responses.add(response);
return responses;
}
ユースケースによっては、特定の要因により、あるLLMが他のLLMよりも適している場合があります。
解決したRAGプロンプトのサイズに対応できる、十分なコンテキストウィンドウサイズを備えたLLMを選択することが重要です。 1トークンはおおよそ3/4語に相当することを考慮してください。 たとえば、100トークンは約75語に相当します。
モデルが強力であるほど、与えられたコンテキストに対してより優れた推論が可能になります。 特定のユースケースにおける推論タスクの難易度を慎重に評価してください。 提供されたコンテキストに重要な情報はほぼすべて含まれているでしょうか?一般的に、RAGソリューションにおける最大の複雑性は、最終的なLLM生成よりも、検索と拡張で多く発生します。 このような場合、生成を実行するLLMへの負担はそこまで大きくならないため、コンテキストウィンドウがユースケースに十分な大きさであれば、小規模なモデル(GPT 3.5など)でも対応することができるようになります。
生成を実行するLLMがコンテンツについてさらに深く推論する必要がある場合(複数の結果を組み合わせたり、入力を変換したり、結論を導き出したりする場合など)のような、さらに複雑なユースケースにおいては、GPT 4(Turbo)など、より強力なモデルが推奨されます。
プロンプトテンプレートでプロンプトのグラウンディングにもっとも一般的に使用されるのが、リトリーバーです。 リトリーバーは、RAGのフローでも使用されます。 さらに、フロー内では、その出力を他の方法で使用することができます。たとえば、自動化のシナリオで出力を既存の類似コンテンツの確認に使用したり、分類タグ付け(セクション13.2で説明)に利用したりすることが可能です。
RAGソリューションは、フロー内で実装できます。 このアプローチでは、フローがリトリーバーを呼び出してグラウンディング結果を取得し、その結果を後続で呼び出すプロンプトテンプレートに引き渡します。 このアプローチにより、ユーザーはRAGプロセス全体をより細かく制御できるようになります。 ユーザーは、連鎖したプロンプトテンプレート、リトリーバー、および変換のパイプライン全体を設定できます。 プロンプトテンプレートを使用してプロセスを推進する代わりに(フローの呼び出しを含む)、フローがオーケストレーション層およびプロセスへの窓口として機能します。 このフロー主導のアプローチは、取得した結果に対して、特定のユーザーアクセス権やその他のプロコードフィルターの確認など、より詳細な事後フィルタリングを提供します。
Flowでリトリーバーを呼び出すには、Flowにアクション要素を追加します。 利用可能なアクションのリストからリトリーバーのリトリーバー名を検索します。 Flow変数(検索文字列など)は、リトリーバーへの入力として利用できます。 実行時には、数値はSalesforceレコード、Flow画面の要素、その他の任意のFlow変数から取得できます。
Flow内でリトリーバーを呼び出す際も、動的事前フィルターがサポートされています。 動的フィルターの数式では、等式の右辺をFlow変数にマッピングします。 実行時に、Flowのコンテキスト(国、言語、カテゴリなど)を使用して、動的フィルターでリトリーバーの結果をフィルタリングします。
以下の標準Flowアクションを使用すると、Flowで高度なRAGパイプラインを構築できます。
| Flowアクション | 説明 |
|---|---|
| 言語を検出 | クエリの言語を検出し、その言語をフィルター値としてリトリーバーノードに引き渡すことで、動的なフィルタリング(言語別)が可能になります。 |
| {ケース/メール/会話}のクエリを変換 | これらの3つのノードはそれぞれ、ケース、メール、会話を検索向けに最適化されたクエリへと変換するLLM変換を呼び出します。 これにより、リトリーバーが検索インデックスに引き渡すクエリが改善されます。 たとえば、会話からクエリへのアクションは、「ご用件をお伺いします」や「お世話になっております」のような関連性のないメッセージで検索インデックスをクエリすることを回避します。 同様に、ケースからクエリおよびメールからクエリは、テキストから関連情報を抽出し、挨拶や検索に使用すべきでないその他のテキストを除去します。 |
リトリーバーの出力は、JSON配列として書式設定されていますが、この書式はFlowではサポートされていません。 したがって、その後Flowで結果を使用するには、処理アクションによってリトリーバーの出力をフラット化された文字列などのFlowがサポートする書式に変換する必要があります。 プロセッサーFlowノードは、以下の例のようにApexクラスを使用して実装できます。
global with sharing class RetrieverProcessor {
@InvocableMethod
class public static List<String> GetWebProduct(List<Requests> queryResults)
{
List<String> resultsList = new List<String>()
for (Requests queryResult : queryResults) {
List<String> segments = new List<String>();
for (ConnectApi.MlRetrieverQueryResultDocumentRepresentation document: queryResult.queryResult.searchResults) {
for (ConnectApi.MlRetrieverQueryResultDocumentContentRepresentation content: document.result) {
if (content.fieldName.equals('Chunk')) {
segments.add(content.value.toString());
}
}}
if
if (segments.size() == 0) {
resultsList.add('No results');
} else {
resultsList.add(String.join(segments, ','));
}
}
return resultsList;
}
global class Requests {
@InvocableVariable
global ConnectApi.MlRetrieverQueryResultRepresentation queryResult;
}
}
この例では、GetWebProductメソッドがリトリーバーの出力要素をループし、「チャンク」という名前の返却フィールドのコンテンツを文字列のリストに追加します。 このFlowは、このリストをダウンストリームで繰り返し処理することも、グラウンディングの入力としてプロンプトテンプレートノードに引き渡すことも可能です。
AIエージェントがRAGを使用して質問に回答した際、その回答が不十分であった場合、RAGに関連するさまざまな要因を考慮する必要があります。 ユーザーにとっては、AIエージェントが単に誤った回答や不十分な回答をしたか、まったく回答しなかったように見えます。 パフォーマンスが低下しているRAG強化型のAIエージェントのトラブルシューティングでは、これらのさまざまな失敗の要因を1つずつ調査し、原因を特定していきます。
これらの失敗は、以下の原因によって発生する可能性があります。
このセクションでは以下のことを説明します。
RAGソリューションでADLを使用する場合は、こちらのトラブルシューティングガイド を参照してください。
Agentforceの推論エンジンによって、正しいトピック内で正しいアクションが実行されているかどうかを判断します。 Agentforce Agentforce Builderまたはテスティングセンターを使用して調査と診断を行います。
正しいトピックが選択されていない場合、または正しいトピックが選択されていても正しいアクションが実行されていない場合、問題は指示および分類説明のAIエージェント設定で発生している可能性が高いです。 これはAIエージェントの問題であり、RAGの問題ではないため、本ホワイトペーパーでは取り扱いません。 この詳細については、以下のページを参照してください。
Agentforce Builderは、推論エンジンの推論パスおよびその中間の結果を示します。 ADLと標準アクションを使用する際は、推論パスにしたがって、正しいリトリーバーやグラウンディングソースがプロンプトテンプレートに引き渡されているかを確認してください。 正しいリトリーバーが引き渡されていない場合は、正しいリトリーバーが引き渡されるようにAIエージェントの設定を修正してください。
注: このアプローチは、カスタムプロンプトテンプレートを使用するカスタムエージェントアクションには適用されません。 これは、リトリーバーの呼び出しが完全にプロンプトテンプレート内で行われ、推論エンジンによって引き渡されるものではないためです。
以下の方法で、検索インデックスにコンテンツが正しく入力されているかどうかを判断できます。
SELECT 'INDEX' AS Location, COUNT(DISTINCT rc.SourceRecordId__c) AS ArticleCount, now() AS Timestamp
FROM <chunk DMO of the Search Index> rc
UNION
SELECT 'DMO' AS Location, COUNT(DISTINCT kav.Id__c) AS ArticleCount, now() AS Timestamp
FROM <DMO that was indexed, e.g. Knowledge Article Version> kav
ORDER BY Location;
プロンプトビルダーで、次のいずれかを判断します。
RAGパイプラインのすべての構成要素が正しく結びついていることを確認したら、質的な問題が回答の誤り、不完全さ、ハルシネーション、またはこれらの症状の組み合わせを引き起こしているかどうかを判断します。 質的な懸念は、根本原因が多岐にわたるため、トラブルシューティングがさらに困難になる場合があります。 検索、埋め込み、拡張、応答生成、さらには元のナレッジソースにおいても、品質の問題が発生する可能性があります。 (該当するコンテンツは実際に検索インデックス内に存在しますか?) この図は、RAGパイプライン内で品質の問題が発生する可能性のある領域と、それらの関連項目を示しています。
RAGの評価品質指標によって、RAGパイプラインで改善すべき領域を判断することができます。 ダッシュボードには、3つの評価指標が計算され、表示されます。 このダッシュボードでは、リトリーバーレベルまで詳細を確認することができます。 指標については以下で説明します。その後、これらを総合的に検討した際に浮き彫りになる点について詳しく見ていきます。
| 指標 | 回答 | 定義 | できること |
| コンテキストの関連性 | 取得されたコンテンツはクエリにどの程度関連しているか? | LLMベースの評価 | 検索の問題を切り離す |
| 忠実性 | 取得したコンテンツに対して、応答はどれほどグラウンディングされているか? | LLMベースの評価 | LLM生成問題を切り離す |
| 回答の関連性 | この回答はクエリにどの程度関連しているか? | LLMベースの評価 | 回答に関する全体的な応答指標。 コンテキストの関連性および忠実性と組み合わせて使用するとさらに有用。 |
品質指標の一般的なパターン
回答は、取得したコンテキストにグラウンディングされていますが、コンテキストはクエリに関連していません。 その結果、回答の関連性も低くなる可能性があります。 この症状は、取得時に問題が発生している可能性を示しています。
実施可能な修正方法は以下のとおりです。
回答は、コンテキストがクエリに関連していますが、コンテキストにグラウンディングされていません。 回答の関連性も低くなる可能性があります。 この症状は、LLM生成に問題があることを示している可能性があります。 LLMが与えられたコンテキストに従うための十分に明確な指示を出せなかったことなど、プロンプトエンジニアリングの不備が原因である可能性があります。
実施可能な修正方法は以下のとおりです。
回答はコンテキストにグラウンディングされており、そのコンテキストは実際にクエリに関連していますが、回答の関連性は依然として低い状態です。 この症状は、クエリに完全に回答するための十分なコンテキストが取得されなかったことを示している可能性があります。 問題はおそらく検索、特に検索のリコールにあると考えられます。
実施可能な修正方法は以下のとおりです。
RAGパイプラインを設定する際、管理者や開発者は、LLMに回答を生成させずにプロンプトを解決したいと考える場合が多くあります。 これにより、インデックス化や検索パイプラインの分析と最適化が可能になります。 目標は、リトリーバーによって取得されたコンテンツを観察することにあります。 LLM応答を生成する必要はありません。
プロンプトビルダーで、プロンプトテンプレートのURLに&c__debug=1を追加します。 これにより、管理者は「解決結果のみ」、「応答のみ」(応答用の画面スペースが広くなります)、または標準の「解決結果および応答」を切り替えることができるトグルが表示されます。
リトリーバーはRAGのユースケース以外でも使用されます。 必ずしも応答が必要とは限りません。 いくつかの要件は、検索インデックスから意味的に類似したコンテンツを取得することで満たされます。 たとえば、サービスのコンテキストでケースが作成される場合を考えてみましょう。 RAGパイプライン全体を実行せずに、ケース調査を担うサービスエージェントにサポート目的で類似ケースを表示するだけでも、非常に大きな価値を提供できます。
このような自動化を設定するには、フローが実行される際にリトリーバーを呼び出すフローにもとづいたソリューションが推奨されます。 クエリと類似した結果セットを生成することから、ケースや記事など、結果の出典をユーザーに提示することができます。
検索インデックスを使用して、インテント検出、トピック注釈、またはケース分類などのテキスト分類を実施します。 分類のユースケースは、多くの場合、学習データセット(入力とクラスラベル)を使用して解決されます。 このデータセットでテキスト分類機能を学習させる代わりに、テキストをベクトル化することができます。 これらの入力をData 360にDMOのレコードとして保存し、検索インデックスに埋め込めるようにします。 検索操作は、クエリと埋め込み入力との間の意味的な類似性にもとづいて行われます。 しかし、「学習」入力のチャンクを返す代わりに、検索は元のクラスラベルを返します。 十分な結果の件数がある場合(50件や100件など)、「多数決」を行い、その結果セット内でどのクラスラベルがもっとも頻繁に出現するかどうかを確認することが可能です。 結果セット内のクラスラベルをその出現頻度で並び替えることで、分類の提案を提供します。 もっとも頻繁に出現するクラスラベルを選択するか、あるいはユーザーに対して上位3つのクラスラベルを選択します。
このシナリオでは、リトリーバーが使用されているSQLクエリ(COUNTにもとづく)をサポートしていないため、補足的なApexコードが必要です。 このコード例では、クエリを使用して上位50件の結果に出現する各クラスラベルの頻度をカウントし、そのカウント値で並べ替え、もっとも頻度の高いクラスラベルを結果として選択しています。
ConnectApi.CdpQueryInput input = new ConnectApi.CdpQueryInput();
input.sql = 'SELECT r.Label_c__c Label, COUNT(r.Label_c__c) AS counter FROM vector_search(table(Intent_Training_index__dlm), topic,'' , 50) v JOIN Intent_Training_chunk__dlm c ON v.RecordId__c = c.RecordId__c JOIN Intent_Training__dlm r ON r.Id__c = c.SourceRecordId__c GROUP BY r.Label_c__c ORDER BY counter DESC LIMIT 1;
ConnectApi.CdpQueryOutput output = ConnectApi.CdpQuery.queryANSISql(input);
Reinier van Leukenは、本ホワイトペーパーの内容をまとめるにあたり、多大なご協力をいただいた次の校正者の皆様に感謝の意を表します。 Eric Ivory-Chambers、Robin de Bondt、Jan van den Broeck、Alejandro Raigon、Vahe Ayvazyan、Giuseppe Cardace、Praveen Gonugunta、Kathryn Baker Parks、Debbie Symanovich。