搭配使用 Gemini 和 SAP 函式呼叫

本文件說明如何使用 ABAP 適用的 Vertex AI SDK,搭配 Gemini 使用 SAP 函式呼叫。

您可以定義自訂函式,並使用函式呼叫功能將其提供給 Gemini 模型。模型不會直接叫用自訂函式,而是產生結構化資料輸出內容,指定函式名稱和建議的引數。您可以使用這項輸出內容編寫應用程式,以便取用結構化輸出內容並呼叫外部 API。接著,您可以將產生的 API 輸出內容納入進一步的模型提示,以便提供更完整的查詢回應。

ABAP 專用的 Vertex AI SDK 可讓 ABAP 開發人員透過下列方式,在 SAP 函式模組中叫用自訂邏輯,簡化函式呼叫程序:

  • SAP 函式模組名稱做為函式宣告傳遞至模型,說明函式名稱、用途和相關參數。
  • 在叫用模型時,隱含設定 SAP 函式模組的自動叫用功能。

以下是 ABAP 開發人員常見的喚起 SAP 函式呼叫程序:

  1. 使用者提供輸入提示。
  2. SDK 會將輸入提示和函式宣告傳遞至模型。
  3. 模型會查看提示和宣告的函式,找出要呼叫的函式,並建議呼叫函式的參數值。
  4. 如果設定自動叫用,SDK 就會呼叫 SAP 函式模組。
  5. 接著,SDK 會使用呼叫函式的輸出內容叫用模型。
  6. 模型會針對最終提示回覆可靠的答案,並加入呼叫函式的輸出內容。
  7. SDK 會將回應傳回給使用者。

使用 Gemini 呼叫 SAP 函式

如果您選擇不自動叫用 SAP 函式模組,SDK 就會讓您使用函式呼叫功能,而無需任何 SAP 函式模組的叫用。在這種情況下,您可以按照一般函式呼叫工作流程使用外部工具,例如 API 和函式。

事前準備

使用 Gemini 搭配 ABAP 適用的 Vertex AI SDK 進行 SAP 函式呼叫前,請確認您或管理員已完成下列先決條件:

使用 SAP 資料豐富 Gemini AI 模型內容

本節說明如何使用 Vertex AI SDK for ABAP,利用 SAP 資料充實 Gemini AI 模型的背景資訊。

將 Gemini 多模態叫用者類別例項化

如要在 SAP 中叫用函式,請使用 /GOOG/CL_GENERATIVE_MODEL 類別。您可以傳遞在模型產生參數中設定的模型鍵,藉此將類別例項化。

DATA(lo_model) = NEW /goog/cl_generative_model( iv_model_key = 'MODEL_KEY' ).

MODEL_KEY 替換為模型鍵名稱,該名稱會在模型產生參數中設定。

建立 SAP 函式模組

如要建立 SAP 函式模組,以便由 SDK 自動叫用,請按照提供的結構定義操作:

類別 參數名稱 關聯類型
匯入中 IT_FUNCTION_PARAMETERS /GOOG/T_FUNCTION_PARAMETERS
匯出中 EV_FUNCTION_RESPONSE STRING
正在進行變更 CV_PROMPT STRING
例外狀況 /GOOG/CX_SDK Exception Class

根據匯入參數,在函式模組中編寫自訂邏輯,可透過 SELECT 查詢擷取 SAP 資料,或呼叫外部 API 或模組來取得遺漏的資訊。

設定匯出參數 EV_FUNCTION_RESPONSE,並將資訊回饋至 LLM 情境。您也可以根據自訂邏輯和業務需求,變更或修改 CV_PROMPT 中的提示文字,進一步根據不同的業務情境指示 LLM。

新增函式宣告

如要在 LLM 上下文中新增函式宣告,您可以使用 ADD_FUNCTION_DECLARATION 方法。每次需要在結構定義中新增函式時,請呼叫 ADD_FUNCTION_DECLARATION 方法。

DATA lt_parameters TYPE /goog/cl_generative_model=>tt_parameter_properties.
APPEND VALUE #( parameter_name = 'PARAMETER_NAME'
                type           = 'PARAMETER_TYPE'
                description    = 'PARAMETER_DESCRIPTION'
                is_required    = 'PARAMETER_IS_REQUIRED' ) TO lt_parameters.
lo_model->add_function_declaration( iv_name        = 'FUNCTION_MODULE_NAME'
                                    iv_description = 'FUNCTION_MODULE_DESCRIPTION'
                                    it_parameters  = lt_parameters ).

