@@ -18,50 +18,72 @@ Scorers are responsible for taking a Response that is made for a Prompt and givi
1818
1919### Abstract Methods
2020
21- ** ` scoreOne(response: PromptResponse, options?: Record<string, any>): Promise<number | undefined> ` **
21+ ** ` scoreOne(response: PromptResponse, options?: Record<string, any>): MaybePromise<PromptScore | undefined> ` **
2222
2323- This is the main scoring method you must implement
2424- Takes a ` PromptResponse ` object containing both the Prompt and Response
2525- Optional ` options ` parameter for configurable scoring behavior
26- - Must return a number between 0 and 1, or ` undefined ` if scoring fails
27- - The number represents the score: 1.0 = perfect, 0.0 = completely wrong
26+ - Must return a ` PromptScore ` object or ` undefined ` if scoring fails
27+ - The ` PromptScore ` object includes the original response data plus a ` score ` field (number between 0 and 1)
28+ - The score represents: 1.0 = perfect, 0.0 = completely wrong
29+ - The ` PromptScore ` structure extends ` PromptResponse ` with additional fields:
30+ - ` score?: number ` - The calculated score (0-1)
31+ - ` metadata?: Record<string, any> ` - Additional metadata about the scoring
2832
29- ** ` canScore(response: PromptResponse): Promise <boolean> ` **
33+ ** ` canScore(response: PromptResponse): MaybePromise <boolean> ` **
3034
3135- This method determines if your Scorer can handle a specific Response
3236- Returns ` true ` if your Scorer implementation is eligible to score the Response and ` false ` if it isn't.
37+ - ` MaybePromise<T> ` means the method can return either ` T ` or ` Promise<T> ` (synchronous or asynchronous)
3338
3439Here's a very simple scorer implementation that demonstrates the basic structure:
3540
3641``` typescript
3742import { AbstractScorer } from " @/scorers/abstract/abstract-scorer" ;
38- import { PromptResponse } from " @/types" ;
43+ import { PromptResponse , PromptScore } from " @/types" ;
3944
4045export class SimpleExactMatchScorer extends AbstractScorer {
4146 readonly identifier = " simple-exact-match" ;
4247
4348 async scoreOne(
4449 response : PromptResponse ,
4550 options ? : Record <string , any >
46- ): Promise <number | undefined > {
51+ ): Promise <PromptScore | undefined > {
52+ if (! (await this .canScore (response ))) {
53+ return undefined ;
54+ }
55+
4756 // Extract the correct answer from the prompt
4857 const correctAnswer = response .prompt .answer ;
4958
5059 // Get the model's response
51- const modelResponse = response .response . content ;
60+ const modelResponse = response .data ;
5261
5362 // Simple exact match scoring (case-insensitive)
5463 const isCorrect =
55- correctAnswer .toLowerCase ().trim () === modelResponse .toLowerCase ().trim ();
56-
57- // Return 1.0 for correct answers, 0.0 for incorrect
58- return isCorrect ? 1.0 : 0.0 ;
64+ correctAnswer ?.toLowerCase ().trim () ===
65+ modelResponse ?.toLowerCase ().trim ();
66+
67+ // Calculate score: 1.0 for correct answers, 0.0 for incorrect
68+ const score = isCorrect ? 1.0 : 0.0 ;
69+
70+ // Return PromptScore object with the original response data plus score and metadata
71+ return {
72+ ... response ,
73+ score ,
74+ metadata: {
75+ scorerIdentifier: this .identifier ,
76+ isExactMatch: isCorrect ,
77+ },
78+ } as PromptScore ;
5979 }
6080
6181 async canScore(response : PromptResponse ): Promise <boolean > {
62- // This scorer can handle any response that has content
82+ // This scorer can handle any response that has data and a prompt with an answer
6383 return (
64- response .response .content && typeof response .response .content === " string"
84+ response .data !== undefined &&
85+ response .prompt !== undefined &&
86+ response .prompt .answer !== undefined
6587 );
6688 }
6789}
@@ -105,7 +127,7 @@ async function main() {
105127 metadata: {},
106128 scorers: [" simple-exact-match" ],
107129 },
108- data: " A " , // Correct answer
130+ data: " Paris " , // Correct answer
109131 provider: " mock" ,
110132 modelId: " mock-model" ,
111133 modelName: " Mock Model" ,
@@ -124,7 +146,7 @@ async function main() {
124146
125147 const wrongResponse = {
126148 ... mockResponse ,
127- data: " C " , // Wrong answer
149+ data: " London " , // Wrong answer
128150 };
129151
130152 // Test if the Scorer can handle these responses
@@ -135,13 +157,17 @@ async function main() {
135157 console .log (" Can score wrong response:" , canScoreWrong );
136158
137159 if (canScoreCorrect ) {
138- const correctScore = await scorer .scoreOne (mockResponse );
139- console .log (" Correct answer score:" , correctScore );
160+ const correctScoreResult = await scorer .scoreOne (mockResponse );
161+ console .log (" Correct answer score result:" , correctScoreResult );
162+ console .log (" Score:" , correctScoreResult ?.score );
163+ console .log (" Metadata:" , correctScoreResult ?.metadata );
140164 }
141165
142166 if (canScoreWrong ) {
143- const wrongScore = await scorer .scoreOne (wrongResponse );
144- console .log (" Wrong answer score:" , wrongScore );
167+ const wrongScoreResult = await scorer .scoreOne (wrongResponse );
168+ console .log (" Wrong answer score result:" , wrongScoreResult );
169+ console .log (" Score:" , wrongScoreResult ?.score );
170+ console .log (" Metadata:" , wrongScoreResult ?.metadata );
145171 }
146172}
147173
@@ -160,9 +186,10 @@ This will execute `dev.ts`.
160186
161187## Examples
162188
163- See the ` examples /scorers/` directory for complete working examples:
189+ See the ` src /scorers/` directory for complete working examples:
164190
165- - ` exact-match-scorer.ts ` - Exact match scoring
166- - ` semantic-similarity-scorer.ts ` - Semantic similarity scoring
191+ - ` exact-match-scorer.ts ` - Exact match scoring that returns PromptScore objects
192+ - ` multiple-choice-scorer.ts ` - Multiple choice scoring with answer extraction
193+ - ` ref-answer-equality-llm-judge-scorer.ts ` - LLM-based scoring for reference answer equality
167194
168- These examples demonstrate real-world implementations and can serve as templates for your own Scorers.
195+ These examples demonstrate real-world implementations and show how to properly return ` PromptScore ` objects with scores and metadata. They can serve as templates for your own Scorers.
0 commit comments