1.使用webman/openai调用ai,我从'complete'事件里加了保存数据的逻辑,当客户端调用时手动停止后,服务端没有停止,还是执行到了complete并且保存的数据是ai回答的完整数据。
public function demo(Request $request)
{
$connection = $request->connection;
$message = '生成500字文章';
$chat = new Chat(['apikey' => 'xxxx', 'api' => 'https://api.deepseek.com/chat/completions']);
$chat->completions(
[
'model' => 'deepseek-chat',
'stream' => true,
'max_tokens' => 8192,
'messages' => array_merge([], [['role' => 'user', 'content' => $message]]),
], [
'stream' => function ($data) use ($connection) {
// 当openai接口返回数据时转发给浏览器
$response = $data;
if (isset($response['choices'][0]['delta']['content'])) {
$connection->send(new Chunk('data: ' . json_encode(['choices' => $response['choices'][0]], JSON_UNESCAPED_UNICODE) . "\n\n"));
$finish_reason = $response['choices'][0]['finish_reason'];
//结束了
if ($finish_reason == 'stop') {
}
}
},
'complete' => function ($result, $response) use ($connection, $request) {
// 响应结束时检查是否有错误
if (isset($result['error'])) {
// 返回错误信息
$err_msg = ' 请求失败,原因:' . json_encode($result['error'], JSON_UNESCAPED_UNICODE);
(new PushErrorServices())->pushMessage($err_msg, null, $request);
$connection->send(new Chunk($this->sendSSEError('解读失败,请联系管理员或稍后重试~')));
} else {
// 直接从$result中获取完整的AI响应结果
$fullResult = $result['choices'][0]['message']['content'];
Db::name('test')->insert([
'test' => $fullResult
]);
}
// 返回空的chunk代表响应结束
$connection->send(new Chunk(''));
},
]);
// 先返回一个http头,后面数据异步返回
return response()->withHeaders([
"Transfer-Encoding" => "chunked",
"Content-Type" => "text/event-stream;charset=utf-8",
]);
}
2.假如这个接口需要增加一些逻辑,我想手动返回一些流式数据,这样写正确的吗
public function demo(Request $request)
{
$connection = $request->connection;
$unique = $request->get('unique');
if (!$unique) {
$connection->send(new Response(200, [
'Transfer-Encoding' => 'chunked',
'Content-Type' => 'text/event-stream;charset=utf-8',
"Access-Control-Allow-Origin" => "*",
]));
$connection->send(new Chunk($this->sendSSEError('uniqid is null')));
$connection->send(new Chunk(''));
return response()->withHeaders(["Transfer-Encoding" => "chunked"]);
}
return response()->withHeaders([
"Transfer-Encoding" => "chunked",
"Content-Type" => "text/event-stream;charset=utf-8",
]);
}
你的观点很奇怪,客户端调用webman,webman调用openai,它们是两个调用,互不影响啊,停止一个当然不影响另外一个。
这这发送了2个http头,肯定是不合规的,应该是这样。