Stage 7 · Master
AIOps: Detection & Triage
Automated Triage & Routing
Classifying severity and paging the right team automatically.
The Triage Goal
Automated triage reduces the time from alert to the right team working on the fix. It classifies severity, determines which team owns the affected service, and provides initial context so the engineer does not start from zero.
Severity Classification
SEVERITY_PROMPT = """Classify this alert's severity.
Rules:
- P1: User-facing outage, data loss risk, security breach
- P2: Degraded performance, partial outage, no data loss
- P3: Non-urgent operational issue, cosmetic impact
- P4: Informational, no immediate action needed
Consider:
- Which service is affected?
- Is there user impact?
- What is the blast radius?
- Are there cascading effects?
Respond with JSON: {"severity": "P1-P4", "confidence": 0.0-1.0, "reasoning": "...", "affected_users": "none/partial/all"}"""
def classify_severity(alert):
response = openai.ChatCompletion.create(
model="gpt-4",
temperature=0.0,
messages=[
{"role": "system", "content": SEVERITY_PROMPT},
{"role": "user", "content": format_alert(alert)}
]
)
return json.loads(response["choices"][0]["message"]["content"])The LLM considers multiple factors — service criticality, user impact, blast radius — rather than relying on a single metric threshold.
Team Routing
# Explicit service ownership mapping
SERVICE_OWNERS = {
"checkout": "payments-team",
"payment-processor": "payments-team",
"search": "discovery-team",
"recommendations": "ml-team",
"kubernetes": "platform-team",
}
def route_alert(alert):
"""Route an alert to the correct team."""
service = alert.get("service", "").lower()
# Direct lookup first
if service in SERVICE_OWNERS:
return SERVICE_OWNERS[service]
# LLM-based routing for unknown services
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
temperature=0.0,
messages=[
{
"role": "system",
"content": f"Route this alert to one of these teams: {list(set(SERVICE_OWNERS.values()))}"
},
{"role": "user", "content": format_alert(alert)}
]
)
return response["choices"][0]["message"]["content"].strip()Use direct lookup for known services and LLM classification for ambiguous or new services. The LLM is a fallback, not the primary router.
The Triage Pipeline
class TriagePipeline:
def __init__(self):
self.correlator = AlertCorrelator()
self.classifier = SeverityClassifier()
self.router = TeamRouter()
self.context_enricher = ContextEnricher()
def triage(self, alert):
# Step 1: Correlate with recent alerts
cluster = self.correlator.add_and_cluster(alert)
if cluster.is_derived:
return {"action": "suppress", "reason": "Derived from root alert"}
# Step 2: Classify severity
severity = self.classifier.classify(alert)
# Step 3: Route to team
team = self.router.route(alert)
# Step 4: Enrich with context
context = self.context_enricher.enrich(alert)
# Step 5: Create or update incident
incident = {
"severity": severity,
"team": team,
"context": context,
"alerts": cluster.alerts,
}
# Step 6: Page on-call for P1 and P2
if severity["severity"] in ["P1", "P2"]:
page_oncall(team, incident)
return incidentThe pipeline processes each alert through correlation, classification, routing, and enrichment before deciding whether to page.
Learning from Triage
- Track when engineers override severity classifications to improve the model.
- Monitor routing accuracy — how often does the alert go to the wrong team first?
- Measure time-to-acknowledge before and after automated triage.
- Review false positive and false negative rates monthly.
Begin by classifying severity without automated routing. Once classification accuracy exceeds 90%, add automated routing to the most common services.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.