Skip to content

feat: support trace propagation via langfuse_trace_id in metadata. #1264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

sagilap
Copy link

@sagilap sagilap commented Jul 21, 2025

🔗 Enable External Trace Linking via metadata['langfuse_trace_id'] in CallbackHandler

Summary

This PR allows users to manually propagate a trace_id across multiple LangGraph or LangChain runs by including a langfuse_trace_id in the metadata of the RunnableConfig.

Problem

Currently, the CallbackHandler in langfuse.langchain uses client.start_span() without providing a way to pass a custom trace_id. This makes it impossible to link multiple distinct LangGraph executions under a single trace, which is especially important for stateful applications where each step (even across executions) is part of a cohesive experience.

Solution

This PR modifies the on_chain_start method to pass a trace_context with a custom trace ID if it's provided under metadata['langfuse_trace_id'].

# Old (no way to pass trace_id)
self.runs[run_id] = self.client.start_span(
    name=span_name,
    metadata=span_metadata,
    input=inputs,
    level=cast(...),
)

# New (allows custom trace_id propagation)
self.runs[run_id] = self.client.start_span(
    trace_context={"trace_id": metadata.get("langfuse_trace_id")},
    name=span_name,
    metadata=span_metadata,
    input=inputs,
    level=cast(...),
)

✅ Usage Example

You can now pass langfuse_trace_id in RunnableConfig.metadata:

graph.invoke(
    input,
    config={
        "metadata": {
            "langfuse_trace_id": my_trace_id
        }
    }
)

This enables all runs within the graph to be linked to the same trace in Langfuse, even if they occur in separate invocations (e.g., due to checkpoints, retries, or async workflows with fastapi).

💡 Why It Matters

📈 Improves observability for multi-step or multi-invocation workflows.

🔗 Links traces across separate LangGraph or Runnable executions without monkey-patching or custom handlers.

🧠 Supports advanced use cases like LangGraph checkpointing, retries, and workflows that resume over time.

🛠️ Notes

✅ This change is fully backward-compatible.

🔒 If langfuse_trace_id is not present in metadata, the behavior remains unchanged.


Important

Adds support for custom trace ID propagation via metadata['langfuse_trace_id'] in CallbackHandler, allowing trace linking across multiple runs.

  • Behavior:
    • Adds support for custom trace ID propagation via metadata['langfuse_trace_id'] in CallbackHandler.
    • Modifies on_chain_start to include trace_context with custom trace ID if provided.
  • Usage:
    • Users can pass langfuse_trace_id in RunnableConfig.metadata to link multiple runs under a single trace.
  • Compatibility:
    • Fully backward-compatible; no change in behavior if langfuse_trace_id is absent.

This description was created by Ellipsis for dccbfaa. You can customize this summary. It will automatically update as commits are pushed.

Disclaimer: Experimental PR review

Greptile Summary

This PR enhances the Langfuse Python SDK's tracing capabilities by adding support for trace propagation across multiple LangGraph or LangChain runs. The core change is in the CallbackHandler class, which now accepts a langfuse_trace_id in the metadata to link related operations under a single trace.

The modification is focused on the on_chain_start method, where the code now checks for a langfuse_trace_id in the metadata and uses it to create a trace context. This allows developers to maintain continuity in tracing across separate executions, which is particularly valuable for stateful applications, async workflows, and scenarios involving checkpoints or retries.

The implementation integrates seamlessly with LangChain's existing patterns by utilizing the RunnableConfig.metadata field, making it intuitive for developers familiar with the ecosystem.

Confidence score: 5/5

  • Safety assessment: This PR is highly safe to merge as it adds functionality in a completely backward-compatible way
  • Reasoning: The change is well-isolated, maintains backward compatibility, and follows established patterns for metadata handling
  • Files needing attention: None - the changes are straightforward and well-implemented

@CLAassistant
Copy link

CLAassistant commented Jul 21, 2025

CLA assistant check
All committers have signed the CLA.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, no comments

Edit Code Review Bot Settings | Greptile

@hassiebp hassiebp self-assigned this Jul 21, 2025
@hassiebp hassiebp self-requested a review July 28, 2025 12:52
@hassiebp hassiebp removed their assignment Jul 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants