fix(api): Langfuse v4.x API 相容性修復

Langfuse SDK v4.0.1 API 變更:
- 移除 client.trace() 方法
- 改用 create_trace_id() + OTEL 整合

修復:
- __enter__: 檢查 trace() 方法存在再使用,否則用 create_trace_id()
- generation/span/score: 加入 hasattr 檢查,v4 改用 debug log

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-03-26 19:34:37 +08:00
parent df04254b57
commit 5f2e5c9763

View File

@@ -123,14 +123,27 @@ class LangfuseTraceContext:
self._otel_trace_id
)
self.trace = self._client.trace(
name=self.name,
metadata=enriched_metadata,
)
# 記錄 Langfuse trace_id 供反向連結
if self.trace:
self._langfuse_trace_id = self.trace.id
# Langfuse v4.x API: 使用 create_trace_id() 取代舊的 trace()
# 舊 API (v2.x): self._client.trace(name=..., metadata=...)
# 新 API (v4.x): 透過 OTEL 整合或裝飾器
if hasattr(self._client, "trace"):
# Legacy API (v2.x)
self.trace = self._client.trace(
name=self.name,
metadata=enriched_metadata,
)
if self.trace:
self._langfuse_trace_id = self.trace.id
else:
# Langfuse v4.x - 使用 create_trace_id() 並記錄
# 完整追蹤依賴 OTEL 整合
self._langfuse_trace_id = self._client.create_trace_id()
logger.debug(
"langfuse_v4_trace_created",
trace_id=self._langfuse_trace_id,
name=self.name,
note="Full tracing via OTEL integration",
)
logger.debug(
"langfuse_trace_started",
@@ -177,25 +190,33 @@ class LangfuseTraceContext:
usage: Token 使用量 {"input": x, "output": y}
metadata: 額外 metadata
"""
if not self.trace:
return None
try:
gen = self.trace.generation(
name=name,
model=model,
input=input,
output=output,
usage=usage,
metadata=metadata or {},
)
return gen
except Exception as e:
logger.warning(
"langfuse_generation_failed",
error=str(e),
# Langfuse v4.x: trace 物件可能不存在,改用 logger 記錄
if self.trace and hasattr(self.trace, "generation"):
try:
gen = self.trace.generation(
name=name,
model=model,
input=input,
output=output,
usage=usage,
metadata=metadata or {},
)
return gen
except Exception as e:
logger.warning(
"langfuse_generation_failed",
error=str(e),
name=name,
model=model,
)
return None
else:
# Langfuse v4.x: 透過 OTEL 追蹤,這裡只記錄 debug log
logger.debug(
"langfuse_generation_logged",
name=name,
model=model,
trace_id=self._langfuse_trace_id,
)
return None
@@ -207,13 +228,15 @@ class LangfuseTraceContext:
name: Span 名稱
metadata: 額外 metadata
"""
if not self.trace:
return None
try:
return self.trace.span(name=name, metadata=metadata or {})
except Exception as e:
logger.warning("langfuse_span_failed", error=str(e), name=name)
if self.trace and hasattr(self.trace, "span"):
try:
return self.trace.span(name=name, metadata=metadata or {})
except Exception as e:
logger.warning("langfuse_span_failed", error=str(e), name=name)
return None
else:
# Langfuse v4.x: OTEL spans
logger.debug("langfuse_span_logged", name=name, trace_id=self._langfuse_trace_id)
return None
def score(
@@ -230,20 +253,26 @@ class LangfuseTraceContext:
value: 分數 (0.0 - 1.0)
comment: 評論
"""
if not self.trace:
return
try:
self.trace.score(
if self.trace and hasattr(self.trace, "score"):
try:
self.trace.score(
name=name,
value=value,
comment=comment,
)
except Exception as e:
logger.warning(
"langfuse_score_failed",
error=str(e),
name=name,
)
else:
# Langfuse v4.x: score via OTEL attributes
logger.debug(
"langfuse_score_logged",
name=name,
value=value,
comment=comment,
)
except Exception as e:
logger.warning(
"langfuse_score_failed",
error=str(e),
name=name,
trace_id=self._langfuse_trace_id,
)