更改下列內容:

  • PARAMETER_NAME:參數名稱。
  • PARAMETER_TYPE:參數的資料類型,例如 stringintegerboolean
  • PARAMETER_DESCRIPTION:清楚說明參數的用途和預期格式。
  • PARAMETER_IS_REQUIRED:如果函式必須使用這個參數才能運作,請將值設為 ABAP_TRUE
  • FUNCTION_MODULE_NAME:SAP 函式模組的名稱。
  • FUNCTION_MODULE_DESCRIPTION:SAP 函式模組的說明。

您也可以宣告不含參數的函式,做為備用或備援函式。如果使用者提示未提供足夠資訊來呼叫特定函式,您可以指示 Gemini 選取這個備用函式。

設定自動叫用 SAP 函式模組

如要設定模型所選 SAP 函式的自動叫用,您可以使用 SET_AUTO_INVOKE_SAP_FUNCTION 方法。如果 ABAP_TRUE 是在匯入參數 IV_AUTO_INVOKE 中傳遞,則 SDK 會叫用函式模組,並將其回應納入 LLM 上下文,以產生最終回應。

您必須依循「建立 SAP 函式模組」一節所述的結構定義函式模組。

lo_model->set_auto_invoke_sap_function( abap_true ).

使用函式呼叫產生內容

如要將提示文字傳遞至 Gemini 模型,您可以使用 GENERATE_CONTENT 方法。如要取得 Gemini 透過函式呼叫從 SAP 函式模組新增的額外背景資訊所產生的回應,請使用 GET_TEXT 方法。

DATA(lv_response) = lo_model->generate_content( iv_prompt_text ='PROMPT'
                           )->get_text( ).

PROMPT 替換為您的文字「提示」

取得所選函式名稱和參數值

如要取得 Gemini 所選函式 (從已宣告的函式中選取) 及其建議參數,請使用 GET_FUNCTION_CALL 方法。

DATA(lo_response) = lo_model_key->set_auto_invoke_sap_function( abap_true
                               )->generate_content( iv_prompt_text = 'PROMPT' ).
lo_response->get_function_call( IMPORTING ev_function_name       = DATA(lv_function_name)
                                          et_function_parameters = DATA(lt_function_parameters) ).

PROMPT 替換為您的文字「提示」

您可以從 LV_FUNCTION_NAME 取得 Gemini 所選函式的名稱,以及 LT_FUNCTION_PARAMETERS 的建議參數。您可以根據企業的安全性資訊和事件管理指南,使用這項資訊驗證、追蹤及記錄 Gemini 動作。

程式碼範例

以下程式碼範例說明如何使用 SAP 函式呼叫,以便接收模型的最終回應。

DATA lt_parameters TYPE /goog/cl_generative_model=>tt_parameter_properties.
TRY.
  DATA(lo_model) = NEW /goog/cl_generative_model( iv_model_key = 'MODEL_KEY' ).
  APPEND VALUE #( parameter_name = 'PARAMETER_NAME'
                  type           = 'PARAMETER_TYPE'
                  description    = 'PARAMETER_DESCRIPTION'
                  is_required    = 'PARAMETER_IS_REQUIRED' ) TO lt_parameters.
  DATA(lv_response) = lo_model->add_function_declaration(
                                    iv_name        = 'FUNCTION_MODULE_NAME'
                                    iv_description = 'FUNCTION_MODULE_DESCRIPTION'
                                    it_parameters  = lt_parameters
                              )->set_auto_invoke_sap_function( abap_true
                              )->generate_content( iv_prompt_text ='PROMPT'
                              )->get_text( ).
  IF lv_response IS NOT INITIAL.
      cl_demo_output=>display( lv_response ).

  ENDIF.
 CATCH /goog/cx_sdk INTO DATA(lo_cx_sdk).
  cl_demo_output=>display( lo_cx_sdk->get_text( ) ).

ENDTRY.

更改下列內容:

  • MODEL_KEY:模型鍵名稱,會在模型產生參數中設定。
  • PARAMETER_NAME:參數名稱。
  • PARAMETER_TYPE:參數的資料類型,例如 stringintegerboolean
  • PARAMETER_DESCRIPTION:清楚說明參數的用途和預期格式。
  • PARAMETER_IS_REQUIRED:如果函式必須使用這個參數才能運作,請將值設為 ABAP_TRUE
  • FUNCTION_MODULE_NAME:SAP 函式模組的名稱。
  • FUNCTION_MODULE_DESCRIPTION:SAP 函式模組的說明。
  • PROMPT:您的文字提示

自動函式鏈結

自動函式鏈結功能可讓您叫用多個使用者定義的函式模組,以產生回應。只有在啟用 SAP 函式模組的自動叫用功能時,系統才支援這項功能。

