Salesforce Einstein Language API:Apex連携による自然言語処理活用ガイド

背景と適用シナリオ

Salesforce 開発者として、私たちは常に顧客体験を向上させ、ビジネスプロセスを自動化するための新しい方法を模索しています。近年、AI (人工知能) の進化は目覚ましく、特に Natural Language Processing (NLP, 自然言語処理) 技術は、テキストデータから価値ある洞察を引き出すための強力なツールとなっています。Salesforce はこの分野で Einstein Language (アインシュタイン言語) と呼ばれる一連の強力な API を提供しており、開発者はこれを利用して、Salesforce プラットフォーム上で直接、高度なテキスト分析機能をアプリケーションに組み込むことができます。

具体的な適用シナリオとしては、以下のようなケースが考えられます。

  • サービス業務の効率化:ケースのコメントや受信メールの内容を分析し、顧客の感情 (ポジティブ、ネガティブ、ニュートラル) を自動的に判定 (Sentiment Analysis, 感情分析)。ネガティブな感情が検出されたケースを優先的にエスカレーションするワークフローを構築できます。
  • リード・問い合わせのルーティング:Web-to-Lead フォームやチャットボット経由で寄せられた問い合わせテキストの意図 (Intent Classification, 意図分類) を「製品に関する質問」「価格に関する問い合わせ」「技術サポート」などに自動分類し、適切な担当部署やキューに割り当てることができます。
  • データ入力の自動化:自由記述形式の活動記録や商談メモから、製品名、競合企業名、連絡先担当者名などの重要な情報 (Named Entity Recognition, 固有表現抽出) を自動的に抽出し、関連オブジェクトの項目に設定することで、データ入力の手間を削減し、データの構造化を促進します。

本記事では、Salesforce 開発者の視点から、Einstein Language API を Apex からどのように利用するか、その原理、具体的なコード例、そして実装する上での注意点について詳しく解説します。


原理説明

Einstein Language は、主に3つの強力な機能を提供する REST API の集合体です。Salesforce 開発者は、Apex の ConnectApi フレームワークを通じて、これらの API を簡単に呼び出すことができます。ConnectApi を利用することで、HTTP コールアウトの複雑な実装 (認証、エンドポイント管理など) を Salesforce プラットフォームに任せることができ、開発者はビジネスロジックに集中できます。

Einstein Language の主要な機能は以下の通りです。

Einstein Sentiment (感情分析)

与えられたテキストが表現している感情を「ポジティブ」「ネガティブ」「ニュートラル」のいずれかに分類します。この API は事前学習済みのモデルを使用するため、開発者が独自にモデルをトレーニングする必要はありません。すぐに利用を開始できるため、最も手軽に導入できる機能の一つです。API は各感情の確率スコアとともに、最も確率の高い感情ラベルを返します。

Einstein Intent (意図分類)

テキストがどのような意図を持っているかを、開発者自身が定義したカテゴリ(ラベル)に分類します。例えば、「請求書の問い合わせ」「配送状況の確認」「製品の返品」といった独自のカテゴリを作成し、それぞれのカテゴリに対応する多数のテキストサンプルをデータセットとして Einstein に学習させる必要があります。モデルのトレーニングが完了すると、新しいテキストがどの意図に最も近いかを予測できるようになります。これにより、ビジネス固有のニーズに合わせたテキスト分類が可能になります。

Einstein NER (Named Entity Recognition, 固有表現抽出)

テキスト内から特定の種類の固有名詞やキーワード(エンティティ)を識別し、抽出します。Intent と同様に、どのようなエンティティ(例:「製品名」「会社名」「人名」「場所」)を抽出したいかを定義し、それに対応するデータセットを学習させる必要があります。これにより、非構造化テキストデータから構造化された情報を抽出し、データベースのレコードとして活用することが可能になります。


示例代码

ここでは、Apex を使用して Einstein Language の各 API を呼び出す具体的なコード例を紹介します。これらの例は、Salesforce の公式ドキュメントで提供されている `ConnectApi.Einstein` クラスの利用方法に基づいています。

1. Einstein Sentiment (感情分析) の呼び出し

Sentiment API はモデル ID が不要で、テキストを渡すだけで簡単に利用できます。以下の例では、与えられた文字列の感情を分析します。

