Transforming SAP use cases with Google’s Vertex AI from within ABAP

This blog is a follow on to our previous blog “Unleash Vertex AI Power from ABAP: Effortless AI Integration” which elaborates on how SAP developers can seamlessly invoke Google Cloud’s Vertex AI models from ABAP environment using ABAP SDK for Google Cloud.

In this blog, I would delve into a specific SAP use case of order processing and showcase how you can bring the power of Generative AI with Vertex AI to your SAP applications using the SDK.

“The goal of the blog is to show the art of the possibility with a reference architecture for SAP customers, developers and architects to take reference and build their own tailored architectures specific to their business use cases.”

 

What are we building

Imagine a business where urgent orders come in on a daily basis and fulfilment of the orders within critical timelines is key to the success of the business. They receive orders through physical (paper based) and digital (PDFs) mediums but do receive a bulk of urgent orders through email messages where order details are just plain text in the email body. They use SAP for their order to cash process and would like to automate the order processing to increase fulfilment efficiency and reduce human errors.

The technical solution architects for the business would like to explore and use Google’s Generative AI to build the automation for urgent orders coming in as Gmail messages. They can write an SAP automation program to run at a frequency to,

  • Poll the Gmail inbox for new order requests using ABAP SDK’s client library ABAP class for Gmail API,
  • For each new order request, read the email body text using the SDK,
  • Invoke the “text-bison” model of Vertex AI API using the SDK and pass the read email text having the order information, along with instructions to extract order attributes, as a prompt.
  • Read the API response to gather the read order attributes for each order,
  • Call SAP BAPI to create a Sales Order based on the read attributes.
  • Publish an order confirmation message to the enterprise using SDK’s client library class for Cloud Pub/Sub.

Below is an example email of an urgent order received by the business from the procurement manager of one of the Google offices to replenish their pantry stock. I would be using the same in the blog to read and create order based on the above steps.

deveshsapcloud_1-1707755682158.png

Here is a high level architecture of the proposed solution.

deveshsapcloud_2-1707755721134.png

“Blog post linked here can be referred for reference architecture for processing physical PDF based POs and blog post here can be referred for reference architecture for processing POs coming as PDF attachments in Gmail inbox.”

 

Before we begin

Before starting, let’s recap on a few entities that we are going to work with in this blog.

  • PaLM 2 for Text — The PaLM 2 for Text (text-bison, text-unicorn) foundation models are optimized for a variety of natural language tasks such as sentiment analysis, entity extraction, and content creation.
  • text-bison — Text-bison is a large language model (LLM) developed by Google AI. It’s a foundational model for GenAI that can understand and generate language.
  • ABAP SDK for Google Cloud — ABAP SDK for Google Cloud, is a Google Cloud product that enables native bi-directional and real-time integration between SAP Applications and Google’s services. It has ABAP classes for each Google’s services embedded as client libraries to be invoked from the ABAP environment.

In this blog we would use,

  • Class /GOOG/CL_GMAIL_V1 to invoke Gmail API.
  • Class /GOOG/CL_VERTEXAI_V1 to invoke Vertex AI API.
  • Class /GOOG/CL_PUBSUB_V1 to invoke Cloud Pub/Sub.

Prerequisites

Before we start, let’s look at the below prerequisites needed for invoking the API.

The solution

Setup client key and service map configurations

Client Key configuration is required for connectivity to Google Cloud APIs through the SDK. For doing that, Login to SAP, goto SPRO > ABAP SDK for Google Cloud > Basic Settings > Configure Client Key and add a new entry.

deveshsapcloud_3-1707755776438.png

 

Client Key Configuration

Service Map configuration is required for specifying region specific endpoints for any API that can have region specific endpoints. For doing that, Login to SAP, goto SPRO > ABAP SDK for Google Cloud > Basic Settings > Configure Service Mapping and add a new entry.

deveshsapcloud_4-1707755775497.png

 

Service Map Configuration

Below are sample entries that you can refer to setup client keys and service maps. Please replace the service account and project id in the below entry as per your environment.

Setup client key for Vertex AI

Ensure that the service account is assigned the role “Vertex AI User”.

Google Cloud Key Name: DEMO_VERTEX_AI

Google Cloud Service Account Name: abap-sdk-dev@gcp-project.iam.gserviceaccount.com

Google Cloud Scope: https://www.googleapis.com/auth/cloud-platform

Google Cloud Project Identifier: gcp-project

Authorization Class: /GOOG/CL_AUTH_GOOGLE

Leave the other fields blank

Setup Service Map for Vertex AI

Goto SM59 and create a new RFC destination with the following details: (Please refer to this link for region specific service endpoints. For the below example I am using “us-central1” endpoint).

deveshsapcloud_2-1707756316365.png

Google Cloud Key Name: DEMO_VERTEX_AI

Google Service Name: aiplatform:v1

RFC Destination: ZGOOG_VERTEXAI_V1 (or whichever RFC destination you have created for your setup)

Setup client key for Gmail

Google Cloud Key Name: DEMO_GMAIL

Google Cloud Project Identifier: gcp-project

Authorization ass: /GOOG/CL_OAUTH_GOOGLE

Auth Param 1 — <Oauth 2.0 Client Profile>

Leave the other fields blank

“Refer to the steps here to create OAuth 2.0 Client Profile and configure authentication for Gmail using OAuth 2.0 Client Credentials based authentication.”

Setup client key for Cloud Pub/Sub

Ensure that the service account is assigned the role “Pub/Sub Admin”.

Google Cloud Key Name: DEMO_PUBSUB

Google Cloud Service Account Name: abap-sdk-dev@gcp-project.iam.gserviceaccount.com

Google Cloud Scope: https://www.googleapis.com/auth/cloud-platform

Google Cloud Project Identifier: gcp-project

Authorization Class: /GOOG/CL_AUTH_GOOGLE

Leave the other fields blank

Polling Gmail for new order requests

The first step is to poll for new order requests. A rule can be built in Gmail to tag each order request with a “Label”.

  • Call method LIST_MESSAGES of SDK’s class /GOOG/CL_GMAIL_V1 to list the new orders by passing the Gmail inbox mail id and label as inputs.
  • GitHub guide can be referred for a code snippet for listing messages from Gmail mailbox against labels.
  • Pass the client key as the one configured for Gmail in the client key configuration step of the blog.

It is also possible to list the messages by specifying more than one label ids, for example if you would like to list all the email messages which are in your “Inbox” and are “Unread”, you can introduce below code snippet in the code sample before calling method “LIST_MESSAGES”.

lo_client->set_overriding_uri(
  EXPORTING
    iv_uri = '/gmail/v1/users/me/messages?labelIds=UNREAD&labelIds=INBOX' ).

Get Gmail message content

The next step is to read the email body text for each new Gmail message/email listed from above step.

  • Call method GET_MESSAGES of SDK’s class /GOOG/CL_GMAIL_V1 to get the content of each listed message.
  • GitHub guide can be referred to for a code snippet to get content from a Gmail message.
  • Pass the client key as the one configured for Gmail in the client key configuration step of the blog.

Get order attributes by passing the content to Vertex AI model

Each read email body text which has the order details is passed to Vertex AI API to get the order attributes. The text is sent to the API along with concise instructions to parse and send back order instructions in JSON format as a prompt.

Below is the prompt that we would be using for the blog.

"I will give you an email context, you identify the parameters from the email to match given cases as following, and return the results in json format, provide concise answers, no explanation. Give the Delivery date in DD.MM.YYYY format. 
CASE 1. When a retailer order : {
"parameters": {
"IVendor":Vendor name,
"IItem":Item name,
"IBoxqty":Box qty,
"ISendername": Sender name,
"ISendercompany": Sender company,
"ISenderdesignation": Sender designation,
"ISenderaddress": Sender address,
"IShippingaddress": Shipping address,
"IDeliverydate": "Deliverydate
 } } 
