Langfuse 文档 中文 英文原文 ↗
文档 / Python v3 → v4

Python v3 → v4

Python SDK v4 引入了**以 observation 为中心的数据模型**。在此模型中,关联属性(user_idsession_idmetadatatags)传播到每个 observation,而非仅存在于 trace 上。这使得无需昂贵 join 的单表查询成为可能,显著提升了规模化时的查询性能。

这改变了你设置 trace 属性的方式:不再用 update_current_trace() 命令式地更新 trace 对象,而是使用 propagate_attributes()——一个上下文管理器,自动将属性应用于其作用域内创建的当前和所有子 observations。

v4 改变了默认的 OpenTelemetry 导出行为:Langfuse 不再默认导出所有 spans。如果你之前依赖非 LLM spans(HTTP、DB、队列、框架内部)被转发,请在升级前查看下面的第一个破坏性变更。

破坏性变更

智能默认 span 过滤取代导出全部行为

在以前的版本中,默认导出所有 OpenTelemetry spans 增加了来自基础设施和非 LLM 埋点(HTTP、DB、队列、框架内部)的 trace 噪声。为保持 traces 聚焦和有用,v4 引入了智能默认 span 过滤器。

默认情况下,如果满足以下任一条件,v4 导出 span:

在 v4 之前,未被阻止的埋点作用域默认被导出。

保留 v4 之前的"导出全部"行为

python
from langfuse import Langfuse

langfuse = Langfuse(should_export_span=lambda span: True)

将自定义过滤器与默认行为组合

python
from langfuse import Langfuse
from langfuse.span_filter import is_default_export_span

langfuse = Langfuse(
    should_export_span=lambda span: (
        is_default_export_span(span)
        or (
            span.instrumentation_scope is not None
            and span.instrumentation_scope.name.startswith("my_framework")
        )
    )
)

Python 兼容性说明:blocked_instrumentation_scopes 已弃用

blocked_instrumentation_scopes 在 v4 中仍然有效,但已弃用,并将在未来版本中移除。请迁移到 should_export_span

使用 should_export_span 的等价拒绝列表行为:

python
from langfuse import Langfuse
from langfuse.span_filter import is_default_export_span

blocked = {"sqlite", "requests"}

langfuse = Langfuse(
    should_export_span=lambda span: (
        is_default_export_span(span)
        and (
            span.instrumentation_scope is None
            or span.instrumentation_scope.name not in blocked
        )
    )
)

如果同时设置了 blocked_instrumentation_scopesshould_export_span,被阻止的作用域仍然胜出(硬否决)。

可能的 trace 树副作用及如何调试

当中间或父 spans 被丢弃而子 spans 仍被导出时,过滤可能会破坏 trace 树。如果 traces 显得断开,请启用 SDK 调试日志以检查被丢弃的 spans,然后在你的回调中将所需作用域加入允许列表。

update_current_trace() 分解为 3 个方法

在新模型中,关联属性(user_idsession_idmetadatatags 和请求作用域的 environment)必须存在于每个 observation 上,而非仅在 trace 上。这就是它们移到 propagate_attributes() 的原因——一个上下文管理器,自动将这些属性应用于其作用域内创建的当前和所有子 observations。

v3:

python
langfuse.update_current_trace(
    name="trace-name",
    user_id="user-123",
    session_id="session-abc",
    version="1.0",
    input={"query": "hello"},
    output={"result": "world"},
    metadata={"key": "value"},
    tags=["tag1"],
    public=True,
)

v4(分解):

python
from langfuse import observe, propagate_attributes, get_client

langfuse = get_client()

@observe()
def my_function():
    # (a) Correlating attributes → propagate_attributes() context manager
    with propagate_attributes(
        trace_name="trace-name",  # note: 'name' is now 'trace_name'
        user_id="user-123",
        session_id="session-abc",
        version="1.0",
        metadata={"key": "value"},
        tags=["tag1"],
        environment="staging",
    ):
        result = call_llm("hello")

    # (b) Trace I/O (deprecated, only for legacy trace-level LLM-as-a-judge configurations)
    langfuse.set_current_trace_io(input={"query": "hello"}, output={"result": result})

    # (c) Public flag
    langfuse.set_current_trace_as_public()

