AI Triage
The AI triage pipeline is the core intelligence layer of the ITSM platform. It processes incoming tickets through a multi-stage classification system: intent classification across 15+ intent types, priority assignment via an Impact x Urgency matrix, entity extraction for 22+ entity types (including Polish-specific identifiers like PESEL, NIP, and IBAN), semantic similarity search against previously resolved tickets, and a final routing decision. All stages are backed by real LLM API calls with tracked token usage.
The triage result model
When a ticket is triaged, the AI pipeline returns a structured result containing the routing decision, classification details, extracted entities, and similar resolved tickets. Every triage result includes token usage metrics for cost tracking and observability.
Properties
- Name
decision- Type
- string
- Description
The routing decision:
auto_resolve(confidence >= 0.7),agent_assist(confidence >= 0.5), orescalate(confidence < 0.5).
- Name
confidence- Type
- number
- Description
Overall confidence score between 0 and 1, aggregated across all classification stages.
- Name
intent- Type
- object
- Description
Intent classification result containing
type(e.g.,incident_report,service_request,password_reset),confidencescore, andalternativesarray of other likely intents.
- Name
priority- Type
- object
- Description
Priority classification containing
level(P1-P5),impact(critical, high, medium, low),urgency(critical, high, medium, low), andsla_targetin minutes. VIP and security adjustments are applied automatically.
- Name
entities- Type
- array
- Description
Extracted entities, each with
type(e.g.,email,hostname,pesel,nip,iban),value,confidencescore, andpositionoffset in the source text.
- Name
similar_tickets- Type
- array
- Description
Previously resolved tickets found via semantic search in Qdrant, each with
id,title,similarityscore (cosine), andresolutiontext.
- Name
suggested_category- Type
- string
- Description
AI-suggested ITSM category for the ticket (e.g.,
hardware,software,network,access_management).
- Name
suggested_team- Type
- string
- Description
Recommended team for routing (e.g.,
l1_support,network_ops,security,desktop_engineering).
- Name
token_usage- Type
- object
- Description
LLM token consumption for this triage, containing
inputtokens,outputtokens,totaltokens, andcostin USD.
Triage a ticket
Submit a ticket for AI triage. You can provide either a ticketId referencing an existing ticket in the database, or a raw title and description for ad-hoc classification. The pipeline runs intent classification, priority assignment, entity extraction, similarity search, and routing in sequence, returning the full triage result.
Required attributes
- Name
ticketId- Type
- string
- Description
The ID of an existing ticket to triage. Mutually exclusive with
title/description.
Alternative attributes
- Name
title- Type
- string
- Description
Ticket title for ad-hoc triage (used when no
ticketIdis provided).
- Name
description- Type
- string
- Description
Ticket description for ad-hoc triage (used when no
ticketIdis provided).
Request
curl -X POST http://localhost:3000/v1/ai/triage \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"ticketId": "tkt_01J5K9QRMX3BVGY7HNDCWZ48TP"
}'
Response
{
"decision": "agent_assist",
"confidence": 0.62,
"intent": {
"type": "incident_report",
"confidence": 0.87,
"alternatives": [
{ "type": "service_request", "confidence": 0.09 },
{ "type": "change_request", "confidence": 0.04 }
]
},
"priority": {
"level": "P2",
"impact": "high",
"urgency": "high",
"sla_target": 240
},
"entities": [
{
"type": "hostname",
"value": "srv-prod-db-03",
"confidence": 0.95,
"position": 42
},
{
"type": "email",
"value": "jan.kowalski@acme.pl",
"confidence": 0.99,
"position": 118
},
{
"type": "error_code",
"value": "ORA-12541",
"confidence": 0.91,
"position": 203
}
],
"similar_tickets": [
{
"id": "tkt_01J4WMRVN8HAXJFGQ2C6YB39KE",
"title": "Database connection timeout on srv-prod-db-03",
"similarity": 0.89,
"resolution": "Restarted Oracle listener service and increased connection pool max_size from 50 to 100 in /etc/oracle/listener.ora."
},
{
"id": "tkt_01J3NP8KFX6DTYRW2B7QHSV5MA",
"title": "Intermittent ORA-12541 errors on production DB cluster",
"similarity": 0.74,
"resolution": "Root cause was network switch failover. Applied static route and restarted TNS listener."
}
],
"suggested_category": "database",
"suggested_team": "dba_operations",
"token_usage": {
"input": 847,
"output": 312,
"total": 1159,
"cost": 0.0023
}
}
Triage a ticket (ad-hoc)
You can also triage a ticket without saving it to the database first by providing raw title and description fields. This is useful for previewing AI classification in real-time, such as while a user is filling out a ticket form.
Request
curl -X POST http://localhost:3000/v1/ai/triage \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"title": "Cannot reset password for Active Directory account",
"description": "User anna.nowak@acme.pl reports she is locked out of her AD account after 5 failed login attempts. PESEL 85010212345. Needs immediate access for month-end financial reporting deadline."
}'
Response
{
"decision": "auto_resolve",
"confidence": 0.84,
"intent": {
"type": "password_reset",
"confidence": 0.93,
"alternatives": [
{ "type": "access_request", "confidence": 0.05 },
{ "type": "account_unlock", "confidence": 0.02 }
]
},
"priority": {
"level": "P3",
"impact": "medium",
"urgency": "high",
"sla_target": 480
},
"entities": [
{
"type": "email",
"value": "anna.nowak@acme.pl",
"confidence": 0.99,
"position": 5
},
{
"type": "pesel",
"value": "85010212345",
"confidence": 0.97,
"position": 112
},
{
"type": "system",
"value": "Active Directory",
"confidence": 0.94,
"position": 32
}
],
"similar_tickets": [
{
"id": "tkt_01J2FHG5NR9PAWQXV4T8CK7YMB",
"title": "AD account lockout after failed password attempts",
"similarity": 0.92,
"resolution": "Unlocked account via ADUC, reset password, and cleared lockout counter. Reminded user of password policy."
}
],
"suggested_category": "access_management",
"suggested_team": "l1_support",
"token_usage": {
"input": 623,
"output": 289,
"total": 912,
"cost": 0.0018
}
}
Batch triage
Submit multiple tickets for triage in a single request. The pipeline processes each ticket independently through all classification stages. Results are returned in the same order as the input ticketIds array. Batch triage is processed via BullMQ for reliability and retry handling.
Required attributes
- Name
ticketIds- Type
- array
- Description
Array of ticket IDs to triage. Maximum 50 tickets per batch request.
Request
curl -X POST http://localhost:3000/v1/ai/triage/batch \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"ticketIds": [
"tkt_01J5K9QRMX3BVGY7HNDCWZ48TP",
"tkt_01J5KA2FNX7CQWRM4D9HYTV6PB",
"tkt_01J5KA8GTY4DPZSN6E2JKVW7RC"
]
}'
Response
{
"batch_id": "batch_01J5KBCNRX8FQWTYV3D2HMZS9P",
"total": 3,
"completed": 3,
"failed": 0,
"results": [
{
"ticketId": "tkt_01J5K9QRMX3BVGY7HNDCWZ48TP",
"decision": "agent_assist",
"confidence": 0.62,
"intent": { "type": "incident_report", "confidence": 0.87 },
"priority": { "level": "P2", "impact": "high", "urgency": "high", "sla_target": 240 },
"suggested_category": "database",
"suggested_team": "dba_operations"
},
{
"ticketId": "tkt_01J5KA2FNX7CQWRM4D9HYTV6PB",
"decision": "auto_resolve",
"confidence": 0.91,
"intent": { "type": "password_reset", "confidence": 0.96 },
"priority": { "level": "P4", "impact": "low", "urgency": "medium", "sla_target": 1440 },
"suggested_category": "access_management",
"suggested_team": "l1_support"
},
{
"ticketId": "tkt_01J5KA8GTY4DPZSN6E2JKVW7RC",
"decision": "escalate",
"confidence": 0.34,
"intent": { "type": "security_incident", "confidence": 0.41 },
"priority": { "level": "P1", "impact": "critical", "urgency": "critical", "sla_target": 60 },
"suggested_category": "security",
"suggested_team": "security_ops"
}
],
"token_usage": {
"input": 2541,
"output": 936,
"total": 3477,
"cost": 0.0069
}
}
Get triage metrics
Retrieve aggregated triage metrics including decision distribution, average confidence scores, classification accuracy, and token usage over time. Useful for monitoring AI performance and cost tracking in dashboards.
Optional attributes
- Name
period- Type
- string
- Description
Time period for aggregation:
1h,24h,7d,30d. Defaults to24h.
- Name
team- Type
- string
- Description
Filter metrics by suggested team.
Request
curl -G http://localhost:3000/v1/ai/triage/metrics \
-H "Authorization: Bearer {token}" \
-d period=24h
Response
{
"period": "24h",
"total_triaged": 847,
"decisions": {
"auto_resolve": 412,
"agent_assist": 298,
"escalate": 137
},
"avg_confidence": 0.71,
"accuracy": {
"intent_classification": 0.89,
"priority_assignment": 0.82,
"routing_accuracy": 0.76
},
"intent_distribution": {
"incident_report": 287,
"service_request": 194,
"password_reset": 132,
"change_request": 78,
"information_request": 61,
"access_request": 45,
"hardware_request": 28,
"security_incident": 12,
"other": 10
},
"priority_distribution": {
"P1": 18,
"P2": 124,
"P3": 389,
"P4": 247,
"P5": 69
},
"avg_processing_time_ms": 1847,
"token_usage": {
"total_input": 714293,
"total_output": 263841,
"total_tokens": 978134,
"total_cost": 1.96
}
}
AI Chat
Send a message to the ITSM AI assistant. The assistant can answer questions about IT policies, troubleshoot common issues, and guide users through service request workflows. Conversations are tracked by conversationId for multi-turn context.
Required attributes
- Name
message- Type
- string
- Description
The user message to the AI assistant.
Optional attributes
- Name
conversationId- Type
- string
- Description
ID of an existing conversation for multi-turn context. Omit to start a new conversation.
Request
curl -X POST http://localhost:3000/v1/ai/chat \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"message": "My laptop screen is flickering after the latest Windows update. What should I try before submitting a ticket?",
"conversationId": "conv_01J5KC7NRX2FQWTYV3D8HMZS4A"
}'
Response
{
"conversationId": "conv_01J5KC7NRX2FQWTYV3D8HMZS4A",
"response": "Screen flickering after a Windows update is commonly caused by an incompatible display driver. Here are the steps to try before submitting a ticket:\n\n1. Restart in Safe Mode - Press Shift while clicking Restart, then navigate to Troubleshoot > Advanced > Startup Settings > Safe Mode.\n2. Roll back the display driver - Open Device Manager > Display adapters > right-click your GPU > Properties > Driver > Roll Back Driver.\n3. Uninstall the recent update - Go to Settings > Update and Security > View update history > Uninstall updates, and remove the latest one.\n4. Restart Desktop Window Manager - Open Task Manager, find Desktop Window Manager, and restart it.\n\nIf none of these resolve the issue, I can create a P3 hardware ticket and route it to Desktop Engineering.",
"suggested_actions": [
{
"label": "Create a ticket",
"action": "create_ticket",
"params": { "category": "hardware", "subcategory": "display" }
},
{
"label": "Escalate to Desktop Engineering",
"action": "escalate",
"params": { "team": "desktop_engineering" }
}
],
"token_usage": {
"input": 312,
"output": 487,
"total": 799,
"cost": 0.0016
}
}
Semantic search
Perform a semantic (vector) search against a specified Qdrant collection. The query text is embedded and compared against stored vectors using cosine similarity. This powers the knowledge base search, ticket deduplication, and similar-issue detection features.
Required attributes
- Name
query- Type
- string
- Description
The natural-language search query to embed and match against.
- Name
collection- Type
- string
- Description
The Qdrant collection to search:
tickets,knowledge_base, orrunbooks.
Optional attributes
- Name
limit- Type
- integer
- Description
Maximum number of results to return. Defaults to 10, maximum 100.
- Name
threshold- Type
- number
- Description
Minimum cosine similarity score (0-1). Defaults to 0.5.
- Name
filters- Type
- object
- Description
Qdrant payload filters to narrow results (e.g.,
{ "status": "resolved" }).
Request
curl -X POST http://localhost:3000/v1/ai/search/semantic \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"query": "Oracle database connection timeout on production server",
"collection": "tickets",
"limit": 5,
"threshold": 0.6
}'
Response
{
"query": "Oracle database connection timeout on production server",
"collection": "tickets",
"results": [
{
"id": "tkt_01J4WMRVN8HAXJFGQ2C6YB39KE",
"score": 0.91,
"payload": {
"title": "Database connection timeout on srv-prod-db-03",
"status": "resolved",
"category": "database",
"resolution": "Restarted Oracle listener service and increased connection pool max_size from 50 to 100.",
"resolved_at": "2025-11-14T09:23:00Z"
}
},
{
"id": "tkt_01J3NP8KFX6DTYRW2B7QHSV5MA",
"score": 0.84,
"payload": {
"title": "Intermittent ORA-12541 errors on production DB cluster",
"status": "resolved",
"category": "database",
"resolution": "Root cause was network switch failover. Applied static route and restarted TNS listener.",
"resolved_at": "2025-10-28T14:47:00Z"
}
},
{
"id": "tkt_01J2R6YMDW3BQNXHK7T5PCVF8A",
"score": 0.77,
"payload": {
"title": "Connection pool exhaustion on Oracle RAC node 2",
"status": "resolved",
"category": "database",
"resolution": "Identified long-running queries holding connections. Killed sessions and added connection timeout of 30s.",
"resolved_at": "2025-09-19T11:05:00Z"
}
}
],
"total_found": 3,
"search_time_ms": 47
}
Similar tickets
Find tickets that are semantically similar to a given ticket. This endpoint embeds the source ticket title and description, then performs a cosine similarity search against all indexed tickets in Qdrant. Results include the resolution text from previously resolved tickets, enabling auto-resolve suggestions and knowledge reuse.
Required attributes
- Name
ticketId- Type
- string
- Description
The ID of the ticket to find similar matches for.
Optional attributes
- Name
limit- Type
- integer
- Description
Maximum number of similar tickets to return. Defaults to 5, maximum 20.
- Name
status- Type
- string
- Description
Filter by ticket status:
resolved,open,in_progress, orall. Defaults toresolved.
Request
curl -X POST http://localhost:3000/v1/ai/similar-tickets \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"ticketId": "tkt_01J5K9QRMX3BVGY7HNDCWZ48TP",
"limit": 3
}'
Response
{
"ticketId": "tkt_01J5K9QRMX3BVGY7HNDCWZ48TP",
"similar": [
{
"id": "tkt_01J4WMRVN8HAXJFGQ2C6YB39KE",
"title": "Database connection timeout on srv-prod-db-03",
"similarity": 0.89,
"status": "resolved",
"category": "database",
"resolution": "Restarted Oracle listener service and increased connection pool max_size from 50 to 100 in /etc/oracle/listener.ora.",
"resolved_at": "2025-11-14T09:23:00Z",
"resolved_by": "marek.wisniewski@acme.pl"
},
{
"id": "tkt_01J3NP8KFX6DTYRW2B7QHSV5MA",
"title": "Intermittent ORA-12541 errors on production DB cluster",
"similarity": 0.74,
"status": "resolved",
"category": "database",
"resolution": "Root cause was network switch failover. Applied static route and restarted TNS listener.",
"resolved_at": "2025-10-28T14:47:00Z",
"resolved_by": "piotr.zielinski@acme.pl"
},
{
"id": "tkt_01J2R6YMDW3BQNXHK7T5PCVF8A",
"title": "Connection pool exhaustion on Oracle RAC node 2",
"similarity": 0.68,
"status": "resolved",
"category": "database",
"resolution": "Identified long-running queries holding connections. Killed sessions and added connection timeout of 30s.",
"resolved_at": "2025-09-19T11:05:00Z",
"resolved_by": "marek.wisniewski@acme.pl"
}
],
"search_time_ms": 52
}