Skip to content

feat: add classifier support#62

Open
Stephen Belanger (Qard) wants to merge 2 commits into
mainfrom
classifiers
Open

feat: add classifier support#62
Stephen Belanger (Qard) wants to merge 2 commits into
mainfrom
classifiers

Conversation

@Qard
Copy link
Copy Markdown
Contributor

@Qard Stephen Belanger (Qard) commented May 25, 2026

Summary

Ports the classifiers feature from the Braintrust spec (and Ruby SDK #154) to the .NET SDK.

Classifiers categorize eval outputs with structured items (id, optional label, optional metadata) instead of numeric 0–1 scores. They run in parallel with scorers; at least one of scorers or classifiers is now required.

  • New types: Classification, IClassifier<TInput,TOutput>, FunctionClassifier<TInput,TOutput>, ITracedClassifier<TInput,TOutput>.
  • Eval<TInput,TOutput>.Builder.Classifiers(...) setter; validation message updated to "Must provide at least one scorer or classifier".
  • Each classifier runs in its own span (classifier:<name>, type=classifier purpose=scorer); per-case results aggregated onto the eval span as braintrust.classifications. Classifier failures are non-fatal — error message merged into braintrust.metadata under classifier_errors.

.NET-specific extension beyond the spec: ITracedClassifier parallel to the existing ITracedScorer, so classifiers can inspect intermediate trace spans (e.g. label conversation patterns).

Test plan

  • dotnet build Braintrust.Sdk.sln — clean (4 pre-existing warnings, unrelated)
  • dotnet test tests/Braintrust.Sdk.Tests — 125/125 passing, including 20 new classifier facts
  • examples/ClassifiersExample builds clean
  • Run dotnet run --project examples/ClassifiersExample against a real Braintrust project and confirm classifications surface in the UI

🤖 Generated with Claude Code

Adds the classifiers feature from the spec
(braintrust-spec/docs/features/classifiers.md). Classifiers return
structured Classification items (id, optional label, optional metadata)
keyed by name and run in parallel with scorers. At least one of scorers
or classifiers is now required.

Includes ITracedClassifier (parallel to ITracedScorer) so classifiers
can inspect intermediate trace spans, e.g. to label conversation
patterns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@realark Andrew Kent (realark) left a comment

Choose a reason for hiding this comment

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

LGTM! Stephen Belanger (@Qard) DM'd you a question about the example to make but no need to block on it if that's the intended behavior

The Ruby reference implementation
(sdk-ruby/lib/braintrust/eval/runner.rb:391, 416-420) uses the
classifier name directly as the span name and includes a `name` key in
braintrust.span_attributes. Java already follows this pattern
(Eval.java:290, 297). .NET was using a "classifier:" prefix on the span
name and omitting the name attribute, which prevented consistent
classifier-span discovery downstream.

Update tests that asserted the prefixed display name; the test helper
now identifies classifier spans by their span_attributes.type tag
instead of a name prefix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

2 participants