关键差异:

属性 v3 v4
name update_current_trace(name=...) propagate_attributes(trace_name=...)
user_idsession_idtagsversion update_current_trace(...) propagate_attributes(...)
metadata update_current_trace(metadata=any) propagate_attributes(metadata=dict[str,str])
inputoutput update_current_trace(...) set_current_trace_io(...)(已弃用)
public update_current_trace(public=True) set_current_trace_as_public()
release update_current_trace(release=...) 已移除——使用 LANGFUSE_RELEASE 环境变量
environment update_current_trace(environment=...) 进程级环境使用 LANGFUSE_TRACING_ENVIRONMENTLangfuse(environment=...)。请求作用域环境使用 propagate_attributes(environment=...)

set_current_trace_io() 已弃用,仅为与依赖 trace 输入/输出的 trace 级 LLM-as-a-judge 评估器向后兼容而存在。对于新代码,请直接在根 observation 上设置输入/输出。

span.update_trace() 分解为 3 个方法

相同的分解适用于 observation 级的 update_trace() 方法。

v3:

python
span.update_trace(
    name="trace-name",
    user_id="user-123",
    session_id="session-abc",
    input={"query": "hello"},
    output={"result": "world"},
    public=True,
)

v4:

python
from langfuse import get_client, propagate_attributes

langfuse = get_client()

with langfuse.start_as_current_observation(as_type="span", name="my-operation") as span:
    with propagate_attributes(trace_name="trace-name", user_id="user-123", session_id="session-abc"):
        result = call_llm("hello")

    span.set_trace_io(input={"query": "hello"}, output={"result": result})  # deprecated
    span.set_trace_as_public()

对于集成(LangChainOpenAI),传入的 trace 属性现在仅传播到子节点——它们不会冒泡到 trace。

Public API 命名空间重映射(api.*)

在 v4 中,高性能 Public API 资源现在是默认值。v2 别名已被移除。

v3 / 过渡名称 v4 名称
langfuse.api.observations_v_2 langfuse.api.observations
langfuse.api.score_v_2 langfuse.api.scores
langfuse.api.metrics_v_2 langfuse.api.metrics
langfuse.api.observations(旧版 v1) langfuse.api.legacy.observations_v1
langfuse.api.score(旧版 v1) langfuse.api.legacy.score_v1
langfuse.api.metrics(旧版 v1) langfuse.api.legacy.metrics_v1

如果你仍需要旧版 v1 行为,请切换到相应的 langfuse.api.legacy._v1 命名空间。

新的默认 langfuse.api.observationslangfuse.api.metrics 方法指向 Observations v2 和 Metrics v2 端点,它们需要 Langfuse v4(Langfuse Cloud,或升级到 v4 的自托管服务器)。在自托管 Langfuse v3 上,请改用 langfuse.api.legacy.observations_v1langfuse.api.legacy.metrics_v1。参见自托管兼容性矩阵

start_span() / start_generation()start_observation()

Observations 是新模型中的主要概念。带 as_type 参数的统一 start_observation() API 取代了单独的方法。

v3 v4
langfuse.start_span(name="x") langfuse.start_observation(name="x")
langfuse.start_as_current_span(name="x") langfuse.start_as_current_observation(name="x")
langfuse.start_generation(name="x", model="gpt-4") langfuse.start_observation(name="x", as_type="generation", model="gpt-4")
langfuse.start_as_current_generation(name="x", model="gpt-4") langfuse.start_as_current_observation(name="x", as_type="generation", model="gpt-4")
span.start_span(name="x") span.start_observation(name="x")
span.start_as_current_span(name="x") span.start_as_current_observation(name="x")
span.start_generation(name="x") span.start_observation(name="x", as_type="generation")
span.start_as_current_generation(name="x") span.start_as_current_observation(name="x", as_type="generation")

