前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

一、评估测试

1、核心概念

1)什么是 AI 评估测试

让另一个 AI 当 “裁判”,检查生成的回答好不好、对不对、有没有胡说八道。

目的:

  • 防止 AI 幻觉(Hallucination)
  • 保证回答和上下文相关
  • 保证回答事实准确

2)Evaluator 评估器接口

事项 说明
Evaluator 裁判
EvaluationRequest 给裁判看的材料
EvaluationResponse 裁判给出的评分(通过 / 不通过 + 评语)
@FunctionalInterface
public interface Evaluator {
    EvaluationResponse evaluate(EvaluationRequest evaluationRequest);
}

a、评估请求 (EvaluationRequest)

字段 含义 作用
userText 用户原始问题 裁判要知道用户问了啥
dataList 参考上下文 / 知识库资料(RAG 中的“证据) 裁判依据什么判断对错
responseContent AI 生成的回答 被打分的对象
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;
	}

  ...
}

b、相关性评估器 (RelevancyEvaluator)

RelevancyEvaluatorEvaluator 接口的一个实现,旨在评估 AI 生成的响应与所提供上下文的相关性。此评估器通过确定 AI 模型的响应是否与用户输入以及检索到的上下文相关,来帮助评估 RAG 流的质量。

  • 目的:判断 AI 的回答是否切题符合上下文
    • 只看:回答和问题、上下文是否相关
    • 不判断事实真假,只判断是否相关
    • 输出:YES / NO
  • 原理:将“问题 + 上下文 + 回答”发给 LLM,让 LLM 回答 YES/NO。
  • 适用场景:验证 RAG 流程是否正常工作,回答是否跑题
    • 问 “苹果手机”,AI 回答 “安卓很好用” → 不相关 → NO
    • 问 “苹果手机”,AI 回答 “iPhone15 搭载 A17” → 相关 → YES
  • 默认提示模板:RelevancyEvaluator 使用的默认提示模板

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

c、事实核查评估器 (FactCheckingEvaluator)

  • 目的:判断 AI 有没有 “胡说八道、造假、幻觉”

  • 原理:将“文档 + 主张”发给专门的核查模型(如 Bespoke-Minicheck),检测幻觉。

    • 严格对比上下文,检查事实是否一致
    • 适合对抗幻觉
    • 推荐用小而专的模型:minicheck、专用核查模型
  • 适用场景:金融、医疗等对准确性要求极高的场景。

    • 上下文:地球是第 3 颗行星
    • AI 回答:地球是第 4 颗行星
      • 事实错误 → 不通过
  • 默认提示词:其中 {document} 是上下文信息,{claim} 是待评估的 AI 模型响应。

    • Document: {document}
      Claim: {claim}
      

3)使用建议

  • 生成模型:负责聊天、回答(可以大而全)
  • 评估模型:负责判断对错(可以更小、更快、更专业)
  • 比如:生成用 Qwen,评估用 minicheck
  • 成本更低、结果更准

2、案例实战

1)案例1:相关性评估 (RelevancyEvaluator)

// ========================================================================
// 1. 相关性评估(RelevancyEvaluator)
// 功能:判断 AI 回答是否与问题 + 上下文相关
// URL: GET  http://localhost:8080/ai/eval/relevancy?question=地球有几颗天然卫星?&context=地球只有一颗天然卫星,叫月球。&aiResponse=地球有一颗天然卫星,是月球。
// ========================================================================
@GetMapping("/relevancy")
public EvaluationResponse relevancy(
        @RequestParam String question,
        @RequestParam String context,
        @RequestParam String aiResponse) {
    // 构建评估器
    RelevancyEvaluator evaluator = new RelevancyEvaluator(chatClientBuilder);

    // 构建评估材料
    EvaluationRequest request = new EvaluationRequest(question, List.of(new Document(context)), aiResponse);

    // 执行评估
    return evaluator.evaluate(request);
}



GET http://localhost:8080/ai/eval/relevancy?question=地球有几颗天然卫星?&context=地球只有一颗天然卫星,叫月球。&aiResponse=地球有一颗天然卫星,是月球。
{
  "feedback": "",
  "metadata": {},
  "pass": true,
  "score": 1.0
}



GET http://localhost:8081/ai/eval/relevancy?question=地球有几颗天然卫星?&context=我是一个人&aiResponse=地球有一颗天然卫星,是月球。
{
  "feedback": "",
  "metadata": {},
  "pass": false,
  "score": 0.0
}

