🔥

SalesforceのフローからHTTPコールアウトでChatGPT 及び Claude APIを叩くには

2024/04/12に公開

HTTPコールアウトの使い方のTrailheadはこちらです。これに沿ってやってみましょう。
https://trailhead.salesforce.com/ja/content/learn/projects/quick-start-create-http-callouts-with-flow-builder

さて、SalesforceのフローからHTTPコールアウトを使うことができるようになりました。なにそれ?っていうのを簡単に言うとフローからAPIを利用することができるようになったということです。
生成AI活用オタクの私からするとこれは願ったりかなったりで、例えば現在SalesforceでまだGAされていないAnthropicのClaudeを使った処理をフローで描くことも可能になるということです。

フローからのコールアウトの仕組み

仕組みはこんな感じになっています

  • Named Credential:指定ログイン情報
  • External Credential:外部ログイン情報
    • プリンシパル
  • 権限セットにプリンシパルを紐づける

なぜこのような複雑な形になっているのかについてはまだ私の理解が至っていないので分からないのですが、理由がわかる方は是非教えて下さい。
外部ログイン情報の中には認証情報が格納されるのですが、それを使いまわしたいからなのかな。

ChatGPT APIを利用するには

外部ログイン情報の作成

なにはともあれ外部ログイン情報を作ります。
Salesforce>設定>指定ログイン情報>外部ログイン情報>新規 で以下の画面

カスタムヘッダの登録

新規作成が完了したら完了画面内にあるカスタムヘッダー>新規で作成する

プリンシパルの登録

同じく画面内にあるプリンシパル>新規で作成

指定ログイン情報の作成

Salesforce>設定>指定ログイン情報>指定ログイン情報>新規 で以下の画面

権限セットの作成

作った外部ログイン情報を使える人を割り当てるために権限セットを作成します
設定>ユーザー>権限セット>新規

作成した権限セットに外部ログイン情報プリンシパルアクセスの紐づけをします

LLM全般で使いそうなのでまとめた権限セットにして紐づけなおした

あとはユーザーに割り当てましょう。

フローに組み込む

今回はレコードトリガフローから使ってみようと思います。
HTTPコールアウトを使う場合、非同期パスが必要になるので開始ノードにある以下の項目(一番下)にチェックを入れて非同期フローのパスを表示しましょう

トリガーレコードの元のトランザクションが正常にコミットされた後に外部システムにアクセスするには、非同期に実行パスを含めます。

非同期パスの中でノードを作成>アクションを選択するとこの画面になるので、HTTPコールアウトを作成ボタンを押します

名前部分はアンダースコア使えないので注意

ChatCompletionモデルを呼ぶのでこんな感じで。
URLパスは
/v1/chat/completions
です。
APIのドキュメントはこちらを参照

https://platform.openai.com/docs/api-reference/chat/create

次へボタンを押しましょう。データ構造の定義をします。

入力のサンプルは上記APIドキュメントから持ってきましょう。

{
  "model": "gpt-4-turbo",
  "messages": [
    {
      "role": "system",
      "content": "You are a helpful assistant."
    },
    {
      "role": "user",
      "content": "Hello!"
    }
  ]
}

確認ボタンを押すと、データ構造の定義が設定されます

次へボタンを押してレスポンス形式を設定します

入力の定義が間違っていなければ、スキーマ用に接続という方を選ぶことで、リターン値から定義を設定できますので、それでやってみましょう。次へボタンを押します。

🎉

確かにできてる…素晴らしいじゃないか。
と思ったら一箇所できてなかった。

logprobsは数値orNullらしいので整数を選択して保存
これでHTTPコールアウトが作成されました。

これをそのまま使いたいと思いきや、これだけじゃだめみたいです。

Apex定義変数を追加する

初めて使うわこの変数。ということで、一度アクションの追加ノードの設定を閉じて、ツールボックスから新キロソースボタンを押して、Apex定義変数を作りましょう
ChatGPTのAPIに投げるJSONの中にはmessagesというリスト型のデータを受け取る場所があるんですけど、その定義をする必要があります。