以下程式碼範例說明自動函式鏈結。針對提示 Get the air quality in my current location,Gemini API 會先叫用函式模組 Z_GET_CURRENT_LOCATION 來取得經緯度資訊,然後將經緯度資訊傳遞至函式模組 Z_GET_CURRENT_AIR_QUALITY,以取得指定經緯度點的空氣品質。

gv_prompt = 'Get the air quality in my current location'.

  gv_system_instruction = 'You are a helpful weather assistant bot. You can turn find my location and get the weather information like temperature' &&
  'You can also alert me about EarthQuakes and Storm.' &&
  'You can also provide me information on Air Quality based on a location' &&
  'Do not perform any other tasks.'.

  TRY.

      DATA(lo_model_key) = NEW /goog/cl_generative_model( iv_model_key = 'gemini-flash-2' ).

      gv_final_op = lo_model_key->gs_ai_config-model_id.

      lo_model_key->add_function_declaration( iv_name        = 'Z_GET_CURRENT_LOCATION'
                                              iv_description = 'Get the current location'
                                              it_parameters  = gt_parameters ).
      CLEAR gt_parameters.

      gs_parameter-parameter_name = |Latitude|.
      gs_parameter-type = 'string'.
      gs_parameter-description = |Latitude|.
      gs_parameter-is_required = abap_true.

      APPEND gs_parameter TO gt_parameters.
      CLEAR gs_parameter.

      gs_parameter-parameter_name = |Longitude|.
      gs_parameter-type = 'string'.
      gs_parameter-description = |Longitude|.
      gs_parameter-is_required = abap_true.

      APPEND gs_parameter TO gt_parameters.
      CLEAR gs_parameter.

      lo_model_key->add_function_declaration( iv_name        = 'Z_GET_WEATHER_INFORMATION'
                                              iv_description = 'Gets weather information like temperature for a given location which is latitude and longitude'
                                              it_parameters  = gt_parameters ).


      lo_model_key->add_function_declaration( iv_name        = 'Z_GET_CURRENT_AIR_QUALITY'
                                              iv_description = 'Gets weather information like temperature for a given location which is latitude and longitude'
                                              it_parameters  = gt_parameters ).


      lo_model_key->add_function_declaration( iv_name        = 'GET_EARTHQUAKE_POSSIBILITY'
                                              iv_description = 'Gets possibility of Earthquake for a given location which is latitude and longitude'
                                              it_parameters  = gt_parameters ).


      lo_model_key->add_function_declaration( iv_name        = 'GET_STORM_POSSIBILITY'
                                              iv_description = 'Gets possibility of a STORM for a given location which is latitude and longitude'
                                              it_parameters  = gt_parameters ).

      lo_model_key->set_system_instructions(
        EXPORTING
          iv_text = gv_system_instruction
      ).

      DATA(lo_response) = lo_model_key->set_auto_invoke_sap_function( abap_true
                                     )->generate_content( iv_prompt_text = gv_prompt ).

      DATA(ls_response) = lo_response->get_response( ).
      /ui2/cl_json=>serialize(
        EXPORTING
          data   = ls_response-candidates[ 1 ]-content-parts           " Data to serialize
        RECEIVING
          r_json = DATA(lv_json_string)                 " JSON string
      ).
      IF lv_json_string IS NOT INITIAL.
        CLEAR gv_output.
        gv_output = lv_json_string.

      ENDIF.

    CATCH /goog/cx_sdk INTO DATA(lo_cx_sdk).
      cl_demo_output=>display( lo_cx_sdk->get_text( ) ).
  ENDTRY.

  lo_model_key->close( ).
  CLEAR lo_model_key.
  CLEAR lo_response.
  CLEAR ls_response.

如要停用自動函式鏈結,並只從大型語言模型取得第一個函式的回應,請使用 SET_FUNCTION_CALLING_CONFIG 方法,並將 IV_DISABLE_FUNCTION_CHAINING 參數設為 ABAP_TRUE。例如:


      lo_model_key->set_function_calling_config( iv_disable_function_chaining = abap_true ).
      DATA(lo_response) = lo_model_key->set_auto_invoke_sap_function( abap_true
                                     )->generate_content( iv_prompt_text = gv_prompt ).

如要取得 SDK 叫用的所有函式模組,以及傳遞至這些模組的參數,請呼叫 GET_ALL_FUNCTION_CALLS 方法:

      DATA(lo_response) = lo_model_key->set_auto_invoke_sap_function( abap_true
                                     )->generate_content( iv_prompt_text = gv_prompt ).

      DATA(ls_response) = lo_response->get_all_function_calls( ).

後續步驟