🔐

Salesforce×OpenAI連携で安全にAI機能を実装する方法【顧客はAPIキーを貼るだけ】

に公開

はじめに

SalesforceでOpenAI APIを使うとき、APIキーの管理場所に悩んでいませんか?
本記事では、Salesforce標準機能の「指定ログイン情報」と「外部ログイン情報」などを使用して安全にAPIキーを管理する方法と、それを使ったAI機能の実装方法を解説します。

前提

本記事では、OpenAIのGPT-4o miniのAPIをSalesforceで呼び出すことを想定しています。

AI連携の仕組みの解説

Salesforce側の設定

  • 外部ログイン情報 (External Credential)
    • APIキーを安全に保管し、それをどう加工するか(例:Bearer sk-... 形式のヘッダー生成)を定義します
  • 指定ログイン情報 (Named Credential)
    • 接続先URL(https://api.openai.com)を管理し、使用する「外部ログイン情報」を紐付けます
  • 権限セット (Permission Set)
    • 外部ログイン情報へのアクセス権をユーザーに与える必要があります

これらの設定を利用することで、顧客は自身が発行したAPIキーを入力するだけでAI機能が安全に利用できるようになります。

OpenAIのAPIを使った要約処理の流れ

具体的な設定手順

※画面で設定する手順と、それをコード(メタデータ)で定義する場合のXMLを並記します。

Step 1: 外部ログイン情報の作成

  1. [設定] > [指定ログイン情報] > [外部ログイン情報タブ]にて新規作成
    • 表示ラベルおよび名前: OpenAI_Auth
    • 認証プロトコル: カスタム
      1
  2. 外部ログイン情報の詳細画面で、プリンシパルを新規作成
    • パラメーター名: General_User
    • 連番: 1
    • 認証パラメータ: 設定不要です。顧客がAPIキーを入力する際に、このプリンシパルに紐づくApiKeyという名前のカスタムパラメータに値が設定されるためです。
      2
  3. 外部ログイン情報の詳細画面で、カスタムヘッダーを新規作成
    • 名前: Authorization
    • : Bearer {!$Credential.OpenAI_Auth.ApiKey}
      3
XML(メタデータ)で外部ログイン情報を定義する場合
force-app/main/default/externalCredentials/OpenAI_Auth.externalCredential-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<ExternalCredential xmlns="http://soap.sforce.com/2006/04/metadata">
    <authenticationProtocol>Custom</authenticationProtocol>
    <externalCredentialParameters>
        <parameterGroup>General_User</parameterGroup>
        <parameterName>General_User</parameterName>
        <parameterType>NamedPrincipal</parameterType>
        <sequenceNumber>1</sequenceNumber>
    </externalCredentialParameters>
    <externalCredentialParameters>
        <parameterGroup>DefaultGroup</parameterGroup>
        <parameterName>Authorization</parameterName>
        <parameterType>AuthHeader</parameterType>
        <parameterValue>Bearer {!$Credential.OpenAI_Auth.ApiKey}</parameterValue>
        <sequenceNumber>1</sequenceNumber>
    </externalCredentialParameters>
    <label>OpenAI_Auth</label>
</ExternalCredential>

Step 2: 指定ログイン情報の作成

  1. [設定] > [指定ログイン情報] > [指定ログイン情報タブ]にて新規作成
    • 表示ラベルおよび名前: OpenAI_Endpoint
    • URL: https://api.openai.com
    • コールアウトに対応: ON
    • 外部ログイン情報: Step1で作成したもの(OpenAI_Auth)を選択
    • コールアウトオプション: HTTP ヘッダーの数式を許可をON、それ以外はOFF
      4
XML(メタデータ)で指定ログイン情報を定義する場合
force-app/main/default/namedCredentials/OpenAI_Endpoint.namedCredential-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<NamedCredential xmlns="http://soap.sforce.com/2006/04/metadata">
    <allowMergeFieldsInBody>false</allowMergeFieldsInBody>
    <allowMergeFieldsInHeader>true</allowMergeFieldsInHeader>
    <calloutStatus>Enabled</calloutStatus>
    <generateAuthorizationHeader>false</generateAuthorizationHeader>
    <label>OpenAI_Endpoint</label>
    <namedCredentialParameters>
        <parameterName>Url</parameterName>
        <parameterType>Url</parameterType>
        <parameterValue>https://api.openai.com</parameterValue>
    </namedCredentialParameters>
    <namedCredentialParameters>
        <externalCredential>OpenAI_Auth</externalCredential>
        <parameterName>ExternalCredential</parameterName>
        <parameterType>Authentication</parameterType>
    </namedCredentialParameters>
    <namedCredentialType>SecuredEndpoint</namedCredentialType>
</NamedCredential>

Step 3: 権限セットの作成

  1. 任意の権限セット > [外部ログイン情報プリンシパルアクセス]
    • 有効な外部ログイン情報プリンシパル: OpenAI_Auth - General_User
      ※今回は新規権限セットとしてOpenAI Callout AccessOpenAI_Callout_Access)を作成しました。
    5
