From 55b7c1c83c59d7fd1b09c1dd492ff435f344a4c7 Mon Sep 17 00:00:00 2001
From: cat_shark <1716967236@qq.com>
Date: Sat, 4 Jul 2026 16:41:21 +0800
Subject: [PATCH] =?UTF-8?q?feat(=E5=90=8E=E7=AB=AF)=EF=BC=9AAiServiceClien?=
=?UTF-8?q?t=20=E6=94=B9=E4=B8=BA=20submit+poll=20=E5=BC=82=E6=AD=A5?=
=?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=A8=A1=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 内部实现重构:每个公有方法内部 submitAndWait() → submitTask() + pollResult()
- submitTask(): POST /ai/tasks,返回 taskId(30s 超时)
- pollResult(): 轮询 GET /ai/tasks/:taskId,500ms 首次延迟,
2s × 10 次后退避到 5s,总超时 600s(10 min)
- 公有方法签名完全不变:aggregateReport()、generateMindMap()、compareRecall()
- 异常失败时返回 Optional.empty(),调用方降级逻辑不变
- application.yml timeout-seconds: 180 → 600
---
.../service/impl/AiServiceClient.java | 182 ++++++++++++------
src/main/resources/application.yml | 2 +-
2 files changed, 126 insertions(+), 58 deletions(-)
diff --git a/src/main/java/com/guo/learningprogresstracker/service/impl/AiServiceClient.java b/src/main/java/com/guo/learningprogresstracker/service/impl/AiServiceClient.java
index d3ebcaf..7f2dd74 100644
--- a/src/main/java/com/guo/learningprogresstracker/service/impl/AiServiceClient.java
+++ b/src/main/java/com/guo/learningprogresstracker/service/impl/AiServiceClient.java
@@ -13,6 +13,7 @@ import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
+import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -20,6 +21,10 @@ import java.util.Optional;
/**
* lpt-ai 独立 AI 服务客户端。
*
通过 {@code lpt.ai-service.url} 配置服务地址;未配置或调用失败时返回 empty,由调用方降级。
+ *
+ * 内部使用异步任务模式:提交任务到 lpt-ai 后轮询等待结果,
+ * 避免同步等待 LLM 响应时阻塞 HTTP 连接。
+ *
*/
@Slf4j
@Component
@@ -29,8 +34,8 @@ public class AiServiceClient {
/** lpt-ai 服务地址,如 http://localhost:5199 */
private String url;
- /** 超时秒数 */
- private int timeoutSeconds = 90;
+ /** 超时秒数(等待 AI 任务完成的最长时间) */
+ private int timeoutSeconds = 600;
private HttpClient httpClient;
private final ObjectMapper objectMapper = new ObjectMapper();
@@ -41,9 +46,9 @@ public class AiServiceClient {
.connectTimeout(Duration.ofSeconds(10))
.build();
if (isConfigured()) {
- log.info("AiServiceClient 已配置: {}", url);
+ log.info("AiServiceClient 已配置: {} (超时 {}s, 异步任务模式)", url, timeoutSeconds);
} else {
- log.info("AiServiceClient 未配置,AI 聚合功能不可用(将降级为拼接)");
+ log.info("AiServiceClient 未配置,AI 功能不可用(将降级为内置逻辑)");
}
}
@@ -51,10 +56,10 @@ public class AiServiceClient {
return url != null && !url.isBlank();
}
+ // ============ 公开 API(签名不变,内部改为 submit + poll)============
+
/**
* 调用 lpt-ai 将残片聚合为学习报告草稿。
- *
- * @return 聚合后的报告文本;服务未配置或调用失败时返回 empty
*/
public Optional aggregateReport(String taskName, List fragments, String expectation) {
if (!isConfigured() || fragments == null || fragments.isEmpty()) {
@@ -64,36 +69,20 @@ public class AiServiceClient {
List