AI · Infra

AI 트리아지로 인입을 자동 분류하기

AI 트리아지(triage) 정책의 배경·설계·고도화·실제 사례를 정리했습니다.

이호수이호수
·
# Triage# Runbook
AI 트리아지로 인입을 자동 분류하기
date
slug
author
status
tags(최대 3개)
summary
type
thumbnail
category
updatedAt
notion image

트리아지란

본격적으로 들어가기 전에 트리아지라는 단어가 어디서 왔는지 짚고 가겠습니다.

원래는 응급실에서 쓰던 말입니다

트리아지(triage)의 원래 뜻은 응급 환자 분류입니다.
어원은 프랑스어 trier(고르다·선별하다)에서 왔고, 의료 분야에서 쓰이기 시작해 오늘날 응급의학에서는 보통 등급 분류로 표준화돼 있습니다.

인프라 운영에서는 이렇게 바뀝니다

notion image
이 개념은 DevOps, SRE 운영에도 꽤 자연스럽게 이어집니다. 응급실에서 환자 상태를 먼저 분류해 적절한 진료실로 보내듯, IT 운영에서는 인입된 알람이나 운영 티켓을 먼저 분류해 적절한 대응 흐름으로 넘깁니다.
여기서 응급실의 환자는 인입된 알람·운영 티켓이 되고, 부상의 심각도는 인시던트의 영향 범위와 긴급도가 되며, 처치 부서로 인계는 적절한 단일 런북으로 라우팅하는 과정에 가깝습니다.
그래서 P1/P2/P3/P4로 등급을 나누고, 가장 시급한 케이스부터 먼저 대응하며, 분류와 실제 처치를 분리한다는 원칙도 그대로 가져올 수 있습니다.
아임웹 인프라팀도 비슷한 흐름으로 장애와 운영 이슈를 대응해 왔습니다. 모니터링 알람이 발생하거나 CX팀을 통해 운영자 이슈가 할당되면, 먼저 영향 범위와 긴급도로 P-level을 판단하고 우선순위에 따라 대응하는 방식입니다.
한마디로, 응급실 간호사가 환자 부상도를 분류해 적절한 진료실로 보내듯, 인프라 인입 이슈를 트리아지로 분류해 적절한 런북으로 보낸다는 것입니다.

전체 흐름

먼저 트리아지가 어떻게 굴러가는지 한눈에 보여드리고, 디테일은 뒤에서 풀겠습니다. 핵심은 트리아지는 분류·라우팅만 하고, 진단·조치는 단일 런북 안에서 일어나며, 사용자 컨펌 없이는 외부 액션이 절대 발생하지 않는다는 점입니다.
notion image
한눈에는 단순한 라우팅처럼 보이지만, 실제로는 쿼리곰으로 사내 히스토리를 먼저 검색합니다. 쿼리곰으로 Slack, Jira, Notion 히스토리를 확인해 이게 처음 보는 패턴인지, 이미 처리한 적 있는 케이스인지를 구분합니다.
그 후 비슷한 사례를 찾고, 전체 런북을 같은 기준으로 평가한 뒤, 가장 매칭되는 후보와 판단 근거를 보여줍니다.
[입력] ├─ Slack URL / Jira URL → 원문 fetch ├─ 알람 메시지 / 자유 텍스트 → 그대로 사용 └─ 명시 키워드 (트리아지 분석해) ↓ [트리아지] 1. 입력 정규화 2. P-level 후보 신호 수집 3. 쿼리곰으로 Slack / Notion / Jira 히스토리 검색 4. frontmatter 기반 런북 카탈로그 동적 스캔 5. 모든 런북의 auto_signals 점수 계산 6. 후보 런북 + P-level + 판단 근거 제시 7. 사용자 컨펌 ├─ OK → 단일 런북 호출 ├─ 애매함 → 추가 확인 / observe └─ 매칭 없음 → propose-new
중요한 지점은 7번입니다. 트리아지가 아무리 강하게 후보를 제시해도, 실제 런북 호출이나 외부 액션은 사용자 컨펌 이후에만 진행됩니다.
AI는 히스토리를 찾고 런북 후보를 좁히는 데 집중하고, 최종 판단과 실행 책임은 사람이 가져갑니다.

온콜 체계에서 막혔던 지점

인프라팀은 신규 입사자를 포함해 새 온콜 체계 시범 운영을 시작했습니다. 그런데 이 체계가 굴러가려면 한 가지가 먼저 풀려야 했습니다. 1차 담당자가 어떤 인입을 받든 이건 어느 영역인가, 어떤 런북인가부터 막히면 안 된다는 점입니다.

아임웹 서비스 구조부터

수많은 고객사가 자기 도메인을 연결해 사이트를 운영하는 구조라, 인프라팀이 받는 인입은 내부 이벤트보다 외부에서 들어오는 이벤트가 많습니다.
notion image
동일한 보안·네트워크 인프라에 모든 고객사 사이트가 얹혀 있다 보니, 인입 건수 자체보다 케이스 타입의 다양성이 대응 부하의 주된 원인이었습니다.
그래서 인입 처리의 길목은 늘 이건 어느 영역인가라는 질문이었습니다. 비슷한 요청이 들어와도 매번 이거 어디서 봤더라부터 시작했다는 뜻이죠. 진짜 일은 그다음 단계인데, 정작 시간은 이게 어느 영역이지를 정하는 데 다 쓰이고 있었습니다.
필요했던 건 새 런북이 아니라, 들어온 요청을 같은 기준으로 빠르게 골라 주는 앞단의 길목이었습니다. 이 앞단의 길목을 코드로 옮긴 게 바로 트리아지입니다.

이미 좋은 런북은 많았습니다

아임웹 인프라팀에는 DDoS 대응, CF/SSL 스왑 대응, 보안 통보 대응, www SSL 대응처럼 이미 잘 정돈된 런북이 여러 개 있었습니다. 동료들이 새벽 장애·고객 응대·반복 사고를 직접 부딪혀가며 이 케이스는 다음에 이렇게 처리하자를 한 줄씩 써내려간 경험의 결정체입니다.

그런데 처음엔 어느 런북이지가 어려웠습니다

런북 품질과는 별개로 구조적 공통점이 하나 있었습니다. 모두 케이스 타입이 이미 식별된 상태에서 시작한다는 점입니다.
유형
시작 가정
DDoS 대응
“이게 DDoS다” 이미 결정됨
CF/SSL 스왑 대응
“특정 알람 코드다” 이미 결정됨
보안 통보 대응
“보안 기관 통보다” 이미 결정됨
www SSL 대응
www만 SSL 미적용이다” 이미 결정됨
합류한 지 얼마 안 된 사람에게는 이슈가 들어왔을 때 운영자 SSL 문의가 들어왔는데 이게 어디 영역이지, 내부 운영 도구 영역인가 CF 영역인가 하는 고민부터 막혔습니다.

만들게 된 계기

직접적인 계기가 있었습니다. 어느 고객사 도메인 이슈 관련 Slack 메시지를 제일 먼저 발견했는데, 과거에 비슷한 이슈가 어떻게 처리돼 왔는지 히스토리를 알 수 없으니 손을 못 댔고, 결국 다른 파트 멤버들이 처리하는 동안 기다리기만 했습니다.
이후 함께 모니터링하며 따라가 보니 진단 결과는 기존 어떤 런북에도 매칭되지 않는 새 패턴으로, 백엔드 R&D 인계 영역이었습니다.
notion image
가장 아쉬웠던 건, 다음 사람이 같은 케이스를 만나도 다시 처음부터 진행하게 된다는 점이었습니다. AI 없이 예전 방식대로 했다면 이 단계에 가장 많은 시간이 들었을 겁니다.
히스토리부터 더듬고, 관련 시스템과 코드를 한참 들여다본 다음에야 아 이건 백엔드 영역이구나 결론에 도달했겠죠.
아임웹 인프라팀은 AI를 잘 활용하는 조직인 만큼, 이번엔 팀이 매번 머릿속에서 돌리던 이 흐름을 하나의 프로세스로 녹여보고 싶었습니다.

그래서 이렇게 설계했습니다

설계할 때 지킨 세 가지

notion image
  1. 분류와 처치를 분리한다. 트리아지는 어떤 런북으로 갈지 판단하는 역할만 맡고, 실제 진단·조치는 각 런북 안에서 수행합니다.
  1. 모든 런북을 같은 기준으로 평가한다. 특정 케이스만 예외 처리하지 않고, frontmatter에 선언된 메타데이터와 auto_signals를 기준으로 전체 런북을 동일하게 평가합니다.
  1. 외부 액션 전에는 반드시 사람이 확인한다. Slack 회신, Jira 댓글, 운영 시스템 변경처럼 외부 영향이 있는 액션은 트리아지 결과만으로 자동 실행하지 않습니다.

