You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Spring AI 1.1.4에도 provider Usage 기반 gen_ai.client.token.usage가 있으므로 현재 token usage metric은 의미가 중복될 수 있다. cost description도 “estimated”로 고정되어 있고, TokenPilot의 차별점인 preflight decision, reservation, pricing miss와 actual reconciliation 지표는 없다.
또한 현재 MetricsOptions.DEFAULT_ALLOWED_TAG_KEYS는 tenant_id다. whitelist는 key만 제한하며 tenant 값의 cardinality를 제한하지 않으므로 “모든 기본 tag가 bounded”라는 목표와 충돌한다.
DefaultLedgerManager는 listener를 순차 호출하며 첫 예외를 그대로 전파한다. optional metric sink의 실패가 성공한 accounting transition이나 provider 응답을 뒤집으면 안 된다. listener failure/state/event 순서는 #46과 #37이 소유하며, 이 이슈는 그 event와 정책을 Micrometer adapter에서 소비한다.
기본 metric 계약
Metric
타입
기본 bounded tag
tokenpilot.cost.total
Counter
currency
tokenpilot.preflight.requests
Counter
decision, reason
tokenpilot.budget.reservations
Counter
state
tokenpilot.reconciliation.error.tokens
DistributionSummary
direction
tokenpilot.reconciliation.outcomes
Counter
outcome, reason
tokenpilot.pricing.missing
Counter
policy
tokenpilot.listener.failures
Counter
listener, phase
tokenpilot.notification.events
Counter
outcome, threshold
reconciliation token 오차는 절대값을 기록하고 direction=underestimate|overestimate|exact으로 방향을 구분한다.
actual unavailable은 0 오차가 아니라 RECONCILIATION_REQUIRED outcome이다.
cost는 #37의 newly COMMITTED actual cost인 경우에만 증가한다.
missing pricing은 0원 cost로 기록하지 않고 tokenpilot.pricing.missing으로 구분한다.
문제와 현재 코드 근거
현재
MicroCostMetricsPublisher는 다음 metric을 기본 발행한다.ai.token.usage.totalai.token.usage.distributionai.token.cost.totalSpring AI 1.1.4에도 provider
Usage기반gen_ai.client.token.usage가 있으므로 현재 token usage metric은 의미가 중복될 수 있다. cost description도 “estimated”로 고정되어 있고, TokenPilot의 차별점인 preflight decision, reservation, pricing miss와 actual reconciliation 지표는 없다.또한 현재
MetricsOptions.DEFAULT_ALLOWED_TAG_KEYS는tenant_id다. whitelist는 key만 제한하며 tenant 값의 cardinality를 제한하지 않으므로 “모든 기본 tag가 bounded”라는 목표와 충돌한다.DefaultLedgerManager는 listener를 순차 호출하며 첫 예외를 그대로 전파한다. optional metric sink의 실패가 성공한 accounting transition이나 provider 응답을 뒤집으면 안 된다. listener failure/state/event 순서는 #46과 #37이 소유하며, 이 이슈는 그 event와 정책을 Micrometer adapter에서 소비한다.기본 metric 계약
tokenpilot.cost.totalcurrencytokenpilot.preflight.requestsdecision,reasontokenpilot.budget.reservationsstatetokenpilot.reconciliation.error.tokensdirectiontokenpilot.reconciliation.outcomesoutcome,reasontokenpilot.pricing.missingpolicytokenpilot.listener.failureslistener,phasetokenpilot.notification.eventsoutcome,thresholddirection=underestimate|overestimate|exact으로 방향을 구분한다.RECONCILIATION_REQUIREDoutcome이다.tokenpilot.pricing.missing으로 구분한다.double기반 운영 뷰이며 BigDecimal 회계 원장이 아니다.기본 tag와 cardinality 정책
MetricsOptions.allowedTagKeys기본값을 빈 집합으로 변경한다.tenant_id,user_id,request_id, reservation/idempotency ID는 기본 tag가 아니다.modeltag는 기본 생략하거나 설정으로 opt-in한다. 활성화 시 [Core] versioned ModelRegistry와 최소 모델 정책 등록 #32 ModelRegistry의 canonical model id만 허용하고 raw/unknown response model 문자열을 그대로 tag로 쓰지 않는다.tenant_id기본 허용 변경은 migration note에 기록한다.legacy
ai.token.*정책ai.token.usage.total,ai.token.usage.distribution,ai.token.cost.total은 starter/autoconfigure 기본값에서 비활성화한다.token-pilot.metrics.legacy-ai-token-metrics-enabled=true와 같은 opt-in 설정을 사용한다.tokenpilot.*metric은 Spring AI latency, trace와 provider input/output/total token metric을 복제하지 않는다.domain event 연결
MeterRegistry를 조작하지 않는다.token-pilot-micrometer가 Budget/Notification event를 소비하는 module dependency 또는 조건부 publisher 구조를 명시하고 external consumer POM에서 검증한다.MeterRegistry가 있고 metrics enabled일 때만 autoconfigure하며 사용자 bean을 우선한다.Listener 실패 정책 소비
#46/#37이 정의한 정책을 다음처럼 검증한다.
tokenpilot.listener.failures와 sanitized error handler로 관측한다.테스트
tokenpilot.cost.total을 증가시킨다.allowedTagKeys가 empty이고 tenant/user/request ID가 노출되지 않는다.ai.token.*은 autoconfigure 기본값에서 발행되지 않고 명시적 opt-in에서만 발행된다.Acceptance criteria
ai.token.*은 starter/autoconfigure 기본 off이며 migration 설정과 문서가 있다.제외 범위
의존관계와 순서
Source