Generative AI and SAP Cloud Integration
2023-12-27 23:14:31 Author: blogs.sap.com(查看原文) 阅读量:9 收藏

2023 has been the year of AI and of generative AI in particular. AI is not a new topic, of course. In fact it’s quite old. But since OpenAI launched ChatGPT in November of 2022, the pace of innovation in AI has gone through the roof with no sign of slowing down any time soon.

So it probably didn’t come as a huge surprise, when Jürgen Müller announced in his SAP TechEd 2023 keynote, that SAP is embedding generative AI into SAP Integration Suite.

(I’m going to refer to generative AI as GenAI in the rest of this blog post.)

One of the areas where GenAI is making a huge impact is coding assistants. That is, an AI copilot that assists developers by generating code, documentation etc. We don’t yet know the details of how SAP intends to embed GenAI into SAP Integration Suite, but an AI copilot for creating integration flows seems a pretty safe bet.

GenAI excels at creating text, so generating scripts in SAP Cloud Integration is another area where an AI copilot would make a lot of sense. And script generation is something we can experiment with already now, without having to wait for SAP’s AI copilot to launch.

Creating Groovy scripts with GenAI is an area I’d been wanting to look into for a while, so when OpenAI launched their custom GPT feature, I decided to give it a go.

Custom GPTs were announced at OpenAI’s DevDay conference in San Francisco in November, 2023. You can check out the announcement here. Custom GPTs are a way to specialise ChatGPT in a particular field or topic. They are built on the GPT-4 foundation model, OpenAI’s most powerful model so far. The model is specialised via prompting and so-called knowledge files; there is no coding or complex (and costly) fine-tuning involved in the process. This made a custom GPT a perfect fit for my project.

Custom GPTs can be shared, but at the moment, they are only available to ChatGPT Plus members (a paid subscription) and OpenAI enterprise customers. OpenAI plans to launch a store for custom GPTs at a later date.

An AI assistant needs a proper name, of course, and I named mine GroovyScriptinator. My approach to training was iterative: Try a prompt, identify anything that needs tweaking in the response, update the instructions accordingly and repeat.

Out of the box, GPT-4 is already very capable of generating Groovy code. For that reason, I focused my training efforts on the following three more specific areas:

  • The SAP Cloud Integration environment
  • Best practices
  • Creating idiomatic Groovy code

Here are some examples of instructions from the first category:

  • All generated code must be compatible with Groovy version 2.4
  • Don’t use Java libraries that require a Java version newer than Java 8
  • The generated script function must either be called processData or the Script step must be configured with the non-default function name

Here are some examples of instructions from the second category:

  • Always pass the payload as a Reader object to XmlSlurper and JsonSlurper
  • Don’t pretty-print XML and JSON unless there is a reason to
  • Use the log level at runtime or an externalized parameter to control logging

Here are some examples of instructions from the third category:

  • Don’t add a semicolon at the end of a statement
  • Don’t use both def and a type when declaring a variable
  • Don’t import classes that are already imported automatically in Groovy

At the moment, my instructions for GroovyScriptinator come in at around 1800 words, but that number will likely keep growing. 1800 words is roughly the length of this blog post without the code listings.

While working on my custom GPT, I’ve been using a number of prompts for testing its performance. I’ve chosen four examples for this blog post to demonstrate what’s possible. For each example I’ve linked to the conversation, so you can see the full response for yourself.

Example 1: JSON processing

The first example is based on this question from the SAP Community. I edited out the part about an existing script, because I wanted GroovyScriptinator to come up with a full solution to the problem. This is the script it generated in response:

import com.sap.gateway.ip.core.customdev.util.Message
import groovy.json.JsonSlurper
import groovy.json.JsonOutput

def Message processData(Message message) {
    // Parse the JSON payload
    def jsonPayload = new JsonSlurper().parseText(message.getBody(String))

    // Remove the 'shippingPackages' object
    jsonPayload.remove('shippingPackages')

    // Set the modified JSON back to the message body
    message.setBody(JsonOutput.toJson(jsonPayload))

    return message
}

This script works and generates the requested output. It’s nicely formatted and even has decent comments. It’s actually pretty similar to my own answer to the same question.

The two scripts differ in one respect, though: The payload should really be passed to JsonSlurper as a Reader object instead of a String object (that way a large payload is not read needlessly into memory). This best practice is actually part of my GroovyScriptinator instructions, but it seems to have temporarily forgotten that (more on that below).

I asked it to correct this and received the following script in response:

import com.sap.gateway.ip.core.customdev.util.Message
import groovy.json.JsonSlurper
import groovy.json.JsonOutput

def Message processData(Message message) {
    // Access the JSON payload as a Reader
    def payloadReader = message.getBody(Reader)

    // Parse the JSON payload
    def jsonPayload = new JsonSlurper().parse(payloadReader)

    // Remove the 'shippingPackages' object
    jsonPayload.remove('shippingPackages')

    // Set the modified JSON back to the message body
    message.setBody(JsonOutput.toJson(jsonPayload))

    return message
}

This script also generates the requested output and correctly accesses the payload via the more efficient Reader. You can view the full conversation here.

Example 2: More JSON

My second example is based on this SAP Community question (JSON is a popular Groovy scripting topic). I once again edited out the part about an existing script to see GroovyScriptinator’s own solution to the problem. This is the script it generated for me:

import com.sap.gateway.ip.core.customdev.util.Message
import groovy.json.JsonSlurper
import groovy.json.JsonOutput

