Skip to content

fix(experiments): emit v4 trace attributes - #119

Merged
kxzk merged 4 commits into
mainfrom
fix/v4-experiment-attributes
Sep 3, 2026
Merged

kxzk merged 4 commits into
mainfrom
fix/v4-experiment-attributes

Conversation

@kxzk

@kxzk kxzk commented Sep 3, 2026 •

Copy link
Copy Markdown
Collaborator

TL;DR

Emit the Langfuse v4 attributes that make Ruby SDK experiment runs visible with complete observation attribution.

Why

Langfuse v4 discovers experiments from OpenTelemetry attributes. Ruby experiment runs linked dataset items, but their observations did not carry the experiment identity, item identity, expected output, or metadata that v4 requires.

The attribute layout matches the local JavaScript and Python SDK behavior. Each run selects its first valid server dataset run ID or a generated fallback ID, then keeps that identity for every item. A later link cannot split the run or redirect its URL and run-level scores to another identity. Identity and metadata propagate to child observations; descriptions and expected outputs remain on each item root. Item scores now target both the trace and root observation.

Manual item.link and item.run flows remain link-only because they cannot retroactively add attributes to an observation that already started.

Checklist

  • Has label
  • Has linked issue
  • Tests added for new behavior
  • Docs updated (if user-facing)

Verification

The complete RSpec suite passed with 1,653 examples and 97.01% line coverage. RuboCop inspected all 110 files with no offenses. Two-item regression tests cover successful and failed dataset links in both orders.

I ran dataset-backed and local-data experiments against Langfuse Cloud using the SDK code from this branch and credentials from .env. Independent Langfuse CLI queries found both v4 experiments. The managed run used its dataset run ID, and the local run used a generated 16-character hexadecimal ID with the expected deterministic item ID.

I also forced the first dataset link to fail and allowed the second link to succeed. The CLI found one experiment with two items. Both roots and both children used the same fallback ID. The late server ID did not create a second v4 experiment, and the SDK did not expose that different ID as a URL or run-score target. The mixed-link validation experiment remains available for inspection.

The CLI also confirmed that root and nested child observations shared experiment identity and metadata. Expected output and description appeared only on the root. The evaluator score targeted that root observation. The managed validation experiment remains available for inspection.

I compared the behavior with the current local JavaScript and Python SDK implementations. I did not run their test suites because this change does not modify either sibling repository.

Closes #118


Note

Medium Risk
Changes experiment tracing, OTel propagation, dataset-link ordering, and score targeting; behavior is well-tested but affects observability and experiment identity in production runs.

Overview
run_experiment now stamps observations with the OpenTelemetry attributes Langfuse v4 uses to discover experiments, aligning Ruby with the JS/Python SDKs.

A new ExperimentAttributes helper builds experiment/item identity, metadata (with masking), root-only description and expected output, and the sdk-experiment environment. ExperimentRunner applies these at trace start via a prepare_context hook on TracedExecution, links dataset items before the task runs, and propagates shared attributes to child spans through Propagation._with_experiment_attributes. Dataset-backed runs use the server dataset run ID when linking succeeds, with a per-run fallback hex ID if not; the first resolved ID is kept even when later links fail. Local runs share one generated experiment ID and deterministic item IDs from hashed inputs.

ExperimentResult exposes experiment_id. Item-level evaluator scores are persisted with both trace_id and observation_id. Docs note that item.run / manual link cannot retrofit v4 experiment attributes after a span has started.

Reviewed by Cursor Bugbot for commit f6472ea. Bugbot is set up for automated code reviews on this repo. Configure here.

@kxzk kxzk added the bug Something isn't working label Sep 3, 2026
Comment thread lib/langfuse/experiment_runner.rb Outdated
@simplepractice simplepractice deleted a comment from linear-code Bot Sep 3, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c758d74. Configure here.

Comment thread lib/langfuse/experiment_runner.rb Outdated
@kxzk
kxzk merged commit c1846c8 into main Sep 3, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Experiment attributes appear to be missing after the v4 OTLP migration

1 participant