XML(メタデータ)で権限セットを定義する場合
force-app/main/default/permissionsets/OpenAI_Callout_Access.permissionset-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
    <externalCredentialPrincipalAccesses>
        <enabled>true</enabled>
        <externalCredentialPrincipal>OpenAI_Auth-General_User</externalCredentialPrincipal>
    </externalCredentialPrincipalAccesses>
    <hasActivationRequired>false</hasActivationRequired>
    <label>OpenAI Callout Access</label>
</PermissionSet>

Apexでの呼び出し方

ここまでの設定が完了していれば、Apexコードで複雑な処理を書かずともOpenAIのAPIを利用した機能を実装することができます。

以下は、引数のプロンプトの文字列をGPT-4o miniに渡し、要約結果を受け取るApexメソッドの一部です。

private static String callOpenAIAPI(String prompt) {
    HttpRequest req = new HttpRequest();
    // Named Credentialを使用することで、Authorizationヘッダーが自動付与される
    String endpoint = 'callout:OpenAI_Endpoint/v1/chat/completions';
    req.setEndpoint(endpoint);
    req.setMethod('POST');
    req.setHeader('Content-Type', 'application/json');
    req.setTimeout(30000);

    Map<String, Object> requestBody = new Map<String, Object>();
    requestBody.put('model', 'gpt-4o-mini');
    requestBody.put('messages', new List<Map<String, Object>>{
        new Map<String, Object>{
            'role' => 'user',
            'content' => prompt
        }
    });
    requestBody.put('max_tokens', 200);

    // MapをJSON文字列に変換
    String requestBodyStr = JSON.serialize(requestBody);
    req.setBody(requestBodyStr);

    Http http = new Http();
    HttpResponse res = http.send(req);
    // ...レスポンス受け取り後の処理など
}

実際にAIによる要約機能を作ってみた

前章までの設定(指定ログイン情報)を使用して、レコードページで動作するレコード要約機能をLWCで実装しました。

  • プロンプト:以下の取引先情報を簡潔に要約してください(日本語で、2-3文程度)[取引先名][説明]
  1. 要約対象の取引先レコード
    取引先名と、営業メモを想定した約1400文字の説明が入力されています。(実在する企業の情報ではありません)
    取引先レコードの例
  2. LWCコンポーネントによる要約
    レコードページに配置したLWCコンポーネントです。「要約を生成」ボタンを押すと、AIが要約を返します。
    長かった説明文が、短い文章に要約されました。
    要約前
    要約中
    要約後

導入時の運用フロー

開発者の作業

  • 外部ログイン情報、指定ログイン情報、権限セットなどを組織に設定する
  • AIを用いた機能を実装する

顧客(管理者)の作業

  • OpenAIのAPIキーを発行
  • APIキーの入力
    1. Salesforceの[設定] > [指定ログイン情報] > [外部ログイン情報タブ]にて、開発者が作成した外部ログイン情報を開く
    2. プリンシパルの編集画面を開く
    3. 発行したAPIキーをペーストして保存

運用上の注意点:APIコスト管理

OpenAI APIは従量課金制のため、コスト管理を考慮することが重要です。

  • リスク: バグやユーザーの意図しない操作によって大量のAPIコールが発生し、予期せぬ高額請求につながる可能性があります。
  • 対策: Salesforce側でAPIのコール回数やトークン消費量をカスタムオブジェクトに記録・集計し、利用状況を監視する仕組みの導入を検討することが望ましいです。

まとめ

本記事では、Salesforce標準機能の「指定ログイン情報」と「外部ログイン情報」などを使用して安全にAPIキーを管理する方法と、それを使ったAI機能の実装方法を解説しました。
もし最新情報と異なっている、記載に誤りがあるなどありましたら、気軽にコメントください。
最後までお読みいただき、ありがとうございました。

Discussion