diff --git a/backend/internal/service/account_test_service.go b/backend/internal/service/account_test_service.go
index b9cd698a..3a58e022 100644
--- a/backend/internal/service/account_test_service.go
+++ b/backend/internal/service/account_test_service.go
@@ -555,14 +555,8 @@ func (s *AccountTestService) testOpenAIAccountConnection(c *gin.Context, account
 		if err != nil {
 			return s.sendErrorAndEnd(c, fmt.Sprintf("Invalid base URL: %s", err.Error()))
 		}
-		// 账号已被探测为不支持 Responses（如 DeepSeek/Kimi 等）时，丢出明确提示。
-		// 账号本身可用（网关会走 CC 直转），仅测试入口需要补齐 CC SSE 处理逻辑。
-		// TODO：实现 CC 格式的账号测试路径（需专门的 CC SSE handler）。
 		if !openai_compat.ShouldUseResponsesAPI(account.Extra) {
-			return s.sendErrorAndEnd(c,
-				"账号已被探测为不支持 OpenAI Responses API（如 DeepSeek/Kimi 等三方兼容上游），"+
-					"账号本身可正常使用，但当前测试接口仅支持 Responses API 路径。请直接通过实际 API 调用验证。",
-			)
+			return s.testOpenAIRawChatCompletionsConnection(c, ctx, account, testModelID, prompt, normalizedBaseURL, authToken)
 		}
 		apiURL = buildOpenAIResponsesURL(normalizedBaseURL)
 	} else {
@@ -1321,6 +1315,133 @@ func (s *AccountTestService) processOpenAIStream(c *gin.Context, body io.Reader)
 	}
 }
 