// Sentiment (感情分析) を実行する Apex メソッド
public static void predictSentiment(String textToAnalyze) {
    // EinsteinPrediction を格納するリストを初期化
    List<ConnectApi.EinsteinPrediction> predictions = new List<ConnectApi.EinsteinPrediction>();

    try {
        // ConnectApi.Einstein.predictSentiment メソッドを呼び出す
        // 第1引数: モデルID (Sentiment では 'CommunitySentiment' を使用)
        // 第2引数: 分析対象のテキスト
        // 第3引数: 予測を返す数 (通常は1)
        // 第4引数: 予約済み (null を指定)
        predictions = ConnectApi.Einstein.predictSentiment('CommunitySentiment', textToAnalyze, 1, null);

        // 予測結果が存在するか確認
        if (predictions != null && !predictions.isEmpty()) {
            // 最初の予測結果を取得
            ConnectApi.EinsteinPrediction prediction = predictions[0];
            
            // 予測結果の確率リストをループ
            for (ConnectApi.EinsteinProbability probability : prediction.probabilities) {
                // 結果をデバッグログに出力
                // probability.label: 感情ラベル (Positive, Negative, Neutral)
                // probability.probability: そのラベルである確率 (0.0 - 1.0)
                System.debug('Sentiment Label: ' + probability.label + ', Probability: ' + probability.probability);
            }
        } else {
            System.debug('Sentiment prediction returned no results.');
        }

    } catch (Exception e) {
        // エラーハンドリング
        System.debug('An error occurred during sentiment prediction: ' + e.getMessage());
    }
}

// 呼び出し例
// predictSentiment('I am so happy with the service I received. It was excellent!');

コード解説:
上記のコードは `ConnectApi.Einstein.predictSentiment` メソッドを使用しています。`CommunitySentiment` という事前学習済みモデルを指定し、分析したいテキストを渡します。戻り値は `ConnectApi.EinsteinPrediction` オブジェクトのリストで、各オブジェクトには `probabilities` というプロパティが含まれています。このプロパティは `ConnectApi.EinsteinProbability` のリストであり、それぞれの要素が感情ラベル (Positive, Negative, Neutral) とその確率を保持しています。

2. Einstein Intent (意図分類) の呼び出し

Intent API を使用するには、事前にデータセットをアップロードし、モデルをトレーニングしておく必要があります。以下のコードでは、トレーニング済みのモデル ID を使用してテキストの意図を分類します。

// Intent (意図分類) を実行する Apex メソッド
public static void predictIntent(String modelId, String textToAnalyze) {
    // EinsteinPrediction を格納するリストを初期化
    List<ConnectApi.EinsteinPrediction> predictions = new List<ConnectApi.EinsteinPrediction>();

    try {
        // ConnectApi.Einstein.predictIntent メソッドを呼び出す
        // 第1引数: トレーニング済みのカスタムモデルID
        // 第2引数: 分析対象のテキスト
        // 第3引数: 予測を返す数
        // 第4引数: 予約済み (null を指定)
        predictions = ConnectApi.Einstein.predictIntent(modelId, textToAnalyze, 1, null);

        // 予測結果が存在するか確認
        if (predictions != null && !predictions.isEmpty()) {
            ConnectApi.EinsteinPrediction prediction = predictions[0];
            
            for (ConnectApi.EinsteinProbability probability : prediction.probabilities) {
                // 結果をデバッグログに出力
                // probability.label: 自身で定義した意図ラベル (例: 'Billing Question')
                // probability.probability: そのラベルである確率
                System.debug('Intent Label: ' + probability.label + ', Probability: ' + probability.probability);
            }
        } else {
            System.debug('Intent prediction returned no results.');
        }

    } catch (Exception e) {
        // エラーハンドリング
        System.debug('An error occurred during intent prediction: ' + e.getMessage());
    }
}

// 呼び出し例 (modelId は自身の環境のものに置き換える)
// String myModelId = 'B25P2P3L6E5A4W6Y7Z8X9C1V2B3N4M5K';
// predictIntent(myModelId, 'What is the status of my recent order?');

コード解説:
`ConnectApi.Einstein.predictIntent` メソッドは Sentiment と似ていますが、第1引数に自身でトレーニングしたモデルの ID を指定する点が異なります。このモデル ID は、Einstein Platform Services の設定画面や API 経由で取得できます。戻り値の構造は Sentiment と同じで、定義した意図ラベルごとの確率が返されます。

3. Einstein NER (固有表現抽出) の呼び出し

NER も Intent と同様に、カスタムモデルのトレーニングが必要です。抽出したいエンティティを定義し、データセットを学習させます。

// NER (固有表現抽出) を実行する Apex メソッド
public static void predictNer(String modelId, String textToAnalyze) {
    // EinsteinPrediction を格納するリストを初期化
    List<ConnectApi.EinsteinPrediction> predictions = new List<ConnectApi.EinsteinPrediction>();

    try {
        // ConnectApi.Einstein.predictNer メソッドを呼び出す
        // 第1引数: トレーニング済みのカスタムモデルID
        // 第2引数: 分析対象のテキスト
        // 第3引数: 予約済み (null を指定)
        // 第4引数: 予約済み (null を指定)
        predictions = ConnectApi.Einstein.predictNer(modelId, textToAnalyze, null, null);

        // 予測結果が存在するか確認
        if (predictions != null && !predictions.isEmpty()) {
            ConnectApi.EinsteinPrediction prediction = predictions[0];

            for (ConnectApi.EinsteinProbability probability : prediction.probabilities) {
                // 結果をデバッグログに出力
                // probability.label: 自身で定義したエンティティラベル (例: 'ProductName')
                // probability.token: 抽出されたテキスト (例: 'Cloud-based CRM')
                System.debug('Entity Label: ' + probability.label + ', Extracted Token: ' + probability.token);
            }
        } else {
            System.debug('NER prediction returned no results.');
        }

    } catch (Exception e) {
        // エラーハンドリング
        System.debug('An error occurred during NER prediction: ' + e.getMessage());
    }
}

