You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, the LangfuseConnector has a hardcoded list of supported LLM generators (_SUPPORTED_GENERATORS and _SUPPORTED_CHAT_GENERATORS) and their tracing logic. This makes it difficult for users to:
Add support for their custom LLM generators
Customize how generator spans are processed and what metadata is captured
Extend tracing functionality without modifying the core code
Proposal
Add a SpanHandler abstraction that allows users to customize how spans are processed after they are yielded. This follows the Open/Closed principle and provides a clean interface for extending Langfuse tracing capabilities.
Code Changes
classSpanHandler(ABC):
""" Abstract base class for handling spans in LangfuseTracer. Implement this class to customize how spans are processed after they are yielded. """@abstractmethoddefhandle(self, span: LangfuseSpan, component_type: Optional[str]) ->None:
""" Handle a span after it has been yielded. :param span: The LangfuseSpan that was yielded :param component_type: The type of the component that created this span """pass
The default implementation preserves current behavior:
classDefaultSpanHandler(SpanHandler):
"""Default implementation of SpanHandler that provides the original Langfuse tracing behavior."""defhandle(self, span: LangfuseSpan, component_type: Optional[str]) ->None:
ifcomponent_typein_SUPPORTED_GENERATORS:
meta=span._data.get(_COMPONENT_OUTPUT_KEY, {}).get("meta")
ifmeta:
m=meta[0]
span._span.update(usage=m.get("usage") orNone, model=m.get("model"))
elifcomponent_typein_SUPPORTED_CHAT_GENERATORS:
replies=span._data.get(_COMPONENT_OUTPUT_KEY, {}).get("replies")
ifreplies:
meta=replies[0].metacompletion_start_time=meta.get("completion_start_time")
ifcompletion_start_time:
try:
completion_start_time=datetime.fromisoformat(completion_start_time)
exceptValueError:
logger.error(f"Failed to parse completion_start_time: {completion_start_time}")
completion_start_time=Nonespan._span.update(
usage=meta.get("usage") orNone,
model=meta.get("model"),
completion_start_time=completion_start_time,
)
Usage Example
Users can implement their own handlers for custom tracing:
classCustomSpanHandler(SpanHandler):
defhandle(self, span: LangfuseSpan, component_type: Optional[str]) ->None:
# Custom logic for handling spansifcomponent_type=="MyCustomChatGenerator":
output=span._data.get("haystack.component.output", {})
span._span.update(
usage=output.get("usage"),
model="my-custom-model",
custom_metadata=output.get("extra_info"),
# Add any other custom metadata
)
# Use in pipelineconnector=LangfuseConnector(
name="My Pipeline",
span_handler=CustomSpanHandler()
)
Benefits
Extensibility: Users can add support for new LLM generators without modifying core code
Flexibility: Complete control over span processing and metadata capture
Clean Interface: Simple abstraction that follows Python's ABC pattern
Backward Compatible: Default behavior preserved through DefaultSpanHandler
Maintainable: Separates span handling logic from tracing infrastructure
Future-Proof: Easy to add support for new LLM providers and metadata formats
Alternative Approaches Considered
List Extension: Simply allowing users to extend the list of supported generators. Too rigid, doesn't allow customizing metadata capture.
Problem
Currently, the
LangfuseConnector
has a hardcoded list of supported LLM generators (_SUPPORTED_GENERATORS
and_SUPPORTED_CHAT_GENERATORS
) and their tracing logic. This makes it difficult for users to:Proposal
Add a
SpanHandler
abstraction that allows users to customize how spans are processed after they are yielded. This follows the Open/Closed principle and provides a clean interface for extending Langfuse tracing capabilities.Code Changes
The default implementation preserves current behavior:
Usage Example
Users can implement their own handlers for custom tracing:
Benefits
DefaultSpanHandler
Alternative Approaches Considered
List Extension: Simply allowing users to extend the list of supported generators. Too rigid, doesn't allow customizing metadata capture.
Obsoletes (to some extent) the following issues:
trace_id
in the response #1263The text was updated successfully, but these errors were encountered: