OpenTelemetry — 꼬이고 멈추는 AI 에이전트 루프 추적하는 법

OpenTelemetry — 꼬이고 멈추는 AI 에이전트 루프 추적하는 법

OpenTelemetry — 꼬이고 멈추는 AI 에이전트 루프 추적하는 법

여러 AI 에이전트가 협력하는 멀티 에이전트 시스템을 만들다 보면 반드시 맞닥뜨리는 골칫거리가 있습니다. 바로 '에이전트가 중간에 어디서 길을 잃었는지 도무지 알 수 없다'는 점입니다.

호출 결과가 매번 달라지고 비동기 루프가 복잡하게 반복되는 에이전트 환경에서는 평범한 서버 로그만으로 버그를 잡기가 거의 불가능합니다. 최근 개발 생태계가 단순한 로그 출력을 넘어 에이전트 전용 관측 가능성 기술과 오픈텔레메트리(OpenTelemetry) 표준 규격에 주목하는 이유입니다.

전통적인 로그가 에이전트 루프 앞에서는 무력한 이유

기존 소프트웨어 개발에서는 에러가 발생하면 스택 트레이스를 보거나 시간순으로 정렬된 텍스트 로그를 확인하면 충분했습니다. 요청이 들어와서 데이터베이스를 거쳐 결과를 반환하기까지의 흐름이 대개 일직선으로 그려지기 때문입니다. 하지만 스스로 판단하고 움직이는 AI 에이전트의 세계로 넘어오면 이야기가 완전히 달라집니다.

에이전트는 사용자의 질문을 해결하기 위해 도구를 호출하고, 그 결과를 분석해 다음 행동을 결정하는 비결정적인 순환 구조를 가집니다. 이 과정에서 에이전트 루프는 끊임없이 반복되며 비동기적으로 작동합니다. 만약 평범한 로그 시스템을 여기에 그대로 가져다 쓰면 어떻게 될까요? LLM 호출 기록과 도구 실행 로그, 데이터를 변환하는 수많은 헬퍼 함수의 기록이 아무런 연결고리 없이 낱개로 쏟아지게 됩니다.

결국 개발자 앞에는 맥락을 알 수 없는 거대한 텍스트 더미만 남습니다. '세 번째 루프의 특정 도구 호출 결과가 왜 다음 LLM의 엉뚱한 답변으로 이어졌는지'를 추적하려면, 수백 줄의 로그를 일일이 대조해가며 맞춰가는 고통스러운 과정을 거쳐야 합니다. 에이전트가 어떤 생각의 흐름을 거쳐 작동했는지 그 실행 맥락을 입체적으로 복원해 줄 새로운 관측 도구와 표준이 절실해진 이유가 바로 여기에 있습니다.

표준으로 자리 잡는 CNCF GenAI 시맨틱 컨벤션

이 문제를 해결하기 위해 클라우드 네이티브 컴퓨팅 재단은 오픈텔레메트리 GenAI 시맨틱 컨벤션(GenAI Semantic Conventions)이라는 공통 규격을 발전시키고 있습니다. 핵심은 프레임워크나 벤더에 종속되지 않고 AI 요청 모델, 입력 메시지, 토큰 사용량 등을 통일된 규격으로 기록하는 것입니다. 이 표준을 따르는 수집기라면 어디서든 동일하게 해석할 수 있는 공통 언어가 생기는 셈입니다.

가장 앞장서서 이 공식 표준을 지원하는 프레임워크가 바로 Pydantic AI입니다. 복잡한 설정 없이 단 한 줄의 코드로 표준 규격에 맞춘 원격 측정을 활성화할 수 있습니다.

python
from pydantic_ai import Agent

# 오픈텔레메트리 표준 규격에 맞춰 에이전트 추적을 시작합니다
Agent.instrument_all()

이렇게 실행하면 내부적으로 gen_ai.system_instructionsgen_ai.input.messages 같은 공식 gen_ai.* 속성들이 자동으로 추적됩니다. 특정 상용 관측 플랫폼의 전용 도구를 덕지덕지 붙이지 않아도, Jaeger나 SigNoz 같은 표준 오픈소스 수집기만 있으면 에이전트의 내부 루프 상태와 토큰 사용량을 투명하게 추적할 수 있습니다.

