
하나의 제어 루프, 세 가지 SigNoz 트랙: 스스로 치유하고, 탄소 비용을 산정하며, 접근성을 제어하는 에이전트
요약
SigNoz와 OpenTelemetry를 활용하여 에이전트의 텔레메트리 데이터를 기반으로 스스로 행동하고 수정하는 'observable-agent' 구축 사례를 소개합니다. 단순 모니터링을 넘어 자가 치유, 탄소 비용 산정, 접근성 제어를 수행하는 폐쇄 루프(Closed-loop) 시스템 설계 방식을 다룹니다.
핵심 포인트
- OpenTelemetry를 활용한 가공되지 않은 사실 기반의 데이터 기록
- PASS, BREACH, UNKNOWN 상태 판결을 통한 Fail-closed 방식 적용
- SigNoz를 센서, 진단 표면, 스코어보드, 트리거로 활용
- 재시도 비용(retry tax) 문제를 해결하는 자가 치유형 SRE 사이드킥 구현
내가 봐온 모든 "AI + 관측성 (Observability)" 데모는 항상 똑같은 지점에서 멈췄다. 무언가 잘못되고 있다는 것을 보여주는 아름다운 트레이스 (Trace) 말이다. 대시보드에 불이 들어오고, 토큰은 소진되었으며, 그 후에 사람이 그것을 읽고 수동으로 수정한다.
관측성 (Observability)은 에이전트가 불타고 있다는 것을 알려줄 뿐이다. 불을 꺼주지는 않는다.
그래서 나는 SigNoz 에이전트 해커톤을 위해 내 노트북에서 실행되는 로컬 모델을 자체 호스팅된 SigNoz에 연결한 observable-agent를 구축했고, 스스로에게 한 가지 규칙을 세웠다. 단순히 에이전트를 지켜보지만 말고, 에이전트의 텔레메트리 (Telemetry)에 따라 안전하게 스스로 행동하고, 그 후에 텔레메트리를 통해 수정되었음을 증명하라. 그리고 나는 이 단일한 아이디어를 세 가지 트랙 모두에 적용했다. 신뢰성 위반을 치유하는 것과 동일한 기본 요소 (Primitives)가 탄소 비용을 산정하고 접근성을 제어하는 데에도 사용되기 때문이다.
여기 전체 프로젝트와 SigNoz가 이를 어떻게 결합하고 있는지에 대한 상세한 내용이 있다.
기본 요소(Primitives), 그리고 그것들이 기반하는 토대
설계는 모든 트랙에서 반복되는 세 가지 단계에 기반한다:
- 요약이 아닌, OpenTelemetry로서 가공되지 않은 사실을 기록한다.
- 해당 사실들을 '실패 시 차단 (Fail closed)' 방식의 세 가지 상태 판결(PASS, BREACH, 또는 UNKNOWN. 결코 안심시키는 거짓 0을 내놓지 않음)로 등급을 매긴다.
- SigNoz에서 판결에 따라 알림을 보내고, 안전한 경우 그에 따라 행동한다.
토대는 의도적으로 지루하고 재현 가능하게 만들었다. SigNoz v0.133은 Foundry (WSL2 및 Docker)를 통해 구축되어 내 노트북에서 실행되며, 저장소(Repo)에는 심사위원이 동일한 배포를 다시 실행할 수 있도록 정확한 casting.yaml 및 casting.yaml.lock 파일이 포함되어 있다. 에이전트는 클라우드나 API 키 없이 로컬 Ollama 모델(qwen2.5:3b)에서 실행된다. 모든 요청은 OpenTelemetry GenAI 시맨틱 컨벤션 (Semantic conventions)을 사용하여 agent.invoke에서 llm.chat을 거쳐 tool.* 스팬 (Span) 트리로 방출되며, 토큰, 비용, 지연 시간 (Latency)이 메트릭 (Metrics)에 이중으로 기록된다.
루프 내에서 SigNoz는 네 가지 역할을 수행하며, 네 가지 역할 모두가 동일한 텔레메트리를 읽기 때문에 하나의 진실의 원천 (Source of truth)을 공유한다: 센서 (Sensor), 진단 표면 (SigNoz MCP 서버를 통한 Diagnostic surface), 스코어보드 (Scoreboard), 그리고 트리거 (Trigger)이다.
트랙 01: 자가 치유형 SRE 사이드킥
내가 추적한 첫 번째 위반 사항은 재시도 비용 (retry tax)이다. 결함이 발생하여 첫 번째로 완료된 LLM 응답이 유실되면, 에이전트는 추론 (inference)을 다시 실행하게 되어 토큰을 두 번 소비하게 된다. 이는 완벽한 타겟이다. 이는 실제 텔레메트리 (telemetry)이며 (retry.reason = "response_dropped" 태그가 붙은 중복된 llm.chat 스팬 (span)), 코호트 (cohort)당 전체 대비 유실된 비율로 SLO (Service Level Objective)로서 측정 가능하며, 유효한 해결책이 하나 이상 존재하므로 모델이 진정한 의사결정을 내려야 하기 때문이다.
단 하나의 명령어가 이 모든 것을 실행하며, 전체 사이클은 단일 분산 트레이스 (distributed trace)로 구성된다.
[
탐지 (Detection) 및 검증 (verification)은 결정론적인 signoz_aggregate_traces 쿼리 (query)를 통해 이루어진다. 판단 과정에는 LLM이 관여하지 않는다. 모델은 확인된 위반 사항에 대해 무엇을 할지 결정하도록 요청받을 뿐이다. 모델의 첫 번째 동작은 read_incident 도구 (tool) 호출이며, 이는 MCP 서버를 통한 두 개의 라이브 쿼리에 의해 뒷받침된다. 모델이 돌려받는 구조화된 증거 (재시도율, dropped_and_retried 횟수, 그리고 근본 원인)는 워크로드 (workload)가 방금 방출한 트레이스 (trace)에서 직접 추출된 것이다.
[
해당 증거를 바탕으로, 로컬 모델은 스스로 disable_fault_injection을 선택하고 실행했다. 재시도율은 40퍼센트에서 0퍼센트로 떨어졌으며, 이 문장에 포함된 모든 숫자는 단순한 출력문 (print statement)이 아니라 SigNoz 쿼리 (query) 결과이다.
실제 알람이 트리거이며, 크론 잡 (cron job)이 아니다
Hands-off 경로는 타이머에 따라 폴링 (polling)하지 않는다. 실제 SigNoz 알람 규칙 (alert rule)이 발생할 때 치유 (heal)가 시작된다. 재시도율 (retry rate)이 SLO를 초과하면, SigNoz는 규칙을 발생 (firing) 상태로 전환하고, 브리지 (bridge)가 Alertmanager 웹훅 (webhook)을 통해 이를 포착하여 heal.trigger 스팬 (span)을 열고 제어된 루프 (governed loop)를 실행한다. 동일한 알람이 다시 해결 (resolved) 상태로 전환되는 방식은 루프가 작업이 완료되었음을 인지하는 방법이다. 알람과 치유는 하나의 분산 트레이스 (distributed trace)이다.

안전을 보장하는 부분: 정책 게이트 (policy gate)
소프트웨어가 프로덕션 (production) 환경에서 동작하도록 허용하는 것은 그 동작이 제한될 때만 합리적이며, 이 부분이 대부분의 자율 에이전트 (autonomous agent) 데모에서 생략되는 지점이다. 모든 액추에이터 (actuator) 변이 (mutation)는 먼저 정책 게이트 (policy gate)를 거쳐 라우팅된다. 자율성 (autonomy)은 네 가지 수준 (관찰 (observe), 제안 (suggest), 승인 (approve), 자동 (auto))으로 실행되며, 각 동작은 위험도 (risk), 가역성 (reversibility), 그리고 폭발 반경 (blast radius)을 수반한다. 낮은 위험도 상한선 (low risk cap)이 설정된 자동 (auto) 모드에서는 위험도가 낮고 가역적인 동작이 스스로 적용되는 반면, switch_model과 같이 더 위험한 동작은 인간의 승인을 위해 대기한다. 모든 결정은 heal.policy 메트릭 (metric)으로서 감사 로그 (audit line)를 기록하며, 적용된 수정 사항이 위반 사항을 해결하지 못할 경우 루프는 사전에 찍어둔 스냅샷 (snapshot)을 복구한다.
두 번째 인시던트 (incident)는 게이트가 제 역할을 다하는 모습을 보여준다. 루프에 빠져 통제 불능 상태가 된 에이전트는 무제한의 비용을 발생시킨다. 센서는 SLO 상한선인 6에 대비하여 트레이스 (traces)로부터 요청당 호출 횟수를 측정하고, 모델은 SigNoz로부터 통제 불능 상태를 읽어 들여 set_cost_budget 서킷 브레이커 (circuit breaker)를 작동시킨다. 그리고 이것이 이 프로젝트 전체에서 내가 가장 좋아하는 프레임이다: 전체 정책 결정 사항이 스팬 (span)에 기록되는 것이다.

해당 차단기(breaker)는 경고가 아니라 구조적인 절단입니다. 요청이 예산을 초과하면 에이전트는 LLM 호출을 중단하고 해당 스팬(span)에 agent.request.severed = true 태그를 지정합니다. 요청당 비용은 0.000700달러에서 0.000122달러로 약 82% 감소했으며, 플러그 앤 플레이(plug and play) 경제 계층(economics layer)은 이를 하루 100,000건의 요청 기준 월 약 1,734달러의 비용 절감으로 산정합니다.
루프가 학습하는 한 가지가 더 있습니다. 해결책이 SigNoz의 검증된 메모리(verified memory)에 기록된다는 점입니다. 따라서 동일한 장애가 재발할 때, 모델 호출을 전혀 하지 않고 메모리로부터 즉시 치유하며, 이는 더 빠를 뿐만 아니라 별도의 보정(calibration)도 필요하지 않습니다. 이 글을 쓰는 동안 다시 실행해 본 결과, 새로운 33% 재시도 위반(retry breach)이 메모리에서 직접 치유되었습니다(현재까지 네 번 증명됨). 모델 호출 없음, MTTR(평균 복구 시간) 149초, 트레이스(trace) d0c14392999aef86af95032a8dd080e0.
트랙 02: MCP 계약 실험실, 세 가지 시그널, 그리고 제로 코드 프록시
트랙 02는 계측(instrumentation)과 대시보드에 관한 것이므로, 저는 동일한 기본 요소(primitives)를 Model Context Protocol (MCP) 자체에 적용했습니다.
mcp2_cert는 계약(contract)에 따라 MCP 서버를 인증하는 능동적 프로브(active probe)입니다. 이는 initialize, tools/list, tools/call을 실행하고, 각 결과에 동일한 세 가지 상태 판결을 부여하며, 모든 교환 내용을 안정적인 지문(fingerprint)을 가진 mcp.* 스팬으로 방출합니다. 저의 SigNoz MCP 서버를 대상으로 테스트했을 때, 지문 ca5859fcf24f5e03과 함께 CERTIFIED(인증됨)를 반환했습니다.
그다음 저는 수동적 동반자(passive companion)인 상시 가동 계측 프록시(mcp-proxy)를 구축했습니다. 이는 모든 MCP 클라이언트와 서버 사이에서 투명하게 위치하며, 양측의 코드 변경 없이 JSON RPC 트래픽을 mcp.<method> 스팬과 mcp.client.* 메트릭으로 변환합니다. 이것이 충실하게 작동함을 증명하기 위해, 전체 인증 배터리(certification battery)를 프록시를 통해 실행했습니다. 결과는 동일한 지문 ca5859fcf24f5e03과 함께 여전히 CERTIFIED였으며, 동시에 프록시는 모든 호출에 대해 올바르게 등급이 매겨진 스팬을 독립적으로 방출했습니다. 여러분은 소유하지 않은 MCP 통합(integration) 환경도 아무런 손실 없이 계측할 수 있습니다.
이 모든 것은 SigNoz v5 Query Builder API를 통해 구축된 세 가지 시그널 대시보드(트레이스 (traces), 메트릭 (metrics), 로그 (logs) 통합)에 반영됩니다. 대시보드가 생성되기 전, 모든 패널은 query_range API를 통해 스스로 검증하며, 해결할 수 없는 패널은 절대 전송되지 않습니다.

트랙 03: 텔레메트리 (telemetry)로서의 에너지, 탄소, 그리고 접근성
트랙 03은 무엇이든 관찰하라고 말합니다. 그래서 저는 보통 텔레메트리 (telemetry)로 취급되지 않는 두 가지를 관찰했습니다.
WattTrace GreenOps는 검증된 답변당 줄 (joules)과 CO2e (이산화탄소 상당량) 그램 (grams)을 측정합니다. 이는 결정론적인 토큰 기준으로 모든 토큰의 가격을 에너지로 책정하며, 실행 과정을 가장 취약한 출처(provenance)로 통합합니다 (따라서 폴백(fallback) 추정치가 하드웨어 판독값으로 표시되지 않도록 합니다). 또한 예산에 대해 'fail closed(실패 시 차단)' 방식으로 등급을 매깁니다. 재시도 오류(retry fault)에 대해 제어 코호트(control cohort)를 실행한 결과, 동일한 검증된 답변의 비용이 753 J에서 1101 J로 나타났으며, 이는 46%의 에너지 퇴보(regression)를 의미합니다. 이 중 대부분은 재시도된 호출에서 발생한 순수 낭비였습니다. 이 '재시도 세금(retry tax)'은 알림을 보낼 수 있는 지속 가능성 퇴보로 재정의됩니다.
AccessTrace는 웹 접근성(accessibility)에 정확히 동일한 'fail closed' 원시값(primitives)을 적용합니다. 실제 헤드리스 브라우저(headless browser)가 WCAG 여정(페이지 로드, 탐색, 주요 콘텐츠, 가입 양식)을 수행하고, 각 단계에서 axe-core를 실행하며, 해당 여정을 트레이스 (trace)로 방출합니다: access.suite에서 access.journey를 거쳐 access.step으로 이어집니다. 핵심적인 뷰는 access.step 스팬 (spans)이 사용자 흐름의 어느 부분이 깨지는지 국지화(localise)한다는 점입니다. 오류가 있는 데모 페이지의 판정은 가중 부채(weighted debt) 40과 함께 BREACH(위반)로 나타나며 (정확히 실패한 단계에서 두 개의 심각한 문제와 네 개의 중대한 문제 발생), 수정된 쌍둥이 페이지는 0점을 기록합니다. 이는 100% 감소를 의미하며, 위반 발생 시 두 개의 실시간 SigNoz 알림이 발송됩니다.
크로스 트랙 피날레: 탄소가 치유 센서가 되다
이 지점에서 세 가지 트랙은 더 이상 세 개의 개별 프로젝트가 아니게 됩니다. 트랙 03의 WattTrace 에너지 판결(verdict)이 트랙 02의 MCP 프로토콜을 통해 읽혀, 트랙 01 자가 치유기(self healer)를 위한 치유 센서(heal sensor)가 됩니다. 자가 치유기는 드롭(dropped)되거나 재시도(retried)된 호출에 낭비된 코호트(cohort)의 추론 에너지 비율로 정의되는 탄소 SLO 위반을 감지하고, 동일한 거버넌스 루프(governed loop)를 통해 이를 해결합니다.
그 이면에 있는 보정(calibration) 과정이 흥미로운 부분입니다. 건강한 멀티 콜(multi call) 워크로드는 답변당 약 867 J이며, 이는 900 J인 단일 콜(single call) 기준 예산보다 약 4% 낮은 수준입니다. 따라서 절대적인 상한선(absolute cap)을 기준으로 검증 단계(verify step)를 제한한다면, 일반적인 토큰 노이즈로 인해 완벽하게 작동하는 수정 사항이 롤백(roll back)될 수 있습니다. 반면 낭비된 비율(wasted fraction)을 기준으로 제한하는 방식은 보정이 필요 없습니다(calibration free). 건강한 코호트는 낭비가 0이므로, 검증된 수정 사항은 절대 롤백되지 않습니다. 실제 탄소 치유(carbon heal) 과정에서 답변당 탄소 발자국은 0.3275 gCO2e에서 0.1183 gCO2e(2649 J에서 958 J)로 감소했으며, 이 수정 사항은 메모리에 학습되었습니다. 하나의 루프, 세 가지 트랙, 하나의 트레이스(trace).
구체적으로 SigNoz를 사용한 방법
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기