前記事の続編として、Salesforceの Einstein 1 Platform 上で作る、カスタム生成AIアプリケーションのサンプル第二弾になります。今回は、前記事にて作成したAIに商談・活動状況を多角的に評価・フィードバックをしてもらうカスタムアプリをベースに、Einstein Copilot カスタムアクションを使用し、「AI商談レビュー」の対話型AIアシスタントアプリを構築します。
〜「AI商談レビュー」シリーズ 〜
- 第一弾 プロンプトテンプレートでカスタム生成AIアプリ「AI商談レビュー」を作る
- 第二弾 Einstein Copilotで「AI商談レビュー」の対話型AIアシスタントアプリを実現(本記事)
Einstein Copilotは米国での一般提供を開始してますが、2024/5/8 現在、日本での提供開始時期は未定です。
前提
以下のSalesforceテクノロジーを使用します。
- プロンプトテンプレート
- Einstein Copilot カスタムアクション
- Apex
- Queueable Apex
開発環境
- プロンプトビルダー / Einstein Copilotが有効化されたDeveloper Edition組織を取得
※有効期限5日
構成
前記事からの続きの手順になります。
1. Salesforceオブジェクト
商談レビューのステータスを管理できるよう、作成済みのカスタムオブジェクトにカスタム項目を一つ追加します。
1-1. 商談レビュー(DealReview__c)
項目 | API名 | データ型 | 備考 |
---|---|---|---|
ステータス | Status__c | 選択リスト | 3つの状態を管理 レビュー前 => レビュー中 => 完了 |
2. Apex
Plannerから商談レビュー用Copilotアクションが呼ばれる際、一部時間のかかる処理を非同期ジョブにオフロードする構成で、いくつかApexクラスを作成します。
- Copilotアクション用Apex
- 非同期ジョブ用Apex
Copilotアクション用Apex
public with sharing class AiDealReviewCopilotAction {
@InvocableMethod(
label='商談レビューの実施'
description='Conduct a deal review for a specific Opportunity record'
)
public static List<Output> startDealReview(List<Input> inputs) {
List<Output> outputs = new List<Output>();
try {
Input input = inputs[0];
Id opptyId = input.OpportunityId;
Output output = new Output();
DealReview__c dr = AiDealReviewController.insertDealReview(opptyId);
List<DealScoreCriteria__c> dscs = AiDealReviewController.getDealScoreCriteria();
List<DealScore__c> dss = new List<DealScore__c>();
AsyncOptions asyncOptions = new AsyncOptions();
asyncOptions.MaximumQueueableStackDepth = dscs.size() + 1;
System.enqueueJob(new AiDealReviewAsyncJob(opptyId, dr.Id, dscs, dss), asyncOptions);
output.dealReview = dr;
output.annotationMessage = 'レビューを開始しました。(レビュー完了まで時間がかかる場合があります)';
outputs.add(output);
} catch (Exception e) {
Output output = new Output();
output.dealReview = null;
output.annotationMessage = 'もう一度実行してください';
outputs.add(output);
}
return outputs;
}
public class Input {
@InvocableVariable(required=true, description='The ID of the Opportunity record to be reviewed')
public Id OpportunityId;
}
public class Output {
@InvocableVariable(description='Display this message as a response')
public String annotationMessage;
@InvocableVariable(description='Display this created Deal Review record (Object name is DealReview__c)')
public DealReview__c dealReview;
}
}
非同期ジョブ用Apex
Copilotアクション用Apex
から呼び出される非同期ジョブをQueueable Apexで作ります。チェーニングしてジョブを連続して実行させます。
public with sharing class AiDealReviewAsyncJob implements Queueable {
String opptyId;
String dealReviewId;
List<DealScoreCriteria__c> dealScoreCriterias;
List<DealScore__c> dealScores;
public AiDealReviewAsyncJob(String opptyId, String dealReviewId, List<DealScoreCriteria__c> dealScoreCriterias, List<DealScore__c> dealScores
) {
this.opptyId = opptyId;
this.dealReviewId = dealReviewId;
this.dealScoreCriterias = dealScoreCriterias;
this.dealScores = dealScores;
}
public void execute(QueueableContext qc) {
if (dealScoreCriterias.isEmpty()) {
getSummaryFeedback();
} else {
getDealScore();
}
}
private void getDealScore() {
DealScoreCriteria__c dsc = dealScoreCriterias.remove(0);
DealScore__c ds = new DealScore__c(
No__c = dsc.No__c,
Name = dsc.Name,
DealReview__c = dealReviewId
);
try {
String jsont = AiDealReviewController.doDealReview(opptyId, dsc.Id);
DealScoringResponse dsr = (DealScoringResponse) JSON.deserialize(
jsont,
DealScoringResponse.class
);
ds.Score__c = Integer.valueOf(dsr.score);
ds.Detail__c = dsr.detail;
ds.RecommendedNextAction__c = dsr.nextStep;
} catch (Exception ex) {
ds.Score__c = null;
ds.Detail__c = ex.getMessage();
ds.RecommendedNextAction__c = null;
} finally {
dealScores.add(ds);
System.enqueueJob(new AiDealReviewAsyncJob(
opptyId,
dealReviewId,
dealScoreCriterias,
dealScores
));
}
}
private void getSummaryFeedback() {
AiDealReviewController.updateDealReview(dealReviewId, dealScores);
}
private class DealScoringResponse {
private String score;
private String detail;
private String nextStep;
}
}
既存Apex AiReviewController
の変更
非同期ジョブ用Apex
用に一部変更します。
public with sharing class AiDealReviewController {
//
// 以下を追加します
//
public static DealReview__c updateDealReview(
String dealReviewId,
List<DealScore__c> dealScores
) {
DealReview__c dr = [
SELECT Id
FROM DealReview__c
WHERE Id = :dealReviewId
WITH USER_MODE
LIMIT 1
];
insertDealScores(dealReviewId, dealScores);
feedbackToDealReview(dr);
return dr;
}
//
// 以下を更新します
//
public static DealReview__c insertDealReview(String opportunityId) {
Datetime dt = Datetime.now();
Opportunity opp = [
SELECT Id, Name, NextStep, StageName
FROM Opportunity
WHERE Id = :opportunityId
WITH USER_MODE
LIMIT 1
];
String dealReviewName = opp.Name + '_商談レビュー_' + dt.format('yyyy-MM-dd HH:mm');
DealReview__c dr = new DealReview__c(
Opportunity__c = opportunityId,
Name = dealReviewName,
NextStep__c = opp.NextStep,
Stage__c = opp.StageName,
Status__c = 'レビュー中' // この行を追加
);
insert dr;
return dr;
}
public static void feedbackToDealReview(DealReview__c dr) {
dr.Summary__c = generateFeedbackForOverview(dr.Id);
dr.Status__c = '完了'; // この行を追加
update dr;
}
}
Einstein Copilot カスタムアクション
商談レビューを実施するEinstein Copilot カスタムアクショを一つ作成し、有効化します。作成するカスタムアクションの実体は上記で作成したApexです。カスタムアクションを準備するだけで、Plannerが会話の中で適切なタイミングでアクションを呼び出し、結果を処理してくれます。
Copilotアクションの定義
設定 > Einstein 生成AI > Einstein Copilot アクション > "+ 新規 Copilot アクション"ボタンを押下し、
以下のようにアクションを定義します。
- 参照アクション種別
- Apex
- 参照アクション
- 商談レビューの実施
- Copilotアクション表示ラベル
- 商談レビューの実施
続いて、入力と出力について以下のように設定します。
- Copilot アクション手順
- Conduct a deal review for a specific Opportunity record
- 入力
- OpportunityId
- Instructions
- The ID of the Opportunity record to be reviewed
- データ型
- lightning__recordIdType
- 入力が必要
- チェック
- Instructions
- OpportunityId
- 出力
- annotationMessage
- Instructions
- Display this message to user as a response
- データ型
- lightning__textType
- 会話に表示
- チェック
- Instructions
- dealReview
- Instructions
- Dsplay this created Deal Review record (Object name is DealReview__c)
- データ型
- lightning__recordInfoType
- 会話に表示
- チェック
- Instructions
- annotationMessage
CopilotアクションはPlannerにより、まるで人間が文章を読んで判断するかのように選択・実行されますので、対話型AIアシスタントアプリの構築では以下要素の自然言語での記述がとても重要になります。
- CopilotアクションのInstrruction
- 入力パラメータのInstrruction
- 出力パラメータのInstrruction
Copilotアクションの有効化
Copilotビルダーで作成した Copilotアクション 商談レビューの実施
を有効化し、CopilotをActivateします。
以上で準備が整いました。
デモ
【シーン①】 商談名を指定して実行
まずは既存商談
- データナビゲーション・テクノロジーズ_ユニバーサル・データネット
に対してレビューを依頼してみましょう。
Einstein Copilotを開き、「Please review my opportunity "データナビゲーション・テクノロジーズ_ユニバーサル・データネット"」とお願いしてみます。
すると、「レビューを開始しました」というメッセージと共に、商談レビューレコードが表示されます。しばらくしてからクリックすると、
商談レビュー結果が表示され、以下内容がスムーズに確認できました。
- 総評コメント
- 各評価項目ごとのスコア・コメント
【シーン②】 商談名を指定せずに実行
今度は敢えて、商談名を指定せずに商談レビューをお願いしてみましょう。商談名を指定しないとどうなるでしょう?Einstein Copilotに、「Please review the opportunity」と聞いてみます。
すると、今後は成功するわけでもエラーになるわけでもなく、なんとEinstein Copilotは、不足している情報を補うために、レビュー対象商談の商談名を入力するよう、聞き返してくれました。
商談名を入力し、"Submit"を押下します。
これで無事、商談レビューを実施してくれました。
【シーン③】 会話の流れから実行
自分の担当商談を確認するという別の会話の流れから、表示された商談に対してレビューをお願いすることもできます。
「Show my Opportunities」に対するEinsteinの回答は、デフォルトで利用できる標準アクションが呼び出された結果となります。
おわりに
本記事では、Einstein Copilotカスタムアクションを活用して、「AI商談レビュー」の対話型AIアシスタントアプリを構築する方法を紹介しました。基本、既存Salesforceテクノロジーで対話型AIアシスタントアプリを構築でき、また、開発者は対話型AIアシスタントそのものの開発ではなく、どのようなソリューションを提供し価値創出できるか?の部分に多くの時間を割くことが可能です。
従来テクノロジーで実現できなかったことが、もしかしたらEinstein 1 Platformで実現できる可能性があります。是非、開発環境で実際にお試しください。
【前記事】プロンプトテンプレートでカスタム生成AIアプリ「AI商談レビュー」を作る
ご参考