Agent APIを使って公開サイトから安全に呼び出せるAI Agentを作ってみよう

みなさんこんにちは。エンジニアの竹田です。

少し前の話題ですが、今年(2025年)の3月ごろにAgent APIがGAになりましたね。 Agent APIはAgentforceを呼び出すための新しいAPIです。

今まではAgentforceで作ったAI Agentとの通信にはMIAWを使っていました。 MIAWはAgentforceのために作られたものというわけではなく、もともとはService Cloud上でコンタクトセンターのオペレータ向けに作られたもので、Webサイト上のチャット窓など問合せに対応するためのものでした。

AI Agentもオペレータの一人と考えると、MIAWをそのままAgentforceでも使えるようにするということは妥当な設計だったと思います。 MIAWがあれば、人から人へのエスカレーションと同様に、AI Agentから人へのエスカレーションなども組み込めて便利です。

というわけでMIAWはよいものなのですが、そうはいっても元々Agentforce用に設計されたものではありません。 設定も仕様も複雑で使いこなすのはなかなか大変です。弊社メンバも少し苦労したことがありました。

そんな背景があって出てきたのがAgent APIです。 このあたりを見るとわかりますが、APIとして使いやすくてheadlessなAgentを作ることもできちゃいますね。 もちろん、Streaming(SSEを使って少しずつレスポンスを返す)にも対応していて、ChatGPTの画面でおなじみの少しずつAIの回答を出力することもできます。

このように便利そうなAgent APIではあるのですが、そうはいってもまだまだ課題があるのです。

今回は最近弊社にお声がけいただいた案件で、Agent APIで技術的に課題になったところを紹介します。

実現したいこととAgent APIの課題

さて、今回のAI Agentに対していただいた要望は次のようなもの

  • AI Agentに接客をさせたい。商品紹介とか注文の確認などを行う
  • 商品のデータや顧客の情報は揃っていて、Data Cloudに投入して使う
  • 公開サイトにも設置して、認証されていないお客様もAI Agentと会話できるようにする
  • (...他にもご要望あり)

ふむふむ。やりたいことは多いですが、いずれもAgentforceでどれも対応可能ですね。 今回はコンタクトセンターに関連した要件はないので、MIAWの選択肢は外してAgent APIを活用して実現することにしました。

Agent APIの使い方としては、クライアント側で次の順序で処理を行っていくことになっています。

  1. 事前準備としてSalesforceからACCESS TOKENを取得する
  2. 同様に事前準備としてACCESS TOKENをrequestに入れてAgent APIでSession IDを取得する
  3. ユーザがメッセージを入力したら、ACCESS TOKENとSession IDをrequestに入れてAgent APIにメッセージを送信する
  4. メッセージを受け取ったAI Agentが回答を返すので、それを表示する

シンプルでいいですね。

ところがここで疑問が生じます。 Experience Cloudで作ったサイトなどSalesforce上ならいつものように(Salesforceと外部連携するときにおなじみの)ACCESS TOKENを取得したり、この順序で処理を進めればいいのですが、公開サイト上のJavaScriptをクライアントとした場合、本当にこの処理はできるのでしょうか?

まず課題となるのが、ACCESS TOKENの取得方法です。ACCESS TOKENを取得するにはあらかじめSalesforce上でConnected Appを設定してClient IDとClient Secretを払い出します。その上で、クライアント側からClient ID/Client SecretをSalesforceに渡してOAuth2.0の仕組みでACCESS TOKENを取得するわけです。

さてここで「クライアント側で」と曖昧に書きましたが、今回は公開サイト上でチャットするわけですから、クライアントとは公開サイト上のJavaScriptのことです。JavaScriptからSalesforceを呼んでACCESS TOKENを取得するということになる? そんなわけにはいきません。なぜなら、JavaScriptでClient ID/Client Secretを使ってACCESS TOKENを取得するということは、そのJavaScriptが動くWebブラウザにClient ID/Client Secretが渡るということで、大事な認証情報が漏れてしまうということになってしまいます。

認証情報をWebブラウザ上で持ってはいけません

認証情報の課題に対応

そこでこの課題を解決するためにACCESS TOKENを取得する処理をサーバ側つまりSalesforceに置くことにします。 SalesforceACCESS TOKENを取得するためのREST APIを作って、それをJavaScriptから呼ぶわけです。

Salesforce上のACCESS TOKENを取得するAPIを用意すれば解決(?)

この場合でもACCESS TOKENがWebブラウザ側に渡るということはちょっと気になりますが、ACCESS TOKENは毎回発行されるものでありまた有効期限が設定できるので、よくある一般的なWebのセッションID程度のリスクと考えてよさそうです。

これで解決...と思いましたが、よく考えたら自前でSalesforce上に作ったREST API(今回はACCESS TOKEN取得API)にアクセスしに行くにはOAuthなどの認証が必要で、その時認証情報を渡さなければいけないわけで、結局何も解決していません...

仕方がないので、こうしましょう。

Sites機能を使って対応

Salesforce Sites機能を使うことにしました。Sites機能というのはSalesforce上に認証不要な公開サイトを作る機能です。 このSitesで作った公開サイト上に先ほどのACCESS TOKENを取得するREST APIを配置します。 こうすれば認証なしでREST APIを呼び出してACCESS TOKENを取得できます。

ACCESS TOKENを取得したら、あとはJavaScriptでAgent APIを呼び出してSession IDを取得し、そのSession IDとACCESS TOKENを指定してAgent API経由でAI Agentと通信すれば、やりたかったことができるようになるわけです。

とはいえ、この方法でも課題がないわけではありません。現時点で気になるところは次の通りです。

  • Sitesには月間ページビュー制限がある
    • 制限を超えたらページビュー数を追加購入にすることになる
  • ACCESS TOKEN がWebブラウザに渡ることに抵抗がないわけではない&OAuthの使い方が不自然
    • 本来クライアントの認証のためにOAuth認証があるわけで、そこをごまかした設計である
  • これらの結果として、公開サイト上で多数の人がAI Agentを使ったときにやばいことになる
    • 月間ページビュー数越えの追加請求に加えて、Agentforceの課金(Conversation数+Einstein Request数 課金 or ActionベースのCredit消費)で膨大な請求になり得る

こうしたことを考えると、もうちょっと工夫が必要そうです。

最終的な形

たとえばこんな構成ではどうでしょうか。

これが今回の最終解

AWS(に代表されるIaaS)を間に挟みます。AWSでは今までのACCESS TOKENを取得する処理を行いますが、WebブラウザACCESS TOKENを返すということはしません。その代わりにACCESS TOKENをAWS内に保持したまま、さらにAgent APIを呼び出して会話のためのSession IDを取得します。そしてそのSession IDのみをWebブラウザに返します。

その後、WebブラウザJavaScriptではこのSession IDを保持しながら、AWS経由でAgent APIを呼び出します。また、その際に流量制限のための制御も行います。 AWS上にリバースプロキシ的なAPIを作るイメージですね。 (AWS上での実現方法としては、API Gateway/Lambda/DynamoDBなどを使うことになるでしょうか)

これで本当にすべての課題解決!と言いたいところですが、実は新たな課題が1点あります。 それは、このような構成にすることでAI Agentからのレスポンスが遅くなるということです。

そこで、少しでも早くするためにAgent APIにあるStreaming Messageを使って、AI Agentの回答を少しずつ滑らかに返すようにしたい(ChatGPTみたいに)わけですが、プログラミング的にはちょっと難しいことをやらないといけません。 Streaming MessageはSSE(Server Side Event)を使った通信方法を取るので、AWSプロキシAPI(リバースプロキシ的API)で、JavaScriptとAgent APIの間のSSE通信の仲介をしないといけないわけです。 できないわけではないですが、ちょっと複雑な仕組みになっちゃいますね。

このようなわけでAgent API自体はよくできているのですが、まだまだ発展途上なところもあり、エンジニア側で技術的な課題を把握して工夫していかなければいけないこともあります。 まだ出たばかりの技術ですので、今後の発展に期待したいですね。

--2025/08/12 追記-- さらに検証を進めた結果、上記Sites方式のとき認証で設定によってはセキュリティ的に問題がある可能性あり。さらに検証を進めます。

--2025/08/13 追記-- 検証を進めましたが、やはり上記のSites方式では問題があることが分かりました。JavaScript側に渡すACCESS TOKENはJWTなのですが、ここでJWTにjtiが含まれておらずセキュリティリスクがあります。また払い出されたACCESS TOKENはAgent API専用というわけではなく、それゆえに十分にSalesforceの権限を絞っておかなければいけないのですが、これが容易ではないのです。 やっぱり、ACCESS TOKENはJavaScript側には渡さないようにして、ACCESS TOKEN発効後はSalesforce内のオブジェクトなどに保持しておく。そのうえでSites上にJavaScript側からAgentforceへのメッセージを受け取り、Agent APIにそのメッセージをACCCESS TOKENとともに渡す(中継する)、そんなリバースプロキシ的なAPIを追加するのがよさそうです。