
프로덕션 이슈 디버깅을 위한 AI
요약
프로덕션 장애 발생 시 AI가 로그, 메트릭, 트레이스 등 이질적인 데이터를 분석하여 디버깅 과정을 어떻게 혁신할 수 있는지 다룹니다. Datadog의 Bits AI SRE와 같은 사례를 통해 AI가 인지적 부하를 줄여주는 역할을 설명합니다.
핵심 포인트
- AI는 방대한 로그와 메트릭 간의 상관관계를 빠르게 분석하는 데 탁월함
- Datadog Bits AI SRE는 장애 해결 시간을 최대 95%까지 단축 가능
- AI는 업무를 대체하는 것이 아니라 인지적 비용이 높은 분석 단계를 보조함
- LLM을 관측성(Observability) 도구와 연결하는 것이 핵심
새벽 2시 47분입니다. 지난 20분 동안 페이저(pager)가 벌써 세 번째 울렸습니다. 체크아웃 지연 시간(latency)이 급증하고 있습니다. /api/orders의 에러율이 상승하고 있습니다. Slack에는 완성되지 않은 트레이스 뷰(trace views) 스크린샷들이 가득 차고 있습니다. 당신의 로그 어딘가에, 정답이 평문(plain text)으로 놓여 있지만, 모두가 똑같이 긴급해 보이는 수백만 개의 다른 줄 아래에 파묻혀 있습니다.
이것이 바로 사람들이 "AI가 우리가 프로덕션 이슈를 디버깅하는 방식을 바꿀 것이다"라고 말할 때 언급하는 바로 그 순간입니다. 누군가가 ChatGPT에게 정규 표현식(regex)을 써달라고 요청하는 데모 같은 것이 아닙니다. 새벽 2시 47분의 순간 말입니다. 지친 인간이 머릿속에 다섯 개의 탭을 열어둔 채 가설을 세워야 하고, 경영진이 예상 복구 시간(ETA)을 묻기 시작하기 전까지 버텨야 하는 바로 그 순간입니다.
결과적으로 그 지점이 기술이 가장 많은 것을 제공할 수 있는 곳인 동시에, 가장 자주 스스로를 당황스럽게 만드는 곳이기도 합니다. 2026년에 실제로 무엇이 작동하고 있는지, 어디에서 여전히 결함이 드러나는지, 그리고 LLM을 사고 대응(incident-response) 루프에 어떻게 연결하여 단순히 쳐다봐야 할 창을 하나 더 추가하는 것이 아니라 제 역할을 다하게 할 수 있는지 자세히 살펴보겠습니다.
장애 발생 시 AI가 진정으로 잘하는 것
먼저 두 가지 지루하지만 강력한 능력은 다음과 같습니다: 빠르게 읽기와 **이질적인 신호 간의 상관관계 분석(correlating across heterogeneous signals)**입니다. 이것들은 인간이 피곤하고 시간 압박을 받을 때 가장 못하게 되는 일들이며, 성능 좋은 LLM이 새벽 2시나 오후 2시나 동일한 속도로 해내는 일들입니다.
Datadog의 Bits AI SRE는 수백 개의 내부 Datadog 팀에서 발생한 실제 장애 사례를 바탕으로 벤치마킹되었으며, 바로 이러한 통찰력을 중심으로 구축되었습니다. 즉, 메트릭 (metrics), 로그 (logs), 트레이스 (traces), 최근 배포 (recent deploys), 그리고 장애 이력 (incident history) 전체를 동시에 훑어본 뒤, 그 결과들을 하나의 읽기 쉬운 서사로 압축해내는 에이전트입니다. Datadog은 수만 개의 평가 시나리오를 통해 이 에이전트를 실행하며, 발표된 자료에 따르면 해결 시간 (time-to-resolution)을 최대 95%까지 단축했다고 주장합니다. 이 헤드라인 수치는 마케팅적인 요소가 포함되어 있지만 (항상 "에이전트가 제대로 작동했을 경우, 이만큼의 시간을 단축했다"라고 해석해야 합니다), 그 근저에 깔린 능력은 실재하며 Datadog만의 독점적인 기능도 아닙니다. Honeycomb의 Query Assistant는 2023년부터 엔지니어들이 일상적인 영어로 트레이스 관련 질문을 할 수 있게 해왔습니다. OpenSRE와 같은 오픈 소스 툴킷 (open-source toolkits)은 LLM을 긴 관측성 (observability) 도구 목록(Datadog, Honeycomb, CloudWatch, Sentry, Elasticsearch)에 연결하여, 여러분의 자체 스택에서도 동일한 아이디어를 실행할 수 있게 해줍니다.
공식 발표를 읽을 때 놓치기 쉬운 부분이 여기 있습니다: AI가 당신의 업무를 대신 해주는 것이 아닙니다. AI는 당신의 업무 중 가장 지루하면서도 동시에 인지적 비용 (cognitively expensive)이 가장 많이 드는 부분, 즉 "지금 이 시스템 전체를 머릿속에 담고 있어야 한다"는 부분을 수행하는 것입니다. 설령 AI가 스스로 단 하나의 정확한 해결책도 제안하지 못하더라도, 이것만으로도 실질적인 승리입니다.
AI가 정체되는 부분
명확히 짚고 넘어가야 할 또 다른 사실은, AI는 쉬워 보이는 디버깅 단계에서 오히려 취약하다는 점입니다.
AI는 해당 장애가 실제 상황인지 아닌지를 판단할 수 없습니다. 2만 줄의 로그 라인을 입력받은 모델은, 실제 답이 "누군가 메트릭 에이전트를 재시작해서 대시보드가 패닉에 빠진 것"일 때조차도 연쇄 장애 (cascading failure)에 대한 아름다운 서사를 기꺼이 만들어낼 것입니다. AI는 이해관계 (skin in the game)가 없습니다. 만약 당신이 근본 원인 (root cause)을 찾아달라고 요청한다면, AI는 어떻게든 찾아낼 것입니다. 그것이 이 게임의 전부입니다.
또한 학계에서 한동안 논의해 온 사고의 사슬 (Chain-of-Thought, CoT) 함정도 존재합니다. arXiv에 게시된 2025년 논문("Chain-of-Thought Prompting Obscures Hallucination Cues in Large Language Models")에 따르면, 모델에게 소리 내어 추론하도록 요청하는 것은 환각 (hallucination) 사실의 발생률을 낮추는 동시에, 남은 환각을 훨씬 더 탐지하기 어렵게 만들 수도 있습니다. 추론 과정 (reasoning trail)이 조작된 결론을 더욱 신뢰할 수 있는 것처럼 보이게 만들기 때문입니다. 실질적인 관점에서 보자면, 장애 상황에 대해 AI가 자신감 있고 논리적으로 설명한다고 해서 그 설명이 옳다는 증거는 아닙니다. 그것은 단지 모델이 추론 과정 (reasoning trails)을 생성하는 데 능숙하다는 증거일 뿐입니다. 이 둘은 엄연히 다른 것입니다.
따라서 모델의 출력값은 장애 상황(incident) 중에 주니어 엔지니어가 처음 내놓은 추측을 대하는 것과 동일하게 취급하십시오. 진지하게 받아들이되, 그것이 어디서 왔는지 묻고, 행동에 옮기기 전에 반드시 검증하십시오.
로그: 연료이자 함정
로그는 LLM (Large Language Model)을 활용하기에 가장 명백한 대상입니다. 장애 대응 (incident response)에 AI를 사용하기 시작하는 대부분의 팀은 여기서부터 시작합니다. 최근 로그의 일정 구간을 프롬프트 (prompt)에 입력하고, 모델에게 무엇이 보이는지 묻는 방식입니다.
이 방식은 **패턴 표면화 (pattern surfacing)**에 놀라울 정도로 효과적입니다. 예를 들어, "02:39부터 payments-internal로의 ECONNREFUSED 급증이 발생했으며, 2분 후 주문 서비스(orders service)에서 504 오류가 파도처럼 밀려왔습니다"와 같은 식입니다. 사람도 이를 볼 수 있지만, 사람은 스크롤을 해야 합니다. 모델은 단 한 번의 패스 (pass)로 이를 포착합니다.
하지만 드물지만 의미 있는 (rare-but-meaningful) 라인에 대해서는 훨씬 더 취약합니다. 만 개의 일상적인 INFO 라인 사이에 파묻힌 단 하나의 WARN: replica lag exceeded threshold는 지친 사람이 보기에 이상해서 알아챌 수도 있는 것이지만, 모델은 지배적인 패턴에 부합하지 않기 때문에 놓치기 쉽습니다. 많은 팀이 느린 방식으로 깨달은 교훈은, LLM에게 가공되지 않은 로그 스트림 (raw log streams)만을 유일한 신호로 주어서는 안 된다는 것입니다. 구조화된 로그 (structured logs)를 사용하고, 심각도 (severity)에 따라 사전 필터링을 수행하며, 일반적인 관측성 (observability) 도구를 통해 이상 징후를 표면화한 다음에, 모델에게 필터링된 데이터 세트를 해석하도록 요청하십시오. 쓰레기가 들어가면, 자신감 있게 들리는 쓰레기가 나옵니다 (Garbage in, confident-sounding garbage out).
또한 컨텍스트 윈도우 (context-window) 경제성 문제도 있습니다. 현재 세대의 롱 컨텍스트 (long-context) 모델들을 사용하더라도, 백만 줄의 로그를 프롬프트에 쏟아붓는 것은 비용이 많이 들고 느립니다. 또한 모델의 정확도는 컨텍스트 윈도우의 중간 부분에서 저하되는데, 이는 여러 롱 컨텍스트 벤치마크에서 문서화된 이른바 "중간에서 길을 잃는 (lost in the middle)" 문제입니다. 실질적인 패턴은 검색 증강 (retrieval-augmented) 방식입니다. 과거 로그와 최근 장애 트랜스크립트 (transcripts)를 벡터 저장소 (vector-store)에 저장한 다음, 현재의 시그널 (signal)과 일치하는 슬라이스(slices)만 가져오는 것입니다. Pinecone, Weaviate, Chroma가 명확한 빌딩 블록이며, 이미 Postgres를 사용 중이라면 pgvector도 괜찮습니다.
트레이스 (Traces): AI가 팀원처럼 보이기 시작하는 지점
트레이스는 "팀원으로서의 LLM (LLM-as-teammate)"이라는 프레임워크가 실제로 맞아떨어지는 지점입니다. 왜냐하면 트레이스는 인간이 수동으로 읽기를 가장 싫어하는 종류의 산출물(artefact)이기 때문입니다. 12개의 서비스에 걸쳐 400개의 스팬 (spans)이 있는 분산 트레이스 (distributed trace)는 읽기 가능한 텍스트인 척하는 구조화된 객체이며, "산문처럼 보이는 구조화된 객체"는 모델이 가장 잘 다루는 영역입니다.
Honeycomb의 Query Assistant가 전형적인 예시입니다. _"EU 사용자들의 결제 요청이 왜 어제보다 느린가요?"_라고 입력하면, 모델은 실제 데이터를 바탕으로 진짜 Honeycomb 쿼리를 생성해 줍니다. 결정적으로, 모델은 정답을 주려고 시도하는 것이 아니라, 사용자가 편집하고 실행하며 추론할 수 있는 _쿼리 (query)_를 제공합니다. 이것이 바로 합리적인 관심사 분리 (separation of concerns)입니다. AI는 영어에서 플랫폼의 쿼리 언어로의 번역을 담당하고, 인간은 판단(judgment call)을 유지합니다.
어떤 트레이싱 (tracing) 시스템 위에서도 동일한 형태를 구축할 수 있습니다. 핵심은 시스템 프롬프트 (system prompt)에 스팬 자체를 주는 것이 아니라, **스팬의 스키마 (schema)**를 모델에게 제공하는 것입니다. 서비스 이름, 속성 키 (attribute keys), 일반적인 값들을 포함해야 합니다. 그런 다음 모델이 쿼리를 구성하도록 합니다. 이 단계를 건너뛰고 채팅창에 가공되지 않은 트레이스를 그대로 붙여넣는다면, 여러분의 스택에 존재하지도 않는 서비스에 대해 그럴듯하게 들리는 쓰레기 정보를 얻게 될 것입니다.
Tip
만약 여러분의 트레이스(traces)에 시맨틱 속성(semantic attributes, 예:http.route,db.statement,messaging.system등)이 없다면, 모델이 아무리 뛰어나더라도 AI는 어려움을 겪을 것입니다. OpenTelemetry의 시맨틱 컨벤션(semantic conventions)이 존재하는 데에는 이유가 있습니다. 만약 여러분의 팀이 마이그레이션(migration) 과정에 있다면, 이를 채택하는 것이 AI 지원 디버깅(AI-assisted debugging)을 위한 가장 레버리지가 높은(highest-leverage) 준비 작업입니다.
에러: 가장 쉬운 승리이자, 가장 위험한 승리
LLM(대규모 언어 모델)에 에러 메시지를 가리키며 설명을 요구하는 것은 장애 대응(incident response)에서 가장 적은 노력으로 가장 큰 효과를 얻을 수 있는 AI 활용법입니다. 특히 신입 엔지니어들은 수십 개의 Stack Overflow 탭을 뒤지는 것보다 AI를 통해 더 많은 것을 얻습니다. "EAI_AGAIN이 무슨 뜻인가요? Node에서 보통 언제 발생하나요?" 같은 질문에 대해 올바른 멘탈 모델(mental model)과 함께 몇 초 만에 답을 얻을 수 있습니다.
위험한 점은 에러 상황이야말로 환각(hallucinations)이 가장 그럴듯하게 보이는 지점이라는 것입니다. 지어낸 Postgres 에러 코드, 존재하지 않는 NGINX 플래그(flag), 런타임(runtime)이 들어본 적도 없는 환경 변수(environment variable)를 자신 있게 설명하는 것 등이 LLM에서 예측 불가능한 비율로 튀어나옵니다. 이러한 오류는 마치 맞는 것처럼 읽히기 때문에 가장 비용이 많이 드는 종류의 오답입니다. 방어적인 습관을 가져야 합니다. 모델이 특정 플래그가 존재한다거나 설정 옵션(config option)이 특정 방식으로 작동한다고 말할 때, 그것을 바로 적용하기 전에 반드시 상위 문서(upstream docs)를 확인하십시오. 항상 그래야 합니다. 새벽 3시라도 말이죠. 특히 새벽 3시라면 더더욱 그렇습니다.
이 지점은 또한 AI에 의존하는 것과 팀의 집단적 기억(collective memory)에 의존하는 것 사이의 트레이드오프(trade-off)를 목격하기 시작하는 지점이기도 합니다. 귀하의 스택(stack)에서 5년 동안 근무한 시니어 엔지니어는 "디스크 풀(full-disk) 이벤트 전후로 발생하는 오류"와 "로드 밸런서(load balancer)의 상태 확인(health-checking)이 이상하게 작동함을 의미하는 오류"에 대한 정신적 인덱스(mental index)를 가지고 있습니다. 그 인덱스는 로컬(local)적이고, 독특하며, 대체 불가능합니다. 귀하의 스택을 본 적이 없는 LLM(Large Language Model)은 해당 지식의 '일반적인' 버전만을 가지고 있을 뿐입니다. 검색(retrieval)을 통해 지난 100개의 사후 분석(postmortem) 보고서를 LLM에 제공하고, 이를 바탕으로 패턴 매칭(pattern-match)을 수행하게 하는 조합이 바로 그 간극을 메워줍니다.
가설(Hypotheses): 판단력을 유지해야 하는 부분
흥미로운 질문은 "모델이 무엇이 잘못되었는지 말해줄 수 있는가"가 아닙니다. 진짜 질문은 "모델이 개연성(plausibility)에 따라 순위가 매겨진 세 가지 가설과, 각 가설을 반증(falsify)하기 위해 실행할 테스트를 제공할 수 있는가"입니다.
이러한 프레임워크(framing)는 프롬프트(prompt)를 바꾸고, 그에 따라 답변도 바꿉니다. 확신에 찬 어조의 단일 근본 원인(root cause) 대신, 각각 검증 방법이 포함된 작은 가능성의 포트폴리오를 얻게 됩니다. "가설 1: payments-svc의 커넥션 풀(connection pool) 고갈. 테스트: 현재 payments DB의 활성 연결에 대해 pg_stat_activity를 쿼리하십시오." "가설 2: Stripe 웹훅(webhook)의 상위(upstream) 속도 제한(rate limit). 테스트: 지난 30분 동안의 stripe_webhook_rejected_total 메트릭(metric)을 확인하십시오." 이와 같은 식입니다.
이것이 실제로 작동하게 만드는 두 가지 요소가 있습니다. 첫째, 시스템 프롬프트(system prompt)를 통해 모델에게 검증 테스트가 포함된 가설을 제공하되, 확인 비용이 가장 저렴한 것부터 가장 비싼 순서대로 나열하라고 지시하는 것입니다. 모델은 확신에 찬 것처럼 말하려는 편향(bias)이 있는데, 대안을 열거하라는 명시적인 지시는 이를 상쇄합니다. 둘째, 어떤 가설을 추적할지 선택하는 주체는 인간으로 유지하는 것입니다. AI는 의사 결정자가 아니라 브레인스토밍 파트너입니다. 이는 유능한 사고 지휘관(incident commander)이 "현재 이론에 대해 당신의 생각을 바꾸게 만들 요소는 무엇인가?"라고 묻게 만드는 것과 동일한 본능입니다. LLM은 단지 빠르고 지치지 않는 '악마의 변호인(devil's-advocate)' 역할을 하는 가설 제공원일 뿐입니다.
여기서 빌려올 만한 가치가 있는 기술은 자기 일관성 프롬프팅 (self-consistency prompting, Wang et al.의 2022년 논문 "Self-Consistency Improves Chain of Thought Reasoning in Language Models")입니다. 메커니즘은 간단합니다. 모델에게 동일한 질문을 여러 번 던지고, 서로 일치하지 않는 답변들은 버리며, 일관된 중간 결과물들을 유지하는 것입니다. 이를 장애 대응 (incident response)에 적용하면, 몇 가지 독립적인 가설 세트를 샘플링하고 반복적으로 나타나는 가설들을 신뢰하는 방식입니다. 이는 모델의 일회성 확신 섞인 추측을 걸러내는 저렴한 방법입니다. 이를 통해 실질적인 신뢰성을 확보할 수 있으며, 주말 동안 여러분의 자체 파이프라인 (pipeline)에 구축할 수도 있습니다.
런북 (Runbooks): 아무도 말하지 않는 누락된 연결 고리
이 모든 것을 하나로 묶어주는 다소 투박한 주장은 다음과 같습니다: AI의 디버깅 능력은 여러분의 런북 (runbooks) 수준에 달려 있습니다.
모델은 여러분의 온콜 (on-call) 에스컬레이션 경로를 알지 못합니다. 여러분의 팀 관례가 SSH로 접속하기 전에 영향을 받는 포드 (pod)를 먼저 비우는(drain) 것이라는 사실도 모릅니다. README에 적힌 "워커 재시작" 명령어가 틀렸으며, 실제 명령어는 2024년에 작성된 Notion 페이지에 있다는 사실도 모릅니다. 만약 장애 발생 시 LLM이 팀원처럼 작동하기를 원한다면, 신입 사원이 입사 2주 차 쉐도잉 로테이션 (shadow rotation) 중에 받는 것과 동일한 컨텍스트 (context)를 모델에게 제공해야 합니다.
효과적인 패턴은 다음과 같습니다:
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기