2)案例2:事实核查评估(FactCheckingEvaluator

// ========================================================================
// 2. 事实核查评估(FactCheckingEvaluator)
// 功能:检查 AI 是否造假、幻觉
// URL: GET http://localhost:8080/ai/eval/fact-check?context=地球是太阳系第三颗行星。&aiResponse=地球是第四颗行星。
// ========================================================================
@GetMapping("/fact-check")
public EvaluationResponse factCheck(
        @RequestParam String context,
        @RequestParam String aiResponse
) {
    FactCheckingEvaluator evaluator =  FactCheckingEvaluator.builder(chatClientBuilder).build();

    EvaluationRequest request = new EvaluationRequest(context, List.of(new Document(context)), aiResponse);

    return evaluator.evaluate(request);
}


GET http://localhost:8080/ai/eval/fact-check?context=地球是太阳系第三颗行星。&aiResponse=地球是第四颗行星。
{
  "feedback": "",
  "metadata": {},
  "pass": false,
  "score": 0.0
}

3)案例3: RAG 完整流程 + 自动双重评估

// ========================================================================
// 3. RAG 完整流程 + 自动双重评估(检索→回答→相关性→事实核查)
// URL: GET http://localhost:8080/ai/eval/rag-evaluate
// ========================================================================
@GetMapping("/rag-evaluate")
public String ragEvaluate(@RequestParam String question) {
    // 1. 从向量库检索相关上下文
    List<Document> docs = vectorStore.similaritySearch(question);
    String context = docs.stream()
            .map(Document::getText)
            .reduce("", (a, b) -> a + "\n---\n" + b);

    // 2. AI 生成回答
    String aiAnswer = chatClient.prompt()
            .system("基于以下上下文回答,不要编造:\n" + context)
            .user(question)
            .call()
            .content();

    // 3. 构建评估请求
    EvaluationRequest request = new EvaluationRequest(question, List.of(new Document(context)), aiAnswer);

    // 4. 双重评估
    RelevancyEvaluator relEval = new RelevancyEvaluator(chatClientBuilder);
    FactCheckingEvaluator factEval = FactCheckingEvaluator.builder(chatClientBuilder).build();

    boolean relPass = relEval.evaluate(request).isPass();
    boolean factPass = factEval.evaluate(request).isPass();

    // 5. 返回结果
    return """
            【用户问题】
            %s

            【参考上下文摘要】
            %s

            【AI 回答】
            %s

            【评估结果】
            相关性:%s
            事实准确性:%s
            """.formatted(
            question,
            context.length() > 200 ? context.substring(0, 200) + "..." : context,
            aiAnswer,
            relPass ? "✅ 相关" : "❌ 不相关",
            factPass ? "✅ 事实正确" : "❌ 事实错误/幻觉"
    );
}




GET http://localhost:8081/ai/eval/rag-evaluate?question=地球有几颗天然卫星?

用户问题
地球有几颗天然卫星

参考上下文摘要

---
Spring Boot 是快速开发Spring应用的框架自动配置内嵌服务器
---
Spring AI 是Spring官方推出的AI开发框架支持RAG智能对话函数调用
---
Java 是跨平台编程语言广泛用于企业级开发

AI 回答
根据您提供的上下文信息无法回答地球有多少颗天然卫星的问题上下文内容仅涉及Spring Boot和Spring AI框架的相关信息未包含天文学或地球卫星数据

评估结果
相关性:✅ 相关
事实准确性:✅ 事实正确
  
  
  
GET http://localhost:8081/ai/eval/rag-evaluate?question=Spring Boot 是快速开发Spring应用的框架  对吗。
  
  用户问题
Spring Boot 是快速开发Spring应用的框架  对吗

参考上下文摘要

---
Spring Boot 是快速开发Spring应用的框架自动配置内嵌服务器
---
Spring AI 是Spring官方推出的AI开发框架支持RAG智能对话函数调用
---
Java 是跨平台编程语言广泛用于企业级开发

AI 回答
是的根据提供的上下文信息Spring Boot 被描述为快速开发Spring应用的框架自动配置内嵌服务器”。因此该说法正确

评估结果
相关性:✅ 相关
事实准确性:✅ 事实正确

ContactAuthor