Skip to content

Commit 879a229

Browse files
committed
Rework evals api
- datasets interface - currently only in-memory datasets, but future proof for fetching from branitrust - task and scorers output to record classes - to support passing secondary data
1 parent 6a96b07 commit 879a229

13 files changed

Lines changed: 278 additions & 102 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ Function<String, String> getFoodType =
5252
var eval = braintrust.<String, String>evalBuilder()
5353
.name("java-eval-x-" + System.currentTimeMillis())
5454
.cases(
55-
EvalCase.of("asparagus", "vegetable"),
56-
EvalCase.of("banana", "fruit"))
57-
.task(getFoodType)
55+
DatasetCase.of("asparagus", "vegetable"),
56+
DatasetCase.of("banana", "fruit"))
57+
.taskFunction(getFoodType)
5858
.scorers(
5959
Scorer.of(
6060
"fruit_scorer",

examples/src/main/java/dev/braintrust/examples/ExperimentExample.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import com.openai.models.ChatModel;
55
import com.openai.models.chat.completions.ChatCompletionCreateParams;
66
import dev.braintrust.Braintrust;
7-
import dev.braintrust.eval.EvalCase;
7+
import dev.braintrust.eval.DatasetCase;
88
import dev.braintrust.eval.Scorer;
99
import dev.braintrust.instrumentation.openai.BraintrustOpenAI;
1010
import java.util.function.Function;
@@ -37,10 +37,10 @@ public static void main(String[] args) throws Exception {
3737
// will append new cases to
3838
// the same experiment
3939
.cases(
40-
EvalCase.of("strawberry", "fruit"),
41-
EvalCase.of("asparagus", "vegetable"),
42-
EvalCase.of("apple", "fruit"),
43-
EvalCase.of("banana", "fruit"))
40+
DatasetCase.of("strawberry", "fruit"),
41+
DatasetCase.of("asparagus", "vegetable"),
42+
DatasetCase.of("apple", "fruit"),
43+
DatasetCase.of("banana", "fruit"))
4444
.taskFunction(getFoodType)
4545
.scorers(
4646
Scorer.of(
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package dev.braintrust.eval;
2+
3+
import java.util.List;
4+
import java.util.Optional;
5+
6+
/**
7+
* Datasets define the cases for evals. This interface provides a means of iterating through all
8+
* cases of a particular dataset.
9+
*
10+
* <p>The most common implementations are in-memory datasets, and datasets fetched from the
11+
* Braintrust API.
12+
*/
13+
public interface Dataset<INPUT, OUTPUT> {
14+
Cursor<DatasetCase<INPUT, OUTPUT>> openCursor();
15+
16+
String id();
17+
18+
String version();
19+
20+
interface Cursor<CASE> extends AutoCloseable {
21+
/**
22+
* Fetch the next case. Returns empty if there are no more cases to fetch.
23+
*
24+
* <p>Implementations may make external requests to fetch data.
25+
*
26+
* <p>If this method is invoked after {@link #close()} an IllegalStateException will be
27+
* thrown
28+
*/
29+
Optional<CASE> next();
30+
31+
/** close all cursor resources */
32+
void close();
33+
}
34+
35+
/** Create an in-memory Dataset containing the provided cases. */
36+
@SafeVarargs
37+
static <INPUT, OUTPUT> Dataset<INPUT, OUTPUT> of(DatasetCase<INPUT, OUTPUT>... cases) {
38+
return new DatasetInMemoryImpl<>(List.of(cases));
39+
}
40+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package dev.braintrust.eval;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
import javax.annotation.Nonnull;
6+
7+
/** A single row in a dataset. */
8+
public record DatasetCase<INPUT, OUTPUT>(
9+
INPUT input,
10+
OUTPUT expected,
11+
@Nonnull List<String> tags,
12+
@Nonnull Map<String, Object> metadata) {
13+
public DatasetCase {
14+
if (!metadata.isEmpty()) {
15+
throw new RuntimeException("TODO: metadata support not yet implemented");
16+
}
17+
if (!tags.isEmpty()) {
18+
throw new RuntimeException("TODO: tags support not yet implemented");
19+
}
20+
}
21+
22+
public static <INPUT, OUTPUT> DatasetCase<INPUT, OUTPUT> of(INPUT input, OUTPUT expected) {
23+
return new DatasetCase<>(input, expected, List.of(), Map.of());
24+
}
25+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package dev.braintrust.eval;
2+
3+
import java.util.List;
4+
import java.util.Optional;
5+
6+
/** A dataset held entirely in memory */
7+
class DatasetInMemoryImpl<INPUT, OUTPUT> implements Dataset<INPUT, OUTPUT> {
8+
private final List<DatasetCase<INPUT, OUTPUT>> cases;
9+
private final String id;
10+
11+
public DatasetInMemoryImpl(List<DatasetCase<INPUT, OUTPUT>> cases) {
12+
this.cases = List.copyOf(cases);
13+
id = "in-memory-dataset<" + this.cases.hashCode() + ">";
14+
}
15+
16+
@Override
17+
public Cursor<DatasetCase<INPUT, OUTPUT>> openCursor() {
18+
return new Cursor<>() {
19+
int nextIndex = 0;
20+
boolean closed = false;
21+
22+
@Override
23+
public Optional<DatasetCase<INPUT, OUTPUT>> next() {
24+
if (closed) {
25+
throw new IllegalStateException("this method may not be invoked after close");
26+
} else if (nextIndex < cases.size()) {
27+
return Optional.of(cases.get(nextIndex++));
28+
} else {
29+
return Optional.empty();
30+
}
31+
}
32+
33+
@Override
34+
public void close() {
35+
closed = true;
36+
}
37+
};
38+
}
39+
40+
@Override
41+
public String id() {
42+
return id;
43+
}
44+
45+
@Override
46+
public String version() {
47+
return "0";
48+
}
49+
}

0 commit comments

Comments
 (0)