5. 왜 죽었는가 — RCA 자동화와 환각 방지
LLM 기반 근본 원인 분석(RCA)의 핵심 - 프롬프트 5단계 진화와 환각 방지 전략. Meta의 접근법과 실전 RCA 파이프라인을 설계합니다.
장애가 감지됐다. 서버가 이상하다는 건 알겠다. 그 다음 질문은 하나다. "왜?"
RCA(Root Cause Analysis)는 SRE 업무에서 가장 어렵고 시간이 오래 걸리는 작업이다. 여러 시스템의 로그, 메트릭, 변경 이력을 종합해서 원인을 추론해야 한다. 시니어 엔지니어가 경험과 직감으로 하는 일이다.
LLM이 이걸 도울 수 있다. 그런데 문제가 하나 있다. LLM은 환각을 일으킨다. 존재하지 않는 파일 경로를 원인으로 지목하기도 한다. 일반 대화에서 환각은 불편한 정도지만, RCA에서 환각은 장애를 키울 수 있다. 엔지니어가 없는 파일을 찾느라 30분을 낭비하는 동안, 진짜 원인은 방치된다.
이 편에서는 RCA 프롬프트를 5단계로 개선하면서, 환각을 어떻게 막는지를 다룬다.
프롬프트 5단계 진화
같은 장애에 대해 프롬프트를 바꿔가면서, 분석 품질이 어떻게 달라지는지 보자. 시나리오는 이거다.
web-01 서버에서 Java API 서비스가 OOM으로 종료됐다. 2시간 전에 v2.3.2를 배포했고, 배포 후 메모리 사용량이 서서히 증가했다.
- v1: 단순 질문. "java.lang.OutOfMemoryError가 났어. 왜?"
이렇게 물어보면 일반적인 OOM 원인을 나열한다. "힙 사이즈를 늘려보세요" 같은 뻔한 답이 나온다. 우리 환경의 맥락이 전혀 없으니까.
- v2: 역할 부여 + 컨텍스트. "당신은 10년 경력의 Linux 시스템 엔지니어입니다"로 시작하고, 에러 로그 + 시스템 상태(메모리 14.8GB/16GB, JVM -Xmx4g) + 최근 변경(2시간 전 v2.3.2 배포)을 함께 넣는다.
역할을 부여하면 전문적인 시각으로 답하고, 컨텍스트를 주면 구체적인 분석이 가능해진다.
- v3: Chain-of-Thought. 단계별 추론을 강제한다.
반드시 아래 순서로 추론하라:
Step 1. 증상 정리 — 무엇이 발생했는가
Step 2. 타임라인 — 시간순 이벤트 나열
Step 3. 가설 수립 — 가능한 원인 3가지
Step 4. 증거 매칭 — 각 가설에 대해 제공된 데이터에서 근거 찾기
Step 5. 결론 — 가장 가능성 높은 원인
Step 6. 조치 방안이게 핵심이다. "가설 → 증거 매칭" 단계가 있으면, 근거 없는 결론을 내리기 어렵다. LLM이 "생각하는 과정"을 거치게 만드는 거다.
- v4: RAG로 과거 이력 포함. v3 프롬프트에 3편에서 만든 RAG 검색 결과를 추가한다. "과거 유사 장애: 2024-03에 api-02에서 OOM 발생, BatchProcessor 메모리 릭이 원인, 스트리밍 처리로 수정"이라는 정보가 들어가면, LLM이 "이전에도 같은 서비스에서 비슷한 패턴이 있었다"는 맥락을 활용한다.
- v5: 환각 방지 장치 추가.
중요 규칙:
- 제공된 데이터에 근거가 없는 추측은 "불확실:" 접두어를 붙여라
- 파일 경로, 설정값은 제공된 정보에서 확인된 것만 언급해라
- 확인할 수 없는 사항은 "확인 필요:"로 표시해라
- 각 결론에 신뢰도(높음/중간/낮음)를 표시해라"모르면 모른다고 해라"를 명시하면 환각이 상당히 줄어든다. 특히 "불확실:" 접두어를 쓰게 하면, 검증이 필요한 부분을 명확히 구분할 수 있다.
v1에서 v5까지 프롬프트만 바꿨을 뿐인데, 분석의 정확도와 실용성이 완전히 달라진다.
같은 OOM 장애에 v1과 v5를 비교하면 차이가 이렇다.
v1의 응답:
Java OutOfMemoryError는 JVM 힙 메모리가 부족할 때 발생합니다.
해결 방법:
1. -Xmx 값을 늘려보세요
2. 메모리 누수를 확인하세요
3. GC 튜닝을 고려하세요교과서 답안이다. 우리 환경에서 뭘 해야 하는지는 모른다.
v5의 응답:
Step 1. 증상: api-service가 OOM으로 종료. JVM 힙 4GB 중 전량 사용.
Step 2. 타임라인:
12:00 v2.3.2 배포 (BatchProcessor 기능 추가)
12:30 메모리 75% → 13:00 82% → 13:30 88% → 14:03 92% → OOM
Step 3. 가설:
(1) v2.3.2의 BatchProcessor에서 메모리 릭 [신뢰도: 높음]
(2) 동시 요청 급증으로 인한 일시적 메모리 부족 [신뢰도: 낮음]
(3) GC 설정 문제 [신뢰도: 낮음]
Step 4. 증거:
- 가설 1: 배포 직후부터 메모리가 선형 증가. BatchProcessor.java:142에서 에러.
과거 유사 사례(2024-03)에서도 같은 클래스에서 메모리 릭 발생.
- 가설 2: 확인 필요: 해당 시간대 요청량 데이터가 제공되지 않음.
- 가설 3: 근거 없음. GC 로그가 제공되지 않아 판단 불가.
Step 5. 결론: 가설 1이 가장 가능성 높음. [신뢰도: 높음]
Step 6. 조치:
즉시: systemctl restart api-service
항구적: BatchProcessor의 대량 데이터 처리를 스트리밍 방식으로 수정
확인 필요: 배포 전후 요청량 비교, GC 로그 확인같은 모델이다. 프롬프트가 다를 뿐이다. v5의 응답에는 "확인 필요"가 명시되어 있고, 신뢰도가 표시되어 있다. 엔지니어가 이걸 보고 "가설 1을 먼저 확인하고, 가설 2는 요청량 데이터를 뽑아서 추가 확인하자"고 판단할 수 있다.
환각이 위험한 이유
일반 대화에서 LLM이 약간 부정확해도 큰 문제가 안 된다. 하지만 RCA에서 환각은 다르다.
실제로 이런 일이 일어난다.
LLM: "/etc/nginx/conf.d/upstream.conf 파일의 max_connections 값이
100으로 설정되어 있어 커넥션 풀이 고갈된 것으로 보입니다."
현실: 그 파일이 존재하지 않는다.엔지니어가 그 파일을 찾느라 시간을 쓰고, 없는 걸 확인하고, 다시 원점에서 조사를 시작한다. 새벽 3시에 이런 일이 벌어지면 MTTR이 30분 이상 늘어난다.
환각이 잘 발생하는 상황은 정해져 있다. 정보가 불충분할 때(로그 일부만 제공). 구체적인 파일 경로, 설정값, 포트 번호를 물어볼 때. 프롬프트가 "확실한 답을 내야 한다"는 압박을 줄 때.
환각 방지 5가지 전략
| 전략 | 방법 | 효과 |
|---|---|---|
| 근거 요구 | "어떤 로그에서 이 결론을 내렸는지 인용해라" | 높음 |
| 불확실 표시 | "확실하지 않으면 '불확실:'로 표시해라" | 높음 |
| RAG 병행 | 실제 과거 이력/문서를 컨텍스트에 포함 | 높음 |
| 교차 검증 | 같은 질문을 두 번 보내서 답이 일치하는지 확인 | 중간 |
| 신뢰도 점수 | "각 결론에 신뢰도를 표시해라" | 중간 |
가장 효과적인 건 근거 요구와 불확실 표시를 같이 쓰는 것이다. LLM이 "이 결론은 로그 3번째 줄의 OOM 에러에서 도출했다"고 밝히게 하면, 근거 없이 지어내기가 어렵다.
경로 B를 쓰는 경우 특히 주의해야 한다. 오픈소스 모델은 Claude보다 환각률이 높다. v5 수준의 환각 방지 프롬프트가 필수다. 경로 A(Claude)는 상대적으로 환각이 적지만, 없는 건 아니다. 어느 경로든 환각 방지는 넣어야 한다.
Meta의 접근법 — 재현성과 설명 가능성
Meta가 2025년에 공개한 "DrP(Doctor P)" 플랫폼이 환각 관리의 좋은 사례다.
DrP에서 엔지니어는 SDK로 자동화 플레이북(analyzer)을 작성한다. 장애 발생 시 이 플레이북이 자동 실행되면서, 규칙 기반 분석 + 통계 분석 + LLM 기반 RCA를 결합한다.
핵심 원칙이 두 가지다.
- 재현성 — 같은 데이터를 넣으면 같은 결과가 나와야 한다.
- 설명 가능성 — 왜 이 결론을 내렸는지 엔지니어가 독립적으로 검증할 수 있어야 한다.
이 원칙이 환각에 대한 가드레일이 된다. "이 분석 결과를 엔지니어가 재현할 수 있는가?"를 기준으로, 재현 불가능한 결론은 신뢰하지 않는 구조다.
전체 RCA 파이프라인
3~5편의 내용을 조합하면 전체 파이프라인이 완성된다.
[장애 감지] (4편)
│
▼
[데이터 수집]
├── 에러 로그 수집 + 전처리 (3편)
├── Prometheus 메트릭/알림
└── 최근 변경 이력 (배포, 설정 변경)
│
▼
[RAG 검색] (3편)
└── 유사 과거 장애 이력 Top 3
│
▼
[프롬프트 조립] (5편)
└── v5: 역할 + CoT + RAG + 환각 방지
│
▼
[LLM 분석]
├── 경로 A: Claude API
└── 경로 B: 사내 vLLM 서버 + ()
│
▼
[분석 보고서]
├── 추정 원인 + 신뢰도
├── 조치 방안 (구체적 명령어 포함)
└── "확인 필요" 항목 목록여기까지가 Level 1(보조)에 해당한다. LLM이 분석하고 보고서를 만들지만, 실제 조치는 사람이 한다.
다음 편부터 Level 2(반자율)로 넘어간다. LLM이 분석 결과를 바탕으로 "이렇게 조치하겠다"고 제안하고, 사람이 승인하면 자동 실행되는 AI Agent를 설계한다.
다음 편에서는 AI Agent가 실제로 서버에 명령을 실행하는 구조를 다룬다. Read-Only(제안만)에서 시작해서, Human-in-the-Loop(승인 후 실행)까지. 안전장치 설계가 이 편의 핵심이다.
이 글이 어떠셨나요?
관련 포스트
4. LLM이 장애를 감지한다 — 알림 피로 끝내기
임계값 알림의 한계를 넘어서는 LLM 기반 이상 탐지. 프롬프트 설계, 알림 상관관계 분석, 실시간 감시 구조와 기존 모니터링과의 통합 방법을 다룹니다.
2026. 05. 17. PM 10:00DevOps3. LLM에게 먹일 데이터 준비 — 전처리와 RAG
운영 데이터 품질이 분석 결과를 결정한다. 로그 전처리 5단계, 컨텍스트 전략, RAG 시스템 구축 방법과 알림이 LLM에 도달하는 전체 파이프라인을 설계합니다.
2026. 05. 10. PM 10:00DevOps2. 어떤 LLM을 쓸 것인가 — 환경별 선택 가이드
Claude API vs 로컬 빅모델의 선택 기준. 파라미터, 토큰, 컨텍스트 윈도우의 실무적 의미와 GPU 메모리별 모델 선택 가이드. SRE 작업별 비교와 비용 분석.
2026. 05. 03. PM 10:00뉴스레터 구독
새 글이 올라오면 이메일로 알려드려요.