// 呼び出し例 (modelId は自身の環境のものに置き換える)
// String myNerModelId = 'A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P';
// predictNer(myNerModelId, 'I would like to purchase the Awesome Widget 3000 for my company, ACME Corporation.');

コード解説:
`ConnectApi.Einstein.predictNer` メソッドを使用します。このメソッドの戻り値も `ConnectApi.EinsteinPrediction` のリストですが、`ConnectApi.EinsteinProbability` オブジェクトには `token` という追加のプロパティが含まれます。`label` がエンティティの種類(例:`ProductName`)を示し、`token` が実際にテキストから抽出された文字列(例:`Awesome Widget 3000`)を示します。


注意事項

Einstein Language API を本番環境で利用する際には、いくつかの重要な点に注意する必要があります。

権限設定

Apex から Einstein Language API を呼び出すユーザには、「Einstein Platform API User」権限セットが割り当てられている必要があります。この権限がない場合、API 呼び出しは失敗します。システムコンテキスト (トリガやバッチ処理など) で実行する場合でも、実行ユーザにこの権限が必要です。

API 制限

Einstein Language API の呼び出しには、組織のライセンスに基づいた月間上限回数が設定されています。例えば、無料の Einstein Language ライセンスでは、月間2,000回までの予測呼び出しが可能です。本番導入前には、予想されるトラフィック量とライセンスの上限を確認し、必要に応じて追加ライセンスの購入を検討してください。API の使用状況は、[設定] > [Einstein] > [使用状況] から確認できます。

エラーハンドリング

API 呼び出しは、ネットワークの問題、無効なモデル ID、API 制限超過など、さまざまな理由で失敗する可能性があります。そのため、コードには必ず `try-catch` ブロックを実装し、例外を適切に処理する必要があります。また、`ConnectApi.EinsteinPrediction` の結果が空である場合や、API から返されるステータスコードを確認するロジックも重要です。

モデルのトレーニングと管理

Einstein Intent と NER を利用するには、質の高いデータセットの準備と、モデルのトレーニングが不可欠です。モデルの精度は、提供するデータの量と質に大きく依存します。一般的に、各ラベルに対して少なくとも50件以上のサンプルデータを用意することが推奨されます。また、ビジネス要件の変化に応じて、モデルを定期的に再トレーニングし、精度を維持・向上させる運用プロセスも考慮する必要があります。

Apex ガバナ制限

`ConnectApi` を介した呼び出しは、Apex のコールアウト制限の対象となります。1つのトランザクション内で実行できるコールアウトは最大100回です。トリガ内から直接 API を呼び出すと、一括処理時にこの制限に抵触する可能性があります。大量のレコードを処理する場合は、トリガから Platform Event を発行し、非同期のトリガハンドラや Queueable Apex, Batch Apex を使用して API を呼び出すアーキテクチャを検討してください。


まとめとベストプラクティス

Salesforce Einstein Language は、開発者が Apex を用いて Salesforce プラットフォームに高度な自然言語処理機能を簡単に組み込むことを可能にする、非常に強力なツールセットです。感情分析、意図分類、固有表現抽出といった機能を活用することで、これまで手作業で行っていた多くのテキスト関連業務を自動化し、顧客エンゲージメントの向上と業務効率化を実現できます。

開発者として Einstein Language を最大限に活用するためのベストプラクティスを以下にまとめます。

  • 再利用可能なサービスクラスの作成:Einstein API 呼び出しのロジックを専用のサービスクラスにカプセル化し、エラーハンドリングやレスポンス解析の処理を共通化します。これにより、コードの再利用性が高まり、メンテナンスが容易になります。
  • 非同期処理の積極的な活用:トリガや一括処理で Einstein API を呼び出す際は、`@future(callout=true)`、Queueable、Batch Apex などの非同期パターンを積極的に利用し、ガバナ制限を回避します。
  • コストとパフォーマンスの考慮:API 呼び出しにはコストがかかるため、本当に必要な場合にのみ呼び出すように設計します。例えば、一度分析した結果はカスタム項目に保存し、レコードが更新されない限り再分析しないように制御します。
  • モデル精度の継続的な監視:特に Intent と NER では、モデルの予測結果を定期的にレビューし、期待通りの精度が出ているかを確認します。必要に応じてデータセットを更新し、モデルを再トレーニングする MLOps (機械学習基盤) の考え方を取り入れることが重要です。

これらのプラクティスを念頭に置くことで、Salesforce 開発者は Einstein Language のポテンシャルを最大限に引き出し、よりスマートで効率的なアプリケーションを構築することができるでしょう。

コメント