こちらがmessagesを格納する変数です。リストなので複数の値を許可にチェックを入れましょう。次に定義するBodyMessageを格納するリストになります。Apexクラスの定義は、ExternalService__sendTextToLLM_ChatCompletion_IN_body_messagesを選択してください

Apexクラスは、先程のHTTPコールアウトを作成したタイイングで作られるようです。
ChatCompletionで検索すると出てきますね。IN_body_messagesを選択します

BodyMessages

次に、Message一つの定義をします。

      {
        "role": "system",
        "content": "You are a helpful assistant."
      },

こういうのが入るやつですね。
変数名をBodyMessageにしてこれはリストじゃないので先程のチェックを入れないパターンでつくります。

Apex定義変数に値を割り当てる

割当ノードを作成し、BodyMessageのcontentに何かしらのプロンプトを与えます。
次に、BodyMessageのroleにuserを入れましょう。
ChatGPTのAPIがわかっている人は、ここにシステムプロンプト入れたり、色々工夫できると思います。

ChatGPT APIへ送るメッセージ定義を割り当てる

リクエストボディ用の変数定義を作る

こんな感じです。ApexクラスはIN_bodyを選択してください。

リクエストボディを割り当てる


モデルの指定と、先程作ったBodyMessagesを割り当てましょう

ChatGPT APIにメッセージを投げるアクションを設定する

ここまで来たら、もう一度アクションノードを追加しましょう

先程作ったChat Completionを選びます

Bodyを選びましょう
ここまでで、メッセージを送信するところまでが定義できました。
次に行うべきは、OpenAIからのレスポンスの展開です

レスポンス用の定義をしていく

OutputChoices

こちらも変数定義を追加します。
OpenAIからのレスポンスは以下のように返ってきます

{
  "id": "chatcmpl-123",
  "object": "chat.completion",
  "created": 1677652288,
  "model": "gpt-3.5-turbo-0125",
  "system_fingerprint": "fp_44709d6fcb",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "\n\nHello there, how may I assist you today?",
    },
    "logprobs": null,
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 9,
    "completion_tokens": 12,
    "total_tokens": 21
  }
}

欲しいのはchoicesってところですね。これの定義を行います

Apex定義はOUT_2xx_choices というものを使います。リストで返ってきますのでコレクションにしてください。

割り当てます

これで変数にレスポンスが展開できました。
choicesはリスト項目なのでループを回して更に展開していきましょう

choicesをchoiceに割り当てるために、リストじゃないバージョンの変数を作ってください。定義は同じです

メッセージからテキストを抜き出す

新規リソース>数式を作ります。余計な改行コードを抜きましょう。

SUBSTITUTE({!ChoiceFromOutput.message.content}, '\n\n', '')

完成

最後はレスポンスをトリガーしたコードの特定項目に入れて更新して完成

全体のフローはこんなかんじになりました

Claudeでも試す

外部ログイン情報の作成

カスタムヘッダの登録


ヘッダにはx-api-keyでいれるみたいですね。

プリンシパルの登録

指定ログイン情報の作成

URLはこちら:https://api.anthropic.com

権限セットの割当は同じようにやってください。割愛します

フローに組みこむ

まずはHTTPコールアウトを作成

ClaudeのmessagesAPIはここに仕様がかいてあります

https://docs.anthropic.com/claude/reference/messages_post

設定したら、スキーマ用に接続を選択して次へ

stop_sequenceだけ入ってませんが、こちらは文字列です
変更したら保存でHTTPコールアウトが保存されます。
externalService-sendTextToClaude.ClaudeMessages

あとはBodyMessagesの割当しましょう

リクエストボディも割り当てましょう

アクションを追加しましょう

レスポンスを引き受ける設定をします

受け取ります

このような感じでできます!以上!

感想

できるといえばできる。
ここまでできる人であればApexで書くのをおすすめかもしれない

リバナレテックブログ

Discussion