+func (s *AccountTestService) testOpenAIRawChatCompletionsConnection(
+	c *gin.Context,
+	ctx context.Context,
+	account *Account,
+	modelID string,
+	prompt string,
+	normalizedBaseURL string,
+	authToken string,
+) error {
+	apiURL := buildOpenAIChatCompletionsURL(normalizedBaseURL)
+
+	c.Writer.Header().Set("Content-Type", "text/event-stream")
+	c.Writer.Header().Set("Cache-Control", "no-cache")
+	c.Writer.Header().Set("Connection", "keep-alive")
+	c.Writer.Header().Set("X-Accel-Buffering", "no")
+	c.Writer.Flush()
+
+	payloadPrompt := strings.TrimSpace(prompt)
+	if payloadPrompt == "" {
+		payloadPrompt = "hi"
+	}
+	payloadBytes, _ := json.Marshal(map[string]any{
+		"model": modelID,
+		"messages": []map[string]any{
+			{
+				"role":    "user",
+				"content": payloadPrompt,
+			},
+		},
+		"stream": true,
+		"stream_options": map[string]any{
+			"include_usage": true,
+		},
+	})
+
+	s.sendEvent(c, TestEvent{Type: "test_start", Model: modelID})
+
+	req, err := http.NewRequestWithContext(ctx, "POST", apiURL, bytes.NewReader(payloadBytes))
+	if err != nil {
+		return s.sendErrorAndEnd(c, "Failed to create request")
+	}
+	req.Header.Set("Content-Type", "application/json")
+	req.Header.Set("Accept", "text/event-stream")
+	req.Header.Set("Authorization", "Bearer "+authToken)
+	if customUA := strings.TrimSpace(account.GetOpenAIUserAgent()); customUA != "" {
+		req.Header.Set("User-Agent", customUA)
+	}
+
+	proxyURL := ""
+	if account.ProxyID != nil && account.Proxy != nil {
+		proxyURL = account.Proxy.URL()
+	}
+
+	resp, err := s.httpUpstream.DoWithTLS(req, proxyURL, account.ID, account.Concurrency, s.tlsFPProfileService.ResolveTLSProfile(account))
+	if err != nil {
+		return s.sendErrorAndEnd(c, fmt.Sprintf("Request failed: %s", err.Error()))
+	}
+	defer func() { _ = resp.Body.Close() }()
+
+	if resp.StatusCode != http.StatusOK {
+		body, _ := io.ReadAll(resp.Body)
+		return s.sendErrorAndEnd(c, fmt.Sprintf("API returned %d: %s", resp.StatusCode, string(body)))
+	}
+
+	return s.processOpenAIChatCompletionsStream(c, resp.Body)
+}
+
+func (s *AccountTestService) processOpenAIChatCompletionsStream(c *gin.Context, body io.Reader) error {
+	reader := bufio.NewReader(body)
+	seenEvent := false
+
+	for {
+		line, err := reader.ReadString('\n')
+		if err != nil {
+			if err == io.EOF && seenEvent {
+				s.sendEvent(c, TestEvent{Type: "test_complete", Success: true})
+				return nil
+			}
+			if err == io.EOF {
+				return s.sendErrorAndEnd(c, "Stream ended before any chat completion event was received")
+			}
+			return s.sendErrorAndEnd(c, fmt.Sprintf("Stream read error: %s", err.Error()))
+		}
+
+		line = strings.TrimSpace(line)
+		if line == "" || !sseDataPrefix.MatchString(line) {
+			continue
+		}
+
+		jsonStr := sseDataPrefix.ReplaceAllString(line, "")
+		if jsonStr == "[DONE]" {
+			s.sendEvent(c, TestEvent{Type: "test_complete", Success: true})
+			return nil
+		}
+
+		seenEvent = true
+
+		var data map[string]any
+		if err := json.Unmarshal([]byte(jsonStr), &data); err != nil {
+			continue
+		}
+
+		if errData, ok := data["error"].(map[string]any); ok {
+			if msg, ok := errData["message"].(string); ok && msg != "" {
+				return s.sendErrorAndEnd(c, msg)
+			}
+			return s.sendErrorAndEnd(c, "Unknown error")
+		}
+
+		choices, ok := data["choices"].([]any)
+		if !ok || len(choices) == 0 {
+			continue
+		}
+		firstChoice, ok := choices[0].(map[string]any)
+		if !ok {
+			continue
+		}
+		delta, ok := firstChoice["delta"].(map[string]any)
+		if !ok {
+			continue
+		}
+		if text, ok := delta["content"].(string); ok && text != "" {
+			s.sendEvent(c, TestEvent{Type: "content", Text: text})
+		}
+	}
+}
+
 // testOpenAIImageAPIKey tests OpenAI image generation using an API Key account.
 func (s *AccountTestService) testOpenAIImageAPIKey(c *gin.Context, ctx context.Context, account *Account, modelID, prompt string) error {
 	authToken := account.GetOpenAIApiKey()
diff --git a/backend/internal/service/openai_apikey_responses_probe.go b/backend/internal/service/openai_apikey_responses_probe.go
index a4eb9252..6935fa6e 100644
--- a/backend/internal/service/openai_apikey_responses_probe.go
+++ b/backend/internal/service/openai_apikey_responses_probe.go
@@ -44,6 +44,28 @@ func openaiResponsesProbePayload(modelID string) []byte {
 	return body
 }
 
+// openaiChatCompletionsProbePayload 是用于交叉验证的最小 Chat Completions 请求体。
+//
+// 当 /v1/responses 返回 403 这类模糊信号时，我们再探一次
+// /v1/chat/completions：若 chat 端点可达，则说明该上游更可能是
+// chat-only OpenAI-compatible，而不是完整支持 Responses 的实现。
+func openaiChatCompletionsProbePayload(modelID string) []byte {
+	if strings.TrimSpace(modelID) == "" {
+		modelID = openai.DefaultTestModel
+	}
+	body, _ := json.Marshal(map[string]any{
+		"model": modelID,
+		"messages": []map[string]any{
+			{
+				"role":    "user",
+				"content": "hi",
+			},
+		},
+		"stream": false,
+	})
+	return body
+}
+
 // ProbeOpenAIAPIKeyResponsesSupport 探测 OpenAI APIKey 账号上游是否支持
 // /v1/responses 端点，并将结果持久化到 accounts.extra.openai_responses_supported。
 //
@@ -51,6 +73,9 @@ func openaiResponsesProbePayload(modelID string) []byte {
 //
 // 探测策略（参见包文档 internal/pkg/openai_compat）：
 //   - 上游 404 / 405 → 不支持，写 false
+//   - 上游 403 → 继续交叉探测 /v1/chat/completions：
+//   - - chat 端点可达（非 404/405）→ 视为 chat-only upstream，写 false
+//   - - chat 端点不可确认 / 探测失败 → 保持旧语义，写 true
 //   - 上游 2xx / 其他 4xx（401/422/400 等）/ 5xx → 支持，写 true
 //   - 网络层失败（连接错误、超时）→ 不写标记，保持 unknown
 //     （后续请求仍按"现状即证据"默认走 Responses）
@@ -116,6 +141,28 @@ func (s *AccountTestService) ProbeOpenAIAPIKeyResponsesSupport(ctx context.Conte
 	}()
 
 	supported := isResponsesEndpointSupportedByStatus(resp.StatusCode)
+	if resp.StatusCode == http.StatusForbidden {
+		chatStatus, chatErr := s.probeOpenAIAPIKeyChatCompletionsStatus(ctx, account)
+		if chatErr != nil {
+			logger.LegacyPrintf(
+				"service.openai_probe",
+				"probe_chat_crosscheck_failed: account_id=%d base_url=%s err=%v",
+				accountID,
+				normalizedBaseURL,
+				chatErr,
+			)
+		} else if isChatCompletionsEndpointSupportedByStatus(chatStatus) {
+			supported = false
+			logger.LegacyPrintf(
+				"service.openai_probe",
+				"probe_chat_crosscheck_chat_only: account_id=%d base_url=%s responses_status=%d chat_status=%d",
+				accountID,
+				normalizedBaseURL,
+				resp.StatusCode,
+				chatStatus,
+			)
+		}
+	}
 
 	if err := s.accountRepo.UpdateExtra(ctx, accountID, map[string]any{
 		openai_compat.ExtraKeyResponsesSupported: supported,
@@ -147,3 +194,59 @@ func isResponsesEndpointSupportedByStatus(status int) bool {
 	}
 	return true
 }
+
+func isChatCompletionsEndpointSupportedByStatus(status int) bool {
+	switch status {
+	case http.StatusNotFound, http.StatusMethodNotAllowed:
+		return false
+	default:
+		return true
+	}
+}
+
+func (s *AccountTestService) probeOpenAIAPIKeyChatCompletionsStatus(ctx context.Context, account *Account) (int, error) {
+	if account == nil {
+		return 0, http.ErrNoLocation
+	}
+
+	apiKey := account.GetOpenAIApiKey()
+	if apiKey == "" {
+		return 0, http.ErrNoCookie
+	}
+	baseURL := account.GetOpenAIBaseURL()
+	if baseURL == "" {
+		baseURL = "https://api.openai.com"
+	}
+	normalizedBaseURL, err := s.validateUpstreamBaseURL(baseURL)
+	if err != nil {
+		return 0, err
+	}
+
+	probeURL := buildOpenAIChatCompletionsURL(normalizedBaseURL)
+	probeCtx, cancel := context.WithTimeout(ctx, openaiResponsesProbeTimeout)
+	defer cancel()
+
+	req, err := http.NewRequestWithContext(probeCtx, http.MethodPost, probeURL, bytes.NewReader(openaiChatCompletionsProbePayload("")))
+	if err != nil {
+		return 0, err
+	}
+	req.Header.Set("Content-Type", "application/json")
+	req.Header.Set("Authorization", "Bearer "+apiKey)
+	req.Header.Set("Accept", "application/json")
+
+	proxyURL := ""
+	if account.ProxyID != nil && account.Proxy != nil {
+		proxyURL = account.Proxy.URL()
+	}
+
+	resp, err := s.httpUpstream.DoWithTLS(req, proxyURL, account.ID, account.Concurrency, s.tlsFPProfileService.ResolveTLSProfile(account))
+	if err != nil {
+		return 0, err
+	}
+	defer func() {
+		_, _ = io.Copy(io.Discard, io.LimitReader(resp.Body, 1<<20))
+		_ = resp.Body.Close()
+	}()
+
+	return resp.StatusCode, nil
+}
diff --git a/backend/internal/service/openai_gateway_chat_completions.go b/backend/internal/service/openai_gateway_chat_completions.go
index 84d85c74..fe6ff300 100644
--- a/backend/internal/service/openai_gateway_chat_completions.go
+++ b/backend/internal/service/openai_gateway_chat_completions.go
@@ -247,6 +247,17 @@ func (s *OpenAIGatewayService) ForwardAsChatCompletions(
 
 		upstreamMsg := strings.TrimSpace(extractUpstreamErrorMessage(respBody))
 		upstreamMsg = sanitizeUpstreamErrorMessage(upstreamMsg)
+		if shouldFallbackResponsesCompatToRawChat(account, resp.StatusCode) {
+			s.markOpenAIResponsesUnsupported(ctx, account)
+			logger.L().Info("openai chat_completions: fallback responses->raw chat after custom upstream incompatibility signal",
+				zap.Int64("account_id", account.ID),
+				zap.String("account_name", account.Name),
+				zap.String("base_url", account.GetOpenAIBaseURL()),
+				zap.Int("responses_status", resp.StatusCode),
+				zap.String("upstream_message", upstreamMsg),
+			)
+			return s.forwardAsRawChatCompletions(ctx, c, account, body, defaultMappedModel)
+		}
 		if s.shouldFailoverOpenAIUpstreamResponse(resp.StatusCode, upstreamMsg, respBody) {
 			upstreamDetail := ""
 			if s.cfg != nil && s.cfg.Gateway.LogUpstreamErrorBody {
@@ -316,6 +327,47 @@ func normalizeResponsesRequestServiceTier(req *apicompat.ResponsesRequest) {
 	req.ServiceTier = normalizedOpenAIServiceTierValue(req.ServiceTier)
 }
 
+func shouldFallbackResponsesCompatToRawChat(account *Account, status int) bool {
+	if account == nil || account.Type != AccountTypeAPIKey {
+		return false
+	}
+	if strings.TrimSpace(account.GetOpenAIBaseURL()) == "" {
+		return false
+	}
+	switch status {
+	case http.StatusForbidden, http.StatusNotFound, http.StatusMethodNotAllowed:
+		return true
+	default:
+		return false
+	}
+}
+
+func (s *OpenAIGatewayService) markOpenAIResponsesUnsupported(ctx context.Context, account *Account) {
+	if account == nil || account.Type != AccountTypeAPIKey {
+		return
+	}
+
+	if account.Extra == nil {
+		account.Extra = map[string]any{}
+	}
+	if supported, ok := account.Extra[openai_compat.ExtraKeyResponsesSupported].(bool); ok && !supported {
+		return
+	}
+	account.Extra[openai_compat.ExtraKeyResponsesSupported] = false
+
+	if s == nil || s.accountRepo == nil {
+		return
+	}
+	if err := s.accountRepo.UpdateExtra(ctx, account.ID, map[string]any{
+		openai_compat.ExtraKeyResponsesSupported: false,
+	}); err != nil {
+		logger.L().Warn("openai chat_completions: persist responses unsupported flag failed",
+			zap.Int64("account_id", account.ID),
+			zap.Error(err),
+		)
+	}
+}
+
 func normalizeResponsesBodyServiceTier(body []byte) ([]byte, string, error) {
 	if len(body) == 0 {
 		return body, "", nil
