OpenTelemetry GenAI 시맨틱 컨벤션
OpenTelemetry의 GenAI SIG는 2024년 4월에 출범했으며, 에이전트 텔레메트리(agent telemetry)를 위한 표준 스키마(schema)를 정의합니다. 스팬(span) 이름, 속성(attribute), 콘텐츠 캡처(content capture) 규칙이 공급사 전반에서 수렴하면, Datadog, Grafana, Jaeger, Honeycomb 어디에서 보더라도 에이전트 추적(agent trace)이 같은 의미를 갖게 됩니다.
유형: Learn + Build
언어: Python (stdlib)
선수 학습: Phase 14 · 13 (LangGraph), Phase 14 · 24 (Observability Platforms)
소요 시간: 약 60분
학습 목표
- GenAI 스팬 범주를 말할 수 있습니다. 모델/클라이언트(model/client), 에이전트(agent), 도구(tool)가 있습니다.
invoke_agent의 CLIENT 스팬과 INTERNAL 스팬을 구분하고, 각각 언제 적용되는지 설명합니다.
- 최상위 GenAI 속성을 나열합니다. 공급자 이름(provider name), 요청 모델(request model), 데이터 소스 ID(data-source ID)가 포함됩니다.
- 콘텐츠 캡처 계약을 설명합니다. 옵트인(opt-in),
OTEL_SEMCONV_STABILITY_OPT_IN, 외부 참조(external-reference) 권장 방식이 핵심입니다.
문제
모든 공급사가 각자의 스팬 이름을 발명합니다. 운영팀은 프레임워크별 대시보드를 따로 만들게 됩니다. OpenTelemetry의 GenAI SIG는 생태계 전체가 목표로 삼을 하나의 표준을 정의함으로써 이 문제를 해결합니다.
개념
스팬 범주
- 모델/클라이언트 스팬(Model / client spans). 원시 LLM 호출(raw LLM calls)을 다룹니다. 공급자 SDK(Anthropic, OpenAI, Bedrock)와 프레임워크 모델 어댑터가 내보냅니다.
- 에이전트 스팬(Agent spans).
create_agent는 에이전트가 생성될 때, invoke_agent는 에이전트가 실행될 때 사용합니다.
- 도구 스팬(Tool spans). 도구 호출(tool invocation)마다 하나씩 생성됩니다. 부모-자식 관계(parent-child relation)를 통해 에이전트 스팬에 연결됩니다.
에이전트 스팬 이름 지정
- 스팬 이름: 이름이 있으면
invoke_agent {gen_ai.agent.name}이고, 없으면 invoke_agent로 폴백(fallback)합니다.
- 스팬 종류(span kind):
- CLIENT — 원격 에이전트 서비스에 사용합니다. OpenAI Assistants API, Bedrock Agents가 여기에 해당합니다.
- INTERNAL — 프로세스 내부 에이전트 프레임워크에 사용합니다. LangChain, CrewAI, 로컬 ReAct가 여기에 해당합니다.
핵심 속성
gen_ai.provider.name — anthropic, openai, aws.bedrock, google.vertex.
gen_ai.request.model — 요청한 모델 ID입니다.
gen_ai.response.model — 실제로 결정된 모델입니다. 라우팅(routing) 때문에 요청 모델과 다를 수 있습니다.
gen_ai.agent.name — 에이전트 식별자입니다.
gen_ai.operation.name — chat, completion, invoke_agent, tool_call.
gen_ai.data_source.id — RAG에서 어떤 말뭉치(corpus)나 저장소(store)를 조회했는지 나타냅니다.
Anthropic, Azure AI Inference, AWS Bedrock, OpenAI를 위한 기술별 컨벤션도 존재합니다.
콘텐츠 캡처
기본 규칙은 다음과 같습니다. 계측(instrumentation)은 기본적으로 입력/출력을 캡처하지 않아야 합니다. 캡처는 다음 속성을 통해 옵트인으로만 켭니다.
gen_ai.system_instructions
gen_ai.input.messages
gen_ai.output.messages
프로덕션에서 권장되는 패턴은 콘텐츠를 외부에 저장하는 것입니다. S3나 자체 로그 저장소에 콘텐츠를 저장하고, 스팬에는 참조(pointer ID)만 기록합니다. 문장을 그대로 넣지 않습니다. 이는 27강의 콘텐츠 오염(content poisoning) 방어를 관측성에 연결한 방식입니다.
안정성
2026년 3월 기준 대부분의 컨벤션은 실험적(experimental)입니다. 안정 프리뷰(stable preview)를 쓰려면 다음 환경 변수를 설정합니다.
OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental
Datadog v1.37+는 GenAI 속성을 자체 LLM Observability 스키마에 네이티브로 매핑합니다. 다른 백엔드(Grafana, Honeycomb, Jaeger)는 원시 속성(raw attributes)을 지원합니다.
이 패턴이 잘못되는 지점
- 전체 프롬프트를 스팬에 캡처하는 경우. PII, 시크릿(secrets), 고객 데이터가 운영자가 읽을 수 있는 추적에 들어갑니다. 외부에 저장해야 합니다.
gen_ai.provider.name이 없는 경우. 공급자가 여러 개인 대시보드는 출처 식별(attribution)이 빠지면 깨집니다.
- 부모 링크가 없는 스팬. 고아(orphaned) 도구 스팬이 생깁니다. 항상 컨텍스트(context)를 전파해야 합니다.
- 안정성 옵트인을 설정하지 않는 경우. 백엔드 업그레이드 때 속성 이름이 바뀔 수 있습니다.
만들어보기
code/main.py는 GenAI 컨벤션에 맞춘 stdlib 스팬 방출기(span emitter)를 구현합니다.
- GenAI 속성 스키마를 가진
Span입니다.
start_span과 중첩 컨텍스트(nested contexts)를 가진 Tracer입니다.
- 스크립트형 에이전트 실행이
create_agent, invoke_agent(INTERNAL), 도구별 스팬, LLM 호출용 chat 스팬을 내보냅니다.
- 프롬프트를 외부에 저장하고 스팬에는 ID만 기록하는 콘텐츠 캡처 모드입니다.
실행합니다.
python3 code/main.py
출력은 필요한 모든 GenAI 속성을 가진 스팬 트리와, 옵트인 콘텐츠 참조를 담은 "외부 저장소(external store)"를 함께 보여줍니다.
사용해보기
- Datadog LLM Observability(v1.37+)는 속성을 네이티브로 매핑합니다.
- Langfuse / Phoenix / Opik(24강)은 생태계 계측을 자동화합니다.
- Jaeger / Honeycomb / Grafana Tempo는 원시 OTel 추적을 다룹니다. GenAI 속성으로 대시보드를 만들 수 있습니다.
- 자체 호스팅(Self-hosted)에서는 GenAI 처리기(processor)를 포함한 OTel Collector를 실행합니다.
산출물 만들기
outputs/skill-otel-genai.md는 기존 에이전트에 OTel GenAI 스팬을 연결하고, 콘텐츠 캡처 기본값과 외부 참조 저장소를 설정합니다.
연습문제
- 1강 ReAct 루프를
invoke_agent(INTERNAL)와 도구별 스팬으로 계측하세요. Jaeger 인스턴스로 보냅니다.
- "참조만 저장(references only)" 모드로 콘텐츠 캡처를 추가하세요. 프롬프트는 SQLite에 저장하고, 스팬 속성에는 행 ID만 담습니다.
gen_ai.data_source.id 스펙을 읽어보세요. 9강 Mem0 검색에 연결합니다.
OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental을 설정하고, Collector가 속성 이름을 바꾸지 않는지 확인합니다.
- GenAI 속성만 사용해 "어떤 도구 오류가 어떤 모델과 상관되는가" 대시보드를 만드세요.
핵심 용어
| 용어 | 흔한 설명 | 실제 의미 |
|---|
| GenAI SIG | "OpenTelemetry GenAI 그룹" | 스키마를 정의하는 OTel 작업 그룹(working group)입니다. |
invoke_agent | "에이전트 스팬" | 에이전트 실행을 나타내는 스팬의 이름입니다. |
| CLIENT 스팬(CLIENT span) | "원격 호출" | 원격 에이전트 서비스 호출을 나타내는 스팬입니다. |
| INTERNAL 스팬(INTERNAL span) | "프로세스 내부" | 프로세스 내부 에이전트 실행을 나타내는 스팬입니다. |
gen_ai.provider.name | "공급자" | anthropic, openai, aws.bedrock, google.vertex 같은 값입니다. |
gen_ai.data_source.id | "RAG 소스" | 검색이 맞힌 말뭉치나 저장소를 나타냅니다. |
| 콘텐츠 캡처(Content capture) | "프롬프트 로깅" | 메시지 캡처는 옵트인입니다. 프로덕션에서는 외부에 저장합니다. |
| 안정성 옵트인(Stability opt-in) | "프리뷰 모드" | 실험적 컨벤션을 고정하기 위한 환경 변수입니다. |
더 읽을거리