AI 관찰 가능성: LLM, 토큰 및 에이전트 모니터링
대규모 채택으로 대형 언어 모델(LLM) 생산 중에 등장 관찰 가능성의 새로운 영역: AI 기반 애플리케이션 모니터링. 통화 LLM은 기존 API와 비교하여 고유한 특성을 가지고 있습니다. 즉, 가변 비용 기반 토큰 사용, 예측할 수 없는 대기 시간, 비결정적 출력 및 위험에 대해 환각. 그만큼'AI 관찰 가능성 고전적인 관찰 가능성의 원칙을 적용합니다. 이 새로운 패러다임에.
이 기사에서는 언어 모델 호출을 계측하는 방법을 살펴보겠습니다. AI 에이전트 행동 추적, 실시간 비용 모니터링 및 감지 OpenTelemetry 및 새로운 의미 체계를 사용한 모델 응답의 이상 현상 AI를 위해.
이 기사에서 배울 내용
- AI 애플리케이션에는 전문적인 관찰 가능성이 필요하기 때문입니다.
- 특정 범위 및 속성을 사용하여 LLM 호출 추적
- 실시간으로 토큰 사용량 및 비용 모니터링
- AI 에이전트의 행동 관찰(툴 호출, 추론)
- 환각 및 품질 저하 감지
- AI 관찰성을 위한 프레임워크 및 도구
AI 애플리케이션에는 전문적인 관찰 가능성이 필요하기 때문입니다.
LLM 기반 응용 프로그램은 근본적으로 다른 특성을 가지고 있습니다. 관찰 가능성의 관점에서 기존 애플리케이션에서:
AI 관찰 가능성의 고유한 과제
| 도전 | 전통적인 응용 | AI/LLM 응용 |
|---|---|---|
| 소송 비용 | 고정(컴퓨팅, 스토리지) | 변수(토큰당, 요청당) |
| 숨어 있음 | 예측 가능(ms 범위) | 높음 및 가변성(스트림당 1~60초) |
| 출력 | 결정적 | 비결정적(온도, 샘플링) |
| 오류 | 상태 코드 지우기 | 환각, 일관되지 않은 반응 |
| 테스트 | 결정적 단위 테스트 | 정성평가(eval) |
LLM 통화 계측
언어 모델 호출의 계측은 OTel과 동일한 패턴을 따릅니다. 외부 API용이지만 AI 메타데이터를 캡처하기 위한 특정 속성 포함: 템플릿 사용, 토큰 수, 온도, 예상 비용.
from opentelemetry import trace, metrics
import time
import tiktoken
tracer = trace.get_tracer("ai-service", "1.0.0")
meter = metrics.get_meter("ai-service", "1.0.0")
# Metriche specifiche per LLM
llm_token_usage = meter.create_counter(
name="llm.token.usage",
description="Token utilizzati nelle chiamate LLM",
unit="token"
)
llm_request_duration = meter.create_histogram(
name="llm.request.duration",
description="Durata delle chiamate LLM",
unit="ms"
)
llm_cost = meter.create_counter(
name="llm.cost.total",
description="Costo stimato delle chiamate LLM",
unit="USD"
)
def call_llm(messages, model="gpt-4", temperature=0.7, max_tokens=1000):
with tracer.start_as_current_span(
"llm.chat.completion",
attributes={
# Semantic conventions per AI (draft)
"gen_ai.system": "openai",
"gen_ai.request.model": model,
"gen_ai.request.temperature": temperature,
"gen_ai.request.max_tokens": max_tokens,
"gen_ai.request.top_p": 1.0,
# Contesto applicativo
"llm.prompt.messages_count": len(messages),
"llm.prompt.system_prompt_length": len(messages[0]["content"])
if messages[0]["role"] == "system" else 0,
}
) as span:
start_time = time.monotonic()
try:
# Conteggio token input (pre-chiamata)
encoding = tiktoken.encoding_for_model(model)
input_tokens = sum(
len(encoding.encode(m["content"])) for m in messages
)
span.set_attribute("gen_ai.usage.prompt_tokens", input_tokens)
# Chiamata al modello
response = openai_client.chat.completions.create(
model=model,
messages=messages,
temperature=temperature,
max_tokens=max_tokens
)
# Attributi dalla risposta
output_tokens = response.usage.completion_tokens
total_tokens = response.usage.total_tokens
span.set_attribute("gen_ai.usage.completion_tokens", output_tokens)
span.set_attribute("gen_ai.usage.total_tokens", total_tokens)
span.set_attribute("gen_ai.response.model", response.model)
span.set_attribute("gen_ai.response.finish_reason",
response.choices[0].finish_reason)
# Calcolo costo stimato
cost = estimate_cost(model, input_tokens, output_tokens)
span.set_attribute("llm.cost.estimated_usd", cost)
# Registrare metriche
duration_ms = (time.monotonic() - start_time) * 1000
common_attrs = {
"gen_ai.system": "openai",
"gen_ai.request.model": model
}
llm_token_usage.add(input_tokens,
{**common_attrs, "gen_ai.token.type": "input"})
llm_token_usage.add(output_tokens,
{**common_attrs, "gen_ai.token.type": "output"})
llm_request_duration.record(duration_ms, common_attrs)
llm_cost.add(cost, common_attrs)
span.set_status(StatusCode.OK)
return response
except RateLimitError as e:
span.record_exception(e)
span.set_status(StatusCode.ERROR, "Rate limit exceeded")
span.set_attribute("llm.error.type", "rate_limit")
raise
except Exception as e:
span.record_exception(e)
span.set_status(StatusCode.ERROR, str(e))
raise
AI 에이전트 추적
그만큼 AI 에이전트 LLM을 사용하여 추론하고, 계획하고, 도구(도구 호출)를 호출하여 복잡한 작업을 완료합니다. 그들의 행동과 여러 추론 주기가 필요하기 때문에 관찰하기가 특히 어렵습니다. 도구 선택 결정 및 결과 구성.
def trace_agent_execution(task, agent):
with tracer.start_as_current_span(
"agent.execute",
attributes={
"agent.name": agent.name,
"agent.model": agent.model,
"agent.task": task.description,
"agent.max_iterations": agent.max_iterations,
"agent.tools_available": ",".join(agent.tool_names)
}
) as agent_span:
iteration = 0
total_tokens = 0
total_cost = 0.0
tools_called = []
while not agent.is_done() and iteration < agent.max_iterations:
iteration += 1
# Span per ogni iterazione del reasoning loop
with tracer.start_as_current_span(
f"agent.iteration.{iteration}",
attributes={
"agent.iteration": iteration,
"agent.state": agent.current_state
}
) as iter_span:
# Span per la chiamata LLM di reasoning
with tracer.start_as_current_span("agent.reasoning") as reason_span:
decision = agent.reason(task)
reason_span.set_attribute("agent.decision.type",
decision.type) # "tool_call" | "final_answer"
reason_span.set_attribute("agent.decision.confidence",
decision.confidence)
total_tokens += decision.tokens_used
# Se l'agente decide di chiamare un tool
if decision.type == "tool_call":
with tracer.start_as_current_span(
"agent.tool_call",
attributes={
"agent.tool.name": decision.tool_name,
"agent.tool.input_summary": decision.tool_input[:200]
}
) as tool_span:
result = agent.execute_tool(decision)
tool_span.set_attribute("agent.tool.success",
result.success)
tool_span.set_attribute("agent.tool.output_length",
len(str(result.output)))
tools_called.append(decision.tool_name)
# Attributi finali dell'agente
agent_span.set_attribute("agent.iterations_total", iteration)
agent_span.set_attribute("agent.tokens_total", total_tokens)
agent_span.set_attribute("agent.cost_total_usd", total_cost)
agent_span.set_attribute("agent.tools_called",
",".join(tools_called))
agent_span.set_attribute("agent.success", agent.is_done())
실시간 비용 모니터링
특히 GPT-4와 같은 모델의 경우 LLM 통화 비용이 빠르게 확장될 수 있습니다. 아니면 클로드. 실시간 비용 모니터링을 통해 이상 징후(루프)를 감지할 수 있습니다. 무한한 토큰 소비), 예산 알림을 설정하고 템플릿 사용을 최적화하세요.
# Alert rules Prometheus per AI cost monitoring
groups:
- name: ai-cost-alerts
rules:
# Alert: spesa oraria sopra il budget
- alert: HighAICostPerHour
expr: |
sum(rate(llm_cost_total[1h])) * 3600 > 50
for: 5m
labels:
severity: warning
annotations:
summary: "AI cost exceeding $50/hour"
# Alert: tasso di errori LLM alto
- alert: HighLLMErrorRate
expr: |
rate(llm_request_duration_count{status="error"}[5m])
/ rate(llm_request_duration_count[5m]) > 0.1
for: 3m
labels:
severity: critical
annotations:
summary: "LLM error rate above 10%"
# Alert: latenza LLM degradata
- alert: HighLLMLatency
expr: |
histogram_quantile(0.95,
rate(llm_request_duration_bucket[5m])
) > 30000
for: 5m
labels:
severity: warning
annotations:
summary: "LLM P95 latency above 30 seconds"
# Alert: anomalia token usage
- alert: AnomalousTokenUsage
expr: |
rate(llm_token_usage[5m]) > 3 * avg_over_time(rate(llm_token_usage[1h])[24h:1h])
for: 10m
labels:
severity: warning
annotations:
summary: "Token usage 3x above 24h average"
AI 관찰 가능성에 대한 주요 지표
- 토큰 사용: 모델별, 엔드포인트별, 사용자별 입력/출력 토큰
- 요청당 비용: 사용된 모델 및 토큰을 기반으로 한 비용 추정
- TFTT 대기 시간: 스트리밍 애플리케이션에 중요한 Time To First Token
- 오류율: 속도 제한, 시간 초과, 모델 오류
- 종료 이유: 배포 중지, max_tokens, tool_call, content_filter
- 에이전트 반복: 완료된 작업당 추론 주기 수
- 도구 호출 성공률: 성공한 도구 호출과 실패한 도구 호출의 비율
환각 감지 및 품질
모니터링 답변의 질 그리고 AI의 독특한 측면 관찰 가능성. 기술적 오류(시간 초과, 속도 제한)는 쉽게 감지할 수 있지만 환각 및 품질이 낮은 응답에는 대리 측정법 및 평가가 필요합니다. 자동.
응답 품질에 대한 프록시 신호
응답 길이: 답변이 너무 짧거나 너무 길어요 존경합니다
평균을 내는 것은 품질 문제를 나타낼 수 있습니다.
비정상 종료 사유: 높은 비율 max_tokens 나타냅니다
잘린 응답; 높은 비율 content_filter 차단된 콘텐츠를 나타냅니다.
사용자 피드백: 응답 후 사용자의 행동을 추적합니다(재시도,
거절, 포기)를 품질의 간접적인 신호로 간주합니다.
유사성 점수: 답변을 참조 답변과 비교
임베딩을 사용하여 품질의 드리프트를 감지합니다.
AI 관찰성을 위한 프레임워크
AI 관찰 가능성을 단순화하기 위해 여러 프레임워크가 등장하고 있습니다. 주요 AI 라이브러리 및 사전 구성된 대시보드를 위한 자동 계측입니다. 가장 관련성이 높은 것 중: OpenLLMetry (LLM용 OTel 기반) 랭스미스 (랭체인의 경우), 헬리콥터 (OpenAI용 프록시) 그리고 GenAI에 대한 Otel 의미 규칙 (신흥 표준).
결론 및 다음 단계
AI 관측 가능성은 관측 가능성의 원칙을 확장하는 빠르게 발전하는 분야입니다. 고전적인 LLM 기반 응용 프로그램. 고유한 과제(가변 비용, 비생산물) 결정론적, 환각)에는 전문적인 지표와 모니터링 패턴이 필요합니다.
AI 관찰 가능성의 세 가지 기둥은 다음과 같습니다. 비용 모니터링 (토큰 사용, 요청당 비용), 성능 모니터링 (지연 시간, TTFT, 오류율) 전자 품질 모니터링 (완료 이유, 사용자 피드백, 유사성 점수).
시리즈의 다음 기사이자 마지막 기사에서는 완전한 사례 연구: 마이크로서비스 아키텍처를 위한 관찰 시스템의 엔드투엔드 구현, OpenTelemetry를 채택하기 전과 후에 측정항목을 사용합니다.







