Python v2 → v3
Python v2 → v3
Python SDK v2를 사용 중이라면 최신 메이저인 v4로 직접 업그레이드할 것을 권장해요. Python v3 → v4 마이그레이션 가이드를 참고하세요. 아래의 v2 → v3 변경 사항이 여전히 적용되므로 먼저 완료한 뒤 v3 → v4 가이드를 따르세요.
출처: 문서
본문
Python SDK v3은 레거시 v2 SDK에 비해 상당한 개선과 변경을 도입해요. 완전히 하위 호환되지는 않아요. 이 포괄적인 가이드는 현재 통합 방식에 따라 마이그레이션을 도와줘요.
v2 SDK 문서 스냅샷은 계속 제공돼요.
중요: 업그레이드 전에 제3자 OpenTelemetry span 검토하기
Langfuse SDK는 이제 OpenTelemetry 네이티브예요. 업그레이드 후 Langfuse는 애플리케이션의 다른 OpenTelemetry 계측 라이브러리가 내보낸 span(데이터베이스, HTTP, 프레임워크 계측 등)도 캡처할 수 있어요.
이로 인해 LLM 관찰성과 관련 없는 인프라 span이 많이 추가되어 Langfuse 비용이 크게 늘 수 있어요. 업그레이드를 널리 배포하기 전에 트레이스를 검토하고 계측 범위 필터링 가이드를 사용해 원치 않는 span을 계측 범위별로 걸러내세요.
SDK v2의 핵심 변경 사항:
- OpenTelemetry 기반: v3은 OpenTelemetry 표준 위에 구축됨
- 트레이스 입력/출력: 이제 기본적으로 루트 observation에서 파생
- 트레이스 속성 (user_id, session_id 등): 둘러싸는 span에서 설정하거나 통합의 metadata 필드(OpenAI 호출, Langchain 호출)로 직접 설정할 수 있음
- 컨텍스트 관리: 자동 OTEL 컨텍스트 전파
통합 유형별 마이그레이션 경로
@observe 데코레이터 사용자
v2 패턴:
from langfuse.decorators import langfuse_context, observe
@observe()
def my_function():
# This was the trace
langfuse_context.update_current_trace(user_id="user_123")
return "result"
v3 마이그레이션:
from langfuse import observe, get_client # new import
@observe()
def my_function():
# This is now the root span, not the trace
langfuse = get_client()
# Update trace explicitly
langfuse.update_current_trace(user_id="user_123")
return "result"
OpenAI 통합
v2 패턴:
from langfuse.openai import openai
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
# Trace attributes directly on the call
user_id="user_123",
session_id="session_456",
tags=["chat"],
metadata={"source": "app"}
)
v3 마이그레이션:
추가 트레이스 속성을 설정하지 않는다면 변경이 필요 없어요.
추가 트레이스 속성을 설정한다면 두 가지 옵션이 있어요:
옵션 1: metadata 필드 사용(가장 간단한 마이그레이션):
from langfuse.openai import openai
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
metadata={
"langfuse_user_id": "user_123",
"langfuse_session_id": "session_456",
"langfuse_tags": ["chat"],
"source": "app" # Regular metadata still works
}
)
옵션 2: 둘러싸는 span 사용(더 많은 제어):
from langfuse import get_client, propagate_attributes
from langfuse.openai import openai
langfuse = get_client()
with langfuse.start_as_current_observation(as_type="span", name="chat-request") as span:
with propagate_attributes(
user_id="user_123",
session_id="session_456",
tags=["chat"],
):
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
metadata={"source": "app"}
)
# Set trace input and output explicitly
span.update_trace(
output={"response": response.choices[0].message.content},
input={"query": "Hello"},
)
update_trace()는 Python SDK v4에서 deprecated예요. v3 → v4 마이그레이션 가이드를 참고하세요.
LangChain 통합
v2 패턴:
from langfuse.callback import CallbackHandler
handler = CallbackHandler(
user_id="user_123",
session_id="session_456",
tags=["langchain"]
)
response = chain.invoke({"input": "Hello"}, config={"callbacks": [handler]})
v3 마이그레이션:
트레이스 속성을 설정하는 두 가지 옵션이 있어요:
옵션 1: chain 호출에서 metadata 필드 사용(가장 간단한 마이그레이션):
from langfuse.langchain import CallbackHandler
handler = CallbackHandler()
response = chain.invoke(
{"input": "Hello"},
config={
"callbacks": [handler],
"metadata": {
"langfuse_user_id": "user_123",
"langfuse_session_id": "session_456",
"langfuse_tags": ["langchain"]
}
}
)
옵션 2: 둘러싸는 span 사용(더 많은 제어):
from langfuse import get_client, propagate_attributes
from langfuse.langchain import CallbackHandler
langfuse = get_client()
with langfuse.start_as_current_observation(as_type="span", name="langchain-request") as span:
with propagate_attributes(
user_id="user_123",
session_id="session_456",
tags=["langchain"],
):
handler = CallbackHandler()
response = chain.invoke({"input": "Hello"}, config={"callbacks": [handler]})
# Set trace input and output explicitly
span.update_trace(
input={"query": "Hello"},
output={"response": response}
)
update_trace()는 Python SDK v4에서 deprecated예요. v3 → v4 마이그레이션 가이드를 참고하세요.
LlamaIndex 통합 사용자
v2 패턴:
from langfuse.llama_index import LlamaIndexCallbackHandler
handler = LlamaIndexCallbackHandler()
Settings.callback_manager = CallbackManager([handler])
response = index.as_query_engine().query("Hello")
v3 마이그레이션:
from langfuse import get_client, propagate_attributes
from openinference.instrumentation.llama_index import LlamaIndexInstrumentor
# Use third-party OTEL instrumentation
LlamaIndexInstrumentor().instrument()
langfuse = get_client()
with langfuse.start_as_current_observation(as_type="span", name="llamaindex-query") as span:
with propagate_attributes(
user_id="user_123",
):
response = index.as_query_engine().query("Hello")
span.update_trace(
input={"query": "Hello"},
output={"response": str(response)}
)
update_trace()는 Python SDK v4에서 deprecated예요. v3 → v4 마이그레이션 가이드를 참고하세요.
Low-Level SDK 사용자
v2 패턴:
from langfuse import Langfuse
langfuse = Langfuse()
trace = langfuse.trace(
name="my-trace",
user_id="user_123",
input={"query": "Hello"}
)
generation = trace.generation(
name="llm-call",
model="gpt-4o"
)
generation.end(output="Response")
v3 마이그레이션:
v3에서는 모든 span / generation이 반환된 객체에서 .end()를 호출해 종료되어야 해요.
from langfuse import get_client, propagate_attributes
langfuse = get_client()
# Use context managers instead of manual objects
with langfuse.start_as_current_observation(
as_type="span",
name="my-trace",
input={"query": "Hello"} # Becomes trace input automatically
) as root_span:
# Propagate trace attributes to all child observations
with propagate_attributes(
user_id="user_123",
):
with langfuse.start_as_current_observation(
as_type="generation",
name="llm-call",
model="gpt-4o"
) as generation:
generation.update(output="Response")
# If needed, override trace output
root_span.update_trace(
input={"query": "Hello"},
output={"response": "Response"}
)
update_trace()는 Python SDK v4에서 deprecated예요. v3 → v4 마이그레이션 가이드를 참고하세요.
핵심 마이그레이션 체크리스트
-
Import 업데이트:
- 환경 변수로 구성된 전역 클라이언트 인스턴스에 접근하려면
from langfuse import get_client사용 - 생성자 파라미터로 구성된 새 클라이언트 인스턴스를 만들려면
from langfuse import Langfuse사용 - observe 데코레이터를 import하려면
from langfuse import observe사용 - 통합 import 업데이트:
from langfuse.langchain import CallbackHandler
- 환경 변수로 구성된 전역 클라이언트 인스턴스에 접근하려면
-
트레이스 속성 패턴:
- 옵션 1: 통합 호출에서 metadata 필드(langfuse_user_id, langfuse_session_id, langfuse_tags) 직접 사용
- 옵션 2: user_id, session_id, tags를 propagate_attributes()로 이동
-
트레이스 입력/출력:
- LLM-as-a-judge에 중요: 트레이스 입력/출력 명시적 설정
- 특정 값이 필요하면 루트 observation에서의 자동 파생에 의존하지 마세요
-
컨텍스트 매니저:
-
LlamaIndex 마이그레이션:
- Langfuse 콜백을 제3자 OTEL 계측으로 교체
- 설치:
pip install openinference-instrumentation-llama-index
-
ID 관리:
from langfuse import Langfuse, observe
# v3: Generate deterministic trace ID from external system
external_request_id = "req_12345"
trace_id = Langfuse.create_trace_id(seed=external_request_id)
@observe(langfuse_trace_id=trace_id)
def my_function():
# This trace will have the deterministic ID
pass
-
초기화:
- 생성자 파라미터 교체:
enabled→tracing_enabledthreads→media_upload_thread_count
- 생성자 파라미터 교체:
-
데이터셋:
- 데이터셋 아이템 객체의
link메서드는 데이터셋 아이템의run메서드로 접근할 수 있는 컨텍스트 매니저로 대체됐어요. 이는 트레이스 생성과 데이터셋 아이템-결과 트레이스 연결을 관리하는 더 높은 수준의 추상화예요. - 자세한 내용은 데이터셋 문서를 참고하세요.
- 데이터셋 아이템 객체의
상세 변경 요약
-
핵심 변경: OpenTelemetry 기반
- 더 나은 생태계 호환성을 위해 OpenTelemetry 표준 위에 구축
-
트레이스 입력/출력 동작:
- v2: 통합이 트레이스 입력/출력을 직접 설정할 수 있음
- v3: 트레이스 입력/출력이 기본적으로 루트 observation에서 파생
- 마이그레이션:
span.update_trace(input=..., output=...)로 명시적 설정
-
트레이스 속성 위치:
-
Observation 생성:
- v2:
langfuse.trace(),langfuse.span(),langfuse.generation() - v3:
langfuse.start_as_current_observation() - 마이그레이션: 컨텍스트 매니저 사용,
.end()호출 또는 with 문 사용 확인
- v2:
-
ID 및 컨텍스트:
- v3: W3C Trace Context 형식, 자동 컨텍스트 전파
- 마이그레이션:
get_trace_id()대신langfuse.get_current_trace_id()사용 - 이벤트 크기 제한:
- v2: 이벤트가 1MB로 제한됨
- v3: 이벤트에 SDK 측 크기 제한 없음
향후 v2 지원
당분간 v2 SDK의 중요 버그 수정과 보안 패치를 계속 지원할 거예요. v2 SDK에 새 기능은 추가하지 않아요. v2 SDK 문서 스냅샷은 계속 제공돼요.
JS/TS SDK v3 → v4
애플리케이션을 v3에서 v4로 업그레이드하려면 아래 각 섹션을 따르세요.
업그레이드 중 질문이나 문제가 생기면 GitHub에 이슈를 올려 주세요.
중요: 업그레이드 전에 제3자 OpenTelemetry span 검토하기
Langfuse SDK는 이제 OpenTelemetry 네이티브예요. 업그레이드 후 Langfuse는 애플리케이션의 다른 OpenTelemetry 계측 라이브러리가 내보낸 span(데이터베이스, HTTP, 프레임워크 계측 등)도 캡처할 수 있어요.
이로 인해 LLM 관찰성과 관련 없는 인프라 span이 많이 추가되어 Langfuse 비용이 크게 늘 수 있어요. 업그레이드를 널리 배포하기 전에 트레이스를 검토하고 계측 범위 필터링 가이드를 사용해 원치 않는 span을 계측 범위별로 걸러내세요.
초기화
Langfuse 기본 URL 환경 변수는 이제 LANGFUSE_BASE_URL이며 더 이상 LANGFUSE_BASEURL이 아니에요. 하위 호환을 위해 후자는 v4에서 여전히 동작하지만 향후 버전에서는 동작하지 않아요.
트레이싱
v4 SDK 트레이싱은 OpenTelemetry 기반의 주요 재작성으로 몇 가지 호환성 파괴 변경을 도입해요.
- OTEL 기반 아키텍처: SDK가 이제 OpenTelemetry 위에 구축돼요.
LangfuseSpanProcessor를 OpenTelemetry NodeSDK에 등록해 OpenTelemetry 설정이 필요해요. - 새 트레이싱 함수:
langfuse.trace(),langfuse.span(),langfuse.generation()메서드가@langfuse/tracing패키지의startObservation,startActiveObservation등으로 대체됐어요. - 관심사 분리:
각각에 대한 자세한 내용은 SDK v4 문서를 참고하세요.
프롬프트 관리
- Import: Langfuse 클라이언트의 import는 이제:
import { LangfuseClient } from "@langfuse/client";
- 사용법: Langfuse 클라이언트의 사용법은 이제:
const langfuse = new LangfuseClient();
const prompt = await langfuse.prompt.get("my-prompt");
const compiledPrompt = prompt.compile({ topic: "developers" });
const response = await openai.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: compiledPrompt }],
});
version은 이제 위치 인자가 아니라langfuse.prompt.get()옵션 객체의 선택적 속성이에요.
const prompt = await langfuse.prompt.get("my-prompt", { version: "1.0" });
OpenAI 통합
- Import: OpenAI 통합의 import는 이제:
import { observeOpenAI } from "@langfuse/openai";
- 이제
LANGFUSE_TRACING_ENVIRONMENT와LANGFUSE_TRACING_RELEASE환경 변수로 environment와 release를 설정할 수 있어요.
Vercel AI SDK
v3와 매우 유사하게 동작하지만, langfuse-vercel의 LangfuseExporter를 @langfuse/otel의 일반 LangfuseSpanProcessor로 대체해요.
AI SDK와의 사용 예시는 여기를 참고하세요.
LLM에 제공된 도구 정의는 이제 metadata.tools에 매핑되고 더 이상 input.tools에 있지 않아요. generation에 대해 평가를 실행하는 경우 관련돼요.
Langchain 통합
- Import: Langchain 통합의 import는 이제:
import { CallbackHandler } from "@langfuse/langchain";
-
이제
LANGFUSE_TRACING_ENVIRONMENT와LANGFUSE_TRACING_RELEASE환경 변수로 environment와 release를 설정할 수 있어요. -
langfuseClient.getTraceUrl메서드는 이제 비동기이며 promise를 반환해요.
const traceUrl = await langfuseClient.getTraceUrl(traceId);
스코어링
- Import: Langfuse 클라이언트의 import는 이제:
import { LangfuseClient } from "@langfuse/client";
- 사용법: Langfuse 클라이언트의 사용법은 이제:
const langfuse = new LangfuseClient();
await langfuse.score.create({
traceId: "trace_id_here",
name: "accuracy",
value: 0.9,
});
새 스코어링 방법은 커스텀 점수 문서를 참고하세요.
데이터셋
새 데이터셋 메서드는 데이터셋 문서를 참고하세요.
더 알아보기 (Learn more)
- 출처 문서: Python v2 → v3