流式传输
结构化提取的一个常见用例是定义一个单一的 schema 类,然后定义另一个 schema 来创建一个列表以进行多次提取。通过启用流式传输,您可以在一个请求中进行多次提取,然后随着结果的到来进行迭代处理。
要查看生产环境中的流式传输示例,请查看此示例
重要:启用流式传输后响应行为的变化
示例:提取会议信息
以下 TypeScript 示例演示了如何使用 Async Generator 进行流式响应。它包含一个用于提取的 schema 定义,并迭代处理数据流以增量更新和显示提取的信息。
import Instructor from "@/instructor"
import OpenAI from "openai"
import { z } from "zod"
const ExtractionValuesSchema = z.object({
users: z
.array(
z.object({
name: z.string(),
email: z.string(),
twitter: z.string()
})
)
.min(5),
date: z.string(),
location: z.string(),
budget: z.number(),
deadline: z.string().min(1)
})
const oai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY ?? undefined,
organization: process.env.OPENAI_ORG_ID ?? undefined
})
const client = Instructor({
client: oai,
mode: "TOOLS"
})
const textBlock = `
In our recent online meeting, participants from various backgrounds joined to discuss the upcoming tech conference.
The names and contact details of the participants were as follows:
- Name: John Doe, Email: [email protected], Twitter: @TechGuru44
- Name: Jane Smith, Email: [email protected], Twitter: @DigitalDiva88
- Name: Alex Johnson, Email: [email protected], Twitter: @CodeMaster2023
- Name: Emily Clark, Email: [email protected], Twitter: @InnovateQueen
...
During the meeting, we agreed on several key points. The conference will be held on March 15th, 2024,
at the Grand Tech Arena located at 4521 Innovation Drive. Dr. Emily Johnson, a renowned AI researcher, will be our keynote speaker.
The budget for the event is set at $50,000, covering venue costs, speaker fees, and promotional activities.
Each participant is expected to contribute an article to the conference blog by February 20th.
A follow-up meeting is scheduled for January 25th at 3 PM GMT to finalize the agenda and confirm the list of speakers.
`
const extractionStream = await client.chat.completions.create({
messages: [{ role: "user", content: textBlock }],
model: "gpt-4o",
response_model: {
schema: ExtractionValuesSchema,
name: "value extraction"
},
stream: true,
seed: 1
})
for await (const result of extractionStream) {
try {
console.clear()
console.log(result)
} catch (e) {
console.log(e)
break
}
}
启用流式传输会改变您收到的响应性质
响应类型:启用流式传输时,响应变为 Async Generator。此生成器会产生增量更新,直到获得最终结果。
数据处理:当 Async Generator 产生结果时,您可以迭代处理这些增量更新。重要的是要注意,每次 yield 的数据都是当前提取状态的完整快照,并且可以立即使用。
最终值:生成器产生的最后一个值代表已完成的提取。此值应作为最终结果使用。
理解 OpenAI 补全请求和流式响应¶
Server-Sent Events (SSE) 和 Async Generators
OpenAI 的补全请求使用 Server-Sent Events (SSE) 返回响应,SSE 是一种用于将实时更新从服务器推送到客户端的协议。在此上下文中,我们 TypeScript 示例中的 Async Generator 与 SSE 的行为非常相似。Async Generator 的每次 yield 都对应于服务器的一个更新,提供连续的数据流,直到请求完成。
流式传输到浏览器或其他客户端¶
使用 Instructor 进行浏览器流式传输的挑战¶
Instructor 在服务器端数据验证和提取方面功能强大,但在直接流式传输到浏览器时会带来某些挑战
-
数据传输复杂性:Instructor 专注于完整的生命周期验证,这意味着流式传输到浏览器通常涉及传输完全构建的模型。这可能导致更大的数据块,增加传输的数据量。
-
在 UI 中处理数据块:流式传输完整对象时,管理多个块、分割、比较差异等会增加复杂性。这会使在浏览器中高效地实现实时更新变得更具挑战性。
利用 WebSocket¶
-
WebSocket 流式传输:将 Instructor 的数据流式传输到浏览器的可行解决方案是通过 WebSocket。这允许连续流式传输部分构建的模型,使其可在 UI 中立即使用。
-
易用性:使用 WebSocket,开发者可以将整个部分构建的模型流式传输到客户端,从而简化实时更新 UI 的过程。
无服务器环境中的替代方案¶
- 无服务器环境中的挑战:在无服务器环境或 WebSocket 可能不可行的场景中,由于高效传输大型数据块的限制,流式传输大型、完全构建的模型变得更加复杂。
利用 zod-stream 和 stream-hooks¶
-
与 zod-stream 集成:Instructor 构建在
zod-stream
之上,这是一个处理 Instructor 提供的流式传输方面的库。zod-stream
促进了从 API 端点构建结构化补全的过程,简化了数据处理流程,并提供了一个客户端用于解析原始流并生成部分构建的模型。 -
使用 stream-hooks 简化 UI 更新:对于 React 应用,将
stream-hooks
与zod-stream
集成可以显著简化动态 UI 的构建。stream-hooks
有效地管理流连接和数据更新,减少实时 UI 交互中的开销和复杂性。
虽然 Instructor 提供强大的服务器端功能,但流式传输到浏览器会带来复杂性,这些复杂性可以通过使用 WebSocket 或 zod-stream
和 stream-hooks
来有效管理。这些工具补充了 Instructor 的服务器端优势,使得在各种环境(包括无服务器架构)中构建动态、实时 UI 的方法更加简化。