Azure OpenAI Service #Chat: パラメータ付き対話

Azure OpenAI Service #Chat: Interact with Parameters

Azure OpenAI Service の API (Microsoft 基盤上で動く ChatGPT) と通信します。高度なパラメータの付与をサポートします。具体的には、サンプリング温度、上位%サンプリング、再出現禁止度、頻出禁止度、Logitバイアスなどが設定可能です。

Auto Step icon
Configs for this Auto Step
AuthzConfU1
U1: HTTP認証設定(Secret API Key @トークン直接指定) *
StrConfU2
U2: リソース名 *#{EL}
StrConfU3
U3: デプロイID *#{EL}
StrConfU4
U4: APIバージョン (default “2023-05-15”)#{EL}
StrConfA0
A0: レスポンス者の役割(SYSTEM Role)#{EL}
StrConfA1
A1: リクエスト PROMPT *#{EL}
StrConfA2
A2: パラメータ(サンプリング温度、サンプリング%、再出現禁止度、頻出禁止度)を4行に分けてセット#{EL}
StrConfA3
A3: Logitバイアス(TokenID と バイアス値のペア)を各行に分けてセット#{EL}
StrConfA4
A4: レスポンス数 (default 1)#{EL}
StrConfA5
A5: レスポンストークンの許容量 (default 2048)#{EL}
StrConfA6
A6: 中断文字を各行に分けてセット (eg “.” “。”)#{EL}
StrConfB1
B1: レスポンス COMPLETION が格納されるフィールド名(文字列型データ項目)を各行に分けてセット(更新)#{EL}
SelectConfB2
B2: レスポンス Json 全体が格納される文字型データ項目(更新)
SelectConfC1
C1: PROMPT トークン数が格納される数値型データ項目(更新)
SelectConfC2
C2: COMPLETION トークン数が格納される数値型データ項目(更新)
SelectConfC3
C3: 合計トークン数が格納される数値型データ項目(更新)
Script (click to open)
// GraalJS Script (engine type: 3)

//////// START "main()" /////////////////////////////////////////////////////////////////

