Showing posts with label machine learning. Show all posts
Showing posts with label machine learning. Show all posts

Sunday, 30 July 2023

Salesforce CLI Open AI Plug-in - Generating Records


Image generated by Stable Diffusion 2.1, based on a prompt from Bob Buzzard

Introduction

After the go-live of Service and Sales GPT, I felt that I had to revisit my Salesforce CLI Open AI Plug-in and connect it up to the GPT 4 Large Language Model. I didn't succeed in this quest, as while I am a paying customer of OpenAI, I haven't satisfied the requirement of making a successful payment of at least $1. The API function I'm hitting, Create Chat Completion, supports gpt-3.5-turbo and the gpt-4 variants, so once I've racked up enough cost using the earlier models I can switch over by changing one parameter. My current spending looks like it will take me a few months to get there, but such is life with competitively priced APIs.

The Use Case

The first incarnation of the plug-in asks the model to describe Apex, CLI or Salesforce concepts, but I wanted something that was more of a tool than a content generator, so I decided on creating test records. The new command takes parameters listing the field names, the desired output format, and the number of records required, and folds these into the messages passed to the API function. Like the Completion API, the interface is very simple:

const response = await openai.createChatCompletion({
     model: 'gpt-3.5-turbo',
     messages,
     temperature: 1,
     max_tokens: maxTokens,
     top_p: 1,
     frequency_penalty: 0,
     presence_penalty: 0,
   });

result = (response.data.choices[0].message?.content as string);

There's a few more parameters than the Completion API:

  • model - the Large Language Model that I send the request to. Right now I've hardcoded this to the latest I can access
  • messages - the collection of messages to send. The messages build on each other, and each message has a content (the instruction/request) and a role (where the instruction is being sent). This allows me to separate the instructions to the model (when the role is assistant, I'm giving it constraints about how to behave) from the request (when the role is user, this is the task/request I'm asking it to carry out).
  • max_tokens is the maximum number of tokens (approximately 4 characters of text) that my request combined with the response can be. I've set this to 3,500, which is approaching the limit of the gpt-3.5 model. If you have a lot of fields you'll have to generate a smaller number of records to avoid breaching this. I was able to create 50 records with 4-5 fields inside this limit, but your mileage may vary.
  • temperature and top_p guide the model as to whether I want precise or creative responses.
  • frequency_penalty and presence_penalty indicate whether I want the model to continually focus on tokens if they are repeated, or focus on new information.

As this is an asynchronous API, I await the response, then pick the first element in the choices array. 

Here's a few executions to show it in action - linebreaks have been added to the commands to aid legibility - remove these if you copy/paste the commands.

> sf bbai data testdata -f 'Index (count starting at 1), Name (Text, product name), 
            Amount (Number), CloseDate (Date yyyy-mm-dd), 
            StageName (One of these values : Negotiating, Closed Lost, Closed Won)' 
            -r csv

Here are the records you requested
Index,Name,Amount,CloseDate,StageName
1,Product A,1000,2022-01-15,Closed Lost
2,Product B,2500,2022-02-28,Closed Won
3,Product C,500,2022-03-10,Closed Lost
4,Product D,800,2022-04-05,Closed Won
5,Product E,1500,2022-05-20,Negotiating

> sf bbai data testdata -f 'FirstName (Text), LastName (Text), Company (Text), 
                            Email (Email), Rating__c (1-10)' 
                            -n 4 -r json

Here are the records you requested
[
  {
    "FirstName": "John",
    "LastName": "Doe",
    "Company": "ABC Inc.",
    "Email": "john.doe@example.com",
    "Rating__c": 8
  },
  {
    "FirstName": "Jane",
    "LastName": "Smith",
    "Company": "XYZ Corp.",
    "Email": "jane.smith@example.com",
    "Rating__c": 5
  },
  {
    "FirstName": "Michael",
    "LastName": "Johnson",
    "Company": "123 Co.",
    "Email": "michael.johnson@example.com",
    "Rating__c": 9
  },
  {
    "FirstName": "Sarah",
    "LastName": "Williams",
    "Company": "Acme Ltd.",
    "Email": "sarah.williams@example.com",
    "Rating__c": 7
  }
]

There's a few interesting points to note here:

  • Formatting field data is conversational - e.g. when I use Date yyyy-mm-dd the model knows that I want the date in ISO8601 format. For picklist values, I just tell it 'One of these values' and it does the rest.
  • In the messages I asked it to generate realistic data, and while it's very good at this for First Name, Last Name, Email, Company, it's not when told a Name field should be a product name, just giving me Product A, Product B etc.
  • It sometimes takes it a couple of requests to generate the output in a format suitable for dropping into a file - I'm guessing this is because I instruct the model and make the request in a single API call.
  • I've generated probably close to 500 records while testing this, and that has cost me the princely sum of $0.04. If you want to play around with the GPT models, it really is dirt cheap.
The final point I'll make, as I did in the last post, is how simple the code is. All the effort went into the messages to ask the model to generate the data in the correct format, not to include additional information that it was responding to the request, to generate realistic data. Truly the key programming language for Generative AI is the supported language that you speak - English in my case!

As before, you can install the plug-in via :
> sf plugins install bbai
or if you have already installed it, upgrade via :
> sf plugins update

More Information





Saturday, 1 April 2023

Artificial Indolence - Your Automated Accomplice



Hot on the heels of the Einstein GPT launch at TrailblazerDX, it gives me great pleasure to announce Artificial Indolence. If you are lazy, workshy, or just plain incompetent, Artificial Indolence can help you to hang on to your job while underperforming, far longer than anyone would reasonably expect.

Artificial Indolence is a general purpose tool (GPT), with use cases across the enterprise, including:

Case Work Deflector

The lazy service rep's worst nightmare - in spite of the best efforts of Einstein, the customer was able to raise a case and it's been assigned to you. Drawing on a training set of over a billion work-dodging communications, Artificial Indolence presents you with a tailored response that clearly explains why you are the worst person to be assigned work for the specific customer and problem. Clearly calling out your lack of ability and experience, it will be obvious to any manager that this can only end in disaster. If you've chosen the Communication Bus add-on, it will also identify a range of your peers who the work would be better assigned to and throw them under the bus.

Closed Lost Justifier

Our most successful feature to date, and perfect for the sales rep who just can't be bothered. When your lack of effort inevitably leads to an Opportunity being marked Closed Lost, Artificial Indolence generates a plausible reason why the stars didn't align in spite of your herculean efforts.

Activity Delayer

Rather than disappointing your customer all at once by not completing a job on time, drip feed the disappointment over weeks if not months with Artificial Indolence Activity Delayer - the customer will receive confusing communications outside working hours, and with any luck will blame themselves for not responding. If you've sprung for the Meeting Avoidance add-on, Indolence will automatically schedule meetings when most of the invitees have conflicts - the meeting will never happen and it's because everyone other than you is too busy!

Coverage Concealer

One for the developers who aren't interested in writing unit tests - Artificial Indolence will generate huge classes with 100% test coverage to bring the org coverage up to 75%. As these classes are based on genuine examples found in other orgs, they serve a real purpose (unless the examples were also generated by Indolence of course). Good enough to convince Salesforce to increase your Apex character limit, or three months free!


As befits it's purpose, Artificial Indolence is right now a collection of smoke, mirrors, mock ups and brochureware. Stay tuned for details of the pilot program that nobody will be accepted on to.





Friday, 17 March 2023

Einstein GPT - Rise of the Machines?

The very first computer magazine that I bought, way back in February 1981, was an issue of Personal Computer World with a story entitled "THE LAST ONE". This was a revolutionary system where you described what you wanted the program to do in plain English and it generated the code for you. This was being sensationalised as the end of programmers as we know them, yet I've managed a fruitful career in the 4 decades since.

Plain English was doing a lot of heavy lifting here, and the reality was that you chose options from menus to build a flowchart that eventually generated BASIC code, but it was pretty cool for it's time. Fast forward 42 years and with Salesforce announcing Einstein GPT at TrailblazerDX 23, it appears we'll be able to describe our requirements in a plain text comment and the class will be generated for us. So does this finally mean the end of programmers as we know them? Once again I think that would be a premature conclusion to jump to. 

If you'll permit me another stroll down memory lane, I'll use a documentary on factory automation to explain why. This was a ceramics factory that produced, among other things, mugs. It was the job of the final worker on the assembly line to take the mug and place it in a cardboard box for shipping. The company had invested in automation and he'd been put on notice that he was to be made redundant as part of this push to automate all the things. The slight downside was that the robot that picked the mug off the assembly line and put it in the box wasn't initially very accurate. it was knocking mugs off the conveyor when it tried to pick them up, and often dropped them when swinging round to the cardboard box, resulting in huge breakage numbers. This worker was then retained to stand near the robot and catch the items that it knocked over or dropped! The robot was continually being adjusted and adapted to do a better job, so he was essentially acting as it's minder until it got smart enough not to need him, at which point he'd be let go.

I think that we are in the same situation with Einstein GPT (and all the other GPTs) - we can ask them to create something, they will have a go, but you still need a human there to check that they got it right and fix what they got wrong. For simple classes with a method or two, it will make a good fist of it, and the same for the test classes, but as the complexity rises it's likely to need more human intervention. Human guardrails if you will, ensuring things stay heading in the right direction.

What Einstein GPT will give us is very useful starting points, rather like templates. Just like templates of old this will remove the need for us to continually rewrite the same few lines of boilerplate code to declare a class, except that these templates will be ever evolving based on what is already present in our codebase, and generated on demand based on what we can articulate (for regular classes) or what a class currently looks like (for test classes). For simple requirements they may be a very good first cut that just needs a bit of polishing.

A real time and money saver if most of the code written is relatively straightforward, and a potentially huge productivity boost for junior developers, as long as it gets it right most of the time. Experienced developers should also get a productivity improvement - they'll focus more of their time on the hard stuff rather than setting up the basics.  

So will Einstein GPT take the jobs of Salesforce developers? I think not. 

Salesforce Developers that use Einstein GPT may take the jobs of Salesforce Developers who don't, especially if the majority of the development work is low complexity.