最近开发智能客服,需要用php调用已有的大模型应用接口流式输出+vue前端调用打字机效果展示。这里整理了php调用大模型流式输出+业务过滤等的核心实现部分,分享给大家。
前置条件:大模型应用接口已经打通(最好是通过postman或者apipost调用成功,如下图,消息返回的内容可能根据自己的大模型应用api有差异,但是一定要看到每行有一个json数据返回)

php7.0 以上的版本,调用方式如下:
php
public function sendRequestStreaming($messages) {
set_time_limit(0);
header('Content-Type: text/plain; charset=utf-8');
header('X-Accel-Buffering: no');
ob_implicit_flush(true);
ob_start();
$data = [
// 此处的参数和你的大模型api对应
'inputs' => [],
'query' => $messages,
'response_mode' => 'streaming'
];
$curl = curl_init($this->baseUrl . 'chat-messages'); // 注意地址改成你自己的大模型api地址
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
$header = [
'Content-Type: application/json',
'Authorization: Bearer ' . $this->apiKey, // 注意改成你的大模型的apiKey
'Accept: text/event-stream'
];
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_TIMEOUT, 0); // 永不超时
curl_setopt($curl, CURLOPT_RETURNTRANSFER, false); // 禁止直接输出到变量
// 全局变量用于跨回调保留状态(如未处理完的缓冲)
$buffer = '';
curl_setopt($curl, CURLOPT_WRITEFUNCTION, function ($curl, $data) {
global $buffer;
// 合并缓冲(处理跨块数据)
$buffer .= $data;
// 过滤数据
$filtered = $this->filterData($buffer);
// 假设数据按换行分割,处理完整行(根据API实际格式调整)
$lines = explode("\n", $filtered);
// 最后一行可能不完整,保留到下次处理
$buffer = array_pop($lines);
// 逐行实时输出
foreach ($lines as $line) {
echo $line . "\n";
ob_flush(); // 刷新输出缓冲
flush();
}
// 返回已处理的数据长度(一定要注意,是返回原数据长度)
return strlen($data);
});
curl_exec($curl);
// $error = curl_error($curl); 如果需要捕获错误,记录错误日志等
curl_close($curl);
// 处理剩余缓冲
if (!empty($buffer)) {
echo $this->filterData($buffer);;
ob_flush();
flush();
}
}
// 过滤流式json数据
protected function filterData($str) {
return $str;
// 根据需要过滤数据,如某些json数据不想返回给前端
// if (strpos($str, 'data: {"event": "message') === 0) {
// return $str;
// } else {
// return "";
// }
}
以上的方法实现了php调用大模型流式输出,可根据自己的需求修改。
注意:CURLOPT_WRITEFUNCTION内部末尾的return是源数据长度,不要自作聪明改成处理后的新数据长度。