关于 task-analysis
用于分析 ServiceNow 中的任务数据,帮助管理者掌握团队工作量、SLA 风险和运营瓶颈。它结合任务趋势、人员负载及重新分配建议,为排班和流程改进提供依据。
主要功能
- 01分析任务数量和状态趋势
- 02识别分配组瓶颈
- 03发现 SLA 违约风险
- 04分析个人工作量分布
- 05生成负载重新分配建议
适用场景
- 01准备每周运营评审数据
- 02找出即将超过 SLA 的任务
- 03了解新团队当前工作状况
MCP 相关
通过 ServiceNow MCP 工具查询任务、SLA 和分配信息,执行聚合与趋势计算,并将分析报告和建议写入记录。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ happy-technologies-llc/ happy-platform-skills --skill task-analysis安装后在 Claude Code 中输入/task-analysis确认已加载。
详细介绍
任务分析
概述
此技能可对 ServiceNow 中的任务数据进行全面分析,以识别运营模式并优化工作分配。涵盖以下内容:
- 分析
task、sc_task和planned_task表中的任务量趋势 - 识别任务量过高的瓶颈分配组和个人
- 通过分析
task_sla记录和当前任务时长,预测 SLA 违约 - 根据工作能力和技能匹配情况,提出工作量重新分配建议
- 生成包含关键绩效指标的任务健康状况仪表板
- 检测任务重新分配、升级和解决时间方面的模式
适用场景: 管理者需要了解团队工作量分布、SLA 合规情况呈下降趋势、需要为即将开展的项目规划能力,或需要识别任务处理中的系统性瓶颈时。
价值主张: 主动分析任务可防止 SLA 违约、平衡各团队的工作量,并为人员配置和流程改进决策提供数据依据。
前提条件
- 角色:
itil、task_admin、assignment_group_manager或admin - 访问权限: 对
task、sc_task、planned_task、task_sla、sys_user_group和sys_user表具有读取权限 - 知识: 了解任务生命周期状态、SLA 定义和组织的分配组结构
流程
第 1 步:评估当前任务量和状态分布
获取所有任务类型中活动任务的快照。
使用 MCP(Claude Code/Desktop):
Tool: SN-Execute-Background-Script
Parameters:
description: Task volume snapshot by type and state
script: |
var snapshot = { timestamp: new GlideDateTime().getDisplayValue(), task_types: [] };
var tables = ['incident', 'sc_task', 'change_request', 'problem', 'sc_req_item'];
tables.forEach(function(tableName) {
var typeData = { table: tableName, states: {} };
var ga = new GlideAggregate(tableName);
ga.addQuery('active', true);
ga.addAggregate('COUNT');
ga.groupBy('state');
ga.query();
var total = 0;
while (ga.next()) {
var state = ga.state.getDisplayValue();
var count = parseInt(ga.getAggregate('COUNT'));
typeData.states[state] = count;
total += count;
}
typeData.total_active = total;
snapshot.task_types.push(typeData);
});
gs.info(JSON.stringify(snapshot, null, 2));
使用 REST API(针对特定任务类型):
GET /api/now/table/sc_task?sysparm_query=active=true&sysparm_fields=sys_id,number,state,assignment_group,assigned_to,priority,opened_at,sla_due&sysparm_limit=100&sysparm_display_value=true
第 2 步:识别分配组瓶颈
找出任务量不成比例地偏高或任务积压时间过长的组。
使用 MCP:
Tool: SN-Execute-Background-Script
Parameters:
description: Identify bottleneck assignment groups
script: |
var bottlenecks = [];
var ga = new GlideAggregate('task');
ga.addQuery('active', true);
ga.addQuery('assignment_group', 'ISNOTEMPTY', '');
ga.addAggregate('COUNT');
ga.addAggregate('AVG', 'reassignment_count');
ga.groupBy('assignment_group');
ga.orderByAggregate('COUNT', 'DESC');
ga.query();
while (ga.next()) {
var groupId = ga.assignment_group.toString();
var count = parseInt(ga.getAggregate('COUNT'));
// Get average age of active tasks
var ageGa = new GlideAggregate('task');
ageGa.addQuery('active', true);
ageGa.addQuery('assignment_group', groupId);
ageGa.addAggregate('AVG', 'sys_mod_count');
ageGa.query();
var avgAge = 0;
if (ageGa.next()) {
avgAge = parseInt(ageGa.getAggregate('AVG', 'sys_mod_count'));
}
// Get group member count
var members = new GlideAggregate('sys_user_grmember');
members.addQuery('group', groupId);
members.addQuery('user.active', true);
members.addAggregate('COUNT');
members.query();
var memberCount = 0;
if (members.next()) memberCount = parseInt(members.getAggregate('COUNT'));
bottlenecks.push({
group: ga.assignment_group.getDisplayValue(),
active_tasks: count,
active_members: memberCount,
tasks_per_person: memberCount > 0 ? (count / memberCount).toFixed(1) : 'N/A',
avg_reassignments: parseFloat(ga.getAggregate('AVG', 'reassignment_count')).toFixed(1)
});
}
// Sort by tasks per person descending
bottlenecks.sort(function(a, b) {
return parseFloat(b.tasks_per_person) - parseFloat(a.tasks_per_person);
});
gs.info(JSON.stringify(bottlenecks.slice(0, 20), null, 2));
第 3 步:预测 SLA 违约
分析任务 SLA 记录,找出存在违约风险的任务。
使用 MCP:
Tool: SN-Query-Table
Parameters:
table_name: task_sla
query: stage=in_progress^has_breached=false^planned_end_time<=javascript:gs.hoursAgoEnd(-24)
fields: sys_id,task,task.number,task.short_description,task.assignment_group,task.assigned_to,task.priority,sla,planned_end_time,percentage,business_percentage,stage
limit: 50
order_by: planned_end_time
使用 REST API:
GET /api/now/table/task_sla?sysparm_query=stage=in_progress^has_breached=false^planned_end_time<=javascript:gs.hoursAgoEnd(-24)&sysparm_fields=sys_id,task,task.number,task.short_description,task.assignment_group,task.assigned_to,task.priority,sla,planned_end_time,percentage,business_percentage&sysparm_limit=50&sysparm_display_value=true
按组分析违约风险:
Tool: SN-Execute-Background-Script
Parameters:
description: SLA breach risk analysis by assignment group
script: |
var riskAnalysis = [];
var ga = new GlideAggregate('task_sla');
ga.addQuery('stage', 'in_progress');
ga.addQuery('has_breached', false);
ga.addQuery('business_percentage', '>=', 75);
ga.addAggregate('COUNT');
ga.groupBy('task.assignment_group');
ga.orderByAggregate('COUNT', 'DESC');
ga.query();
while (ga.next()) {
var group = ga.getValue('task.assignment_group');
var atRisk = parseInt(ga.getAggregate('COUNT'));
// Count already breached
var breached = new GlideAggregate('task_sla');
breached.addQuery('stage', 'in_progress');
breached.addQuery('has_breached', true);
breached.addQuery('task.assignment_group', group);
breached.addAggregate('COUNT');
breached.query();
var breachedCount = 0;
if (breached.next()) breachedCount = parseInt(breached.getAggregate('COUNT'));
riskAnalysis.push({
group: ga.getDisplayValue('task.assignment_group'),
at_risk_75_plus: atRisk,
already_breached: breachedCount,
total_exposure: atRisk + breachedCount
});
}
gs.info(JSON.stringify(riskAnalysis, null, 2));
第 4 步:分析个人工作量分布
检查分配组内每位团队成员的工作量。
使用 MCP:
Tool: SN-Execute-Background-Script
Parameters:
description: Individual workload analysis for assignment group
script: |
var groupId = '[group_sys_id]';
var workload = [];
var ga = new GlideAggregate('task');
ga.addQuery('active', true);
ga.addQuery('assignment_group', groupId);
ga.addQuery('assigned_to', 'ISNOTEMPTY', '');
ga.addAggregate('COUNT');
ga.groupBy('assigned_to');
ga.orderByAggregate('COUNT', 'DESC');
ga.query();
while (ga.next()) {
var userId = ga.assigned_to.toString();
// Get priority breakdown
var priorities = {};
var pa = new GlideAggregate('task');
pa.addQuery('active', true);
pa.addQuery('assigned_to', userId);
pa.addAggregate('COUNT');
pa.groupBy('priority');
pa.query();
while (pa.next()) {
priorities['P' + pa.priority.toString()] = parseInt(pa.getAggregate('COUNT'));
}
// Count tasks with SLA at risk
var slaRisk = new GlideAggregate('task_sla');
slaRisk.addQuery('task.assigned_to', userId);
slaRisk.addQuery('stage', 'in_progress');
slaRisk.addQuery('business_percentage', '>=', 75);
slaRisk.addAggregate('COUNT');
slaRisk.query();
var riskCount = 0;
if (slaRisk.next()) riskCount = parseInt(slaRisk.getAggregate('COUNT'));
workload.push({
user: ga.assigned_to.getDisplayValue(),
active_tasks: parseInt(ga.getAggregate('COUNT')),
priorities: priorities,
sla_at_risk: riskCount
});
}
// Unassigned tasks
var unassigned = new GlideAggregate('task');
unassigned.addQuery('active', true);
unassigned.addQuery('assignment_group', groupId);
unassigned.addQuery('assigned_to', 'ISEMPTY', '');
unassigned.addAggregate('COUNT');
unassigned.query();
var unassignedCount = 0;
if (unassigned.next()) unassignedCount = parseInt(unassigned.getAggregate('COUNT'));
var result = {
group: '[group_name]',
members: workload,
unassigned_tasks: unassignedCount
};
gs.info(JSON.stringify(result, null, 2));
第 5 步:分析任务随时间变化的趋势
跟踪任务创建、完成和积压增长趋势。
使用 MCP:
Tool: SN-Execute-Background-Script
Parameters:
description: Weekly task trend analysis
script: |
var trends = [];
for (var i = 7; i >= 0; i--) {
var weekStart = gs.daysAgoStart(i * 7);
var weekEnd = gs.daysAgoEnd((i - 1) * 7);
var week = { period: 'Week -' + i, created: 0, closed: 0, backlog: 0 };
// Created
var created = new GlideAggregate('task');
created.addQuery('opened_at', '>=', weekStart);
created.addQuery('opened_at', '<=', weekEnd);
created.addAggregate('COUNT');
created.query();
if (created.next()) week.created = parseInt(created.getAggregate('COUNT'));
// Closed
var closed = new GlideAggregate('task');
closed.addQuery('closed_at', '>=', weekStart);
closed.addQuery('closed_at', '<=', weekEnd);
closed.addAggregate('COUNT');
closed.query();
if (closed.next()) week.closed = parseInt(closed.getAggregate('COUNT'));
week.net_change = week.created - week.closed;
trends.push(week);
}
// Current backlog
var backlog = new GlideAggregate('task');
backlog.addQuery('active', true);
backlog.addAggregate('COUNT');
backlog.query();
var currentBacklog = 0;
if (backlog.next()) currentBacklog = parseInt(backlog.getAggregate('COUNT'));
var result = {
current_backlog: currentBacklog,
weekly_trends: trends
};
gs.info(JSON.stringify(result, null, 2));
第 6 步:生成工作量重新分配建议
根据分析结果,提出可执行的建议。
使用 MCP:
Tool: SN-Add-Work-Notes
Parameters:
table_name: sys_user_group
sys_id: [group_sys_id]
work_notes: |
=== TASK ANALYSIS & WORKLOAD REPORT ===
Group: Service Desk Team A
Date: 2026-03-19
CURRENT STATE:
- Active tasks: 87
- Unassigned: 12
- Members: 8 active
- Average per person: 10.9 tasks
WORKLOAD DISTRIBUTION:
- Alice Johnson: 18 tasks (5 P1/P2) - OVERLOADED
- Bob Smith: 15 tasks (3 P1/P2)
- Carol Davis: 12 tasks (2 P1/P2)
- Dan Wilson: 11 tasks (1 P1/P2)
- Eve Martinez: 10 tasks (2 P1/P2)
- Frank Lee: 8 tasks (0 P1/P2)
- Grace Chen: 7 tasks (1 P1/P2)
- Henry Patel: 6 tasks (0 P1/P2) - CAPACITY AVAILABLE
SLA RISK:
- 14 tasks at 75%+ SLA consumption (breach within 24 hours)
- 3 tasks already breached
- Highest risk: Alice Johnson (5 tasks at risk)
TRENDS (8 weeks):
- Creation rate: 45/week average (trending up +8%)
- Closure rate: 41/week average (stable)
- Backlog growing at ~4 tasks/week
RECOMMENDATIONS:
1. IMMEDIATE: Redistribute 5 tasks from Alice to Henry/Grace (capacity available)
2. IMMEDIATE: Assign 12 unassigned tasks prioritizing SLA-at-risk items
3. SHORT-TERM: Backlog growing - request 1 additional team member or cross-train
4. PROCESS: Investigate high reassignment rate (avg 2.3 per task) - routing rules may need tuning
工具用法
MCP 工具参考
| 工具 | 适用场景 |
|---|---|
SN-Query-Table | 查询任务、SLA、组和分配信息 |
SN-Get-Record | 获取单个任务或组的详细信息 |
SN-Natural-Language-Search | 查找符合自然语言描述的任务 |
SN-Execute-Background-Script | 执行复杂聚合、趋势分析和工作量计算 |
SN-Add-Work-Notes | 发布分析报告和建议 |
REST API 参考
| 端点 | 方法 | 用途 |
|---|---|---|
/api/now/table/task | GET | 查询所有类型的任务 |
/api/now/table/sc_task | GET | 专门查询目录任务 |
/api/now/table/planned_task | GET | 查询计划任务/项目任务 |
/api/now/table/task_sla | GET | 分析 SLA 状态和违约风险 |
/api/now/table/sys_user_group | GET | 获取分配组详细信息 |
/api/now/stats/task | GET | 使用 Stats API 在服务器端进行聚合 |
最佳实践
- 在恰当的层级进行分析: 使用特定任务表(
incident、sc_task)进行类型专属分析;使用task查看跨类型数据 - 按团队规模进行标准化: 始终同时展示人均任务数和总数,以识别真正的瓶颈
- 考虑工作时间: 进行 SLA 分析时,使用
task_sla中的business_percentage,而不是日历经过时间 - 查看重新分配模式: 重新分配次数过高表明存在路由或技能不匹配问题
- 单独跟踪未分配任务: 未分配任务是隐形瓶颈;务必将其列出
- 设置阈值警报: 定义明确的阈值(例如,每人 >15 个任务、SLA 消耗 >80%),用于自动警报
- 纳入容量因素: 分析工作负载时,应考虑带薪休假(PTO)、培训日和兼职安排
- 配套行动建议: 每次分析都应至少提出一条具体且可执行的建议
故障排除
任务计数与仪表板不符
原因: 仪表板可能使用了不同的筛选条件(例如,排除某些状态或任务类型) 解决方案: 将仪表板小组件使用的确切查询与分析查询进行比较。检查访问控制是否会针对不同用户筛选出不同结果。
SLA 数据出现意外值
原因: SLA 定义可能已更改,或者追溯附加 SLA 影响了计算结果
解决方案: 检查 task_sla.sla 引用,确认附加了正确的 SLA 定义。查看 has_breached 与 stage,以准确判断状态。
分配组成员人数不正确
原因: 非活跃用户可能仍是组成员,或者用户可能属于多个组
解决方案: 使用 user.active=true 筛选 sys_user_grmember,并检查是否存在重复成员关系。
趋势数据存在缺口
原因: 某些时段没有任务创建或关闭,或者数据归档移除了历史记录 解决方案: 在趋势输出中包含计数为零的时段。检查是否为任务表配置了表轮换或归档。
示例
示例 1:每周运营评审数据
输入:“为每周运营评审会议准备任务分析数据”
流程: 执行步骤 1、2、5 和 6,生成包含任务量、瓶颈、趋势和建议的综合快照。
示例 2:防止 SLA 违约
输入:“接下来 24 小时内哪些任务即将违反 SLA?”
Tool: SN-Query-Table
Parameters:
table_name: task_sla
query: stage=in_progress^has_breached=false^planned_end_time<=javascript:gs.hoursAgoEnd(-24)^planned_end_time>=javascript:gs.beginningOfToday()
fields: task.number,task.short_description,task.assigned_to,task.assignment_group,planned_end_time,business_percentage
limit: 30
order_by: planned_end_time
示例 3:新经理入职
输入:“我刚接管 Team B。请向我展示团队当前的工作状况。”
流程: 执行步骤 2、4 和 5,并筛选特定组,生成完整的工作负载概况,包括个人明细、SLA 风险和 8 周趋势。
相关技能
reporting/sla-analysis- 详细的 SLA 性能分析reporting/trend-analysis- 通用趋势分析功能reporting/executive-dashboard- 面向高管的报告itsm/incident-lifecycle- 事件专属任务管理catalog/request-fulfillment- 目录任务履行工作流admin/workflow-creation- 自动执行任务路由和升级