SigNoz에게 환각을 일으키는 에이전트를 어떻게 식별하냐고 물었습니다. 그들은 "아직 방법을 찾지 못했다"고 답했습니다. 그래서 우리가 직접
요약
SigNoz 해커톤에서 개발된 SentinelX는 AI 에이전트의 환각(hallucination)을 실시간으로 포착하고 예측하는 관측성 플랫폼입니다. MCP 서버와 SigNoz를 활용하여 에이전트가 스스로 텔레메트리를 분석하고 대시보드를 생성하도록 설계되었습니다.
핵심 포인트
- AI 에이전트의 환각 현상을 실시간으로 식별하고 예측하는 SentinelX 개발
- MCP 서버를 통해 SigNoz와 통신하며 SRE 방식의 텔레메트리 분석 수행
- Foundry를 통한 SigNoz 배포 과정에서의 부팅 및 설정 이슈 해결 사례 공유
- 전통적 관측성을 넘어 에이전트 스스로 대시보드를 생성하는 기능 구현
Team ThunderBoltz 작성 · Agents of SigNoz 해커톤 · 트랙 1: AI & Agent Observability
Agents of SigNoz 해커톤의 킥오프 Q&A 세션에서, 우리는 SigNoz 팀에게 오랫동안 고민해 온 질문을 던졌습니다. 환각 (hallucination)을 일으키는 AI 에이전트를 어떻게 식별할 수 있을까요? 그들의 공식적인 답변은 다음과 같았습니다: "우리는 아직 그 방법을 찾아내지 못했습니다."
그래서 우리는 다음 5일 동안 그 방법을 찾아내는 데 몰두했습니다. 이것은 SentinelX에 대한 이야기입니다. SentinelX는 실시간으로 AI 환각을 포착하고, 장애가 발생하기 전에 예측하며, 에이전트가 스스로 대시보드를 작성할 수 있게 해주는 예측형 관측성 (observability) 플랫폼입니다. 이 모든 것은 SigNoz 위에서 작동하며, Foundry를 통해 배포되고, MCP 서버를 통해 읽고 쓰는 에이전트를 사용합니다.
이것이 중요한 이유 (이론적인 이야기가 아닙니다)
AI 에이전트들은 지금 이 순간에도 실제 사용자들에게 답변을 전달하고 있습니다. 법률 코파일럿 (legal copilot)은 실제 서면에는 존재하지 않는 판례를 인용합니다. 분류 (triage) 봇은 투여량을 지어냅니다. 고객 지원 에이전트는 회사가 승인하지 않은 환불을 약속합니다. 그리고 이들이 실행되는 시스템은 조용히 실패합니다. 모든 대시보드가 여전히 초록색을 나타내고 당직 엔지니어가 잠든 사이, 새벽 3시에 커넥션 풀 (connection pool)이 고갈되는 식입니다.
전통적인 관측성 (observability)은 실패가 발생한 후에 이를 포착합니다. 우리는 거짓말이 태어나는 즉시 포착하고, 경고가 울리기 전에 실패를 예측하고 싶었습니다. SentinelX는 MCP 서버를 통해 SigNoz와 통신하는 세 개의 AI 에이전트를 사용하여 이 두 가지를 모두 수행합니다. 이 에이전트들은 숙련된 SRE (Site Reliability Engineer)가 하는 방식대로 텔레메트리 (telemetry)를 읽고, 인간이 한 번도 클릭해 본 적 없는 대시보드를 스스로 생성합니다.
Foundry를 통한 SigNoz 배포 (그리고 우리를 거의 죽일 뻔했던 부팅 버그)
우리는 해커톤 규칙에 따라 Foundry를 통해 SigNoz를 배포했습니다. casting.yaml과 커밋된 casting.yaml.lock을 사용하여 누구나 처음부터 스택을 재현할 수 있도록 했습니다.
# casting.yaml (단순화 버전)
apiVersion: v1alpha1
kind: Installation
...
그리고 첫날 새벽 2시, 컬렉터(collector)는 빈 파이프라인(pipeline)을 생성하며 나타났습니다. OTLP 수신기(receivers)도 없었고, 트레이스(traces)도 없었습니다. 포트 4318이 TCP 연결을 수락하고 아무것도 반환하지 않는 동안, 헬스 체크(health check)는 그저 "모든 준비가 완료되었습니다"라고만 말하고 있었습니다.
근본 원인은 시작 시 발생하는 '닭이 먼저냐 달걀이 먼저냐' 식의 문제였습니다. 백엔드(backend)의 OpAMP 설정 채널(config channel)은 데이터베이스에 조직(organization)이 존재하기 전까지는 컬렉터에 서비스를 제공하기를 거부합니다. 하지만 조직은 UI를 통해 첫 번째 관리자 사용자를 생성해야만 존재하게 되는데, 백엔드가 완전히 가동되기 전까지는 UI를 사용할 수 없습니다. 서비스를 제공하지 않는 채널을 기다리던 컬렉터는 수신기가 하나도 없는 nop (no-operation) 파이프라인으로 대체되었습니다.
해결책은 두 가지였습니다. 첫째, 환경 변수(environment variables)를 통해 루트 관리자(root admin) 사용자를 프로비저닝(provision)하여 부팅 시 조직이 존재하도록 하는 것이고, 둘째, compose.override.yaml을 추가하여 인제스터(ingester)에서 --manager-config 플래그를 제거함으로써 OpAMP를 기다리는 대신 자체적인 정적 수신기 설정(static receiver config)을 사용하도록 하는 것이었습니다:
# pours/deployment/compose.override.yaml
services:
sentinel-signoz-signoz-0:
...
이 오버라이드(override) 설정은 커밋되었으며 문서화되었습니다. 만약 Foundry를 통해 SigNoz를 배포 중인데 컬렉터에 수신기가 나타나지 않는다면, 이것이 바로 주의 깊게 살펴봐야 할 부팅 레이스 컨디션(boot race)입니다. 캐스팅(cast)을 하기 전에 루트 사용자를 먼저 프로비저닝하십시오.
환각 레이더(The Hallucination Radar) — "모델이 거짓말을 하고 있는가?"를 지표(metric)로 바꾸기
핵심 통찰: 환각(hallucination)은 막연한 느낌(vibes)의 문제가 아닙니다. 그것은 그라운딩(grounding, 근거 제시)의 문제입니다. 만약 AI의 응답에 주어진 컨텍스트(context)에 의해 뒷받침되지 않는 정보가 포함되어 있다면, 이는 측정 가능한 영역입니다.
그래서 우리는 두 모델 설계(two-model design)를 구축했습니다. RAG 에이전트(agent)가 검색된 컨텍스트를 사용하여 질문에 답합니다. 그런 다음 별도의 LLM — 즉 "비평가(critic)" — 가 해당 답변을 소스(sources)와 대조하여 다시 읽고, 답변 중 근거가 없는 부분이 얼마나 되는지를 0.0(완전한 그라운딩)에서 1.0(완전한 날조) 사이로 점수를 매깁니다. 이 점수는 실제 OpenTelemetry 스팬 속성(span attribute)으로 방출됩니다:
span.set_attribute("gen_ai.evaluation.hallucination_score", float(score))
span.set_attribute("gen_ai.evaluation.hallucination_reason", reason)
span.set_attribute("gen_ai.evaluation.method", "llm_critic")
이 단일 속성(attribute)은 "LLM이 수상한 말을 했다"는 사실과 "SigNoz에서 쿼리, 그래프화, 알람 설정이 가능한 메트릭 (metric)" 사이를 잇는 가교 역할을 합니다. Traces 탐색기(explorer)에서 임의의 hallucination_radar.evaluate 스팬(span)을 클릭하면 점수와 비평가(critic)가 작성한 한 줄짜리 이유를 읽을 수 있습니다. 이를 바탕으로 우리는 온콜(on-call) 엔지니어가 하는 방식 그대로 스택을 쌓아 올렸습니다:
- Query Builder의 3단 패널 대시보드: 고위험 횟수(Value 패널), 시간에 따른 위험 추이(Time Series), 그리고 포착된 정확한 날조 내용 목록(Table). 이 모든 것은
name = 'hallucination_radar.evaluate' AND gen_ai.evaluation.hallucination_score > 0.7범위로 설정되었습니다. - 점수가 0.8을 넘는 즉시 발생하는 트레이스(traces) 기반 알람.
이로써 환각(hallucination)은 고객에게 그대로 전달되는 유형의 '보이지 않는 실패'에서, 그래프를 그리고 임계값(threshold)을 설정하며 페이지(page) 알림을 받을 수 있는 대상으로 변모했습니다.
Oracle — 알람이 울리기 전 장애를 예측하기
예측 에이전트(predictive agent)를 위해, 우리는 가장 흔한 운영 환경의 장애 중 하나인 커넥션 풀 고갈(connection-pool exhaustion)을 시뮬레이션했습니다. 풀(pool)은 재사용 가능한 데이터베이스 커넥션(connection)의 고정된 집합이며, "누수(leak)"는 커넥션이 대여된 후 반환되지 않아 점유 수가 최대 한도(hard ceiling)까지 치솟는 버그를 의미합니다. 최대치에 도달하면 새로운 요청이 차단되고 앱이 죽은 것처럼 보이게 됩니다. 보통은 새벽 3시에 발생하며, 아직 임계값을 넘지 않았기 때문에 모든 대시보드는 여전히 초록색(정상)을 나타내고 있을 때입니다.
우리는 대상 앱에 db_pool_active 게이지(gauge)를 추가하고(10초마다 OTLP를 통해 SigNoz로 내보냄), 누수를 시뮬레이션하는 /chaos/leak 엔드포인트를 추가했습니다. 그런 다음 Oracle은 MCP 도구인 signoz_query_metrics를 통해 SigNoz에서 해당 시계열(time-series) 데이터를 직접 읽어옵니다:
result = await mcp.query_metrics(
metricName="db_pool_active",
timeRange="30m",
...
이 프로세스는 데이터 포인트에 대해 선형 회귀 (linear regression, numpy polyfit)를 실행하여 기울기 (slope)와 $R^2$ 신뢰도 (confidence)를 계산하고, 위반까지 남은 시간을 구하기 위해 (임계값 − 현재값) / 기울기를 해결합니다. 예측 결과는 sentinel.prediction.minutes_until_breach 및 sentinel.prediction.confidence와 같은 속성을 가진 별도의 스팬 (span, oracle.predict)으로 방출됩니다.
핵심적인 차이점: 일반적인 임계값 경고 (threshold alert)는 사후 반응적 (reactive)입니다. 즉, 이미 위험 구역에 진입했을 때 발생합니다. 반면 Oracle은 예측적 (predictive)입니다. 풀 (pool)이 여전히 50에 머물러 있어 완전히 "정상"이고 어디에서도 경고가 발생하지 않는 상태에서, "18분이 남았습니다"라고 경고합니다. 이 간극은 장애가 발생한 도중에 호출을 받는 대신, 사람이 침착하게 누수를 해결할 수 있는 시간적 여유 (window)가 됩니다.
Scribe — 관측성 (observability)을 작성하는 에이전트
읽기 (Read)가 루프의 절반이라면, 쓰기 (Write)는 나머지 절반입니다. Scribe는 제목, 위젯, 쿼리, 레이아웃을 포함한 전체 대시보드 페이로드 (payload)를 구축하고, MCP 도구인 signoz_create_dashboard를 통해 SigNoz에 게시합니다:
result = await mcp.call_tool("signoz_create_dashboard", {
"title": "🛡️ SentinelX — Auto-Generated",
"layout": [], # 서버가 패널을 자동으로 배치함
...
대시보드가 SigNoz에 나타납니다. 사람이 UI를 열지도 않았고, 사람이 패널을 클릭하지도 않았습니다. 에이전트가 관측성 (observability) 자체를 구축한 것입니다. 동일한 MCP 브리지 (bridge)를 통해 읽기와 쓰기가 이루어집니다.
디버깅 여정 (직접 해본 사람만이 알 수 있는 세부 사항)
고난의 과정이 없었다면 해커톤 이야기는 솔직하지 못한 것입니다. 우리가 겪은 일들은 다음과 같습니다:
IPv6 함정. Windows에서 localhost는 ::1 (IPv6)로 해석되었지만, Docker는 OTLP 포트를 IPv4로만 매핑했습니다. 우리의 Python exporter는 모든 엔드포인트에 127.0.0.1을 고정하기 전까지 모든 trace (추적)를 조용히 누락시켰습니다. 만약 Windows Docker Desktop에서 OTLP export가 사라진다면, 이 부분을 가장 먼저 확인하십시오.
Gemini 할당량(quota)의 종말. 우리의 첫 번째 LLM 백엔드 (Gemini 2.0 Flash 무료 티어)는 빌드 도중 할당량이 완전히 소진되었습니다 —
우리가 배운 것 (그리고 과거의 우리 자신에게 해주고 싶은 말)
성공한 것: 재현 가능한 배포 (reproducible deployment)를 위한 Foundry (casting.yaml.lock은 심사위원들에게 주는 선물입니다). 에이전트의 눈과 손 역할을 하는 MCP 서버 — 하나의 브릿지를 통해 읽기 및 쓰기 수행. LLM 평가 (evaluation)와 관측성 (observability) 사이의 가교 역할을 하는 hallucination_score 속성. 그리고 커뮤니티: SigNoz Slack 팀 (Nagesh, Chethan, Bishal, Vibhu)이 전체 스택의 막힌 부분을 뚫어줄 root-user 수정 방법을 알려주었습니다. 그 작은 조언 하나가 전환점이 되었습니다.
실패한 것: Windows에서 localhost를 신뢰한 것. 무료 LLM 티어가 유지될 것이라고 가정한 것. MCP 인증이
"환각 (hallucination)을 일으키는 에이전트를 어떻게 식별하나요?" — 킥오프 Q&A에서 던져진 질문입니다. SigNoz 팀의 답변은 다음과 같았습니다: "아직 그 방법을 찾지 못했습니다." Sentinel이 그 해답입니다. Sentinel은 AI 환각을 실시간으로 감지하고, 알람이 울리기 전에 운영 환경의 장애를 예측합니다. 또한, Sentinel의 에이전트들은 MCP 서버를 통해 SigNoz를 읽고 쓸 수 (read and write) 있습니다.
Sentinel이 하는 일
| 에이전트 (Agent) | 역할 (Role) | SigNoz 접점 (SigNoz surface) |
|---|---|---|
| 🎯 Hallucination Radar | ||
실시간 LLM 비평가 (critic)가 모든 AI 답변의 근거(grounding)를 0~1 사이로 점수화합니다. 이 점수는 OTel 속성인 gen_ai.evaluation.hallucination_score로 전송되어 대시보드와 알람에 반영됩니다. | traces · dashboard · alert | |
| 🔮 Oracle | ||
| MCP를 통해 메트릭(metric) 추세를 가져와 선형 회귀 (linear regression)를 실행하고, 알람이 발생하기 몇 분 전에 임계값 위반을 예측합니다 (R² 신뢰도 포함). | metrics (MCP read) · prediction spans | |
| 📝 Scribe | ||
| 자동으로 생성합니다 |
…
데모 영상:
SigNoz: signoz.io · Foundry docs · MCP server
Team SentinelX가 SigNoz 에이전트 해커톤을 위해 제작했습니다. 구현 속도를 높이기 위해 AI 코딩 어시스턴트가 사용되었으나, 모든 아키텍처 결정, 디버깅 및 검증은 팀에 의해 수행되었습니다. 해커톤 규칙에 따라 공개합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기