def Message processData(Message message) {
    // Parse the JSON payload
    def jsonParser = new JsonSlurper()
    def jsonPayload = message.getBody(Reader)
    def parsedJson = jsonParser.parse(jsonPayload)

    // Add the new root node
    def modifiedJson = [data: parsedJson]

    // Convert the modified JSON back to String
    String jsonString = JsonOutput.toJson(modifiedJson)

    // Set the modified JSON as the new payload
    message.setBody(jsonString)

    return message
}

The script works correctly and this time around, GroovyScriptinator correctly used a Reader to access the payload. It even pointed out that the provided input JSON is, in fact, not valid and that the script only works, when the input is valid.

The only thing I’d point out is that it’s a little odd to declare all variables with def except jsonString, which is declared with its type (String). It’s a tiny detail, though. You can view the full conversation here.

Example 3: Environment variables

My third example is a script that I needed for myself. This is the prompt I used:

“I need a script that creates a plain text payload containing the names of all environment variables and their values. I would like the output formatted as “NAME = VALUE”, one name/value pair on each line.”

This is the script I received in response:

import com.sap.gateway.ip.core.customdev.util.Message

def Message processData(Message message) {
    // StringBuilder for constructing the output
    def output = new StringBuilder()

    // Iterate over all environment variables and append them to the output
    System.env.each { key, value ->
        output << key << " = " << value << '\n'
    }

    // Set the generated string as the message payload
    message.setBody(output.toString())

    return message
}

This script works and it’s a very decent solution to my problem. Short, sweet and to the point. It uses a StringBuilder to compose the payload efficiently and even uses the Groovy way of appending to the StringBuilder with the << operator. The only thing I’d point out is that the appended string with the equals sign really should be in single quotes, but that’s a very minor gripe. You can view the full conversation here.

Example 4: Fixed-length format to CSV

The last example is a requirement I made up specifically for testing GroovyScriptinator. I used the following prompt:

“I need a script that turns a fixed-length format text payload into a comma-separated text payload.

The payload contains a number of lines. The columns in the file has the following lengths: 3, 6, 3, 5, 2

Trailing spaces should be removed from the fourth column (but only from the fourth column).

Here is an example input line:

xyz123456abcdef 99

Here is the corresponding output line:

xyz,123456,abc,def,99

You can assume that each line has the same length, and this length is the sum of the column lengths.”

Here’s the script that GroovyScriptinator responded with:

import com.sap.gateway.ip.core.customdev.util.Message

def Message processData(Message message) {
    // Define column lengths
    def columnLengths = [3, 6, 3, 5, 2]

    // Get the payload as a string
    def payload = message.getBody(String)
    def lines = payload.split('\n')
    def newLines = []

    lines.each { line ->
        def start = 0
        def columns = columnLengths.collect { length ->
            def column = line.substring(start, start + length)
            start += length
            column
        }

        // Trim trailing spaces from the fourth column
        columns[3] = columns[3].trim()

        // Join columns with commas
        newLines << columns.join(',')
    }

    // Set the modified payload back into the message
    message.setBody(newLines.join('\n'))

    return message
}

This script solves the problem as stated and is really quite nice. I basically don’t have any notes. It kept the column lengths in an appropriate data structure, rather than hardcoding them into the script. It even got it right that the fourth column has index 3. You can view the full conversation here.

The above examples are not staged and have not been doctored in any way. They are representative of the standard of the code created by the custom GPT. It does make mistakes (see the below FAQ), but in general the quality of the responses is very high. Many of the generated scripts are so good that they can be added to your integration flow as is or with minimal modifications. I’d like you to pause for a moment and think about how powerful that is!

So my conclusion is rather obvious: An AI copilot is a perfect fit for Groovy scripting in SAP Cloud Integration and there is no question whatsoever about feasibility. I have no doubt that GenAI will be part of your daily work as an SAP Cloud Integration developer. And it will likely happen sooner rather than later.

You probably have a lot of questions! I’ve tried to answer some of them in the following FAQ, but please feel free to ask questions in the comments as well. If I missed any obvious ones I’ll add them to the FAQ.

Does this mean I don’t have to learn Groovy?

No. You can do SAP Cloud Integration development without knowing Groovy, but if you want to add Groovy scripting to your toolbox (and I definitely think you should!), then you need to learn the language.

But whyyyy? Can’t I just use GenAI to write all the code?

You could, of course. But what happens after the script has been generated? First off, you won’t know if it actually works. And even if it seems to work, you won’t know why or under which circumstances. If you then throw caution to the wind, deploy the script in production and it breaks, it will be your responsibility to fix it, but you’ll have no idea how to fix it.

This is the reason why it’s generally a really, really bad idea to add code that you do not understand to your integration solution. It will come back to bite you in the haunt you later on.

Does GenAI make mistakes?

Yes. If you have used ChatGPT or similar GenAI chatbots before, you have very likely experienced this yourself as well.

I’m really impressed with the quality of the code generated by my custom GPT. That doesn’t mean it’s foolproof, though! It will still sometimes gladly and confidently present you with code that has syntax errors or code that is syntactically correct but just doesn’t work. It also sometimes forgets parts of its instructions.

So if GenAI makes mistakes, does that mean it sucks and I can safely ignore it?

Absolutely not. It really just emphasizes the copilot role of GenAI coding assistants. A human in the pilot’s seat is still needed and with GenAI that person has a powerful productivity tool available to them.

If you ignore GenAI right now, you do so at your peril. This is not another technology fad that can be waited out with a bit of patience. Love it or hate it, you need to understand what GenAI is, what it can and cannot do and how it can be applied in your context.

Will you be releasing GroovyScriptinator?

If there’s interest, I might at some point. I’d like to tinker with it some more first, though.


文章来源: https://blogs.sap.com/2023/12/27/generative-ai-and-sap-cloud-integration/
如有侵权请联系:admin#unsafe.sh