CASE 2. Others : None
Email Content: <Email Content>
Place the ordered items in JSON nest."
  • Call method PREDICT_MODELS of SDK’s class /GOOG/CL_AIPLATFORM_V1 to invoke Vertex AI text-bison model.
  • Code snippet below can be referred to pass the prompt to the API and get the response, pass the client key as the one configured for Vertex AI in the client key configuration step of the blog.
  • The ABAP types declarations are to prepare the request for and capture the response from Vertex AI PaLM 2 Text model as per documentation here.
* Types declarations
TYPES:
  BEGIN OF ty_instances,
    content TYPE string,
  END OF ty_instances.

TYPES:
     tt_instances TYPE STANDARD TABLE OF ty_instances WITH DEFAULT KEY .

TYPES:
  BEGIN OF ty_parameters,
    max_output_tokens TYPE i,
    temperature       TYPE f,
    top_k             TYPE i,
    top_p             TYPE f,
  END OF ty_parameters.

TYPES ty_categories TYPE string .
TYPES:
  BEGIN OF ty_scores,
    scores TYPE string,
  END OF ty_scores .
TYPES:
  tt_categories TYPE STANDARD TABLE OF ty_categories WITH DEFAULT KEY .
TYPES:
  tt_scores TYPE STANDARD TABLE OF ty_scores WITH DEFAULT KEY .

TYPES:
  BEGIN OF ty_safety_attributes,
    blocked    TYPE abap_bool,
    categories TYPE tt_categories,
    scores     TYPE tt_scores,
  END OF ty_safety_attributes .

TYPES:
  BEGIN OF ty_predictions,
    content           TYPE string,
    safety_attributes TYPE ty_safety_attributes,
  END OF ty_predictions .
TYPES:
  tt_predictions TYPE STANDARD TABLE OF ty_predictions WITH DEFAULT KEY .

TYPES:
  BEGIN OF ty_output,
    deployed_model_id  TYPE string,
    metadata           TYPE REF TO data,
    model              TYPE string,
    model_display_name TYPE string,
    model_version_id   TYPE string,
    predictions        TYPE tt_predictions,
  END OF ty_output.

* Data declarations
DATA:
  lv_p_projects_id   TYPE string,
  lv_p_locations_id  TYPE string,
  lv_p_publishers_id TYPE string,
  lv_p_models_id     TYPE string,
  ls_input           TYPE /goog/cl_aiplatform_v1=>ty_001.

DATA:
      lv_email_text TYPE string.

CONSTANTS: lc_ob TYPE c VALUE '{',
           lc_cb TYPE c VALUE '}'.

* Email content having order request
lv_email_text =  <Read Gmail message content>.

TRY.
    DATA(lv_raw) = VALUE string( ).
* Open HTTP Connection
    DATA(lo_client) = NEW /goog/cl_aiplatform_v1( iv_key_name = 'DEMO_VERTEX_AI' ).

* Populate relevant parameters
    lv_p_projects_id = lo_client->gv_project_id.
    lv_p_locations_id = <location id of the endpoint>.
    lv_p_publishers_id = 'google'.
    lv_p_models_id = 'text-bison'.

* Call API method: aiplatform.projects.locations.publishers.models.predict
    CALL METHOD lo_client->predict_models
      EXPORTING
        iv_p_projects_id   = lv_p_projects_id
        iv_p_locations_id  = lv_p_locations_id
        iv_p_publishers_id = lv_p_publishers_id
        iv_p_models_id     = lv_p_models_id
        is_input           = VALUE #(
     parameters = NEW ty_parameters(
           max_output_tokens  = 256
           temperature = '0.2'
           top_k = '40'
           top_p  = '0.8' )
      instances = NEW tt_instances( ( content =
* Context to AI Model
       |I will give you an email context, you identify the parameters from the email to match given cases as following, and | &&
       |return the results in json format, | &&
       |provide concise answers, no explanation. Give the Delivery date in DD.MM.YYYY format. | &&
       |CASE 1. When a retailer order : | && lc_ob &&
* Desired Output for an order email
|"parameters": | && lc_ob &&
|"IVendor":Vendor name,"IItem":Item name,"IBoxqty":Box qty, "ISendername": Sender name, "ISendercompany": Sender company| &&
|, "ISenderdesignation": Sender designation, "ISenderaddress": Sender address, "IShippingaddress": Shipping address, "IDeliverydate": "Deliverydate| &&
         lc_cb && lc_cb &&
       |CASE 2. Others : None | &&
* Actual email content passed to AI Model. You can also try with different verbiage and evaluate the output
       |Email Content: | && lv_email_text && |Place the ordered items in JSON nest.| ) ) )
      IMPORTING
        es_raw             = lv_raw
        ev_ret_code        = DATA(lv_ret_code)
        ev_err_text        = DATA(lv_err_text)
        es_err_resp        = DATA(ls_err_resp).

    IF lo_client->is_success( lv_ret_code ).
      DATA(ls_output_llm) = VALUE ty_output( ).
