評估測試

測試 AI 應用程式需要評估產生的內容,以確保 AI 模型沒有產生幻覺回應。

評估回應的一種方法是使用 AI 模型本身進行評估。選擇最適合評估的 AI 模型,這可能與用於產生回應的模型不同。

Spring AI 用於評估回應的介面是 Evaluator,定義如下

@FunctionalInterface
public interface Evaluator {
    EvaluationResponse evaluate(EvaluationRequest evaluationRequest);
}

評估的輸入是 EvaluationRequest,定義如下

public class EvaluationRequest {

	private final String userText;

	private final List<Content> dataList;

	private final String responseContent;

	public EvaluationRequest(String userText, List<Content> dataList, String responseContent) {
		this.userText = userText;
		this.dataList = dataList;
		this.responseContent = responseContent;
	}

  ...
}
  • userText:使用者的原始輸入,為 String 型別

  • dataList:上下文資料,例如來自檢索增強生成 (Retrieval Augmented Generation),附加到原始輸入。

  • responseContent:AI 模型的回應內容,為 String 型別

RelevancyEvaluator

其中一個實作是 RelevancyEvaluator,它使用 AI 模型進行評估。未來版本將提供更多實作。

RelevancyEvaluator 使用輸入 (userText) 和 AI 模型的輸出 (chatResponse) 來詢問問題

Your task is to evaluate if the response for the query
is in line with the context information provided.\n
You have two options to answer. Either YES/ NO.\n
Answer - YES, if the response for the query
is in line with context information otherwise NO.\n
Query: \n {query}\n
Response: \n {response}\n
Context: \n {context}\n
Answer: "

以下是一個 JUnit 測試範例,該測試對載入向量儲存區的 PDF 文件執行 RAG 查詢,然後評估回應是否與使用者文字相關。

@Test
void testEvaluation() {

    dataController.delete();
    dataController.load();

    String userText = "What is the purpose of Carina?";

    ChatResponse response = ChatClient.builder(chatModel)
            .build().prompt()
            .advisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()))
            .user(userText)
            .call()
            .chatResponse();
    String responseContent = response.getResult().getOutput().getContent();

    var relevancyEvaluator = new RelevancyEvaluator(ChatClient.builder(chatModel));

    EvaluationRequest evaluationRequest = new EvaluationRequest(userText,
            (List<Content>) response.getMetadata().get(QuestionAnswerAdvisor.RETRIEVED_DOCUMENTS), responseContent);

    EvaluationResponse evaluationResponse = relevancyEvaluator.evaluate(evaluationRequest);

    assertTrue(evaluationResponse.isPass(), "Response is not relevant to the question");

}

上面的程式碼來自 此處 的範例應用程式。

FactCheckingEvaluator

FactCheckingEvaluator 是 Evaluator 介面的另一個實作,旨在評估 AI 產生回應的事實準確性,並對照提供的上下文。此評估器透過驗證給定的陳述(主張)是否在邏輯上受到提供的上下文(文件)支援,來幫助偵測和減少 AI 輸出的幻覺。

「主張」和「文件」會呈現給 AI 模型進行評估。有更小且更有效率的 AI 模型專用於此目的,例如 Bespoke 的 Minicheck,與 GPT-4 等旗艦模型相比,這有助於降低執行這些檢查的成本。Minicheck 也可透過 Ollama 使用。

使用方式

FactCheckingEvaluator 建構子採用 ChatClient.Builder 作為參數

public FactCheckingEvaluator(ChatClient.Builder chatClientBuilder) {
  this.chatClientBuilder = chatClientBuilder;
}

評估器使用以下提示範本進行事實查核

Document: {document}
Claim: {claim}

其中 {document} 是上下文資訊,而 {claim} 是要評估的 AI 模型回應。

範例

以下是如何將 FactCheckingEvaluator 與基於 Ollama 的 ChatModel(特別是 Bespoke-Minicheck 模型)一起使用的範例

@Test
void testFactChecking() {
  // Set up the Ollama API
  OllamaApi ollamaApi = new OllamaApi("https://127.0.0.1:11434");

  ChatModel chatModel = new OllamaChatModel(ollamaApi,
				OllamaOptions.builder().withModel(BESPOKE_MINICHECK).withNumPredict(2).withTemperature(0.0d).build())


  // Create the FactCheckingEvaluator
  var factCheckingEvaluator = new FactCheckingEvaluator(ChatClient.builder(chatModel));

  // Example context and claim
  String context = "The Earth is the third planet from the Sun and the only astronomical object known to harbor life.";
  String claim = "The Earth is the fourth planet from the Sun.";

  // Create an EvaluationRequest
  EvaluationRequest evaluationRequest = new EvaluationRequest(context, Collections.emptyList(), claim);

  // Perform the evaluation
  EvaluationResponse evaluationResponse = factCheckingEvaluator.evaluate(evaluationRequest);

  assertFalse(evaluationResponse.isPass(), "The claim should not be supported by the context");

}