main();
function main(){ 

////// == Config Retrieving / 工程コンフィグの参照 ==
const strAuthzSetting = configs.get      ( "AuthzConfU1" );  /// REQUIRED
  engine.log( " AutomatedTask Config: Authz Setting: " + strAuthzSetting );
/*
const strModel        = configs.get( "StrConfM" ) !== "" ?   // NotRequired
                        configs.get( "StrConfM" ) : "gpt-4"; // (default)
  engine.log( " AutomatedTask Config: OpenAI Model: " + strModel );
*/
const strResourceName = configs.get( "StrConfU2" );
const strDeployId     = configs.get( "StrConfU3" );
const strAPIVersion   = configs.get( "StrConfU4" ) !== "" ?        // NotRequired
                        configs.get( "StrConfU4" ) : "2023-05-15"; // (default)

const strSystemRole   = configs.get      ( "StrConfA0" );    // NotRequired
/*
const strLogPro1      = configs.get      ( "StrConfPro1" );  // NotRequired
const strLogCom1      = configs.get      ( "StrConfCom1" );  // NotRequired
const strLogPro2      = configs.get      ( "StrConfPro2" );  // NotRequired
const strLogCom2      = configs.get      ( "StrConfCom2" );  // NotRequired
const strLogPro3      = configs.get      ( "StrConfPro3" );  // NotRequired
const strLogCom3      = configs.get      ( "StrConfCom3" );  // NotRequired
*/
const strPrompt       = configs.get      ( "StrConfA1" );    /// REQUIRED
  if( strPrompt     === "" ){
    throw new Error( "\n AutomatedTask ConfigError:" +
                     " Config {A1:Prompt} MUST NOT be empty \n" );
  }

const strParams       = configs.get      ( "StrConfA2" );    // NotRequired
const arrParams       = strParams !== "" ? strParams.split("\n") : null;
const numTemperature  = isNaN(parseFloat(arrParams?.[0])) ? 1 : parseFloat( arrParams[0] );
const numTopP         = isNaN(parseFloat(arrParams?.[1])) ? 1 : parseFloat( arrParams[1] );
const numPresPenalty  = isNaN(parseFloat(arrParams?.[2])) ? 0 : parseFloat( arrParams[2] );
const numFreqPenalty  = isNaN(parseFloat(arrParams?.[3])) ? 0 : parseFloat( arrParams[3] );
// const jsonLogitBias   = arrParams?.[4] ? JSON.stringify( arrParams[4] ) : null;
  // Number(undefined)     // NaN
  // Number(null)          // 0 ☆
  // Number('100a')        // NaN
  // parseFloat(undefined) // NaN
  // parseFloat(null)      // NaN

const strBias         = configs.get      ( "StrConfA3" );    // NotRequired
const arrBias         = strBias !== "" ? strBias.split("\n") : null;
const strChoises      = configs.get      ( "StrConfA4" );    // NotRequired
const numChoises      = isNaN(parseInt(strChoises,10)) ? 1 : parseInt(strChoises,10);
const strLimit        = configs.get      ( "StrConfA5" );    // NotRequired
const numLimit        = isNaN(parseInt(strLimit,10)) ? 2048 : parseInt(strLimit,10);
const strStops        = configs.get      ( "StrConfA6" );    // NotRequired
const arrStops        = strStops !== "" ? strStops.split("\n") : null;
const strQfields      = configs.get      ( "StrConfB1" );    // NotRequired
const arrQfields      = strQfields !== "" ? strQfields.split("\n") : null;

const strPocketResponseJson     = configs.getObject( "SelectConfB2" ); // NotRequired
const numPocketPromptTokens     = configs.getObject( "SelectConfC1" ); // NotRequired
const numPocketCompletionTokens = configs.getObject( "SelectConfC2" ); // NotRequired
const numPocketTotalTokens      = configs.getObject( "SelectConfC3" ); // NotRequired


////// == Data Retrieving / ワークフローデータの参照 ==
// (Nothing. Retrieved via Expression Language in Config Retrieving)


////// == Calculating / 演算 ==

//// OpenAI API > Documentation > API REFERENCE > CHAT
//// https://platform.openai.com/docs/api-reference/chat

/// prepare json
let strJson = {};
//    strJson.model = strModel;
    strJson.messages = [];
    if ( strSystemRole !=="" ) {
      let objSystemRole = {};
          objSystemRole.role = "system";
          objSystemRole.content = strSystemRole;
      strJson.messages.push ( objSystemRole );
    }
/*
    if ( strLogPro1 !=="" && strLogCom1 !=="" ) {
      let objLogPro = {};
          objLogPro.role = "user";
          objLogPro.content = strLogPro1;
      strJson.messages.push ( objLogPro );
      let objLogCom = {};
          objLogCom.role = "assistant";
          objLogCom.content = strLogCom1;
      strJson.messages.push ( objLogCom );
    }
    if ( strLogPro2 !=="" && strLogCom2 !=="" ) {
      let objLogPro = {};
          objLogPro.role = "user";
          objLogPro.content = strLogPro2;
      strJson.messages.push ( objLogPro );
      let objLogCom = {};
          objLogCom.role = "assistant";
          objLogCom.content = strLogCom2;
      strJson.messages.push ( objLogCom );
    }
    if ( strLogPro3 !=="" && strLogCom3 !=="" ) {
      let objLogPro = {};
          objLogPro.role = "user";
          objLogPro.content = strLogPro3;
      strJson.messages.push ( objLogPro );
      let objLogCom = {};
          objLogCom.role = "assistant";
          objLogCom.content = strLogCom3;
      strJson.messages.push ( objLogCom );
    }
*/

    let objNewMsg = {};
        objNewMsg.role = "user";
        objNewMsg.content = strPrompt;
    strJson.messages.push ( objNewMsg );

    if ( arrParams?.[0] !=="" ) {
      strJson.temperature       = numTemperature;
    }
    if ( arrParams?.[1] !=="" ) {
      strJson.top_p             = numTopP;
    }
    if ( arrParams?.[2] !=="" ) {
      strJson.presence_penalty  = numPresPenalty;
    }
    if ( arrParams?.[3] !=="" ) {
      strJson.frequency_penalty = numFreqPenalty;
    }

    strJson.n          = numChoises;
    strJson.max_tokens = numLimit;
    strJson.user       = "m" + processInstance.getProcessModelInfoId().toString();
    if ( arrStops !== null ){
      strJson.stop = [];
      for ( let i = 0; i < arrStops.length; i++ ){
        if ( arrStops[i] === "- - -" ){
          strJson.stop.push ( "\n" );
        }else{
          strJson.stop.push ( arrStops[i] );
        }
      }
    }
    if ( arrBias !== null ){
      strJson.logit_bias = {};
      for ( let i = 0; i < arrBias.length; i++ ){
        let arrNumParts = arrBias[i].match( /-?\d+/g ); // numbers (including with minus signs)
        if (arrNumParts.length >= 2) {
          strJson.logit_bias[arrNumParts[0]] = Number(arrNumParts[1]);
        }
      }
    }

//engine.log( JSON.stringify( strJson ) ); // debug


/// prepare request1
let request1Uri = "https://" + strResourceName + ".openai.azure.com/openai/deployments/" + strDeployId + "/chat/completions?api-version=" + strAPIVersion;
const apiKey = httpClient.getOAuth2Token(strAuthzSetting);

let request1 = httpClient.begin(); // HttpRequestWrapper
    request1 = request1.header("api-key", apiKey);
    request1 = request1.body( JSON.stringify( strJson ), "application/json" );

/// try request1
const response1     = request1.post( request1Uri ); // HttpResponseWrapper
  engine.log( " AutomatedTask ApiRequest1 Start: " + request1Uri );
const response1Code = response1.getStatusCode() + ""; // JavaNum to string
const response1Body = response1.getResponseAsString();
  engine.log( " AutomatedTask ApiResponse1 Status: " + response1Code );

if( response1Code !== "200"){
  throw new Error( "\n AutomatedTask UnexpectedResponseError: " +
                    response1Code + "\n" + response1Body + "\n" );
}


/// parse response1
const response1Obj = JSON.parse( response1Body );


////// == Data Updating / ワークフローデータへの代入 ==

if( strPocketResponseJson !== null ){
  engine.setData( strPocketResponseJson, response1Body );
}

if ( arrQfields !== null ) {
  for ( let i = 0; i < response1Obj.choices.length; i++ ) {
    if( engine.findDataDefinitionByVarName ( arrQfields?.[i] ) !== null ){
      engine.setDataByVarName( arrQfields[i], 
                    response1Obj.choices[i].message.content ?? ""
                  );
    }
  }
}

if( numPocketPromptTokens !== null ){
  engine.setData( numPocketPromptTokens, new java.math.BigDecimal(
                  response1Obj.usage.prompt_tokens ?? 0
                ));
}
if( numPocketCompletionTokens !== null ){
  engine.setData( numPocketCompletionTokens, new java.math.BigDecimal(
                  response1Obj.usage.completion_tokens ?? 0
                ));
}
if( numPocketTotalTokens !== null ){
  engine.setData( numPocketTotalTokens, new java.math.BigDecimal(
                  response1Obj.usage.total_tokens ?? 0
                ));
}

// "??": Nullish coalescing operator (ES11)
// https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing

} //////// END "main()" /////////////////////////////////////////////////////////////////

Download

warning 自由改変可能な JavaScript (ECMAScript) コードです。いかなる保証もありません。
(アドオン自動工程のインストールは Professional editionでのみ可能です)

Notes

  • Azure OpenAI Service の詳細はこちらのページを確認してください。Microsoft 基盤上で、OpenAI 社が提供する ChatGPT 等が利用できます。
  • 認証は「APIキー認証」を利用しています(Questetra BPM Suite Ver.15.1 以降で動作します)。APIキーは Azure ポータルの「キーとエンドポイント」から取得できます。
  • 設定項目がほぼ同じである「OpenAI #Chat: パラメータ付き対話」の Notes および Appendix を参考にして、設定してください。
  • モデル(AIエンジン)は、Azure OpenAI Service 側のモデルデプロイ時に指定しますので、設定項目にはありません。
  • リソース名とデプロイIDは、Azure OpenAI Service 側のリソース作成・モデルデプロイ時に決定したものをセットしてください。
  • API バージョンは、デフォルトの 2023-05-15 のみです(2023/9/1時点)。

Capture

See Also

%d人のブロガーが「いいね」をつけました。