* Deserializing API response to get model response
      /goog/cl_json_util=>deserialize_json( EXPORTING iv_json        = lv_raw
                                                      iv_pretty_name = /ui2/cl_json=>pretty_mode-extended
                                            IMPORTING es_data        = ls_output_llm ).
      cl_demo_output=>new(
        )->begin_section( 'API Call Successful:'
        )->write_text( 'Respose from model:'
        )->write_text( ls_output_llm-predictions[ 1 ]-content
        )->display( ).
    ELSE.
      cl_demo_output=>new(
        )->begin_section( 'API Call Unsuccessful:'
        )->write_text( 'Error Message:'
        )->write_text( lv_err_text
        )->display( ).

    ENDIF.

* Close HTTP Connection
    lo_client->close( ).

  CATCH /goog/cx_sdk INTO DATA(lo_exception).
    DATA(lv_error) = lo_exception->get_text( ).
    cl_demo_output=>new(
     )->begin_section( 'Exception Occured:'
     )->write_text( lv_error
     )->display( ).

For the in mail order request below,

deveshsapcloud_0-1707756228487.png

the above code snippet would give output with read order attributes in a JSON format as below.

deveshsapcloud_1-1707756255417.png

Call SAP BAPI to create order

Deserialise the JSON received in above step into a local ABAP type and then pass the same to SAP BAPI “BAPI_SALESORDER_CREATEFROMDAT2” to create a Sales Order.

Publish order confirmation message to the enterprise

An order confirmation message is published to a Cloud Pub/Sub topic for any follow on business process to ensue.

  • Call method “PUBLISH_TOPICS” of class /GOOG/CL_PUBSUB_V1 to publish a message with sales order number to a Cloud Pub/Sub topic.
  • GitHub guide can be referred along with the code snippet to publish a message to a topic.
  • Pass the client key as the one configured for Cloud Pub/Sub in the client key configuration step of the blog.

Below is a representation of the above steps to build automation for the business for processing urgent orders coming as Gmail texts using Google Cloud’s Vertex AI platform all made possible natively from your SAP automation application by ABAP SDK for Google Cloud.

deveshsapcloud_8-1707755982657.png

Have a look at the below video to see the solution in action.

Summary and next steps

This blog showed an art of the possible SAP relevant use case of leveraging Generative AI in a business use case to achieve operational efficiency. We also learnt how ABAP SDK for Google Cloud can be used to bring the power of Google’s Vertex AI directly to your ABAP environment and empowers SAP customers, developers and architects to build SAP applications and consume the AI capabilities natively from the applications.

We would be releasing more blogs talking about more reference architectures for you to refer and build solutions for your businesses.

Join the community !!!!

The ABAP SDK for Google Cloud Community is now open! This is a place for you to ask questions, share knowledge, and collaborate with other ABAP developers who are using Google Cloud. We encourage you to get involved in the community and help us make the ABAP SDK for Google Cloud even better. We have a lot of exciting things planned for the future, and we want you to be a part of it.

Click the link below to join and innovate with us.

Join the Community 

Solved Solved
0 1 347
1 ACCEPTED SOLUTION

Roderick
Community Manager
Community Manager

Solid resources @devesh-sapcloud! Thanks for sharing with the Community.

 

View solution in original post

1 REPLY 1

Roderick
Community Manager
Community Manager

Solid resources @devesh-sapcloud! Thanks for sharing with the Community.