Skip to content

Commit e0bad05

Browse files
guanxucericbottard
authored andcommitted
Add Builder for FactCheckingEvaluator (#4652)
Signed-off-by: guanxu <[email protected]> Signed-off-by: Eric Bottard <[email protected]>
1 parent 935ef80 commit e0bad05

File tree

2 files changed

+110
-7
lines changed

2 files changed

+110
-7
lines changed

spring-ai-client-chat/src/main/java/org/springframework/ai/chat/evaluation/FactCheckingEvaluator.java

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import org.springframework.ai.evaluation.EvaluationRequest;
2323
import org.springframework.ai.evaluation.EvaluationResponse;
2424
import org.springframework.ai.evaluation.Evaluator;
25+
import org.springframework.lang.Nullable;
26+
import org.springframework.util.Assert;
2527

2628
/**
2729
* Implementation of {@link Evaluator} used to evaluate the factual accuracy of Large
@@ -59,6 +61,7 @@
5961
*
6062
* @author Eddú Meléndez
6163
* @author Mark Pollack
64+
* @author guan xu
6265
* @see Evaluator
6366
* @see EvaluationRequest
6467
* @see EvaluationResponse
@@ -69,13 +72,20 @@ public class FactCheckingEvaluator implements Evaluator {
6972
private static final String DEFAULT_EVALUATION_PROMPT_TEXT = """
7073
Evaluate whether or not the following claim is supported by the provided document.
7174
Respond with "yes" if the claim is supported, or "no" if it is not.
72-
Document: \\n {document}\\n
73-
Claim: \\n {claim}
75+
76+
Document:
77+
{document}
78+
79+
Claim:
80+
{claim}
7481
""";
7582

7683
private static final String BESPOKE_EVALUATION_PROMPT_TEXT = """
77-
Document: \\n {document}\\n
78-
Claim: \\n {claim}
84+
Document:
85+
{document}
86+
87+
Claim:
88+
{claim}
7989
""";
8090

8191
private final ChatClient.Builder chatClientBuilder;
@@ -89,7 +99,7 @@ public class FactCheckingEvaluator implements Evaluator {
8999
* evaluation
90100
*/
91101
public FactCheckingEvaluator(ChatClient.Builder chatClientBuilder) {
92-
this(chatClientBuilder, DEFAULT_EVALUATION_PROMPT_TEXT);
102+
this(chatClientBuilder, null);
93103
}
94104

95105
/**
@@ -99,9 +109,10 @@ public FactCheckingEvaluator(ChatClient.Builder chatClientBuilder) {
99109
* evaluation
100110
* @param evaluationPrompt The prompt text to use for evaluation
101111
*/
102-
public FactCheckingEvaluator(ChatClient.Builder chatClientBuilder, String evaluationPrompt) {
112+
public FactCheckingEvaluator(ChatClient.Builder chatClientBuilder, @Nullable String evaluationPrompt) {
113+
Assert.notNull(chatClientBuilder, "chatClientBuilder cannot be null");
103114
this.chatClientBuilder = chatClientBuilder;
104-
this.evaluationPrompt = evaluationPrompt;
115+
this.evaluationPrompt = evaluationPrompt != null ? evaluationPrompt : DEFAULT_EVALUATION_PROMPT_TEXT;
105116
}
106117

107118
/**
@@ -138,4 +149,33 @@ public EvaluationResponse evaluate(EvaluationRequest evaluationRequest) {
138149
return new EvaluationResponse(passing, "", Collections.emptyMap());
139150
}
140151

152+
public static FactCheckingEvaluator.Builder builder() {
153+
return new FactCheckingEvaluator.Builder();
154+
}
155+
156+
public static final class Builder {
157+
158+
private ChatClient.Builder chatClientBuilder;
159+
160+
private String evaluationPrompt;
161+
162+
private Builder() {
163+
}
164+
165+
public FactCheckingEvaluator.Builder chatClientBuilder(ChatClient.Builder chatClientBuilder) {
166+
this.chatClientBuilder = chatClientBuilder;
167+
return this;
168+
}
169+
170+
public FactCheckingEvaluator.Builder evaluationPrompt(String evaluationPrompt) {
171+
this.evaluationPrompt = evaluationPrompt;
172+
return this;
173+
}
174+
175+
public FactCheckingEvaluator build() {
176+
return new FactCheckingEvaluator(this.chatClientBuilder, this.evaluationPrompt);
177+
}
178+
179+
}
180+
141181
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2023-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ai.chat.evaluation;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import org.springframework.ai.chat.client.ChatClient;
22+
import org.springframework.ai.chat.model.ChatModel;
23+
24+
import static org.assertj.core.api.Assertions.assertThat;
25+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
26+
import static org.mockito.Mockito.mock;
27+
28+
/**
29+
* Unit tests for {@link FactCheckingEvaluator}.
30+
*
31+
* @author guan xu
32+
*/
33+
class FactCheckingEvaluatorTests {
34+
35+
@Test
36+
void whenChatClientBuilderIsNullThenThrow() {
37+
assertThatThrownBy(() -> new FactCheckingEvaluator(null)).isInstanceOf(IllegalArgumentException.class)
38+
.hasMessageContaining("chatClientBuilder cannot be null");
39+
40+
assertThatThrownBy(() -> FactCheckingEvaluator.builder().chatClientBuilder(null).build())
41+
.isInstanceOf(IllegalArgumentException.class)
42+
.hasMessageContaining("chatClientBuilder cannot be null");
43+
}
44+
45+
@Test
46+
void whenEvaluationPromptIsNullThenUseDefaultEvaluationPromptText() {
47+
FactCheckingEvaluator evaluator = new FactCheckingEvaluator(ChatClient.builder(mock(ChatModel.class)));
48+
assertThat(evaluator).isNotNull();
49+
50+
evaluator = FactCheckingEvaluator.builder()
51+
.chatClientBuilder(ChatClient.builder(mock(ChatModel.class)))
52+
.build();
53+
assertThat(evaluator).isNotNull();
54+
}
55+
56+
@Test
57+
void whenForBespokeMinicheckThenUseBespokeEvaluationPromptText() {
58+
FactCheckingEvaluator evaluator = FactCheckingEvaluator
59+
.forBespokeMinicheck(ChatClient.builder(mock(ChatModel.class)));
60+
assertThat(evaluator).isNotNull();
61+
}
62+
63+
}

0 commit comments

Comments
 (0)