用 Livewire 的 wire:stream 开发流式聊天机器人(Server-sent events, 百度文心一言)
上周见 Twitter 上有人提到用 wire:stream 处理 SSE (Server-sent event),看了 Livewire 的文档,wire:stream 还真是为创建聊天机器人而生的。而且它的 API 非常简单易用,只有两行代码:
后端发送 SSE 事件:
$this->stream(to: 'answer', content: 'hello');
前端处理 SSE 事件:
<div wire:stream="answer"></pre>
于是我试着用百度的千帆大模型 API,搭建了一个聊天功能,你可以在 learn-qianfan-livewire.xuchunyang.... 尝试,代码在 github.com/xuchunyang/learn-qianfa...
运行演示
一些收获
Dependency Injection
通过把百度 API 请求封装成一个 Service,然后在 Service Provider 中注册,最后在 App 即 Service Container 通过 Dependency injection 引入。虽然用常规的 Class 也能,但是借机了解了 Laravel 的核心概念。
Server-sent event
初步了解了如何用原生 PHP 编写 SSE 的服务器端,Livewire 把 ob_flush/X-Accel-Buffering 封装好了,方便我们调用。
用 symfony/http-client 处理 SSE 请求,symfony/http-client 是我注意到明确说支持 SSE 协议的客户端库,尽管 SSE 协议不复杂,百度的 API 也只用了最简单的部份,但感觉自行手动处理不大靠谱,容易出现截断或标准支持不全的情况。
laravel-markdown
渲染 Markdown,并支持语法高亮,尽管是通过第三方 Node 库实现的,但有个正常点儿的高亮还是不错的:
我是直接用
guzzle
包请求,然后自己解析出结果直接返回给客户端的,目前用了半年多了,没出问题。关键代码:
我装了 Pulse 和 Telescope,可以公开访问:
之前写过一个通用的 sse 类 app/Support/Sse/ServerSentEvent.php,可方便的单独使用或者配合 symfony 的流响应类使用。