Skip to content

fix(langfuse): Parameter usage= for tracing is ignored and silently dropped. #2471

@Hansehart

Description

@Hansehart

Describe the bug
When using the LangfuseConnector, you have the posibility to add usage. This usage will be used for the Langfuse Python SDK. However for whatever reason the Langfuse Python SDK uses usage_details instead usage in their update() method. This error silently drops, because they are accepting **kwargs and ignoring it. Seams for me to be some broken backward compability. The haystack problems happens here:

https://github.com/deepset-ai/haystack-core-integrations/blob/main/integrations/langfuse/src/haystack_integrations/tracing/langfuse/tracer.py

Everywhere where this is used:

 span.raw_span().update(usage....

To confirm take a look at their source code:

https://github.com/langfuse/langfuse-python/blob/main/langfuse/_client/span.py
https://python.reference.langfuse.com/langfuse

Here you can the method header:

def update(
      self,
      *,
      name: Optional[str] = None,
      input: Optional[Any] = None,
      output: Optional[Any] = None,
      metadata: Optional[Any] = None,
      version: Optional[str] = None,
      level: Optional[SpanLevel] = None,
      status_message: Optional[str] = None,
      completion_start_time: Optional[datetime] = None,
      model: Optional[str] = None,
      model_parameters: Optional[Dict[str, MapValue]] = None,
      usage_details: Optional[Dict[str, int]] = None,
      cost_details: Optional[Dict[str, float]] = None,
      prompt: Optional[PromptClient] = None,
      **kwargs: Any,
  ) -> "LangfuseObservationWrapper":
      """Update this observation with new information.

      This method updates the observation with new information that becomes available
      during execution, such as outputs, metadata, or status changes.

      Args:
          name: Observation name
          input: Updated input data for the operation
          output: Output data from the operation
          metadata: Additional metadata to associate with the observation
          version: Version identifier for the code or component
          level: Importance level of the observation (info, warning, error)
          status_message: Optional status message for the observation
          completion_start_time: When the generation started (for generation types)
          model: Model identifier used (for generation types)
          model_parameters: Parameters passed to the model (for generation types)
          usage_details: Token or other usage statistics (for generation types)
          cost_details: Cost breakdown for the operation (for generation types)
          prompt: Reference to the prompt used (for generation types)
          **kwargs: Additional keyword arguments (ignored)
      """

And this one is the biggest trap, as you can see it supports only usage_details. Usage can be also be used, but will be dropped. In the frontend you can think it works, because Langfuse ignores your parameter and can automatically detect it from the metadata (sometimes). Very weird if you ask me.

To Reproduce
Place a breakpoint in tracer.py anywhere with span.raw_span().update(usage, then insert some values and see if they apply or not. Then try it again with usage_details and it will work.

Describe your environment (please complete the following information):

  • OS: Ubuntu 24.04
  • Haystack version: 2.19.0
  • Integration version: 3.0.1
  • Langfuse @ 3.8.0

simple fix:

replace usage by usage_details

Metadata

Metadata

Assignees

Type

No type

Projects

Status

In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions