id; if (RateLimiter::tooManyAttempts($key, $client->rate_limit)) { $seconds = RateLimiter::availableIn($key); throw new \RuntimeException("请求过于频繁,请在 {$seconds} 秒后重试。"); } try { /** @var \App\Models\LlmProvider $provider */ $provider = $client->llmProvider; if ($provider->status !== 'active') { throw new \RuntimeException('LLM 提供商当前不可用。'); } // 发送请求到 LLM 提供商 $response = Http::timeout($client->timeout) ->withToken($provider->api_token) ->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json', ]) ->post($provider->api_url, array_merge([ 'prompt' => $prompt, ], $options)); if (!$response->successful()) { Log::error('LLM provider request failed', [ 'status' => $response->status(), 'body' => $response->body(), 'provider' => $provider->name, 'client_id' => $client->id, ]); throw new \RuntimeException('LLM 提供商服务异常,请稍后重试。'); } // 记录成功的请求 RateLimiter::hit($key, 60); $result = $response->json(); return [ 'response' => $result['choices'][0]['text'] ?? $result['response'] ?? '', 'usage' => $result['usage'] ?? [], ]; } catch (\Illuminate\Http\Client\ConnectionException $e) { Log::error('LLM provider connection timeout', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), 'provider' => $provider->name ?? null, 'client_id' => $client->id, ]); throw new \RuntimeException('LLM 提供商响应超时,请稍后重试。'); } } }