☰
Laravel AI 流式输出实战:如何接入 Vercel AI SDK 实现 AI 回答逐字实时显示
2026/10/15 16:23:54 网站建设 项目流程

【免费下载链接】ai

The Laravel AI SDK provides a unified, expressive API for interacting with AI providers such as OpenAI, Anthropic, Gemini, and more.

项目地址:https://gitcode.com/gh_mirrors/ai89/ai
点击查看免费下载

Laravel AI是 Laravel 官方推出的 AI SDK,提供统一、简洁的 API 来调用 OpenAI、Anthropic、Gemini、Mistral 等主流 AI 提供商。本文聚焦它的流式输出(Streaming)能力:AI 回答不再干等几十秒,而是逐字实时显示在页面上。更妙的是,SDK 内置了Vercel AI SDK 前端协议,你的 Laravel 后端可以直接对接useChat这类现成前端组件,几乎不用写胶水代码。

为什么流式输出是 AI 应用的标配?

普通请求模式下,用户点击"发送"后要盯着转圈等待完整回答,体验很差。流式输出的工作方式完全不同:

后端把模型生成的每一个词元(token)产生一个就推送一个,前端收到一块就渲染一块。用户几乎在 1 秒内就能看到回答"打字机式"地浮现出来。

在 Laravel AI 中,一次流式调用背后的数据流是这样的:

AI 提供商 → Agent 事件流(TextDelta/ToolCall…)→ 协议层 → SSE(data: xxx)→ 前端 useChat
  • 事件层:SDK 把各提供商的差异抹平,统一为 TextDelta、ToolCall 等事件
  • 协议层:StreamProtocol 基类负责把事件编码为服务器发送事件(SSE),Content-Type为text/event-stream
  • 响应对象:StreamableAgentResponse 同时支持"边推送给浏览器"和"在 PHP 侧消费事件"两种用法

三步开启流式输出

第一步:把 prompt 换成 stream

你已经会调用 Agent 的话,改造只有一处——把prompt()换成stream()(定义于 Promptable.php):

$response = $agent->stream('用三句话介绍 Laravel'); return $response;

直接把StreamableAgentResponse作为路由返回值即可。它实现了 Laravel 的Responsable接口,toResponse() 会自动生成一个流式 HTTP 响应,并带上防止代理缓冲的响应头(Cache-Control: no-cache, no-transform),保证每个词元即时送达。

第二步:绑定前端协议

想直接对接 Vercel AI SDK 的前端(比如 React 的useChat),只需一行:

return $agent->stream($message) ->usingVercelDataProtocol();

usingVercelDataProtocol() 会挂上 VercelDataProtocol,把内部事件翻译成 Vercel AI SDK 的 data stream 协议,并自动注入协议识别头x-vercel-ai-ui-message-stream: v1。前端useChat配置defaultProtocol: 'data'后就能直接消费这条流。

除了 Vercel 协议,SDK 还提供了另一套 AgentUserInteractionProtocol(AG-UI 协议),适合需要工具审批等交互能力的场景,workbench/routes/web.php 中有一个完整的官方示例路由。

第三步:让前端"打字机"跑起来

前端侧只需要标准的useChat用法,请求发往你的 Laravel 路由即可。协议负责剩下的事:

前端看到的 part 类型含义
text-delta一段新文字,前端追加渲染——逐字显示的核心
reasoning-delta模型的"思考过程"增量,可渲染在折叠的思考区
tool-input-available/tool-output-available工具调用开始 / 工具结果返回,多步 Agent 也能实时展示中间过程
source-url引用来源链接,可做"参考来源"角标
finish-step/finish一个推理步骤结束 / 整个回答结束(附带 token 用量统计)
error出错时发送,流不会莫名中断

多步工具调用时,协议会在步骤之间自动发送finish-step+start-step(见 VercelDataProtocol::parts()),前端因此能把"先查资料、再写回答"的过程分段呈现。

对接 useChat 的请求格式:Vercel::chat()

