{"id":91587,"date":"2026-08-08T01:48:41","date_gmt":"2026-08-07T17:48:41","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/91587.html"},"modified":"2026-08-08T01:48:41","modified_gmt":"2026-08-07T17:48:41","slug":"%e7%94%a8spring-boot%e6%90%ad%e5%bb%baai%e8%af%84%e6%b5%8b%e4%b8%8e%e5%8f%91%e5%b8%83%e8%b4%a8%e9%87%8f%e9%97%a8%e7%a6%81%ef%bc%9a%e6%95%b0%e6%8d%ae%e9%9b%86%e3%80%81judge%e3%80%81%e5%9b%9e%e5%bd%92","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/91587.html","title":{"rendered":"\u7528Spring Boot\u642d\u5efaAI\u8bc4\u6d4b\u4e0e\u53d1\u5e03\u8d28\u91cf\u95e8\u7981\uff1a\u6570\u636e\u96c6\u3001Judge\u3001\u56de\u5f52\u5bf9\u6bd4\u4e0eCI\/CD\u5b8c\u6574\u5b9e\u6218"},"content":{"rendered":"<h3>\u6587\u7ae0\u6458\u8981<\/h3>\n<p>\u4f20\u7edf\u8f6f\u4ef6\u53ef\u4ee5\u901a\u8fc7\u5355\u5143\u6d4b\u8bd5\u548c\u63a5\u53e3\u6d4b\u8bd5\u5224\u65ad\u8f93\u51fa\u662f\u5426\u6b63\u786e&#xff0c;AI\u5e94\u7528\u5374\u7ecf\u5e38\u5b58\u5728\u591a\u4e2a\u53ef\u63a5\u53d7\u7b54\u6848\u3001\u6a21\u578b\u975e\u786e\u5b9a\u6027\u3001RAG\u8bc1\u636e\u53d8\u5316\u3001Tool Calling\u8f68\u8ff9\u5dee\u5f02\u548c\u6210\u672c\u5ef6\u8fdf\u6ce2\u52a8\u3002\u4ec5\u5728CI\u4e2d\u6267\u884c\u51e0\u6761assertThat(answer).isNotBlank()&#xff0c;\u65e0\u6cd5\u963b\u6b62Prompt\u3001\u6a21\u578b\u3001\u77e5\u8bc6\u7d22\u5f15\u6216\u5de5\u5177\u76ee\u5f55\u5347\u7ea7\u9020\u6210\u7684\u8d28\u91cf\u9000\u5316\u3002<\/p>\n<p>\u672c\u6587\u4ece\u96f6\u5b9e\u73b0\u4e00\u4e2aSpring Boot AI\u8bc4\u6d4b\u4e0e\u53d1\u5e03\u8d28\u91cf\u95e8\u7981\u670d\u52a1\u3002\u7cfb\u7edf\u7ba1\u7406\u7248\u672c\u5316\u6570\u636e\u96c6\u548cCase&#xff0c;\u652f\u6301Baseline\u4e0eCandidate\u53cc\u8dd1&#xff0c;\u8bb0\u5f55\u5b8c\u6574Runtime Manifest&#xff1b;\u901a\u8fc7\u786e\u5b9a\u6027Evaluator\u3001Spring AI RelevancyEvaluator\u3001\u4e8b\u5b9e\u68c0\u67e5\u5668\u548c\u81ea\u5b9a\u4e49LLM-as-Judge\u5bf9\u56de\u7b54\u3001RAG\u5f15\u7528\u548c\u5de5\u5177\u8f68\u8ff9\u8bc4\u5206&#xff1b;\u6309\u4e1a\u52a1Slice\u805a\u5408\u901a\u8fc7\u7387\u3001\u6700\u4f4e\u5206\u3001\u6210\u672c\u548c\u5ef6\u8fdf&#xff1b;\u518d\u6839\u636e\u786c\u5931\u8d25\u4e0e\u56de\u5f52\u9608\u503c\u751f\u6210Quality Gate\u7ed3\u679c\u3002<\/p>\n<p>\u6700\u7ec8\u8bc4\u6d4b\u670d\u52a1\u4ee5\u9000\u51fa\u7801\u3001REST API\u548cGitHub Actions\u68c0\u67e5\u4e09\u79cd\u65b9\u5f0f\u63a5\u5165CI\/CD\u3002\u53d7\u4fdd\u62a4\u5206\u652f\u53ef\u5c06ai-quality-gate\u8bbe\u7f6e\u4e3a\u5fc5\u9700\u72b6\u6001\u68c0\u67e5&#xff0c;\u8bc4\u6d4b\u5931\u8d25\u65f6\u7981\u6b62\u5408\u5e76\u6216\u53d1\u5e03\u3002<\/p>\n<h3>\u4e00\u3001\u9879\u76ee\u76ee\u6807<\/h3>\n<p>\u7cfb\u7edf\u9700\u8981\u5b8c\u6210&#xff1a;<\/p>\n<p>1. \u7ba1\u7406\u7248\u672c\u5316\u8bc4\u6d4b\u6570\u636e\u96c6<br \/>\n2. \u652f\u6301\u9ec4\u91d1\u3001\u5408\u6210\u3001\u751f\u4ea7\u56de\u653e\u548c\u4e8b\u6545\u6837\u672c<br \/>\n3. \u56fa\u5b9aBaseline\u4e0eCandidate\u8fd0\u884c\u6e05\u5355<br \/>\n4. \u5bf9\u6bcf\u4e2aCase\u91cd\u590d\u6267\u884c\u5e76\u4fdd\u5b58\u539f\u59cb\u8f68\u8ff9<br \/>\n5. \u652f\u6301\u786e\u5b9a\u6027\u3001\u7b97\u6cd5\u548cLLM Judge<br \/>\n6. \u652f\u6301RAG\u3001\u7ed3\u6784\u5316\u8f93\u51fa\u548cAgent\u8f68\u8ff9\u8bc4\u6d4b<br \/>\n7. \u6309Slice\u805a\u5408\u8d28\u91cf\u3001\u6210\u672c\u4e0e\u5ef6\u8fdf<br \/>\n8. \u9ad8\u98ce\u9669\u786c\u5931\u8d25\u96f6\u5bb9\u5fcd<br \/>\n9. \u8f93\u51fa\u673a\u5668\u53ef\u8bfbQuality Gate\u7ed3\u679c<br \/>\n10. \u63a5\u5165Maven\u3001GitHub Actions\u548c\u53d1\u5e03\u6d41\u6c34\u7ebf<br \/>\n11. \u4fdd\u5b58\u8bc4\u6d4b\u5386\u53f2\u5e76\u6bd4\u8f83\u8d8b\u52bf<br \/>\n12. \u8bc4\u6d4b\u5931\u8d25\u53ef\u5b9a\u4f4d\u5230\u5177\u4f53Case\u4e0e\u7ec4\u4ef6<\/p>\n<h3>\u4e8c\u3001\u603b\u4f53\u67b6\u6784<\/h3>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 GitHub Actions \/ Jenkins \/ Release Pipeline  \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n                       \u2502 Start Eval<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 Evaluation API \/ CLI                         \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n               \u2502                 \u2502<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 Dataset Registry     \u2502 \u2502 Release Manifest   \u2502<br \/>\n\u2502 Dataset\/Case\/Tags    \u2502 \u2502 Model\/Prompt\/Index \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n               \u2502                 \u2502<br \/>\n               \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n                        \u2502<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 Evaluation Runner                           \u2502<br \/>\n\u2502 Baseline \/ Candidate \/ Repetitions          \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n        \u2502           \u2502             \u2502<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 Rules      \u2502 \u2502 Spring AI \u2502 \u2502 LLM-as-Judge  \u2502<br \/>\n\u2502 Schema\/ACL \u2502 \u2502 Evaluator \u2502 \u2502 Pairwise      \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n        \u2502           \u2502             \u2502<br \/>\n        \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n                    \u2502<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 Metric Aggregation \/ Slice Comparison       \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n                    \u2502<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 Quality Gate Engine                         \u2502<br \/>\n\u2502 PASS \/ FAIL \/ NEEDS_REVIEW \/ ERROR          \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n                    \u2502<br \/>\n          Report \/ Check Run \/ Artifacts<\/p>\n<h3>\u4e09\u3001\u9879\u76ee\u7ed3\u6784<\/h3>\n<p>ai-quality-gate<br \/>\n\u251c\u2500\u2500 pom.xml<br \/>\n\u251c\u2500\u2500 src\/main\/java\/com\/example\/eval<br \/>\n\u2502   \u251c\u2500\u2500 api<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 EvaluationRunController.java<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 DatasetController.java<br \/>\n\u2502   \u2502   \u2514\u2500\u2500 EvaluationReportController.java<br \/>\n\u2502   \u251c\u2500\u2500 dataset<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 EvaluationDataset.java<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 EvaluationCase.java<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 DatasetManifest.java<br \/>\n\u2502   \u2502   \u2514\u2500\u2500 DatasetRepository.java<br \/>\n\u2502   \u251c\u2500\u2500 release<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 RuntimeManifest.java<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 ReleaseTarget.java<br \/>\n\u2502   \u2502   \u2514\u2500\u2500 ReleaseTargetRegistry.java<br \/>\n\u2502   \u251c\u2500\u2500 runner<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 EvaluationRunner.java<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 CaseExecutionService.java<br \/>\n\u2502   \u2502   \u2514\u2500\u2500 EvaluationRunContext.java<br \/>\n\u2502   \u251c\u2500\u2500 evaluator<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 EvaluationRule.java<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 DeterministicEvaluator.java<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 SpringAiEvaluatorAdapter.java<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 LlmJudgeEvaluator.java<br \/>\n\u2502   \u2502   \u2514\u2500\u2500 ToolTraceEvaluator.java<br \/>\n\u2502   \u251c\u2500\u2500 metric<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 MetricAggregator.java<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 SliceMetric.java<br \/>\n\u2502   \u2502   \u2514\u2500\u2500 StatisticalComparisonService.java<br \/>\n\u2502   \u251c\u2500\u2500 gate<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 QualityGateEngine.java<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 QualityGatePolicy.java<br \/>\n\u2502   \u2502   \u2514\u2500\u2500 QualityGateDecision.java<br \/>\n\u2502   \u251c\u2500\u2500 report<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 EvaluationReportService.java<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 MarkdownReportRenderer.java<br \/>\n\u2502   \u2502   \u2514\u2500\u2500 JsonReportRenderer.java<br \/>\n\u2502   \u2514\u2500\u2500 integration<br \/>\n\u2502       \u251c\u2500\u2500 GitHubCheckPublisher.java<br \/>\n\u2502       \u2514\u2500\u2500 CliEvaluationCommand.java<br \/>\n\u2514\u2500\u2500 src\/test<br \/>\n    \u251c\u2500\u2500 DatasetVersionTest.java<br \/>\n    \u251c\u2500\u2500 EvaluationRunnerTest.java<br \/>\n    \u251c\u2500\u2500 JudgeCalibrationTest.java<br \/>\n    \u2514\u2500\u2500 QualityGateTest.java<\/p>\n<h3>\u56db\u3001Maven\u4f9d\u8d56<\/h3>\n<p><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependencies<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.springframework.boot<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>spring-boot-starter-web<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.springframework.boot<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>spring-boot-starter-validation<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.springframework.boot<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>spring-boot-starter-data-jpa<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.springframework.ai<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>spring-ai-starter-model-openai<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.springframework.ai<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>spring-ai-rag<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.postgresql<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>postgresql<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>scope<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>runtime<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>scope<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.springframework.boot<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>spring-boot-starter-actuator<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>io.micrometer<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>micrometer-registry-prometheus<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.apache.commons<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>commons-math3<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>3.6.1<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>version<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>org.springframework.boot<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>groupId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>spring-boot-starter-test<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>artifactId<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>scope<\/span><span class=\"token punctuation\">&gt;<\/span><\/span>test<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>scope<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependency<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br \/>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dependencies<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<h3>\u4e94\u3001\u6838\u5fc3\u6570\u636e\u5e93\u8868<\/h3>\n<p><span class=\"token keyword\">create<\/span> <span class=\"token keyword\">table<\/span> eval_dataset <span class=\"token punctuation\">(<\/span><br \/>\n    dataset_id <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    version <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">64<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    name <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">256<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">status<\/span> <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">32<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    content_hash <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    created_by <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    created_at timestamptz <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">primary<\/span> <span class=\"token keyword\">key<\/span> <span class=\"token punctuation\">(<\/span><br \/>\n        dataset_id<span class=\"token punctuation\">,<\/span><br \/>\n        version<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">create<\/span> <span class=\"token keyword\">table<\/span> eval_case <span class=\"token punctuation\">(<\/span><br \/>\n    case_id <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    case_version <span class=\"token keyword\">integer<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    dataset_id <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    dataset_version <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">64<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    source <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">32<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    task_type <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">64<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    risk_level <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">32<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    input jsonb <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    expected jsonb <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    provenance jsonb <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    content_hash <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">status<\/span> <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">32<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">primary<\/span> <span class=\"token keyword\">key<\/span> <span class=\"token punctuation\">(<\/span><br \/>\n        case_id<span class=\"token punctuation\">,<\/span><br \/>\n        case_version<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">create<\/span> <span class=\"token keyword\">table<\/span> eval_case_tag <span class=\"token punctuation\">(<\/span><br \/>\n    case_id <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    case_version <span class=\"token keyword\">integer<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    tag <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">primary<\/span> <span class=\"token keyword\">key<\/span> <span class=\"token punctuation\">(<\/span><br \/>\n        case_id<span class=\"token punctuation\">,<\/span><br \/>\n        case_version<span class=\"token punctuation\">,<\/span><br \/>\n        tag<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">create<\/span> <span class=\"token keyword\">table<\/span> eval_run <span class=\"token punctuation\">(<\/span><br \/>\n    run_id <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">64<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">primary<\/span> <span class=\"token keyword\">key<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    baseline_release <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    candidate_release <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    dataset_manifest jsonb <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    evaluator_manifest jsonb <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">status<\/span> <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">32<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    started_at timestamptz <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    completed_at timestamptz<span class=\"token punctuation\">,<\/span><br \/>\n    failure_code <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">64<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">create<\/span> <span class=\"token keyword\">table<\/span> eval_case_execution <span class=\"token punctuation\">(<\/span><br \/>\n    execution_id <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">64<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">primary<\/span> <span class=\"token keyword\">key<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    run_id <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">64<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    case_id <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    case_version <span class=\"token keyword\">integer<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    target <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">32<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    repetition <span class=\"token keyword\">integer<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    runtime_manifest jsonb <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    input_hash <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    output <span class=\"token keyword\">text<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    evidence jsonb<span class=\"token punctuation\">,<\/span><br \/>\n    tool_trace jsonb<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">usage<\/span> jsonb<span class=\"token punctuation\">,<\/span><br \/>\n    latency_ms <span class=\"token keyword\">bigint<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">status<\/span> <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">32<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    error_code <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">64<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">unique<\/span> <span class=\"token punctuation\">(<\/span><br \/>\n        run_id<span class=\"token punctuation\">,<\/span><br \/>\n        case_id<span class=\"token punctuation\">,<\/span><br \/>\n        case_version<span class=\"token punctuation\">,<\/span><br \/>\n        target<span class=\"token punctuation\">,<\/span><br \/>\n        repetition<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">create<\/span> <span class=\"token keyword\">table<\/span> eval_result <span class=\"token punctuation\">(<\/span><br \/>\n    result_id <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">64<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">primary<\/span> <span class=\"token keyword\">key<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    execution_id <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">64<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    evaluator_id <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">128<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    evaluator_version <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">64<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">status<\/span> <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">32<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    score <span class=\"token keyword\">numeric<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">10<\/span><span class=\"token punctuation\">,<\/span><span class=\"token number\">6<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    decision <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">32<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    details jsonb <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">create<\/span> <span class=\"token keyword\">table<\/span> eval_gate_result <span class=\"token punctuation\">(<\/span><br \/>\n    run_id <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">64<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">primary<\/span> <span class=\"token keyword\">key<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    decision <span class=\"token keyword\">varchar<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">32<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    summary jsonb <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    hard_failures jsonb <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    generated_at timestamptz <span class=\"token operator\">not<\/span> <span class=\"token boolean\">null<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<h3>\u516d\u3001\u6570\u636e\u96c6\u5b9e\u4f53<\/h3>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">EvaluationCase<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> caseId<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">int<\/span> caseVersion<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> taskType<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">RiskLevel<\/span> riskLevel<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">EvaluationSource<\/span> source<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">JsonNode<\/span> input<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">ExpectedBehavior<\/span> expected<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">Set<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> tags<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">DataProvenance<\/span> provenance<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">ExpectedBehavior<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">JsonNode<\/span> exactOutput<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> requiredFacts<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> forbiddenFacts<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">Set<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> expectedDocumentIds<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">Set<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> forbiddenDocumentIds<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">ToolTraceExpectation<\/span> toolTrace<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">RefusalExpectation<\/span> refusal<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">OutputContract<\/span> outputContract<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">QualityRubric<\/span> rubric<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">OperationalBudget<\/span> budget<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>\u4e03\u3001Dataset Manifest<\/h3>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">DatasetManifest<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">DatasetReference<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> datasets<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> combinedHash<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> tagCounts<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">Instant<\/span> frozenAt<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">DatasetReference<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> datasetId<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> version<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> contentHash<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Runner\u542f\u52a8\u540e\u5148\u91cd\u65b0\u8ba1\u7b97Hash\u3002\u5982\u679c\u6570\u636e\u5e93\u5185\u5bb9\u4e0eManifest\u4e0d\u4e00\u81f4&#xff0c;\u76f4\u63a5\u505c\u6b62\u8bc4\u6d4b\u3002<\/p>\n<h3>\u516b\u3001Runtime Manifest<\/h3>\n<p>\u6bcf\u6b21\u6267\u884c\u5fc5\u987b\u8bb0\u5f55\u5b9e\u9645\u8fd0\u884c\u7ec4\u4ef6&#xff1a;<\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">RuntimeManifest<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> releaseId<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> gitCommit<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> modelProfileId<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> requestedModel<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> resolvedModel<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> promptManifestHash<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> knowledgeIndexVersion<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> toolCatalogVersion<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> outputSchemaVersion<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> applicationConfigHash<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> environment<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u4e0d\u80fd\u53ea\u8bb0\u5f55\u4ee3\u7801Commit&#xff0c;\u56e0\u4e3aPrompt\u3001\u6a21\u578b\u548c\u77e5\u8bc6\u7d22\u5f15\u53ef\u80fd\u72ec\u7acb\u66f4\u65b0\u3002<\/p>\n<h3>\u4e5d\u3001Release Target\u62bd\u8c61<\/h3>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">ReleaseTarget<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token class-name\">String<\/span> <span class=\"token function\">releaseId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">RuntimeManifest<\/span> <span class=\"token function\">manifest<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">TargetExecutionResult<\/span> <span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationCase<\/span> evaluationCase<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">EvaluationExecutionContext<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5b9e\u73b0\u53ef\u4ee5\u662f&#xff1a;<\/p>\n<ul>\n<li>\u5f53\u524dJVM\u5185Service&#xff1b;<\/li>\n<li>\u8fdc\u7a0bHTTP\u73af\u5883&#xff1b;<\/li>\n<li>Docker\u5019\u9009\u7248\u672c&#xff1b;<\/li>\n<li>Kubernetes Preview&#xff1b;<\/li>\n<li>\u56fa\u5b9aBaseline\u670d\u52a1\u3002<\/li>\n<\/ul>\n<h3>\u5341\u3001TargetExecutionResult<\/h3>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">TargetExecutionResult<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> output<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">JsonNode<\/span> structuredOutput<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RetrievedEvidence<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> evidence<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">ToolTraceEvent<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> toolTrace<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">UsageSnapshot<\/span> usage<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">Duration<\/span> latency<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">RuntimeManifest<\/span> runtimeManifest<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u8d28\u91cf\u8bc4\u6d4b\u5fc5\u987b\u4fdd\u5b58\u4e2d\u95f4\u8f68\u8ff9&#xff0c;\u4e0d\u80fd\u53ea\u6709\u6700\u7ec8\u6587\u672c\u3002<\/p>\n<h3>\u5341\u4e00\u3001\u8bc4\u6d4b\u8fd0\u884c\u914d\u7f6e<\/h3>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">EvaluationRunConfig<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> runId<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> baselineReleaseId<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> candidateReleaseId<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">DatasetManifest<\/span> datasetManifest<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">EvaluatorManifest<\/span> evaluatorManifest<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">int<\/span> repetitions<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">int<\/span> concurrency<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">boolean<\/span> failFastOnHardFailure<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>\u5341\u4e8c\u3001Case\u6267\u884c\u670d\u52a1<\/h3>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CaseExecutionService<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">ReleaseTargetRegistry<\/span> targetRegistry<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">EvalCaseExecutionRepository<\/span> repository<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">TargetExecutionResult<\/span> <span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationRunContext<\/span> run<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">EvaluationCase<\/span> evaluationCase<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">EvaluationTarget<\/span> target<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token keyword\">int<\/span> repetition<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">ReleaseTarget<\/span> releaseTarget <span class=\"token operator\">&#061;<\/span><br \/>\n                targetRegistry<span class=\"token punctuation\">.<\/span><span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        target <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token class-name\">EvaluationTarget<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">BASELINE<\/span><br \/>\n                                <span class=\"token operator\">?<\/span> run<span class=\"token punctuation\">.<\/span><span class=\"token function\">baselineReleaseId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token operator\">:<\/span> run<span class=\"token punctuation\">.<\/span><span class=\"token function\">candidateReleaseId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">RuntimeManifest<\/span> expected <span class=\"token operator\">&#061;<\/span><br \/>\n                releaseTarget<span class=\"token punctuation\">.<\/span><span class=\"token function\">manifest<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">String<\/span> executionId <span class=\"token operator\">&#061;<\/span><br \/>\n                <span class=\"token constant\">UUID<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">randomUUID<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">toString<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        repository<span class=\"token punctuation\">.<\/span><span class=\"token function\">insertRunning<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                executionId<span class=\"token punctuation\">,<\/span><br \/>\n                run<span class=\"token punctuation\">.<\/span><span class=\"token function\">runId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                evaluationCase<span class=\"token punctuation\">,<\/span><br \/>\n                target<span class=\"token punctuation\">,<\/span><br \/>\n                repetition<span class=\"token punctuation\">,<\/span><br \/>\n                expected<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">long<\/span> started <span class=\"token operator\">&#061;<\/span><br \/>\n                <span class=\"token class-name\">System<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">nanoTime<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">TargetExecutionResult<\/span> result <span class=\"token operator\">&#061;<\/span><br \/>\n                    releaseTarget<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                            evaluationCase<span class=\"token punctuation\">,<\/span><br \/>\n                            run<span class=\"token punctuation\">.<\/span><span class=\"token function\">executionContext<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token function\">assertManifestMatches<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    expected<span class=\"token punctuation\">,<\/span><br \/>\n                    result<span class=\"token punctuation\">.<\/span><span class=\"token function\">runtimeManifest<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            repository<span class=\"token punctuation\">.<\/span><span class=\"token function\">completeSuccess<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    executionId<span class=\"token punctuation\">,<\/span><br \/>\n                    result<span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token function\">elapsedMillis<\/span><span class=\"token punctuation\">(<\/span>started<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">return<\/span> result<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> ex<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            repository<span class=\"token punctuation\">.<\/span><span class=\"token function\">completeFailure<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    executionId<span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token function\">classify<\/span><span class=\"token punctuation\">(<\/span>ex<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token function\">elapsedMillis<\/span><span class=\"token punctuation\">(<\/span>started<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> ex<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>\u5341\u4e09\u3001\u91cd\u590d\u6267\u884c<\/h3>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">TargetExecutionResult<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">executeRepeated<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">EvaluationRunContext<\/span> run<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">EvaluationCase<\/span> evaluationCase<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">EvaluationTarget<\/span> target<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">IntStream<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">range<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    run<span class=\"token punctuation\">.<\/span><span class=\"token function\">repetitions<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">mapToObj<\/span><span class=\"token punctuation\">(<\/span>repetition <span class=\"token operator\">-&gt;<\/span><br \/>\n                    <span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                            run<span class=\"token punctuation\">,<\/span><br \/>\n                            evaluationCase<span class=\"token punctuation\">,<\/span><br \/>\n                            target<span class=\"token punctuation\">,<\/span><br \/>\n                            repetition<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u9ad8\u98ce\u9669\u6570\u636e\u96c6\u53ef\u914d\u7f6e5\u6b21&#xff0c;\u666e\u901aPR\u5feb\u901f\u96c6\u53ef\u914d\u7f6e1\u20143\u6b21\u3002<\/p>\n<h3>\u5341\u56db\u3001Evaluator\u63a5\u53e3<\/h3>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">interface<\/span> <span class=\"token class-name\">EvaluationRule<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token class-name\">String<\/span> <span class=\"token function\">evaluatorId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">String<\/span> <span class=\"token function\">version<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">boolean<\/span> <span class=\"token function\">supports<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationCase<\/span> evaluationCase<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">EvaluationResult<\/span> <span class=\"token function\">evaluate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationContext<\/span> context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">EvaluationContext<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">EvaluationCase<\/span> evaluationCase<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">TargetExecutionResult<\/span> baseline<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">TargetExecutionResult<\/span> candidate<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">int<\/span> repetition<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">EvaluatorManifest<\/span> manifest<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>\u5341\u4e94\u3001EvaluationResult<\/h3>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">EvaluationResult<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> evaluatorId<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> evaluatorVersion<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">EvaluationStatus<\/span> status<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">Double<\/span> score<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">EvaluationDecision<\/span> decision<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">JsonNode<\/span> details<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">boolean<\/span> hardFailure<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u72b6\u6001&#xff1a;<\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">EvaluationStatus<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">COMPLETED<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token constant\">EVALUATOR_ERROR<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token constant\">SKIPPED<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u51b3\u7b56&#xff1a;<\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">EvaluationDecision<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token constant\">PASS<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token constant\">FAIL<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token constant\">BASELINE_WINS<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token constant\">CANDIDATE_WINS<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token constant\">TIE<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token constant\">NEEDS_REVIEW<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>\u5341\u516d\u3001\u786e\u5b9a\u6027Evaluator<\/h3>\n<h4>JSON Schema<\/h4>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">JsonSchemaEvaluator<\/span><br \/>\n        <span class=\"token keyword\">implements<\/span> <span class=\"token class-name\">EvaluationRule<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Override<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">EvaluationResult<\/span> <span class=\"token function\">evaluate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationContext<\/span> context<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">OutputContract<\/span> contract <span class=\"token operator\">&#061;<\/span><br \/>\n                context<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluationCase<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">expected<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">outputContract<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>contract <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token function\">skipped<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token class-name\">ValidationReport<\/span> report <span class=\"token operator\">&#061;<\/span><br \/>\n                schemaValidator<span class=\"token punctuation\">.<\/span><span class=\"token function\">validate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        contract<span class=\"token punctuation\">.<\/span><span class=\"token function\">schema<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        context<span class=\"token punctuation\">.<\/span><span class=\"token function\">candidate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">structuredOutput<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> report<span class=\"token punctuation\">.<\/span><span class=\"token function\">valid<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token operator\">?<\/span> <span class=\"token function\">pass<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1.0<\/span><span class=\"token punctuation\">,<\/span> report<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token operator\">:<\/span> <span class=\"token function\">fail<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        <span class=\"token number\">0.0<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        report<span class=\"token punctuation\">,<\/span><br \/>\n                        contract<span class=\"token punctuation\">.<\/span><span class=\"token function\">hardGate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>\u7981\u6b62\u8bc1\u636e<\/h4>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">ForbiddenEvidenceEvaluator<\/span><br \/>\n        <span class=\"token keyword\">implements<\/span> <span class=\"token class-name\">EvaluationRule<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">EvaluationResult<\/span> <span class=\"token function\">evaluate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationContext<\/span> context<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">Set<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> forbidden <span class=\"token operator\">&#061;<\/span><br \/>\n                context<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluationCase<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">expected<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">forbiddenDocumentIds<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Set<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> actual <span class=\"token operator\">&#061;<\/span><br \/>\n                context<span class=\"token punctuation\">.<\/span><span class=\"token function\">candidate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">evidence<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                <span class=\"token class-name\">RetrievedEvidence<\/span><br \/>\n                                        <span class=\"token operator\">::<\/span><span class=\"token function\">documentId<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                <span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toSet<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Set<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> violations <span class=\"token operator\">&#061;<\/span><br \/>\n                <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">HashSet<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span>actual<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        violations<span class=\"token punctuation\">.<\/span><span class=\"token function\">retainAll<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                forbidden<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> violations<span class=\"token punctuation\">.<\/span><span class=\"token function\">isEmpty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token operator\">?<\/span> <span class=\"token function\">pass<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token operator\">:<\/span> <span class=\"token function\">hardFail<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        <span class=\"token string\">&#034;\u547d\u4e2d\u7981\u6b62\u6587\u6863&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        violations<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>Tool\u8c03\u7528\u6b21\u6570<\/h4>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">ToolCallCountEvaluator<\/span><br \/>\n        <span class=\"token keyword\">implements<\/span> <span class=\"token class-name\">EvaluationRule<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">EvaluationResult<\/span> <span class=\"token function\">evaluate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationContext<\/span> context<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">Long<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> counts <span class=\"token operator\">&#061;<\/span><br \/>\n                context<span class=\"token punctuation\">.<\/span><span class=\"token function\">candidate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">toolTrace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">filter<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                <span class=\"token class-name\">ToolTraceEvent<\/span><br \/>\n                                        <span class=\"token operator\">::<\/span><span class=\"token function\">isInvocation<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                <span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">groupingBy<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                        <span class=\"token class-name\">ToolTraceEvent<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">toolName<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                                        <span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">counting<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> toolExpectationValidator<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">validate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        context<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluationCase<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">expected<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">toolTrace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        counts<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>\u5341\u4e03\u3001Spring AI Evaluator\u9002\u914d<\/h3>\n<p>Spring AI\u63d0\u4f9b\u76f8\u5173\u6027\u548c\u4e8b\u5b9e\u68c0\u67e5\u7b49Evaluator\u3002<\/p>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">SpringAiRelevancyEvaluatorAdapter<\/span><br \/>\n        <span class=\"token keyword\">implements<\/span> <span class=\"token class-name\">EvaluationRule<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">RelevancyEvaluator<\/span> evaluator<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">SpringAiRelevancyEvaluatorAdapter<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token annotation punctuation\">&#064;Qualifier<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;judgeChatModel&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token class-name\">ChatModel<\/span> judgeChatModel<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token keyword\">this<\/span><span class=\"token punctuation\">.<\/span>evaluator <span class=\"token operator\">&#061;<\/span><br \/>\n                <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RelevancyEvaluator<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        <span class=\"token class-name\">ChatClient<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">builder<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                judgeChatModel<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation punctuation\">&#064;Override<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">EvaluationResult<\/span> <span class=\"token function\">evaluate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationContext<\/span> context<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">EvaluationRequest<\/span> request <span class=\"token operator\">&#061;<\/span><br \/>\n                <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">EvaluationRequest<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        context<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluationCase<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">input<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">toString<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        context<span class=\"token punctuation\">.<\/span><span class=\"token function\">candidate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">evidence<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                        <span class=\"token class-name\">RetrievedEvidence<\/span><br \/>\n                                                <span class=\"token operator\">::<\/span><span class=\"token function\">toDocument<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        context<span class=\"token punctuation\">.<\/span><span class=\"token function\">candidate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">output<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">EvaluationResponse<\/span> response <span class=\"token operator\">&#061;<\/span><br \/>\n                    evaluator<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                            request<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">return<\/span> response<span class=\"token punctuation\">.<\/span><span class=\"token function\">isPass<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token operator\">?<\/span> <span class=\"token function\">pass<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                            response<span class=\"token punctuation\">.<\/span><span class=\"token function\">getScore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                            response<span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token operator\">:<\/span> <span class=\"token function\">fail<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                            response<span class=\"token punctuation\">.<\/span><span class=\"token function\">getScore<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                            response<span class=\"token punctuation\">,<\/span><br \/>\n                            <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> ex<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token function\">evaluatorError<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    <span class=\"token string\">&#034;SPRING_AI_RELEVANCY_ERROR&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    ex<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Evaluator\u5f02\u5e38\u4e0d\u80fd\u76f4\u63a5\u7b97\u5019\u9009\u5931\u8d25\u3002<\/p>\n<h3>\u5341\u516b\u3001\u4e8b\u5b9e\u68c0\u67e5\u9002\u914d<\/h3>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">ClaimFactCheckEvaluator<\/span><br \/>\n        <span class=\"token keyword\">implements<\/span> <span class=\"token class-name\">EvaluationRule<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">FactCheckingEvaluator<\/span> evaluator<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">ClaimExtractor<\/span> claimExtractor<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">EvaluationResult<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">evaluateClaims<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationContext<\/span> context<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">AnswerClaim<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> claims <span class=\"token operator\">&#061;<\/span><br \/>\n                claimExtractor<span class=\"token punctuation\">.<\/span><span class=\"token function\">extract<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        context<span class=\"token punctuation\">.<\/span><span class=\"token function\">candidate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">output<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">String<\/span> document <span class=\"token operator\">&#061;<\/span><br \/>\n                context<span class=\"token punctuation\">.<\/span><span class=\"token function\">candidate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">evidence<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                <span class=\"token class-name\">RetrievedEvidence<\/span><br \/>\n                                        <span class=\"token operator\">::<\/span><span class=\"token function\">text<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                <span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">joining<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                        <span class=\"token string\">&#034;\\\\n\\\\n&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> claims<span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span>claim <span class=\"token operator\">-&gt;<\/span><br \/>\n                        <span class=\"token function\">evaluateOne<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                claim<span class=\"token punctuation\">,<\/span><br \/>\n                                document<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token class-name\">EvaluationResult<\/span> <span class=\"token function\">evaluateOne<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">AnswerClaim<\/span> claim<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">String<\/span> document<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">EvaluationResponse<\/span> response <span class=\"token operator\">&#061;<\/span><br \/>\n                evaluator<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">EvaluationRequest<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                claim<span class=\"token punctuation\">.<\/span><span class=\"token function\">text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                                <span class=\"token class-name\">List<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">of<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                        <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Document<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                                document<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                                claim<span class=\"token punctuation\">.<\/span><span class=\"token function\">text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> response<span class=\"token punctuation\">.<\/span><span class=\"token function\">isPass<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token operator\">?<\/span> <span class=\"token function\">pass<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token operator\">:<\/span> <span class=\"token function\">fail<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        <span class=\"token number\">0.0<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        response<span class=\"token punctuation\">,<\/span><br \/>\n                        claim<span class=\"token punctuation\">.<\/span><span class=\"token function\">highRisk<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5bf9\u6570\u5b57\u3001\u65e5\u671f\u548c\u679a\u4e3e\u5e94\u5148\u8fd0\u884c\u786e\u5b9a\u6027Evaluator&#xff0c;\u518d\u8fd0\u884c\u8bed\u4e49\u4e8b\u5b9e\u68c0\u67e5\u3002<\/p>\n<h3>\u5341\u4e5d\u3001\u81ea\u5b9a\u4e49LLM Judge<\/h3>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">LlmJudgeEvaluator<\/span><br \/>\n        <span class=\"token keyword\">implements<\/span> <span class=\"token class-name\">EvaluationRule<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">ChatClient<\/span> judgeClient<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">JudgePromptRegistry<\/span> promptRegistry<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">EvaluationResult<\/span> <span class=\"token function\">evaluate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationContext<\/span> context<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">JudgePrompt<\/span> prompt <span class=\"token operator\">&#061;<\/span><br \/>\n                promptRegistry<span class=\"token punctuation\">.<\/span><span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        context<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluationCase<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">taskType<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        context<span class=\"token punctuation\">.<\/span><span class=\"token function\">manifest<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">rubricVersion<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">JudgeResult<\/span> result <span class=\"token operator\">&#061;<\/span><br \/>\n                    judgeClient<span class=\"token punctuation\">.<\/span><span class=\"token function\">prompt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                            <span class=\"token punctuation\">.<\/span><span class=\"token function\">system<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                    prompt<span class=\"token punctuation\">.<\/span><span class=\"token function\">systemPrompt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                            <span class=\"token punctuation\">.<\/span><span class=\"token function\">user<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                    prompt<span class=\"token punctuation\">.<\/span><span class=\"token function\">render<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                            context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                            <span class=\"token punctuation\">.<\/span><span class=\"token function\">call<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                            <span class=\"token punctuation\">.<\/span><span class=\"token function\">entity<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                    <span class=\"token class-name\">JudgeResult<\/span><span class=\"token punctuation\">.<\/span><span class=\"token keyword\">class<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            judgeResultValidator<span class=\"token punctuation\">.<\/span><span class=\"token function\">validate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    result<span class=\"token punctuation\">,<\/span><br \/>\n                    context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">return<\/span> <span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span>result<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> ex<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token function\">evaluatorError<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    <span class=\"token string\">&#034;LLM_JUDGE_ERROR&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    ex<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Judge\u6a21\u578b\u3001Prompt\u3001Rubric\u3001\u91cd\u590d\u6b21\u6570\u548c\u5b9e\u73b0Hash\u90fd\u8fdb\u5165Evaluator Manifest\u3002<\/p>\n<h3>\u4e8c\u5341\u3001Pairwise\u53cc\u5411\u6bd4\u8f83<\/h3>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token class-name\">PairwiseEvaluationResult<\/span> <span class=\"token function\">evaluatePairwise<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">EvaluationContext<\/span> context<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token class-name\">PairwiseJudgeResult<\/span> normal <span class=\"token operator\">&#061;<\/span><br \/>\n            <span class=\"token function\">judgePair<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    context<span class=\"token punctuation\">,<\/span><br \/>\n                    context<span class=\"token punctuation\">.<\/span><span class=\"token function\">baseline<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                            <span class=\"token punctuation\">.<\/span><span class=\"token function\">output<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    context<span class=\"token punctuation\">.<\/span><span class=\"token function\">candidate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                            <span class=\"token punctuation\">.<\/span><span class=\"token function\">output<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token class-name\">CandidatePosition<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">SECOND<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">PairwiseJudgeResult<\/span> reversed <span class=\"token operator\">&#061;<\/span><br \/>\n            <span class=\"token function\">judgePair<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    context<span class=\"token punctuation\">,<\/span><br \/>\n                    context<span class=\"token punctuation\">.<\/span><span class=\"token function\">candidate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                            <span class=\"token punctuation\">.<\/span><span class=\"token function\">output<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    context<span class=\"token punctuation\">.<\/span><span class=\"token function\">baseline<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                            <span class=\"token punctuation\">.<\/span><span class=\"token function\">output<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token class-name\">CandidatePosition<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">FIRST<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">return<\/span> pairwiseCalibrator<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">aggregate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    normal<span class=\"token punctuation\">,<\/span><br \/>\n                    reversed<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u82e5\u4e24\u4e2a\u987a\u5e8f\u7ed3\u8bba\u51b2\u7a81&#xff0c;\u8fd4\u56de&#xff1a;<\/p>\n<p>NEEDS_REVIEW<\/p>\n<p>\u800c\u4e0d\u662f\u5f3a\u884c\u51b3\u5b9a\u80dc\u8d1f\u3002<\/p>\n<h3>\u4e8c\u5341\u4e00\u3001Evaluator\u7f16\u6392<\/h3>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">EvaluationService<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">EvaluationRule<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> rules<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">EvaluationResultRepository<\/span> resultRepository<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">EvaluationResult<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> <span class=\"token function\">evaluate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationContext<\/span> context<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">EvaluationResult<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> results <span class=\"token operator\">&#061;<\/span><br \/>\n                <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">ArrayList<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">EvaluationRule<\/span> rule <span class=\"token operator\">:<\/span><br \/>\n                rules<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">supports<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    context<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluationCase<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">continue<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token class-name\">EvaluationResult<\/span> result <span class=\"token operator\">&#061;<\/span><br \/>\n                    rule<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluate<\/span><span class=\"token punctuation\">(<\/span>context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            resultRepository<span class=\"token punctuation\">.<\/span><span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    context<span class=\"token punctuation\">,<\/span><br \/>\n                    result<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            results<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>result<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>result<span class=\"token punctuation\">.<\/span><span class=\"token function\">hardFailure<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">break<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> results<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u786c\u5931\u8d25\u53ef\u4ee5\u7ec8\u6b62\u5f53\u524dCase\u540e\u7eed\u6602\u8d35Judge&#xff0c;\u4f46\u6574\u4e2aRun\u662f\u5426Fail Fast\u7531\u914d\u7f6e\u51b3\u5b9a\u3002<\/p>\n<h3>\u4e8c\u5341\u4e8c\u3001Evaluation Runner<\/h3>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">EvaluationRunner<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">DatasetService<\/span> datasetService<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">CaseExecutionService<\/span> executionService<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">EvaluationService<\/span> evaluationService<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">MetricAggregator<\/span> metricAggregator<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">final<\/span> <span class=\"token class-name\">QualityGateEngine<\/span> qualityGateEngine<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">EvaluationRunResult<\/span> <span class=\"token function\">run<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationRunConfig<\/span> config<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">EvaluationRunContext<\/span> context <span class=\"token operator\">&#061;<\/span><br \/>\n                runLifecycle<span class=\"token punctuation\">.<\/span><span class=\"token function\">start<\/span><span class=\"token punctuation\">(<\/span>config<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">EvaluationCase<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> cases <span class=\"token operator\">&#061;<\/span><br \/>\n                    datasetService<span class=\"token punctuation\">.<\/span><span class=\"token function\">loadApproved<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                            config<span class=\"token punctuation\">.<\/span><span class=\"token function\">datasetManifest<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">ExecutorService<\/span> executor <span class=\"token operator\">&#061;<\/span><br \/>\n                    <span class=\"token class-name\">Executors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">newFixedThreadPool<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                            config<span class=\"token punctuation\">.<\/span><span class=\"token function\">concurrency<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">Future<\/span><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CaseRunResult<\/span><span class=\"token punctuation\">&gt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> futures <span class=\"token operator\">&#061;<\/span><br \/>\n                    cases<span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                            <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span>evaluationCase <span class=\"token operator\">-&gt;<\/span><br \/>\n                                    executor<span class=\"token punctuation\">.<\/span><span class=\"token function\">submit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span><br \/>\n                                            <span class=\"token function\">executeCase<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                                    context<span class=\"token punctuation\">,<\/span><br \/>\n                                                    evaluationCase<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                            <span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CaseRunResult<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> results <span class=\"token operator\">&#061;<\/span><br \/>\n                    <span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span>futures<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">AggregatedMetrics<\/span> metrics <span class=\"token operator\">&#061;<\/span><br \/>\n                    metricAggregator<span class=\"token punctuation\">.<\/span><span class=\"token function\">aggregate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                            context<span class=\"token punctuation\">,<\/span><br \/>\n                            results<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token class-name\">QualityGateDecision<\/span> gate <span class=\"token operator\">&#061;<\/span><br \/>\n                    qualityGateEngine<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                            context<span class=\"token punctuation\">,<\/span><br \/>\n                            metrics<span class=\"token punctuation\">,<\/span><br \/>\n                            results<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            runLifecycle<span class=\"token punctuation\">.<\/span><span class=\"token function\">complete<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    context<span class=\"token punctuation\">,<\/span><br \/>\n                    metrics<span class=\"token punctuation\">,<\/span><br \/>\n                    gate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>            <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">EvaluationRunResult<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    context<span class=\"token punctuation\">.<\/span><span class=\"token function\">runId<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    metrics<span class=\"token punctuation\">,<\/span><br \/>\n                    gate<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Exception<\/span> ex<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            runLifecycle<span class=\"token punctuation\">.<\/span><span class=\"token function\">fail<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    context<span class=\"token punctuation\">,<\/span><br \/>\n                    ex<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">throw<\/span> ex<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>\u4e8c\u5341\u4e09\u3001\u5355Case\u53cc\u8dd1<\/h3>\n<p><span class=\"token keyword\">private<\/span> <span class=\"token class-name\">CaseRunResult<\/span> <span class=\"token function\">executeCase<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">EvaluationRunContext<\/span> run<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">EvaluationCase<\/span> evaluationCase<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">RepeatedComparisonResult<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> repetitions <span class=\"token operator\">&#061;<\/span><br \/>\n            <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">ArrayList<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">int<\/span> repetition <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n         repetition <span class=\"token operator\">&lt;<\/span> run<span class=\"token punctuation\">.<\/span><span class=\"token function\">repetitions<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n         repetition<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">TargetExecutionResult<\/span> baseline <span class=\"token operator\">&#061;<\/span><br \/>\n                executionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        run<span class=\"token punctuation\">,<\/span><br \/>\n                        evaluationCase<span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token class-name\">EvaluationTarget<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">BASELINE<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        repetition<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">TargetExecutionResult<\/span> candidate <span class=\"token operator\">&#061;<\/span><br \/>\n                executionService<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        run<span class=\"token punctuation\">,<\/span><br \/>\n                        evaluationCase<span class=\"token punctuation\">,<\/span><br \/>\n                        <span class=\"token class-name\">EvaluationTarget<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">CANDIDATE<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        repetition<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">EvaluationContext<\/span> context <span class=\"token operator\">&#061;<\/span><br \/>\n                <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">EvaluationContext<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        evaluationCase<span class=\"token punctuation\">,<\/span><br \/>\n                        baseline<span class=\"token punctuation\">,<\/span><br \/>\n                        candidate<span class=\"token punctuation\">,<\/span><br \/>\n                        repetition<span class=\"token punctuation\">,<\/span><br \/>\n                        run<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluatorManifest<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">EvaluationResult<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> evaluation <span class=\"token operator\">&#061;<\/span><br \/>\n                evaluationService<span class=\"token punctuation\">.<\/span><span class=\"token function\">evaluate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        context<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        repetitions<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">RepeatedComparisonResult<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        repetition<span class=\"token punctuation\">,<\/span><br \/>\n                        baseline<span class=\"token punctuation\">,<\/span><br \/>\n                        candidate<span class=\"token punctuation\">,<\/span><br \/>\n                        evaluation<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">return<\/span> repeatedResultAggregator<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">aggregate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    evaluationCase<span class=\"token punctuation\">,<\/span><br \/>\n                    repetitions<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5982\u679c\u6ca1\u6709Baseline&#xff0c;\u53ef\u53ea\u8fd0\u884cCandidate\u7edd\u5bf9\u95e8\u7981\u3002<\/p>\n<h3>\u4e8c\u5341\u56db\u3001\u6210\u672c\u63a7\u5236<\/h3>\n<p>\u8bc4\u6d4b\u53ef\u80fd\u6d88\u8017\u5927\u91cfToken\u3002<\/p>\n<p>\u9700\u8981&#xff1a;<\/p>\n<ul>\n<li>\u6700\u5927\u5e76\u53d1&#xff1b;<\/li>\n<li>\u6bcfRun\u9884\u7b97&#xff1b;<\/li>\n<li>\u6bcfCase\u9884\u7b97&#xff1b;<\/li>\n<li>Judge\u7f13\u5b58&#xff1b;<\/li>\n<li>\u5931\u8d25\u5feb\u901f\u505c\u6b62&#xff1b;<\/li>\n<li>\u6570\u636e\u96c6\u5206\u5c42&#xff1b;<\/li>\n<li>Batch\u6216\u79bb\u7ebf\u8fd0\u884c\u3002<\/li>\n<\/ul>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">EvaluationBudget<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> maximumRunCost<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> maximumCaseCost<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">int<\/span> maximumJudgeCalls<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">Duration<\/span> maximumDuration<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u9884\u7b97\u8d85\u51fa&#xff1a;<\/p>\n<p>RUN_ABORTED_BUDGET<\/p>\n<p>\u4e0d\u80fd\u751f\u6210\u4e00\u4e2a\u4e0d\u5b8c\u6574\u4f46\u663e\u793aPASS\u7684\u62a5\u544a\u3002<\/p>\n<h3>\u4e8c\u5341\u4e94\u3001Judge\u7f13\u5b58<\/h3>\n<p>\u76f8\u540c&#xff1a;<\/p>\n<p>Judge Manifest<br \/>\n&#xff0b;Case<br \/>\n&#xff0b;\u8f93\u51fa<br \/>\n&#xff0b;Evidence<\/p>\n<p>\u53ef\u4ee5\u7f13\u5b58Judge\u7ed3\u679c\u3002<\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">JudgeCacheKey<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> evaluatorManifestHash<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> caseHash<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> outputHash<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> evidenceHash<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Baseline\u4e0eCandidate\u8f93\u51fa\u76f8\u540c&#xff0c;\u907f\u514d\u91cd\u590d\u6536\u8d39\u3002<\/p>\n<h3>\u4e8c\u5341\u516d\u3001Slice Metric<\/h3>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">SliceMetric<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> slice<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">int<\/span> caseCount<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">double<\/span> passRate<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">double<\/span> meanScore<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">double<\/span> minimumScore<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">double<\/span> candidateWinRate<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">double<\/span> baselineWinRate<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">double<\/span> evaluatorErrorRate<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">double<\/span> p95LatencyMs<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> meanCost<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>Slice\u6765\u6e90\u4e8eCase\u6807\u7b7e&#xff1a;<\/p>\n<p>contract-review<br \/>\nhigh-risk<br \/>\nrag<br \/>\ncitation<br \/>\nsecurity<br \/>\ntool-side-effect<br \/>\nlong-context<\/p>\n<h3>\u4e8c\u5341\u4e03\u3001\u6307\u6807\u805a\u5408<\/h3>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">MetricAggregator<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">AggregatedMetrics<\/span> <span class=\"token function\">aggregate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationRunContext<\/span> run<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CaseRunResult<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> results<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">List<\/span><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CaseRunResult<\/span><span class=\"token punctuation\">&gt;<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> slices <span class=\"token operator\">&#061;<\/span><br \/>\n                sliceResolver<span class=\"token punctuation\">.<\/span><span class=\"token function\">group<\/span><span class=\"token punctuation\">(<\/span>results<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">Map<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">SliceMetric<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> metrics <span class=\"token operator\">&#061;<\/span><br \/>\n                slices<span class=\"token punctuation\">.<\/span><span class=\"token function\">entrySet<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                <span class=\"token class-name\">Collectors<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toMap<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                        <span class=\"token class-name\">Map<span class=\"token punctuation\">.<\/span>Entry<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">getKey<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                                        entry <span class=\"token operator\">-&gt;<\/span><br \/>\n                                                <span class=\"token function\">calculate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                                        entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">getKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                                                        entry<span class=\"token punctuation\">.<\/span><span class=\"token function\">getValue<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">AggregatedMetrics<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                metrics<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;global&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                metrics<span class=\"token punctuation\">,<\/span><br \/>\n                hardFailureCollector<br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span><span class=\"token punctuation\">(<\/span>results<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>\u4e8c\u5341\u516b\u3001\u7edf\u8ba1\u6bd4\u8f83<\/h3>\n<p>Candidate\u4e0eBaseline\u662f\u540c\u4e00Case\u7684\u914d\u5bf9\u6570\u636e\u3002<\/p>\n<p>\u53ef\u4ee5\u8ba1\u7b97&#xff1a;<\/p>\n<ul>\n<li>\u901a\u8fc7\u7387Delta&#xff1b;<\/li>\n<li>\u5e73\u5747\u5206Delta&#xff1b;<\/li>\n<li>Pairwise Win Rate&#xff1b;<\/li>\n<li>Bootstrap\u533a\u95f4&#xff1b;<\/li>\n<li>McNemar&#xff1b;<\/li>\n<li>\u91cd\u590d\u4e00\u81f4\u7387\u3002<\/li>\n<\/ul>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">StatisticalComparison<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token keyword\">double<\/span> delta<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">double<\/span> lowerConfidenceBound<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">double<\/span> upperConfidenceBound<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">boolean<\/span> meaningful<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u8d28\u91cf\u95e8\u7981\u4e0d\u5e94\u56e0\u4e3a\u6781\u5c0f\u968f\u673a\u6ce2\u52a8\u9891\u7e41\u6296\u52a8\u3002<\/p>\n<h3>\u4e8c\u5341\u4e5d\u3001Quality Gate Policy<\/h3>\n<p><span class=\"token key atrule\">quality-gate<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">global<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">minimum-pass-rate<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.92<\/span><br \/>\n    <span class=\"token key atrule\">maximum-pass-rate-regression<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.02<\/span><br \/>\n    <span class=\"token key atrule\">minimum-mean-score<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">4.20<\/span><br \/>\n    <span class=\"token key atrule\">maximum-evaluator-error-rate<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.01<\/span><\/p>\n<p>  <span class=\"token key atrule\">slices<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">contract-review<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">minimum-pass-rate<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.95<\/span><br \/>\n      <span class=\"token key atrule\">maximum-regression<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.00<\/span><\/p>\n<p>    <span class=\"token key atrule\">rag-citation<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">minimum-claim-support-rate<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.97<\/span><br \/>\n      <span class=\"token key atrule\">maximum-forbidden-document-rate<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.00<\/span><\/p>\n<p>    <span class=\"token key atrule\">security<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">allowed-failures<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">0<\/span><\/p>\n<p>    <span class=\"token key atrule\">tool-side-effect<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">duplicate-tool-call-rate<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.00<\/span><\/p>\n<p>  <span class=\"token key atrule\">operations<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">maximum-p95-latency-regression<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.15<\/span><br \/>\n    <span class=\"token key atrule\">maximum-cost-regression<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">0.20<\/span><\/p>\n<h3>\u4e09\u5341\u3001Gate\u89c4\u5219\u6a21\u578b<\/h3>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">GateRule<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> ruleId<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> slice<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">MetricName<\/span> metric<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">ComparisonOperator<\/span> operator<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> threshold<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">GateSeverity<\/span> severity<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">boolean<\/span> compareWithBaseline<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">record<\/span> <span class=\"token class-name\">GateViolation<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> ruleId<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">String<\/span> slice<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> actual<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">BigDecimal<\/span> threshold<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">GateSeverity<\/span> severity<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">String<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> affectedCaseIds<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>\u4e09\u5341\u4e00\u3001Quality Gate Engine<\/h3>\n<p><span class=\"token annotation punctuation\">&#064;Service<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">QualityGateEngine<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token class-name\">QualityGateDecision<\/span> <span class=\"token function\">evaluate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">EvaluationRunContext<\/span> context<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">AggregatedMetrics<\/span> metrics<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">CaseRunResult<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> cases<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">List<\/span><span class=\"token generics\"><span class=\"token punctuation\">&lt;<\/span><span class=\"token class-name\">GateViolation<\/span><span class=\"token punctuation\">&gt;<\/span><\/span> violations <span class=\"token operator\">&#061;<\/span><br \/>\n                policy<span class=\"token punctuation\">.<\/span><span class=\"token function\">rules<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span>rule <span class=\"token operator\">-&gt;<\/span><br \/>\n                                <span class=\"token function\">evaluateRule<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                        rule<span class=\"token punctuation\">,<\/span><br \/>\n                                        metrics<span class=\"token punctuation\">,<\/span><br \/>\n                                        cases<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">flatMap<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                <span class=\"token class-name\">Optional<\/span><span class=\"token operator\">::<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">boolean<\/span> blocking <span class=\"token operator\">&#061;<\/span><br \/>\n                violations<span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">anyMatch<\/span><span class=\"token punctuation\">(<\/span>violation <span class=\"token operator\">-&gt;<\/span><br \/>\n                                violation<span class=\"token punctuation\">.<\/span><span class=\"token function\">severity<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                                        <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token class-name\">GateSeverity<\/span><span class=\"token punctuation\">.<\/span><span class=\"token constant\">BLOCKING<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">boolean<\/span> needsReview <span class=\"token operator\">&#061;<\/span><br \/>\n                cases<span class=\"token punctuation\">.<\/span><span class=\"token function\">stream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">anyMatch<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                <span class=\"token class-name\">CaseRunResult<\/span><br \/>\n                                        <span class=\"token operator\">::<\/span><span class=\"token function\">needsHumanReview<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>blocking<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">QualityGateDecision<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">fail<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    violations<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>needsReview<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">QualityGateDecision<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">needsReview<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                            violations<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token class-name\">QualityGateDecision<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">pass<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h3>\u4e09\u5341\u4e8c\u3001REST API<\/h3>\n<p>\u542f\u52a8&#xff1a;<\/p>\n<p>POST \/api\/v1\/evaluation-runs<\/p>\n<p><span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token string-property property\">&#034;baselineReleaseId&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;release-v41&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;candidateReleaseId&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;release-v42&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;datasets&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token string-property property\">&#034;datasetId&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;enterprise-rag&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;version&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;2026.08.06-v3&#034;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;repetitions&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">3<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;concurrency&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">8<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;gatePolicy&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;production-release-v5&#034;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u54cd\u5e94&#xff1a;<\/p>\n<p><span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token string-property property\">&#034;runId&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;RUN-1001&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;status&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;QUEUED&#034;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u67e5\u8be2&#xff1a;<\/p>\n<p>GET \/api\/v1\/evaluation-runs\/RUN-1001<\/p>\n<h3>\u4e09\u5341\u4e09\u3001CLI\u6a21\u5f0f<\/h3>\n<p><span class=\"token annotation punctuation\">&#064;Component<\/span><br \/>\n<span class=\"token annotation punctuation\">&#064;Profile<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;eval-cli&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">CliEvaluationCommand<\/span><br \/>\n        <span class=\"token keyword\">implements<\/span> <span class=\"token class-name\">CommandLineRunner<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">void<\/span> <span class=\"token function\">run<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token class-name\">String<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span> args<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token class-name\">EvaluationRunResult<\/span> result <span class=\"token operator\">&#061;<\/span><br \/>\n                runner<span class=\"token punctuation\">.<\/span><span class=\"token function\">run<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        configLoader<br \/>\n                                <span class=\"token punctuation\">.<\/span><span class=\"token function\">fromArgs<\/span><span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        reportWriter<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                result<span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token class-name\">Path<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">of<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        <span class=\"token string\">&#034;build\/eval-report&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token keyword\">int<\/span> exitCode <span class=\"token operator\">&#061;<\/span><br \/>\n                <span class=\"token keyword\">switch<\/span> <span class=\"token punctuation\">(<\/span>result<span class=\"token punctuation\">.<\/span><span class=\"token function\">gate<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">.<\/span><span class=\"token function\">decision<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">case<\/span> <span class=\"token constant\">PASS<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    <span class=\"token keyword\">case<\/span> <span class=\"token constant\">NEEDS_REVIEW<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                    <span class=\"token keyword\">case<\/span> <span class=\"token constant\">FAIL<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token constant\">ERROR<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token class-name\">SpringApplication<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">exit<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                applicationContext<span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> exitCode<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>CI\u4f7f\u7528\u9000\u51fa\u7801\u963b\u65ad\u3002<\/p>\n<h3>\u4e09\u5341\u56db\u3001GitHub Actions<\/h3>\n<p><span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> AI Quality Gate<\/p>\n<p><span class=\"token key atrule\">on<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">pull_request<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">workflow_dispatch<\/span><span class=\"token punctuation\">:<\/span><\/p>\n<p><span class=\"token key atrule\">jobs<\/span><span class=\"token punctuation\">:<\/span><br \/>\n  <span class=\"token key atrule\">ai-quality-gate<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token key atrule\">runs-on<\/span><span class=\"token punctuation\">:<\/span> ubuntu<span class=\"token punctuation\">&#8211;<\/span>latest<br \/>\n    <span class=\"token key atrule\">timeout-minutes<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">45<\/span><\/p>\n<p>    <span class=\"token key atrule\">permissions<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token key atrule\">contents<\/span><span class=\"token punctuation\">:<\/span> read<br \/>\n      <span class=\"token key atrule\">checks<\/span><span class=\"token punctuation\">:<\/span> write<\/p>\n<p>    <span class=\"token key atrule\">steps<\/span><span class=\"token punctuation\">:<\/span><br \/>\n      <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">uses<\/span><span class=\"token punctuation\">:<\/span> actions\/checkout&#064;v4<\/p>\n<p>      <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">uses<\/span><span class=\"token punctuation\">:<\/span> actions\/setup<span class=\"token punctuation\">&#8211;<\/span>java&#064;v4<br \/>\n        <span class=\"token key atrule\">with<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">distribution<\/span><span class=\"token punctuation\">:<\/span> temurin<br \/>\n          <span class=\"token key atrule\">java-version<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;21&#034;<\/span><br \/>\n          <span class=\"token key atrule\">cache<\/span><span class=\"token punctuation\">:<\/span> maven<\/p>\n<p>      <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> Build<br \/>\n        <span class=\"token key atrule\">run<\/span><span class=\"token punctuation\">:<\/span> .\/mvnw <span class=\"token punctuation\">&#8211;<\/span>B <span class=\"token punctuation\">&#8211;<\/span>DskipTests package<\/p>\n<p>      <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> Run AI evaluation<br \/>\n        <span class=\"token key atrule\">env<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">EVAL_API_KEY<\/span><span class=\"token punctuation\">:<\/span> $<span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">{<\/span> secrets.EVAL_API_KEY <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">}<\/span><br \/>\n          <span class=\"token key atrule\">BASELINE_RELEASE<\/span><span class=\"token punctuation\">:<\/span> production<br \/>\n          <span class=\"token key atrule\">CANDIDATE_RELEASE<\/span><span class=\"token punctuation\">:<\/span> $<span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">{<\/span> github.sha <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token key atrule\">run<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">|<\/span><span class=\"token scalar string\"><br \/>\n          .\/mvnw -B spring-boot:run \\\\<br \/>\n            -Dspring-boot.run.profiles&#061;eval-cli \\\\<br \/>\n            -Dspring-boot.run.arguments&#061;&#034;\\\\<br \/>\n            &#8211;baseline&#061;${BASELINE_RELEASE} \\\\<br \/>\n            &#8211;candidate&#061;${CANDIDATE_RELEASE} \\\\<br \/>\n            &#8211;dataset&#061;pr-fast&#064;2026.08.06-v1 \\\\<br \/>\n            &#8211;report-dir&#061;build\/eval-report&#034;<\/span><\/p>\n<p>      <span class=\"token punctuation\">&#8211;<\/span> <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> Upload evaluation report<br \/>\n        <span class=\"token key atrule\">if<\/span><span class=\"token punctuation\">:<\/span> always()<br \/>\n        <span class=\"token key atrule\">uses<\/span><span class=\"token punctuation\">:<\/span> actions\/upload<span class=\"token punctuation\">&#8211;<\/span>artifact&#064;v4<br \/>\n        <span class=\"token key atrule\">with<\/span><span class=\"token punctuation\">:<\/span><br \/>\n          <span class=\"token key atrule\">name<\/span><span class=\"token punctuation\">:<\/span> ai<span class=\"token punctuation\">&#8211;<\/span>evaluation<span class=\"token punctuation\">&#8211;<\/span>report<br \/>\n          <span class=\"token key atrule\">path<\/span><span class=\"token punctuation\">:<\/span> build\/eval<span class=\"token punctuation\">&#8211;<\/span>report<\/p>\n<p>\u5c06ai-quality-gate\u914d\u7f6e\u4e3a\u53d7\u4fdd\u62a4\u5206\u652f\u7684Required Status Check\u540e&#xff0c;\u5931\u8d25\u7684\u68c0\u67e5\u4f1a\u963b\u6b62\u5408\u5e76\u3002<\/p>\n<h3>\u4e09\u5341\u4e94\u3001\u62a5\u544a\u5185\u5bb9<\/h3>\n<p>Markdown\u62a5\u544a&#xff1a;<\/p>\n<p># AI Quality Gate<\/p>\n<p>Decision: FAIL<\/p>\n<p>Global:<br \/>\n&#8211; Pass rate: 93.1% \u2192 91.7%<br \/>\n&#8211; Mean score: 4.31 \u2192 4.18<br \/>\n&#8211; P95 latency: &#043;8%<br \/>\n&#8211; Mean cost: &#043;12%<\/p>\n<p>Blocking:<br \/>\n&#8211; security: 1 failure<br \/>\n&#8211; contract-review pass rate: 94% &lt; 95%<\/p>\n<p>Top regressions:<br \/>\n&#8211; CASE-CONTRACT-108<br \/>\n&#8211; CASE-RAG-CITATION-022<\/p>\n<p>JSON\u62a5\u544a\u7528\u4e8e\u673a\u5668\u8bfb\u53d6\u3002<\/p>\n<h3>\u4e09\u5341\u516d\u3001GitHub Check\u6ce8\u91ca<\/h3>\n<p>\u53ef\u4ee5\u5c06\u5931\u8d25Case\u6620\u5c04\u5230Prompt\u3001\u914d\u7f6e\u6216\u6d4b\u8bd5\u6587\u4ef6&#xff0c;\u53d1\u5e03Check Run Annotation\u3002<\/p>\n<p>\u4f46\u4e0d\u8981\u5728\u516c\u5f00PR\u4e2d\u8f93\u51fa&#xff1a;<\/p>\n<ul>\n<li>\u751f\u4ea7\u7528\u6237\u8f93\u5165&#xff1b;<\/li>\n<li>\u79df\u6237\u6587\u6863&#xff1b;<\/li>\n<li>\u654f\u611fEvidence&#xff1b;<\/li>\n<li>\u5bc6\u94a5&#xff1b;<\/li>\n<li>\u5b8c\u6574\u5408\u540c\u3002<\/li>\n<\/ul>\n<p>\u62a5\u544a\u4f7f\u7528\u8131\u654fCase ID\u548c\u6388\u6743\u8be6\u60c5\u9875\u3002<\/p>\n<h3>\u4e09\u5341\u4e03\u3001\u8fd0\u884c\u5206\u5c42<\/h3>\n<h4>PR Fast<\/h4>\n<ul>\n<li>50\u2014200\u6761&#xff1b;<\/li>\n<li>\u4f4e\u6210\u672c&#xff1b;<\/li>\n<li>\u5173\u952e\u786c\u5931\u8d25&#xff1b;<\/li>\n<li>1\u20143\u6b21\u91cd\u590d\u3002<\/li>\n<\/ul>\n<h4>Nightly Full<\/h4>\n<ul>\n<li>\u5b8c\u6574\u56de\u5f52&#xff1b;<\/li>\n<li>\u591aJudge&#xff1b;<\/li>\n<li>\u751f\u4ea7Trace\u56de\u653e&#xff1b;<\/li>\n<li>\u7edf\u8ba1\u5206\u6790\u3002<\/li>\n<\/ul>\n<h4>Release Acceptance<\/h4>\n<ul>\n<li>\u9690\u85cf\u96c6&#xff1b;<\/li>\n<li>\u9ad8\u98ce\u9669&#xff1b;<\/li>\n<li>\u4eba\u5de5\u62bd\u6837&#xff1b;<\/li>\n<li>\u5f71\u5b50\u73af\u5883\u3002<\/li>\n<\/ul>\n<p>\u4e0d\u540cRun\u4f7f\u7528\u4e0d\u540cGate Policy\u3002<\/p>\n<h3>\u4e09\u5341\u516b\u3001\u5931\u8d25\u8bca\u65ad<\/h3>\n<p>\u62a5\u544a\u6309\u7ec4\u4ef6\u5b9a\u4f4d&#xff1a;<\/p>\n<p>Generation Regression<br \/>\nRetrieval Regression<br \/>\nCitation Regression<br \/>\nTool Regression<br \/>\nPermission Regression<br \/>\nJudge Infrastructure<br \/>\nOperational Regression<\/p>\n<p>Case\u4fdd\u5b58\u7684Evidence\u548cTool Trace\u53ef\u4ee5\u627e\u5230\u7b2c\u4e00\u6b21\u5206\u53c9\u3002<\/p>\n<h3>\u4e09\u5341\u4e5d\u3001\u7ebf\u4e0a\u5931\u8d25\u56de\u6d41<\/h3>\n<p>\u53d1\u5e03\u540e&#xff1a;<\/p>\n<p>\u7528\u6237\u70b9\u8e29<br \/>\n\u5b89\u5168\u544a\u8b66<br \/>\n\u4eba\u5de5\u4fee\u6b63<br \/>\n\u5de5\u5177\u5931\u8d25<br \/>\n\u4f4eJudge\u5206<br \/>\n\u2193<br \/>\n\u8fdb\u5165Eval Candidate Pool<br \/>\n\u2193<br \/>\n\u8131\u654f\u4e0e\u5ba1\u6838<br \/>\n\u2193<br \/>\n\u751f\u6210\u65b0Case\u7248\u672c<br \/>\n\u2193<br \/>\n\u52a0\u5165Regression\/Incident<\/p>\n<h3>\u56db\u5341\u3001\u76d1\u63a7\u6307\u6807<\/h3>\n<p>ai_eval_run_total{<br \/>\n  status,<br \/>\n  policy<br \/>\n}<\/p>\n<p>ai_eval_case_total{<br \/>\n  status,<br \/>\n  task_type<br \/>\n}<\/p>\n<p>ai_eval_pass_rate{<br \/>\n  slice<br \/>\n}<\/p>\n<p>ai_eval_score{<br \/>\n  evaluator,<br \/>\n  slice<br \/>\n}<\/p>\n<p>ai_eval_evaluator_error_rate{<br \/>\n  evaluator<br \/>\n}<\/p>\n<p>ai_eval_candidate_win_rate{<br \/>\n  slice<br \/>\n}<\/p>\n<p>ai_eval_latency_seconds{<br \/>\n  target<br \/>\n}<\/p>\n<p>ai_eval_cost_total{<br \/>\n  target,<br \/>\n  evaluator<br \/>\n}<\/p>\n<p>ai_eval_gate_violation_total{<br \/>\n  rule,<br \/>\n  severity<br \/>\n}<\/p>\n<p>ai_eval_dataset_stale_case_total<\/p>\n<h3>\u56db\u5341\u4e00\u3001\u96c6\u6210\u6d4b\u8bd5<\/h3>\n<h4>\u6570\u636e\u96c6Hash\u53d8\u5316<\/h4>\n<p>Manifest\u4e0e\u5b9e\u9645\u5185\u5bb9\u4e0d\u4e00\u81f4\u65f6&#xff0c;Run\u5fc5\u987b\u5931\u8d25\u3002<\/p>\n<h4>Runtime Manifest\u4e0d\u4e00\u81f4<\/h4>\n<p>\u5019\u9009\u58f0\u660e\u7d22\u5f15V42&#xff0c;\u5b9e\u9645\u56de\u663eV41\u65f6\u505c\u6b62\u3002<\/p>\n<h4>Judge\u5f02\u5e38<\/h4>\n<p>Judge 5xx\u4e0d\u80fd\u76f4\u63a5\u7b97\u5019\u9009\u5931\u8d25\u3002<\/p>\n<h4>\u786c\u5931\u8d25<\/h4>\n<p>\u8de8\u79df\u6237Case\u5931\u8d25\u7acb\u5373\u751f\u6210Blocking Violation\u3002<\/p>\n<h4>Slice\u56de\u5f52<\/h4>\n<p>\u5168\u5c40\u63d0\u5347\u4f46\u5408\u540cSlice\u4e0b\u964d\u65f6\u4ecdFAIL\u3002<\/p>\n<h4>GitHub\u9000\u51fa\u7801<\/h4>\n<p>PASS&#061;0&#xff0c;FAIL&#061;1&#xff0c;NEEDS_REVIEW\u6309\u56e2\u961f\u7b56\u7565\u8bbe2\u6216\u963b\u65ad\u3002<\/p>\n<h3>\u56db\u5341\u4e8c\u3001\u4e0a\u7ebf\u68c0\u67e5\u6e05\u5355<\/h3>\n<p>\u25a1 \u6570\u636e\u96c6\u548cCase\u5747\u7248\u672c\u5316\u5e76\u6709Hash<br \/>\n\u25a1 \u53ea\u8fd0\u884cAPPROVED Case<br \/>\n\u25a1 Baseline\u4e0eCandidate\u4fdd\u5b58Runtime Manifest<br \/>\n\u25a1 \u6bcf\u4e2aCase\u4fdd\u5b58Evidence\u3001Tool Trace\u3001Usage\u548c\u5ef6\u8fdf<br \/>\n\u25a1 \u9ad8\u98ce\u9669Case\u91cd\u590d\u6267\u884c<br \/>\n\u25a1 \u786e\u5b9a\u6027Evaluator\u4f18\u5148<br \/>\n\u25a1 Spring AI Evaluator\u5f02\u5e38\u5355\u72ec\u7edf\u8ba1<br \/>\n\u25a1 Pairwise Judge\u6267\u884c\u4f4d\u7f6e\u4e92\u6362<br \/>\n\u25a1 Judge\u4f7f\u7528\u56fa\u5b9aManifest<br \/>\n\u25a1 \u6307\u6807\u6309\u4e1a\u52a1Slice\u805a\u5408<br \/>\n\u25a1 \u5b89\u5168\u548c\u526f\u4f5c\u7528\u96f6\u5bb9\u5fcd<br \/>\n\u25a1 Gate\u540c\u65f6\u68c0\u67e5\u8d28\u91cf\u3001\u6210\u672c\u548c\u5ef6\u8fdf<br \/>\n\u25a1 CI\u8f93\u51fa\u673a\u5668\u53ef\u8bfb\u9000\u51fa\u7801<br \/>\n\u25a1 \u62a5\u544a\u4e0d\u6cc4\u9732\u751f\u4ea7\u654f\u611f\u6570\u636e<br \/>\n\u25a1 PR\u3001Nightly\u548cRelease\u4f7f\u7528\u4e0d\u540c\u6570\u636e\u96c6<br \/>\n\u25a1 Required Status Check\u5df2\u542f\u7528<br \/>\n\u25a1 \u751f\u4ea7\u5931\u8d25\u6301\u7eed\u56de\u6d41\u6570\u636e\u96c6<\/p>\n<h3>\u603b\u7ed3<\/h3>\n<p>AI\u8d28\u91cf\u95e8\u7981\u4e0d\u662f\u5728CI\u4e2d\u518d\u8c03\u7528\u4e00\u6b21\u6a21\u578b&#xff0c;\u800c\u662f\u5efa\u7acb\u53ef\u590d\u73b0\u7684\u7248\u672c\u6bd4\u8f83\u7cfb\u7edf&#xff1a;<\/p>\n<p>\u56fa\u5b9a\u6570\u636e\u96c6<br \/>\n&#xff0b;Runtime Manifest<br \/>\n&#xff0b;Baseline\/Candidate\u53cc\u8dd1<br \/>\n&#xff0b;\u786e\u5b9a\u6027\u89c4\u5219<br \/>\n&#xff0b;Spring AI Evaluator<br \/>\n&#xff0b;\u6821\u51c6Judge<br \/>\n&#xff0b;Slice\u6307\u6807<br \/>\n&#xff0b;\u786c\u5931\u8d25<br \/>\n&#xff0b;\u8d28\u91cf\u95e8\u7981<\/p>\n<p>\u5f53\u5019\u9009\u7248\u672c\u53ea\u6709\u5728\u5173\u952e\u4e1a\u52a1\u3001\u5b89\u5168\u3001\u5f15\u7528\u3001\u5de5\u5177\u3001\u6210\u672c\u548c\u5ef6\u8fdf\u5168\u90e8\u6ee1\u8db3\u6807\u51c6\u540e\u624d\u80fd\u5408\u5e76\u6216\u53d1\u5e03&#xff0c;AI\u5e94\u7528\u624d\u771f\u6b63\u62e5\u6709\u4e0e\u4f20\u7edf\u8f6f\u4ef6\u6d4b\u8bd5\u76f8\u5f53\u7684\u5de5\u7a0b\u63a7\u5236\u529b\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u6587\u7ae0\u6458\u8981<br \/>\n\u4f20\u7edf\u8f6f\u4ef6\u53ef\u4ee5\u901a\u8fc7\u5355\u5143\u6d4b\u8bd5\u548c\u63a5\u53e3\u6d4b\u8bd5\u5224\u65ad\u8f93\u51fa\u662f\u5426\u6b63\u786e&#xff0c;AI\u5e94\u7528\u5374\u7ecf\u5e38\u5b58\u5728\u591a\u4e2a\u53ef\u63a5\u53d7\u7b54\u6848\u3001\u6a21\u578b\u975e\u786e\u5b9a\u6027\u3001RAG\u8bc1\u636e\u53d8\u5316\u3001Tool Calling\u8f68\u8ff9\u5dee\u5f02\u548c\u6210\u672c\u5ef6\u8fdf\u6ce2\u52a8\u3002\u4ec5\u5728CI\u4e2d\u6267\u884c\u51e0\u6761assertThat(answer).isNotBlank()&#xff0c;\u65e0\u6cd5\u963b\u6b62Prompt\u3001\u6a21\u578b\u3001\u77e5\u8bc6\u7d22\u5f15\u6216\u5de5\u5177\u76ee\u5f55\u5347\u7ea7\u9020\u6210\u7684\u8d28\u91cf\u9000\u5316\u3002<br \/>\n\u672c\u6587\u4ece\u96f6\u5b9e\u73b0\u4e00\u4e2aSpring Boot AI\u8bc4\u6d4b\u4e0e\u53d1\u5e03\u8d28\u91cf\u95e8\u7981\u670d\u52a1\u3002\u7cfb\u7edf\u7ba1\u7406\u7248\u672c\u5316\u6570\u636e\u96c6\u548cCase&#xff0c;\u652f\u6301Basel<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[98,50,3684],"topic":[],"class_list":["post-91587","post","type-post","status-publish","format-standard","hentry","category-server","tag-spring-boot","tag-50","tag-3684"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u7528Spring Boot\u642d\u5efaAI\u8bc4\u6d4b\u4e0e\u53d1\u5e03\u8d28\u91cf\u95e8\u7981\uff1a\u6570\u636e\u96c6\u3001Judge\u3001\u56de\u5f52\u5bf9\u6bd4\u4e0eCI\/CD\u5b8c\u6574\u5b9e\u6218 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/91587.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u7528Spring Boot\u642d\u5efaAI\u8bc4\u6d4b\u4e0e\u53d1\u5e03\u8d28\u91cf\u95e8\u7981\uff1a\u6570\u636e\u96c6\u3001Judge\u3001\u56de\u5f52\u5bf9\u6bd4\u4e0eCI\/CD\u5b8c\u6574\u5b9e\u6218 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"\u6587\u7ae0\u6458\u8981 \u4f20\u7edf\u8f6f\u4ef6\u53ef\u4ee5\u901a\u8fc7\u5355\u5143\u6d4b\u8bd5\u548c\u63a5\u53e3\u6d4b\u8bd5\u5224\u65ad\u8f93\u51fa\u662f\u5426\u6b63\u786e&#xff0c;AI\u5e94\u7528\u5374\u7ecf\u5e38\u5b58\u5728\u591a\u4e2a\u53ef\u63a5\u53d7\u7b54\u6848\u3001\u6a21\u578b\u975e\u786e\u5b9a\u6027\u3001RAG\u8bc1\u636e\u53d8\u5316\u3001Tool Calling\u8f68\u8ff9\u5dee\u5f02\u548c\u6210\u672c\u5ef6\u8fdf\u6ce2\u52a8\u3002\u4ec5\u5728CI\u4e2d\u6267\u884c\u51e0\u6761assertThat(answer).isNotBlank()&#xff0c;\u65e0\u6cd5\u963b\u6b62Prompt\u3001\u6a21\u578b\u3001\u77e5\u8bc6\u7d22\u5f15\u6216\u5de5\u5177\u76ee\u5f55\u5347\u7ea7\u9020\u6210\u7684\u8d28\u91cf\u9000\u5316\u3002 \u672c\u6587\u4ece\u96f6\u5b9e\u73b0\u4e00\u4e2aSpring Boot AI\u8bc4\u6d4b\u4e0e\u53d1\u5e03\u8d28\u91cf\u95e8\u7981\u670d\u52a1\u3002\u7cfb\u7edf\u7ba1\u7406\u7248\u672c\u5316\u6570\u636e\u96c6\u548cCase&#xff0c;\u652f\u6301Basel\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/91587.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-07T17:48:41+00:00\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/91587.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/91587.html\",\"name\":\"\u7528Spring Boot\u642d\u5efaAI\u8bc4\u6d4b\u4e0e\u53d1\u5e03\u8d28\u91cf\u95e8\u7981\uff1a\u6570\u636e\u96c6\u3001Judge\u3001\u56de\u5f52\u5bf9\u6bd4\u4e0eCI\/CD\u5b8c\u6574\u5b9e\u6218 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-08-07T17:48:41+00:00\",\"dateModified\":\"2026-08-07T17:48:41+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/91587.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/91587.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/91587.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u7528Spring Boot\u642d\u5efaAI\u8bc4\u6d4b\u4e0e\u53d1\u5e03\u8d28\u91cf\u95e8\u7981\uff1a\u6570\u636e\u96c6\u3001Judge\u3001\u56de\u5f52\u5bf9\u6bd4\u4e0eCI\/CD\u5b8c\u6574\u5b9e\u6218\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\u7528Spring Boot\u642d\u5efaAI\u8bc4\u6d4b\u4e0e\u53d1\u5e03\u8d28\u91cf\u95e8\u7981\uff1a\u6570\u636e\u96c6\u3001Judge\u3001\u56de\u5f52\u5bf9\u6bd4\u4e0eCI\/CD\u5b8c\u6574\u5b9e\u6218 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/91587.html","og_locale":"zh_CN","og_type":"article","og_title":"\u7528Spring Boot\u642d\u5efaAI\u8bc4\u6d4b\u4e0e\u53d1\u5e03\u8d28\u91cf\u95e8\u7981\uff1a\u6570\u636e\u96c6\u3001Judge\u3001\u56de\u5f52\u5bf9\u6bd4\u4e0eCI\/CD\u5b8c\u6574\u5b9e\u6218 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"\u6587\u7ae0\u6458\u8981 \u4f20\u7edf\u8f6f\u4ef6\u53ef\u4ee5\u901a\u8fc7\u5355\u5143\u6d4b\u8bd5\u548c\u63a5\u53e3\u6d4b\u8bd5\u5224\u65ad\u8f93\u51fa\u662f\u5426\u6b63\u786e&#xff0c;AI\u5e94\u7528\u5374\u7ecf\u5e38\u5b58\u5728\u591a\u4e2a\u53ef\u63a5\u53d7\u7b54\u6848\u3001\u6a21\u578b\u975e\u786e\u5b9a\u6027\u3001RAG\u8bc1\u636e\u53d8\u5316\u3001Tool Calling\u8f68\u8ff9\u5dee\u5f02\u548c\u6210\u672c\u5ef6\u8fdf\u6ce2\u52a8\u3002\u4ec5\u5728CI\u4e2d\u6267\u884c\u51e0\u6761assertThat(answer).isNotBlank()&#xff0c;\u65e0\u6cd5\u963b\u6b62Prompt\u3001\u6a21\u578b\u3001\u77e5\u8bc6\u7d22\u5f15\u6216\u5de5\u5177\u76ee\u5f55\u5347\u7ea7\u9020\u6210\u7684\u8d28\u91cf\u9000\u5316\u3002 \u672c\u6587\u4ece\u96f6\u5b9e\u73b0\u4e00\u4e2aSpring Boot AI\u8bc4\u6d4b\u4e0e\u53d1\u5e03\u8d28\u91cf\u95e8\u7981\u670d\u52a1\u3002\u7cfb\u7edf\u7ba1\u7406\u7248\u672c\u5316\u6570\u636e\u96c6\u548cCase&#xff0c;\u652f\u6301Basel","og_url":"https:\/\/www.wsisp.com\/helps\/91587.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-08-07T17:48:41+00:00","author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"13 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/91587.html","url":"https:\/\/www.wsisp.com\/helps\/91587.html","name":"\u7528Spring Boot\u642d\u5efaAI\u8bc4\u6d4b\u4e0e\u53d1\u5e03\u8d28\u91cf\u95e8\u7981\uff1a\u6570\u636e\u96c6\u3001Judge\u3001\u56de\u5f52\u5bf9\u6bd4\u4e0eCI\/CD\u5b8c\u6574\u5b9e\u6218 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-08-07T17:48:41+00:00","dateModified":"2026-08-07T17:48:41+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/91587.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/91587.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/91587.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"\u7528Spring Boot\u642d\u5efaAI\u8bc4\u6d4b\u4e0e\u53d1\u5e03\u8d28\u91cf\u95e8\u7981\uff1a\u6570\u636e\u96c6\u3001Judge\u3001\u56de\u5f52\u5bf9\u6bd4\u4e0eCI\/CD\u5b8c\u6574\u5b9e\u6218"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/91587","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=91587"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/91587\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=91587"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=91587"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=91587"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=91587"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}