OpenAI Chat Completions API:stream设为false无响应的原因及解决方法
问题原因与解决方案
为什么stream => false时无返回结果?
- 状态码判断时机错误:在
CURLOPT_WRITEFUNCTION回调中调用curl_getinfo获取HTTP状态码时,curl尚未完成响应头接收,导致状态码不为200,触发错误分支,无法处理正常响应。 - 回调逻辑仅适配流式响应:当前回调是为
stream=true的分段响应设计的,虽语法上能解析完整JSON,但因状态码判断错误,根本无法进入正常解析流程。 - 选项冲突导致响应未处理:同时设置
CURLOPT_RETURNTRANSFER => true和CURLOPT_WRITEFUNCTION时,curl优先使用回调处理数据,但代码中回调外的else块为空,无兜底处理逻辑。
解决方法
方法1:移除回调,改用常规非流式处理
适合仅需stream=false的场景,直接获取完整响应后解析:
$API_KEY = "API_KEY_HERE"; $model = 'gpt-3.5-turbo'; $header = [ "Authorization: Bearer " . $API_KEY, "Content-type: application/json", ]; $temperature = 0.6; $frequency_penalty = 0; $presence_penalty= 0; $prompt = 'What can you help me with? For example: What do you suggest to keep me motivated?'; $messages = array( array( "role" => "system", "content" => "Your name is 'JOHN DOE'. I want you to act as a motivational coach. I will provide you with some information about someone's goals and challenges, and it will be your job to come up with strategies that can help this person achieve their goals. This could involve providing positive affirmations, giving helpful advice or suggesting activities they can do to reach their end goal. if you don't understand the question, don't think too much, tell the user to be more specific with more details" ), array( "role" => "assistant", "content" => "Hello, I'm JOHN DOE, and I'm a motivational coach who loves helping people find their drive and achieve their goals. With years of experience in coaching and personal development, I've developed a unique approach to motivation that combines mindset, energy, and action." ), array( "role" => "user", "content" => $prompt ) ); $url = "https://api.openai.com/v1/chat/completions"; $params = json_encode([ "messages" => $messages, "model" => $model, "temperature" => $temperature, "max_tokens" => 1024, "frequency_penalty" => $frequency_penalty, "presence_penalty" => $presence_penalty, "stream" => false ]); $curl = curl_init($url); $options = [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => $header, CURLOPT_POSTFIELDS => $params, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => 0, ]; curl_setopt_array($curl, $options); $response = curl_exec($curl); $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); if ($response === false) { echo 'data: {"error": "[ERROR]","message":"'.curl_error($curl).'"}' . PHP_EOL; } else { if ($httpCode != 200) { $r = json_decode($response); echo 'data: {"error": "[ERROR]","message":"'.$r->error->message.'"}' . PHP_EOL; } else { $response_array = json_decode($response, true); $content = $response_array['choices'][0]['message']['content']; echo $content; ob_flush(); flush(); } } curl_close($curl);
方法2:修改回调,兼容流式与非流式响应
如需同时支持两种模式,调整回调逻辑,将状态码判断移到回调外:
$API_KEY = "API_KEY_HERE"; $model = 'gpt-3.5-turbo'; $header = [ "Authorization: Bearer " . $API_KEY, "Content-type: application/json", ]; $temperature = 0.6; $frequency_penalty = 0; $presence_penalty= 0; $prompt = 'What can you help me with? For example: What do you suggest to keep me motivated?'; $messages = array( array( "role" => "system", "content" => "Your name is 'JOHN DOE'. I want you to act as a motivational coach. I will provide you with some information about someone's goals and challenges, and it will be your job to come up with strategies that can help this person achieve their goals. This could involve providing positive affirmations, giving helpful advice or suggesting activities they can do to reach their end goal. if you don't understand the question, don't think too much, tell the user to be more specific with more details" ), array( "role" => "assistant", "content" => "Hello, I'm JOHN DOE, and I'm a motivational coach who loves helping people find their drive and achieve their goals. With years of experience in coaching and personal development, I've developed a unique approach to motivation that combines mindset, energy, and action." ), array( "role" => "user", "content" => $prompt ) ); $url = "https://api.openai.com/v1/chat/completions"; $paramsArray = [ "messages" => $messages, "model" => $model, "temperature" => $temperature, "max_tokens" => 1024, "frequency_penalty" => $frequency_penalty, "presence_penalty" => $presence_penalty, "stream" => false ]; $params = json_encode($paramsArray); $curl = curl_init($url); $fullResponse = ''; $options = [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => $header, CURLOPT_POSTFIELDS => $params, CURLOPT_RETURNTRANSFER => false, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => 0, CURLOPT_WRITEFUNCTION => function($curl, $data) use (&$fullResponse) { $fullResponse .= $data; return strlen($data); }, ]; curl_setopt_array($curl, $options); $response = curl_exec($curl); $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); if ($response === false) { echo 'data: {"error": "[ERROR]","message":"'.curl_error($curl).'"}' . PHP_EOL; } else { if ($httpCode != 200) { $r = json_decode($fullResponse); echo 'data: {"error": "[ERROR]","message":"'.$r->error->message.'"}' . PHP_EOL; } else { if ($paramsArray['stream']) { $lines = explode("\n", $fullResponse); foreach ($lines as $line) { $trimmed = trim($line); if (empty($trimmed) || strpos($trimmed, 'data: ') !== 0) continue; $dataStr = substr($trimmed, 6); if ($dataStr === '[DONE]') continue; $responseObj = json_decode($dataStr, true); $content = $responseObj['choices'][0]['delta']['content'] ?? ''; echo $content; ob_flush(); flush(); } } else { $response_array = json_decode($fullResponse, true); $content = $response_array['choices'][0]['message']['content']; echo $content; ob_flush(); flush(); } } } curl_close($curl);
内容的提问来源于stack exchange,提问作者AlwaysStudent
相关产品推荐
相关产品推荐