useChat每次请求都会把完整消息历史(UI messages 数组)POST 给后端,而不是只发最新一句话。SDK 专门为此提供了 Vercel::chat():

use Laravel\Ai\Vercel\Vercel; Route::post('/chat', function (Request $request) { $chat = Vercel::chat($request); // 解析 useChat 请求体 return (new Assistant) ->stream($chat) // 自动携带历史 + 最新一条用户消息 ->usingVercelDataProtocol($chat->messageId()); });

Chat 实现了AgentInput接口,SDK 会自动帮你:

  • 从消息历史中提取最新一条用户消息作为本轮输入
  • 把其余消息还原为上下文(history())
  • 还原用户消息中的图片、文档等附件(URL 或 base64 均可)
  • 续写被中断的回答时,通过messageId关联到正确的助手消息

反向也一样:页面刷新后要用历史消息回填聊天窗口,Vercel::toUiMessages() 能把数据库里的会话消息转成useChat认识的 UI messages 格式,文本、思考过程、工具卡片、附件一个不少。

前端如何消费这条流?

用 Node/PHP 之外的工具(比如浏览器 DevTools 的 Network 面板)观察你的流式接口,看到的是标准 SSE 帧:

data: {"type":"start","messageId":"0193..."} data: {"type":"start-step"} data: {"type":"text-start","id":"0193..."} data: {"type":"text-delta","id":"0193...","delta":"Laravel"} data: {"type":"text-delta","id":"0193...","delta":" 是一个"} ... data: {"type":"finish-step"} data: {"type":"finish","finishReason":"stop","messageMetadata":{"usage":{...}}} data: [DONE]
  • 每个事件编码为一行data: {json}(StreamProtocol::encode())
  • 以data: [DONE]作为流的结束标记(terminator())
  • finishpart 里附带本次回答的 token 用量,前端可以顺手展示"已消耗 N tokens"

想验证自己实现的协议输出,可以参考官方测试 VercelDataProtocolStreamTest.php,里面逐个断言了各类事件对应的 part 序列,是非常好的行为对照表。

常见问题排查

1. 页面卡住,回答最后一次性全部出现?典型的"流被缓冲"症状。检查响应头是否被中间层(Nginx、CDN、X-Accel-Buffering)吞掉。SDK 已自带no-cache, no-transform头,若用 Nginx 还需确认proxy_buffering off或X-Accel-Buffering: no生效。

2.useChat收到流却不解析?确认useChat指定了defaultProtocol: 'data',且响应头里有x-vercel-ai-ui-message-stream: v1。

3. 流中途出错会怎样?不会裸抛异常断开连接。StreamProtocol::response() 会捕获异常并发送一个脱敏的errorpart("An error occurred."),避免把提供商的原始错误细节泄露到浏览器,同时异常仍会记录到 Laravel 日志。

4. 想在 PHP 侧同时拿到完整文本?流式响应本身就是可迭代的。你可以在返回给浏览器前用then()注册完成回调(见 StreamableAgentResponse::then()),流结束后拿到包含完整text、usage和事件的StreamedAgentResponse,方便落库或统计。

小结

Laravel AI 的流式输出把"逐字实时显示"这件看似复杂的事简化成了三步:

  1. prompt()改为stream()
  2. ->usingVercelDataProtocol()绑定 Vercel AI SDK 协议
  3. 前端useChat指过来

事件流、SSE 编码、多步骤切换、错误兜底、token 统计全部由 SDK 代劳。相关源码集中在 src/Streaming/ 与 src/Vercel/ 两个目录,配合 tests/Feature/VercelDataProtocolStreamTest.php 的行为断言,即使你想自定义协议也心中有数。现在就可以动手,让你的 AI 应用告别漫长白屏。

【免费下载链接】ai

The Laravel AI SDK provides a unified, expressive API for interacting with AI providers such as OpenAI, Anthropic, Gemini, and more.

项目地址:https://gitcode.com/gh_mirrors/ai89/ai
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询