diff --git a/src/main/java/com/yunhai/agent/llm/DeepSeekClient.java b/src/main/java/com/yunhai/agent/llm/DeepSeekClient.java index 0122ba6..b186b85 100644 --- a/src/main/java/com/yunhai/agent/llm/DeepSeekClient.java +++ b/src/main/java/com/yunhai/agent/llm/DeepSeekClient.java @@ -19,6 +19,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; +import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; @@ -51,6 +52,34 @@ public class DeepSeekClient implements LlmClient { this.settings = settings; } + /** + * 启动自检:把「大模型到底配好没有」这件事在启动日志里说清楚(可 grep {@code [大模型]})。 + * + *

线上最容易被忽略的一类故障:容器没有注入 {@code DEEPSEEK_API_KEY}, + * 于是 api-key 落到 application.yml 里的中文占位符,直到某个用户发起一次对话才以 + * HTTP 401(表现为 {@code HttpRetryException: cannot retry due to server authentication, + * in streaming mode})暴露出来 —— 排查成本很高。这里改成启动时就 ERROR 出来。 + */ + @PostConstruct + void checkLlmConfig() { + AgentSettings.Llm llm = settings.getLlm(); + String key = llm.getApiKey(); + if (StringUtils.isBlank(key)) { + log.error("[大模型] agent.llm.api-key 为空 —— 任何对话都会鉴权失败。" + + "请在 application-prod.yml 填写真实 key,或给容器注入环境变量 DEEPSEEK_API_KEY。"); + } else if (key.contains("请替换")) { + log.error("[大模型] agent.llm.api-key 仍是占位符(长度 {})—— 说明容器没有注入环境变量 " + + "DEEPSEEK_API_KEY。任何对话都会 401:请在 application-prod.yml 写真实 key," + + "或给容器注入该环境变量后重启。", key.length()); + } else if (!key.startsWith("sk-")) { + log.warn("[大模型] agent.llm.api-key 已配置,但格式可疑(不以 sk- 开头,长度 {}),请确认是否填错。", + key.length()); + } else { + log.info("[大模型] api-key 已配置(长度 {}),host={} model={}", + key.length(), llm.getHost(), llm.getModel()); + } + } + @Override public ChatResult chat(List messages, JSONArray tools) { AgentSettings.Llm llm = settings.getLlm();