DatasetItemClient.run() 已移除 → 使用 Experiment SDK

Experiment SDK(dataset.run_experiment())在底层处理实验属性的传播(运行元数据、数据集条目链接)。

v3:

python
for item in dataset.items:
    with item.run(run_name="my-run", run_metadata={...}) as span:
        result = my_llm(item.input)
        span.update(output=result)

v4:

python
from langfuse import get_client

dataset = get_client().get_dataset("my-dataset")

def my_task(*, item, **kwargs):
    return my_llm(item.input)

dataset.run_experiment(name="my-run", task=my_task)

DatasetItem 对象仍具有相同的数据属性(idinputexpected_outputmetadata 等),但 run() 方法已移除。

LangChain CallbackHandler:update_trace 参数已移除

该 handler 现在在内部使用 propagate_attributes()update_trace 参数不再存在——传递它会引发 TypeError

v3:

python
from langfuse.langchain import CallbackHandler

handler = CallbackHandler(update_trace=True, trace_context={...})

v4:

python
handler = CallbackHandler(trace_context={...})

你仍然可以通过将 LangChain 调用包装在带 propagate_attributes() 的外层 span 中来设置 trace 属性(user_idsession_idtags 等)。参见 v2 → v3 迁移指南中的 LangChain 集成示例自定义 trace 属性文档。

已移除的类型

以下类型已从 langfuse.types 中移除:

已移除的类型 描述
TraceMetadata nameuser_idsession_idversionreleasemetadatatagspublic 的 TypedDict
ObservationParams 扩展 TraceMetadata 并带 observation 字段的 TypedDict
MapValueModelUsagePromptClient 不再从 langfuse.types 重新导出,请改为从 langfuse.model 导入

放弃 Pydantic v1 支持

SDK 现在需要 Pydantic v2。如果你的应用仍使用 Pydantic v1,你必须使用 pydantic.v1 兼容性垫片

校验变更

迁移清单

  1. 审计依赖非 LLM OpenTelemetry spans 的 traces/仪表盘:这些可能在 v4 默认过滤器下停止出现
  2. 如需要,设置 should_export_span=lambda span: True 以保留 v4 之前的"导出所有 spans"行为
  3. 如果你仍使用 blocked_instrumentation_scopes,请在弃用被移除之前迁移到 should_export_span 组合
  4. 搜索 update_current_trace → 拆分为 propagate_attributes() + set_current_trace_io()(仅当依赖旧版 trace 级 LLM-as-a-judge 配置时)+ set_current_trace_as_public()
  5. 搜索 .update_trace( → 在 observation 对象上做相同拆分
  6. 搜索 start_span / start_generation → 替换为 start_observation
  7. 搜索 item.run( → 替换为 dataset.run_experiment()
  8. 搜索 CallbackHandler(update_trace= → 移除参数
  9. 验证 metadata 值为 dict[str, str],值 ≤200 字符
  10. 如果仍在 v1,将 Pydantic 升级到 v2
  11. 搜索 api.observations_v_2 / api.score_v_2 / api.metrics_v_2 → 替换为 api.observations / api.scores / api.metrics
  12. 搜索 api.observations / api.score / api.metrics 上的旧版 v1 用法 → 移到 api.legacy.observations_v1 / api.legacy.score_v1 / api.legacy.metrics_v1
  13. 如果你自托管 Langfuse v3,请使用 api.legacy.observations_v1api.legacy.metrics_v1;默认的 api.observations / api.metrics 需要 Langfuse v4(参见自托管兼容性矩阵)
  14. 移除任何剩余的 *_v_2 别名引用(它们在 v4 中已被移除)
非官方中文翻译 · 图片/视频/代码均链接官方资源 · 版权归 Langfuse GmbH 所有 查看英文原文 ↗