Alisa Tipisova
ServiceNow Employee
ServiceNow Employee

Recently, one of my customers asked how to build a kind of “Hot Topics” report for incident management.

Before jumping into the solution, let’s clarify the requirement:
When an incident is created, we want ServiceNow to analyze the Short Description and Description fields and identify the key topics users are reporting. These pain points should be stored for reporting, so we can track long-term trends.

If you look at this from a product perspective, it sounds a lot like something Predictive Intelligence or Text Analytics could do.

 

Why Not Use the OOTB Options?

Predictive Intelligence (or Task Intelligence)

This functionality analyzes incident data and categorizes it automatically. Sounds promising—if you have a well-defined CSDM with services and service offerings in place.
But if you don’t? Well, you can still use Predictive Intelligence to analyze the data and build custom logic to store the identified keywords in a custom table—but that’s not an out of the box solution and it requires knowledge of how LLMs work.

 

Text Analytics

This one actually does exactly what my customer needs—and it’s 100% OOTB. Perfect, right? Not quite. The big blocker: Text Analytics isn’t supported by Platform Analytics Dashboards, and to the best of my knowledge, it’s not on the short-term roadmap.

So we needed another option.

 

Can GenAI Help?

And that brings us to the topic of this post: Can we do this using the new GenAI tools in ServiceNow?
Let’s find out.

In this post, I’ll walk through two different approaches using:

  • Custom Now Assist Skill

  • Custom AI Agent (covered in the next post)

Let’s start with Now Assist.

 

Building a Custom Skill with Now Assist

Since no OOTB skill fits our needs, I created a custom one.

Go to the Now Assist Skill Kit console and create a new skill. Give it a name and description, and choose the provider. In my case, I used Now LLM, but you can select another provider if needed.

Next, add the input fields your prompt will use. I added two:

  • Short Description

  • Description

AlisaTipisova_0-1749135363281.png

AlisaTipisova_1-1749135377748.png

 

Click “Go to summary” and you’ll land on the screen where you can write and configure your prompt.

 

Writing the Prompt

Here’s the prompt I came up with (ChatGPT helped me generate it):

You are an AI assistant that analyzes IT incident tickets and extracts the most relevant topics based on the incident's short description and full description.
Identify the specific systems, services, technologies, components, or error types involved in the incident.
Use the provided list of existing keywords to map relevant topics. If the incident clearly involves a new topic not covered by any existing keyword, you may add a new concise keyword that follows the same style.
Focus on what the issue is about, not the symptoms.
Use concise, domain-relevant terms (e.g., “VPN connectivity”, “Outlook sync failure”, “Access denied for shared folder”).
If multiple distinct issues are described, list each as a separate topic.
Avoid generic words like "issue", "problem", or phrases like "user cannot access".

Output the result as a JSON array of strings.

Input:
Short Description: {{short_description}}
Description: {{description}}
Existing Keywords:  {{GetExistingKeywords.output}} 

Output example:
[  
  "Email delivery failure",  
  "Outlook calendar sync",  
  "Active Directory group permissions"  
]

 

The prompt includes:

  • Clear instructions for what the skill should do

  • Format expectations (JSON for easy parsing)

  • Input variables: short_description, description, and GetExistingKeywords.output (more on this in a moment)

  • Example output to guide the LLM’s response style

  • Rules to avoid generic or vague wording

 

AlisaTipisova_0-1749140888321.png

 

Reusing Existing Keywords

To make sure Now Assist doesn’t invent new keywords every time, I added logic to reuse existing ones.

🔍 By this point, I had already created a custom table to store keywords and their related incident records. The table has two fields: keyword and record.

To retrieve existing keywords, I created a Tool in the Skill Kit:

  1. Go to the Tool Editor tab

  2. Click the + icon before the prompt node

  3. Create a Script Tool node

AlisaTipisova_3-1749136698940.png

 

Choose “Write my own script” and paste in something like this:

(function runScript(context) {
    /*  {Object} context - Execution context, which may include:*/
    /*                         - Previous tool outputs/inputs (e.g., context['ToolName.attributeName'] or context.getValue('ToolName.attributeName')).*/
    /*                         - Additional context information (e.g., context.getAllValues()).*/
    /* @returns {Object} - The computed value for the attribute.*/
    var kwGr = new GlideAggregate('sn_itsm_gen_ai_ai_key_topics');
    kwGr.addAggregate('COUNT');
    kwGr.groupBy('u_keyword');
    kwGr.query();

    var items = [];
    while (kwGr.next()) {
        items.push(kwGr.u_keyword.getDisplayValue());
    }
    
    return {"keywords": items.toString()};
})(context);

 

AlisaTipisova_4-1749137815058.png

 

Then return to the Prompt Editor, click “Insert inputs”, and add the output from this script to your prompt.

 

Publishing the Skill

Once everything is set up:

  1. Click “Finalize prompt”

  2. Go to the Skill Settings tab

  3. Under Deployment Settings, choose how the skill should be triggered

For this use case, I selected Flow Action, since the skill should run automatically when an incident is created.

Finally, publish the skill and activate it from the Now Assist Admin console (under ITSM).

AlisaTipisova_5-1749138372437.png

AlisaTipisova_7-1749138848280.png

 

Automating with a Flow

The skill is ready and can analyze data—but to make it actually do something, we need to automate the process.

I created a simple Flow triggered when an incident is created. It:

  • Calls the skill

  • Waits for the keywords list

  • Parses the result

  • Inserts records into the keywords table

AlisaTipisova_1-1749139601846.png

 

I also built a custom action called “Parse AI Keywords”, which parses the skill’s JSON response and saves it to the table:

 

(function execute(inputs, outputs) {

    var modelOutput = (JSON.parse(inputs.KeywordsJson)).model_output;
    var keywords = JSON.parse(modelOutput.replace(/\n/g, '')).topics;

    for (var i in keywords) {
        var grKeyword = new GlideRecord('sn_itsm_gen_ai_ai_key_topics');
        grKeyword.initialize();
        grKeyword.u_keyword = keywords[i];
        grKeyword.u_record = inputs.RecordId;
    }

})(inputs, outputs);

 

AlisaTipisova_0-1749139552511.png

 

Final Thoughts

Now everything is in place:

  • Incidents are analyzed automatically

  • Keywords are extracted and stored

  • Long-term trends can be tracked and reported

It’s a lightweight but powerful setup—using just Now Assist, one custom table, and one Flow.

In the next post, I’ll show how to do something similar using Custom AI Agents.

 

1 Comment