diff --git a/app/api/endpoints/llm.py b/app/api/endpoints/llm.py index 871e96c4..387fe319 100644 --- a/app/api/endpoints/llm.py +++ b/app/api/endpoints/llm.py @@ -68,6 +68,14 @@ def _sanitize_llm_test_error(message: str, api_key: Optional[str] = None) -> str "Authorization: ***", sanitized, ) + + normalized_message = sanitized.lower().replace("_", "").replace(" ", "") + if "str" in normalized_message and "modeldump" in normalized_message: + return ( + "LLM 调用失败:服务返回内容不是兼容的模型响应," + "请检查基础地址是否填写为 API Base URL,不要填写网页地址或完整的 " + "chat/completions 路径" + ) return sanitized diff --git a/tests/test_llm_endpoint_error_messages.py b/tests/test_llm_endpoint_error_messages.py new file mode 100644 index 00000000..04098847 --- /dev/null +++ b/tests/test_llm_endpoint_error_messages.py @@ -0,0 +1,26 @@ +import asyncio +from unittest.mock import AsyncMock, patch + +from app.api.endpoints import llm as llm_endpoint + + +def test_llm_test_maps_internal_model_dump_error_to_base_url_hint(): + """LLM 测试遇到 SDK 内部响应解析错误时应提示检查基础地址。""" + with patch.object(llm_endpoint.settings, "AI_AGENT_ENABLE", True), patch.object( + llm_endpoint.settings, "LLM_PROVIDER", "openai" + ), patch.object(llm_endpoint.settings, "LLM_MODEL", "gpt-4o-mini"), patch.object( + llm_endpoint.settings, "LLM_API_KEY", "sk-test" + ), patch.object( + llm_endpoint.settings, "LLM_BASE_URL", "https://example.com/not-api" + ), patch.object( + llm_endpoint.LLMHelper, + "test_current_settings", + AsyncMock(side_effect=RuntimeError("'str' object has no attribute 'model_dump'")), + create=True, + ): + resp = asyncio.run(llm_endpoint.llm_test(_="token")) + + assert not resp.success + assert "基础地址" in resp.message + assert "API Base URL" in resp.message + assert "model_dump" not in resp.message