Contents
In the world of AI-driven tools, two prominent platforms have emerged for ServiceNow developers: ChatGPT-4 and NowAssist for Creator Code Generation. In this blog post, we’ll dive into a comparison of these two tools, specifically focusing on their capabilities for generating ServiceNow (SN) code.
What is ChatGPT-4?
ChatGPT-4, launched by OpenAI on November 30, 2022, is a conversational AI designed for various tasks, including code generation. With its ability to learn from past interactions, it offers personalized suggestions, making it a versatile tool for developers.
What is NowAssist for Creator Code Generation?
NowAssist, launched as part of the Vancouver release on September 29, 2023, provides code generation capabilities as part of ServiceNow’s suite of tools. However, code generation is just one aspect of its broader NowCreator capabilities. The NowAssist code generation model is based on HuggingFace, which differs from ChatGPT.
Testing the Differences
In this blog, we will explore the code generation abilities of both platforms using the same prompt, highlighting where they excel and differ. While both tools are designed to aid developers, their approach and functionality vary significantly.
Caveats
- Version Tested: This comparison uses NowAssist version 25.1.2 for the Washington DC release.
- Availability: NowAssist for creator code generation became generally available on September 29, 2023.
- Head Start: ChatGPT-4 has been available since November 30, 2022, giving the model and prompt response more time to develop
- Focused on Code Generation: While both platforms offer a wide range of capabilities, today’s comparison focuses solely on code generation.
- Personalization: ChatGPT-4 may already have learned from my previous usage (and millions of others), giving it an edge in understanding my style for ServiceNow (SN) code generation at this time.
- Different Approaches: ChatGPT is conversational, whereas NowAssist is not—at least not yet, in terms of code generation.
- GenAI Is Non-Deterministic: Both platforms generate results that can vary with each run, meaning your results may not be the same as mine.
Join me as we test these tools to see how they perform under identical conditions.
ServiceNow Strong Prompts
We will start by using some examples of good prompts provided by ServiceNow. I pre-empted this in ChatGPT:
Im going to provide some prompts for ServiceNow code generation
I will be prompting for code from within a function in a Script Include in the global scope for ServiceNow. I’ll be naming the function in line with the prompt as I would in a realistic scenario, which I will include in the response. I will consist of function parameters when it makes sense to do so. If responses were a bit off the mark I retried until a result was reasonably correct.
ServiceNow Now Assist Code Generation
getIncidentsWithRelatedTasks: function() { var records = new GlideRecord('incident'); records.addEncodedQuery('RLQUERYtask_ci.task,>=1^ENDRLQUERY'); records.query(); var incidents = []; while (records.next()) { incidents.push(records.getValue('number')); } return incidents; },
This code looks to be finding incidents that have any related CI records and pushing each result number to an array.
ChatGPT 4o
var IncidentWithTasks = Class.create(); IncidentWithTasks.prototype = { initialize: function() {}, // Function to get incidents with related tasks getIncidentsWithTasks: function() { var result = []; // Query incidents var incidentGR = new GlideRecord('incident'); incidentGR.query(); while (incidentGR.next()) { // Create a structure for the incident var incidentData = { number: incidentGR.number.toString(), short_description: incidentGR.short_description.toString(), incident_sys_id: incidentGR.sys_id.toString(), tasks: [] // To store related tasks }; // Query related tasks using the incident sys_id var taskGR = new GlideRecord('task'); taskGR.addQuery('parent', incidentGR.sys_id); // Fetch tasks related to the incident taskGR.query(); while (taskGR.next()) { // Push each related task into the tasks array incidentData.tasks.push({ task_number: taskGR.number.toString(), task_short_description: taskGR.short_description.toString(), task_sys_id: taskGR.sys_id.toString(), task_state: taskGR.state.toString() }); } // Push incident with related tasks to the result array result.push(incidentData); } return result; }, type: 'IncidentWithTasks' };
ChatGPT has interpreted related tasks and child records and provided short description, sys_id and state in addition to the number.
“Use glide aggregate to count number of P1 incidents closed between 3rd March to 13 April assigned to admin”
ServiceNow NowAssist Code Generation
countP1IncidentsInDate: function() { var records = new GlideAggregate('incident'); records.addQuery('priority', 1); records.addQuery('closed_at', '>=', '2023-03-03 00:00:00'); records.addQuery('closed_at', '<=', '2023-04-13 23:59:59'); records.addQuery('assigned_to', 'admin'); records.addAggregate('COUNT'); records.query(); var count = 0; if (records.next()) { count = records.getAggregate('COUNT'); } return count; },
ServiceNow is counting the number of incidents Priority 1 incidents closed assigned to admin “user” from the 3rd of March to 23rd of April. The admin user does not have a sys_id of ‘admin’ so this query is unlikely to work. While it the query does not explicitly check for the state field being closed, it has inferred that the incidents are in a closed state by checking the closed_at field.
ChatGPT 4o
var agg = new GlideAggregate('incident'); // Set the conditions for the query agg.addAggregate('COUNT'); agg.addQuery('priority', '1'); // Priority 1 (P1) agg.addQuery('state', '7'); // Closed state (7 = Closed) agg.addQuery('assigned_to.user_name', 'admin'); // Assigned to admin // Date query between 3rd March and 13th April agg.addEncodedQuery('closed_atBETWEEN2023-03-03@00:00:00@2023-04-13@23:59:59'); // Run the query agg.query(); // Retrieve the count if (agg.next()) { var count = agg.getAggregate('COUNT'); gs.print('Number of P1 incidents closed between 3rd March and 13th April assigned to admin: ' + count); }
ChatGPT 4.0 explicitly looks at the state and the user_name of the ‘assigned to ‘user. Rather than using two separate queries for dates, it has opted to use an encoded query with a comment to explain.
“if open change request is P1, do not allow reducing the severity unless it’s the creator. “
ServiceNow NowAssist Code Generation
preventChangeUpdate: function(changeRequestGr) { if (changeRequestGr.getValue('priority') == 1 && changeRequestGr.getValue('state') == 1 && changeRequestGr.getValue('sys_created_by') != gs.getUserName()) { gs.addErrorMessage(gs.getMessage('P1 changes can only be set to Critical')); changeRequestGr.setAbortAction(true); } },
This would most likely be in a business rule, or at least this function would be called from a script include.
ChatGPT 4o
// Business Rule: Prevent severity reduction unless the current user is the creator (function executeRule(current, previous /*null when async*/) { // Check if the priority is P1 and the change request is still open if (current.priority == 1 && current.state != 'closed') { // Check if the severity is being reduced if (current.severity < previous.severity) { // Check if the current user is NOT the creator if (current.opened_by != gs.getUserID()) { // Prevent the update gs.addErrorMessage("You are not allowed to reduce the severity of a P1 change request unless you are the creator."); current.setAbortAction(true); // Stops the update from happening } } } })(current, previous);
ChatGPT has recognised that this code would be called in a Business Rule and included details on how this would be configured.
“gliderecord of the most recent change “
ServiceNow NowAssist Code Generation
getMostRecentChange: function() { var changeGr = new GlideRecord('change_request'); changeGr.orderByDesc('sys_created_on'); changeGr.setLimit(1); changeGr.query(); changeGr.next(); return changeGr; },
ServiceNow has interpreted “change” to mean “change_request”. When ordering dates descending, the most recent date has the higher value and therefore would result in the most recent change.
ChatGPT 4o
var gr = new GlideRecord('change_request'); // Table for change requests gr.orderByDesc('sys_created_on'); // Sort by sys_created_on in descending order gr.setLimit(1); // Get only the most recent record gr.query(); if (gr.next()) { gs.print('Most Recent Change Request: ' + gr.number + ' | Created on: ' + gr.sys_created_on); // You can access other fields from the 'change_request' record, such as: // gr.short_description, gr.state, gr.priority, etc. } else { gs.print('No Change Request found.'); }
ChatGPT’s response is very similar to ServiceNow’s, with additional logic to handle when there are no change requests.
Experimental Prompts
Let’s try out some of my prompts for code generation:
“Add incident caller’s manager to the watch list field”
ServiceNow NowAssist Code Generation
addEmailToWatchList: function(grIncident) { grIncident.watch_list = grIncident.caller_id.manager; grIncident.update(); },
This one took several prompts to get right, with some really strange responses. This will override existing users on the watch list, which may not be ideal.
ChatGPT 4o
(function executeRule(current, previous /*null when async*/) { // Ensure the caller_id field is not empty if (current.caller_id) { // Query the caller's manager from the sys_user table var callerGR = new GlideRecord('sys_user'); if (callerGR.get(current.caller_id)) { // Check if the caller has a manager if (callerGR.manager) { var managerSysId = callerGR.manager.toString(); // Get the manager's sys_id // Check if the manager is already in the watch list if (!current.watch_list.includes(managerSysId)) { // Add the manager to the watch list current.watch_list += ',' + managerSysId; } } else { gs.addInfoMessage('Caller does not have a manager defined.'); } } } })(current, previous);
ChatGPT has assumed this code would likely be called from a Business Rule. Unlike ServiceNow’s solution, the code will not override existing watch list users.
“when a work note is made on a catalog task, add the same work note to the parent request item”
ServiceNow NowAssist Code Generation
For this particular prompt, I tried something different. I set up the Business Rule with all the applicable configuration settings and made this prompt into the script field.
(function executeRule(current, previous /*null when async*/) { var records = new GlideRecord('sc_req_item'); records.addQuery('sys_id', current.request_item); records.query(); if (records.next()) { records.work_notes = current.work_notes; records.update(); } })(current, previous);
The code finds all requested items and adds the current work note. There can only be one parent so there are simpler ways to achieve this.
Chat GPT 4o
(function executeRule(current, previous /*null when async*/) { // Check if the work notes field has been updated if (current.work_notes != previous.work_notes && current.work_notes != '') { // Retrieve the parent request item (RITM) associated with the catalog task var ritmGR = new GlideRecord('sc_req_item'); // Check if the catalog task has a valid RITM if (ritmGR.get(current.request_item)) { // Add the work notes to the RITM work notes ritmGR.work_notes = current.work_notes; ritmGR.update(); // Save the RITM with the new work notes gs.addInfoMessage('Work note copied to the parent request item.'); } else { gs.addErrorMessage('Failed to find the parent request item.'); } } })(current, previous);
ChatGPT assumes this would be placed in a Business Rule. Requested Item is retrieved and a work note is added.
Closing thoughts
While ServiceNow’s code generation is designed to excel at platform-specific contexts, leveraging its deep knowledge of ServiceNow structures, ChatGPT’s early lead in development time and its vast user base still give it the edge in ServiceNow code generation. The conversational nature also makes it more powerful, which is currently absent from ServiceNow’s offering.
I anticipate we will continue to see improvements in ServiceNow offering and it will only get better from here, with the inclusion of a similar conversational code generation likely to be introduced in future versions of ServiceNow. The convenience of having ServiceNow code generation built directly into the platform offers a significant advantage for developers working within the tool as its responses are improved over time as it is further trained on larger data sets.
Whether or not ServiceNow’s code generation ever catches up to ChatGPT’s high standards, its real advantage will be its ability to generate low-code configurations like applications and flows directly into the platform, which ChatGPT is currently unable to handle for some time. With this foundation in place, the future looks bright for the continued growth of Now Assist for creators in upcoming releases.
Until then, happy prompting!