使用webman/openai调用ai,客户端手动中断后服务端没有停止

最好

问题描述

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",
        ]);
    }
49 1 0
1个回答

yongdao35

你的观点很奇怪,客户端调用webman,webman调用openai,它们是两个调用,互不影响啊,停止一个当然不影响另外一个。

        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"]);
        }

这这发送了2个http头,肯定是不合规的,应该是这样。

if (!$unique) {
    $body = new Chunk($this->sendSSEError('uniqid is null'));
    $body .= new Chunk('');
    return response($body)->withHeaders(["Transfer-Encoding" => "chunked"]);
}
  • 暂无评论
🔝