同一次请求里,事件流与逐段响应的边界
给聊天界面接入逐字输出时,“开启流式响应”和“使用服务器发送事件”常被当成同一件事。它们经常一起出现,却不在同一层:流式响应描述数据逐步交付,服务器发送事件(SSE)则规定一种文本事件格式。把两者分开看,才能判断客户端应该怎样读取、解析和收尾。
§ 交付方式与事件格式
流式响应:服务器不必等全部结果生成完毕,就可以陆续发送响应体。内容可以是文本、音频、逐行对象,也可以是 SSE。它回答的是“数据是否边生成边交付”。
SSE:通常使用 text/event-stream 内容类型,以空行分隔事件,并通过 data、event、id 等字段表达内容和元信息。它回答的是“连续到达的数据如何划分为事件”。SSE 是流式交付的一种选择,不是所有流式响应的统称。
§ 网络分块与业务增量
读取响应流时:一次读取只代表当前收到了一段字节。它可能截在中文字符中间,也可能包含半个事件或多个事件,不能直接视为一个完整对象。
解析 SSE 时:先用支持流式处理的解码器还原文本,再缓存尚未完整的行与事件。遇到事件边界后,按照所选接口协议解析载荷。同一事件中的多行 data 需要按规则合并;注释行不应当作模型正文。
§ 相同入口与不同协议
连接入口:Vana API 的统一入口是 https://api.vanaapi.com,兼容 OpenAI 接口,同时支持 Anthropic Messages 和 Gemini 原生协议。使用现有客户端时,应先确认请求采用哪一种协议,再选择对应的流式解析方式。
事件语义:使用同一个入口,不代表所有事件结构相同。文本增量、工具参数、结束原因和用量信息的位置可能随协议变化。不要把某一种接口的结束标记或字段路径套用到其他协议;优先让匹配的 SDK 处理这些差异。
§ 浏览器订阅与请求式读取
原生 EventSource:适合持续订阅服务器事件,但通常以 GET 建立连接,也不便直接设置任意鉴权请求头。它提供的自动重连能力,不等于模型生成能够自动续接。
通过 fetch 或 SDK 读取:模型接口通常需要 POST 请求体和鉴权头,因此更常采用这种方式。客户端可以主动取消请求,但需要自行管理缓冲区、超时与异常。浏览器应用也不应因此把长期 API 密钥暴露到前端。
§ 更早显示与更早完成
流式显示:用户可以在完整答案生成前看到内容,改善等待体验。应分别记录请求发出、首个有效内容到达和生成结束的时间;收到响应头或心跳,并不代表已经收到答案。
整体完成:流式传输不保证降低总耗时,也不保证降低费用。代理缓冲、压缩配置和界面刷新频率都可能影响可见效果。Vana API 按实际令牌用量计费、没有月费;不要把界面收到的事件数量当作用量。
§ 正常结束与中途断开
正常结束:根据协议识别完成状态,并保存需要的结束原因和用量。工具调用参数可能分多次到达,应在对应参数完整、完成解析和校验后再执行工具。
中途断开:连接关闭不一定表示生成成功。若没有收到预期的完成信号,应保留已显示内容并标记结果不完整。重新发起请求可能产生不同答案和额外用量;除非服务明确支持恢复,否则不要假设事件编号能够续接原来的生成。
§ 上线前的一次对照测试
用相同输入分别测试完整响应和流式响应,核对正文、工具调用、结束状态与用量,再模拟网络中断和用户取消。比较重点不是逐字完全一致,而是业务结果是否正确、状态是否明确。若准备通过 Vana API 验证现有客户端,可以创建一个账户,从一条短请求开始,确认解析与收尾都可靠后,再接入正式界面。