프레임워크마다 다른 추적 접근법: LangGraph와 Mastra

에이전트를 움직이는 엔진에 따라 추적 데이터를 구조화하는 전략도 달라집니다. 업계에서 주목받는 두 프레임워크인 LangGraph와 Mastra는 에이전트 루프의 복잡성을 해결하기 위해 서로 다른 흥미로운 길을 선택했습니다.

상태 머신을 기반으로 하는 LangGraph는 복잡한 데이터 흐름을 계층형 트리 구조로 꼼꼼하게 매핑합니다. 전체 그래프 실행을 최상위 루트 스팬으로 설정한 뒤, 그 아래로 개별 노드의 상태 전환과 라우팅을 자식 스팬으로 정렬합니다. 실제 LLM 호출이나 도구 실행은 가장 아래 단계인 손자 스팬에 할당하는 방식입니다. 덕분에 에이전트가 어떤 조건 분기에서 길을 잃었는지, 혹은 무한 루프에 빠져 대기 상태가 길어지는지 시각적으로 한눈에 파악할 수 있습니다.

반면 Mastra는 불필요한 추적 데이터가 지나치게 쌓여 모니터링 환경이 혼잡해지는 문제를 해결하는 데 집중했습니다. 일반적인 오픈텔레메트리 자동 추적을 적용하면 내부 헬퍼 함수나 데이터 변환 과정까지 전부 기록되어 정작 중요한 LLM 호출 기록이 무수한 로그 속에 파묻히게 됩니다. Mastra는 핵심 에이전트 이벤트만 가볍게 로컬에 먼저 기록하는 독자적인 AI 트레이싱 방식을 선택했습니다.

동시에 기존 인프라와의 호환성을 유지하기 위해 양방향으로 동작하는 전용 OTel 브리지를 제공합니다. Mastra v1.x 환경에서는 다음과 같이 가벼운 브리지를 선언하여 적용할 수 있습니다.

ts
import { Mastra } from "@mastra/core/mastra";
import {
  Observability,
  MastraStorageExporter,
  SensitiveDataFilter,
} from "@mastra/observability";

export const mastra = new Mastra({
  observability: new Observability({
    configs: {
      default: {
        serviceName: "my-agent-service",
        exporters: [new MastraStorageExporter()],
        spanOutputProcessors: [new SensitiveDataFilter()],
      },
    },
  }),
});

이렇게 등록된 브리지는 백엔드 APM 솔루션과 연동할 때 복잡한 설정 없이도 Mastra의 로컬 로그를 기존 분산 추적 시스템의 OTel 스팬 컨텍스트에 매끄럽게 편입시킵니다.

이렇듯 에이전트의 상태 흐름 자체를 정밀하게 분석하고 싶다면 LangGraph 같은 계층형 트리 매핑 방식이 직관적입니다. 반면 기존 모니터링 시스템의 로그 부하를 최소화하면서 핵심 데이터만 실용적으로 결합하고 싶다면 Mastra의 양방향 브리지 방식이 훌륭한 대안이 됩니다.

결국 핵심은 투명성입니다

에이전트를 로컬에서 실행하는 단계를 넘어 실제 서비스 환경에 배포하려면 관측 가능성 확보가 필수적입니다. 비결정적인 인공지능 환경에서는 에이전트가 왜 멈췄고 왜 같은 실수를 반복하는지 투명하게 들여다볼 수 있어야만 문제를 빠르게 해결할 수 있기 때문입니다.

다행히 오픈텔레메트리 표준 기술이 빠르게 정착하면서, 이제 특정 벤더에 종속되지 않고 에이전트의 행동을 모니터링할 수 있는 길이 넓어지고 있습니다. 지금 다루고 있는 프레임워크가 추적 데이터를 어떻게 내보내는지 먼저 살펴보세요. 꼬여버린 에이전트 루프의 실타래를 푸는 첫 단추가 될 것입니다.

(수정됨)