키워드를 몰라도 알아차리게 만들었습니다

notion image
DDoS 트리아지 분석해 같은 키워드를 외워야만 발동된다면, 처음 합류한 사람에게는 그것 자체가 또 다른 진입 장벽이 됩니다.
그래서 Slack/Jira/알람 메시지만으로 자동 발동하도록 설계했습니다. 키워드는 명시적으로 부를 때 쓰는 보조 수단이고, 기본 동작은 메시지가 들어오면 알아서 분류 후보를 띄우는 것입니다.
대신 자동 발동에는 안전장치를 함께 걸었습니다.
  • 임계값은 false positive 최소화에 우선순위를 둠 → 확신이 낮으면 분류를 단정하지 않고 후보만 제시
  • 사용자 컨펌 없이는 외부 액션 0건 → 자동 발동돼도 Slack 회신/Jira 댓글/운영환경 변경은 사람 승인 전까지 절대 나가지 않음
요약하면 트리거는 적극적으로, 액션은 보수적으로라는 비대칭 기준으로 묶은 셈입니다.

런북 후보는 점수로 측정합니다

notion image
자동 인식 룰은 단순 키워드 매칭이 아니라 점수 기반으로 동작합니다. 각 런북은 frontmatter에 메타데이터를 선언하고, 트리아지는 입력 메시지, Slack/Jira 컨텍스트, 알람 내용, 그리고 사내 검색으로 찾은 과거 유사 사례를 기준으로 모든 런북을 평가합니다. 예를 들면 이렇게 점수를 더합니다.
  • 명확한 키워드 매칭: +3
  • 관련 채널 또는 시스템 매칭: +2
  • 과거 유사 사례 검색 결과와 매칭: +2
  • 배제 조건 또는 다른 런북에 더 가까운 신호: -3
최종 점수가 가장 높은 런북을 후보로 제시하되, 이 점수는 자동 실행을 위한 값이 아니라 왜 이 런북이 후보인지를 설명하는 근거입니다. 실제 실행은 사용자 컨펌 이후에만 진행됩니다.
예를 들어 특정 고객 도메인에서 www 접속 시 SSL 오류가 발생한다는 입력이 들어오면, 전체 런북을 평가해 www SSL 대응 런북을 가장 유력한 후보로 제시합니다. 반대로 최고 점수가 낮거나 후보 간 점수 차가 작다면, 기존 런북으로 확정하기 어렵다고 보고 새로운 제안(propose-new) 흐름으로 넘깁니다.

고도화

첫 번째, 런북 목록을 자동으로 읽게 했습니다

notion image
처음에는 런북 목록을 표 형태로 트리아지 정책 본문에 하드코딩했습니다. 그런데 금방 한계가 보였습니다. 신규 런북을 등록할 때마다 트리아지 본문을 같이 손대야 했고, 머지않아 카탈로그 drift(런북은 추가됐는데 트리아지는 모르는 상태)로 이어질 게 분명했습니다.
그래서 각 런북 파일 상단에 메타데이터를 선언하는 frontmatter 기반 동적 스캔 방식으로 바꿨습니다.
--- triage_runbook: true keyword: <Quick Command 키워드> severity: P2 # P1/P2/P3/P4 channels: # 등급 자동 추론용 (선택) - "<채널 식별자>" guards: # P1 한정 컨펌 전 근거 제시 (선택) - dual_location_check auto_signals: # 자동 인식 신호 (필수) - "<신호 1>" - "<신호 2>" --- # <런북 이름>
매 호출마다 정책 디렉토리의 모든 *.md를 스캔해 triage_runbook: true가 선언된 파일을 모아 카탈로그를 구성합니다. 이렇게 바꾼 뒤로 신규 런북 등록 시 트리아지 본문은 한 줄도 손대지 않습니다.

두 번째, P-level도 후보로 제시했습니다

notion image
팀은 매주 AI SyncUp 미팅을 진행하는데, 그 회의에서 트리아지 프로세스를 공유했습니다. 특히 설계 원칙으로 삼은 분석은 자동으로 하되 실제 액션은 사람이 하자는 취지에 많은 분이 공감해 주셨습니다.
이는 곧 자동 분류 결과로 외부 액션(Slack 회신/Jira 댓글/운영 시스템 변경)이 자동으로 일어나면 안 된다는 뜻이기도 합니다. 이 원칙을 등급 체계로 구체화한 게 P-level입니다. 중요한 건 P-level도 자동 확정값이 아니라 후보라는 점입니다.

