feat(复习):回忆对比优先走 AI 语义对比,失败时降级为内置算法

- CompareResult.java:新增 evaluation 字段(AI 对比时写入评价文本)
- AiServiceClient.java:新增 compareRecall(),调用 lpt-ai /ai/compare-recall
- StandardMindMapServiceImpl.java:recallCompare() 中注入 AiServiceClient,
  优先 try AI 语义对比,含层级上下文和同义表达识别;
  AI 不可用或失败时自动 fallback 到内置标题匹配算法
- StandardMindMapServiceImplTest.java:适配新增的 AiServiceClient 依赖
This commit is contained in:
2026-07-04 15:47:24 +08:00
parent cd5ee0b404
commit 7ac7868511
4 changed files with 66 additions and 3 deletions
@@ -39,6 +39,7 @@ public class StandardMindMapServiceImpl implements StandardMindMapService {
private final List<MindMapAiClient> aiClients;
private final ObjectMapper objectMapper;
private final AiServiceClient aiServiceClient;
private static final String GENERATOR_BUILTIN = "BUILTIN";
private static final String GENERATOR_USER = "USER";
@@ -105,8 +106,28 @@ public class StandardMindMapServiceImpl implements StandardMindMapService {
MindMapNode standardRoot = MindMapTreeTool.fromJson(standard.getContent(), objectMapper);
MindMapNode recallRoot = MindMapTreeTool.parseOutline(recallOutline);
// 3. 执行对比
CompareResult result = compareTrees(standardRoot, recallRoot);
// 3. 执行对比(优先 AI 语义对比,失败时降级为内置算法)
CompareResult result;
if (aiServiceClient.isConfigured()) {
String taskName = tasksMapper.selectOne(
Wrappers.<TaskEntity>lambdaQuery().eq(TaskEntity::getTaskNum, taskNum).last("LIMIT 1"))
.getTaskName();
var optResult = aiServiceClient.compareRecall(
taskName,
MindMapTreeTool.toFullOutline(standardRoot),
recallOutline
);
if (optResult.isPresent()) {
result = optResult.get();
log.info("AI 回忆对比: taskNum={}, recallRatio={}, evaluation={}",
taskNum, result.getRecallRatio(),
result.getEvaluation() != null ? result.getEvaluation().substring(0, Math.min(50, result.getEvaluation().length())) : "");
} else {
result = compareTrees(standardRoot, recallRoot);
}
} else {
result = compareTrees(standardRoot, recallRoot);
}
// 4. 序列化对比结果
String resultJson;