세 번째, 새 패턴도 남기게 했습니다

notion image
운영하다 보면 매칭되는 런북이 없을 때가 종종 있었습니다. 사실 트리아지를 만든 직접적 계기였던 그 이슈도 결국 기존 런북에 매칭되지 않는 새 패턴이었습니다. 그래서 런북 매칭에 실패하면 새 런북을 생성하는 프로세스가 필요했습니다. 트리아지 분석 후 매칭이 없으면 다음 옵션을 띄웁니다.
(a) 1회용 분석/처리 — 상황 보고 그때그때 처리 (런북 안 만듦) (b) 신규 런북 만들기 검토 — 반복 발생 가능성 있는 패턴이라면 정식 등록 (c) 종료
트리아지에서 매칭 실패는 실패가 아니라 다음 런북 후보를 발견하는 신호로 취급했습니다. 기존 런북에 매칭되지 않는 패턴이 반복된다면, 그 자체가 운영 지식으로 누적돼야 합니다.
그래서 매칭 0건이 나오면 단순히 모르겠다로 끝내지 않고, 1회성 처리로 볼지, 신규 런북 후보로 등록할지, 종료할지를 선택하게 했습니다.
이 흐름 덕분에 새 패턴이 흩어지지 않고 결정 트리에 남아, 다음 사람이 같은 케이스를 만나면 처음부터 히스토리를 뒤지는 대신 이전 판단 근거를 출발점으로 삼을 수 있습니다.

실제로는 이렇게 쓰였습니다

설계·고도화 이야기가 길었으니, 실제 처리 사례 두 가지를 가볍게 보겠습니다. 하나는 매칭된 런북이 실행된 케이스, 다른 하나는 매칭이 안 돼 다른 파트로 인계된 케이스입니다.

매칭된 런북이 실행된 케이스 — ACM/SSL 만료 대응

CX팀으로부터 SSL을 정상 결제했는데 인증서 뷰어에 반영이 안 되고 사이트가 주의 요함으로 뜬다는 Jira 티켓이 등록됐습니다. 온콜 자동화 프로세스에 따라 온콜 담당자였던 제가 처리하게 됐고, 즉시 트리아지 분석을 시작했습니다.
트리아지는 SSL 만료, CF 인증서, 운영자 도메인을 기준으로 이슈를 평가했고, 기존에 등록된 ACM/SSL 만료 대응 런북을 최상위 후보로 제시하며 이유와 과거 사례를 함께 요약해 줬습니다.내용을 확인한 뒤 런북을 실행했고, 인증서가 이미 만료돼 HTTPS가 깨진 상태라는 결론을 확인할 수 있었습니다.

매칭이 안 돼 다른 파트로 인계된 케이스 — propose-new

타 스쿼드 채널에 위젯 추가 버튼이 안 눌린다는 메시지가 올라왔습니다. 즉시 트리아지 분석을 진행했고, 인프라 쪽 문제가 아니어서 모든 런북이 해당되지 않아 **propose-new(1회용 분석)**가 제안됐습니다.
결과적으로 인프라팀은 cross-check 보조만 하고, 스쿼드 쪽에서 해결할 수 있도록 상황을 파악해 결과만 전달해 이슈를 해결했습니다.

정리하며

트리아지를 도입한 뒤로 어디서부터 봐야 할지 모르겠다는 순간이 확실히 줄었습니다. 합류한 지 얼마 안 된 저뿐 아니라, 이슈 처리에 아직 익숙하지 않은 다른 팀원에게도 트리아지 하나로 동일한 품질의 답변이 생성되는 것이 가장 큰 변화였습니다.
이 프로세스를 구축하며 느낀 점은, AI에게 자유를 주는 게 아니라 좋은 울타리를 만들어 주는 일이 본질이라는 것입니다. 그리고 그 울타리는 혼자 만들 수 없습니다. 같은 방향을 바라보며 함께 쌓아 올린 동료들 덕분에, 혼자 잘하는 AI가 아니라 팀과 함께 나아가는 AI를 만들 수 있었습니다.
앞으로도 분야를 막론하고 AI로 문제를 해결할 여러 시도를 이어가려 합니다. 특히 팀이 매일 마주치는 작은 병목을 하나씩 줄이면서, 반복되는 판단과 경험이 더 나은 프로세스로 남도록 다듬고, 그 과정에서 배운 점도 계속 공유하겠습니다.

댓글