ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Electric Streams Durable Proxy:让 AI 流式 API 具备可恢复、可重连能力

Electric Streams Durable Proxy:让 AI 流式 API 具备可恢复、可重连能力 Electric Streams Durable Proxy让 AI 流式 API 具备可恢复、可重连能力【免费下载链接】electricThe agent platform built on sync.项目地址: https://gitcode.com/GitHub_Trending/el/electric导读本文围绕 Electric Streams托管版 Durable Streams 实现提供的Durable Proxy持久化代理展开它能把durable-streams/proxy放在任何现有 SSE / 流式 AI 接口之前将上游响应持久化写入 Durable Streams并向客户端返回一个可断点续读的持久化 URL。读完本文你将掌握如何启动代理服务器、如何用createDurableFetch在客户端实现跨刷新、跨断网的续读以及它与 Vercel AI SDK、TanStack AI 等集成的选型边界。一、为什么需要 Durable ProxyDurable Streams 是一种可寻址URL 化、只追加append-only、可回放replayable的持久化 HTTP 流生产者向流追加事件任意数量的消费者既可以实时订阅也可以从任意 offset 回放历史数据见 Electric Streams 概览。大多数现有 AI 流式 API如 OpenAI、Anthropic 的/v1/chat/completions走的是传统 SSE 单向推送连接一旦断开客户端就丢失了未读完的内容也无法从断点继续。Durable Proxy 解决的正是这个问题代理把请求转发给上游供应商把流式响应持久化写入 Durable Streams然后给客户端一个持久化读 URL。客户端即使刷新页面、切换设备甚至断网重连都能从上次读到的 offset 继续而不需要修改上游协议——上游供应商依然只看到一次普通的流式请求。从实现原理看它把「一次性的 SSE 会话」翻译成了「一条可续读的流」这正是 Vercel AI SDK 集成 与 TanStack AI 集成 中Durable Session模式的基础设施层。二、安装Durable Proxy 以独立 npm 包分发pnpm add durable-streams/proxy包内包含两部分能力服务端createProxyServer主入口客户端createDurableFetch位于子路径durable-streams/proxy/client。在本仓库中durable-streams/*系列包被作为基础设施广泛使用——例如 packages/agents/package.json 依赖durable-streams/stateexamples/agents-chat-starter/package.json 与 examples/deep-survey/package.json 同样如此说明 Durable Streams 生态是 Agent 平台底层的数据原语protocol 见 website/docs/streams/index.md。三、启动一个代理服务器createProxyServer的典型用法如下import { createProxyServer } from durable-streams/proxy const server await createProxyServer({ port: 4440, durableStreamsUrl: http://localhost:4441, jwtSecret: process.env.JWT_SECRET, allowlist: [https://api.openai.com/**, https://api.anthropic.com/**], }) console.log(Proxy running at ${server.url})3.1 配置项说明配置项作用说明port代理监听的本地端口示例中使用4440durableStreamsUrl上游 Durable Streams 服务器的地址代理把上游响应持久化写入这里示例为http://localhost:4441jwtSecret签发/校验客户端读取凭证的 JWT 密钥通常从环境变量注入如process.env.JWT_SECRET不应硬编码allowlist允许转发到哪些上游 URL 的 glob 白名单示例允许 OpenAI 与 Anthropic 的 API**表示该 host 下的任意路径allowlist是安全关键配置它约束了代理只能转发到白名单内的上游地址防止代理被当作任意 HTTP 转发器滥用。生产环境中应尽量收紧为具体的域名 路径前缀。3.2 工作流程一次典型请求的处理链路是客户端向代理发送请求携带上游地址与凭证代理校验请求含allowlist校验后转发给上游供应商上游开始流式返回代理把流式响应逐块追加写入durableStreamsUrl指向的 Durable Streams代理把该流的持久化读 URL返回给客户端可通过Location头与响应体携带客户端之后可以随时用该读 URL 从头或从任意 offset 续读。这里底层依赖的正是 Durable Streams 协议的追加POST、读取GET ?offset…、实时模式livesse/livelong-poll与Stream-Next-Offset游标语义详见 website/docs/streams/index.md。四、客户端Durable Fetch客户端通过createDurableFetch获得一个fetch 兼容的调用入口import { createDurableFetch } from durable-streams/proxy/client const durableFetch createDurableFetch({ proxyUrl: https://my-proxy.example.com/v1/proxy, proxyAuthorization: service-secret, autoResume: true, storage: localStorage, }) const response await durableFetch( https://api.openai.com/v1/chat/completions, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer sk-..., }, body: JSON.stringify({ model: gpt-4, messages: [{ role: user, content: Hello }], stream: true, }), requestId: conversation-123, } )4.1 createDurableFetch 配置项配置项作用说明proxyUrl代理服务器的入口地址形如https://my-proxy.example.com/v1/proxyproxyAuthorization访问代理所需的凭证例如service-secret用于服务间鉴权autoResume是否自动续读为true时客户端会自动从上次保存的 offset 继续读取storage保存续读游标offset的存储后端浏览器中可传localStorage便于跨刷新保留进度4.2 requestId续读的钥匙普通fetch请求没有身份而 durableFetch 的请求参数里多了requestIdrequestId: conversation-123,requestId让客户端可以在刷新页面、重新连接后继续读取同一条持久化流。其工作方式与 TypeScript 客户端 中「保存返回的 offset 以便后续续读」的思路一脉相承流内每个位置由不透明但可字典序排序的 offset标识服务器通过Stream-Next-Offset响应头告知下次从哪读见 website/docs/streams/index.md。客户端把requestId与 offset 关联起来autoResume配合storage即可做到断点续读首次请求携带requestId代理为它创建/关联一条流响应过程中客户端把最新Stream-Next-Offset存入storage刷新或重连后客户端用同一个requestId发起请求从上次 offset 继续消费已读完的部分不会重复出现读取是有游标的。五、何时使用 Durable Proxy官方文档给出了清晰的选型建议使用 Durable Proxy当你有现成的 SSE 或流式 AI 端点希望获得可恢复resumability能力但不想改动上游协议。代理对上游透明最适合包一层的场景使用 Vercel AI SDK 集成见 website/docs/streams/integrations/vercel-ai-sdk.md当你直接基于 Vercel AI SDK 开发时durable-streams/aisdk-transport的createDurableChatTransport可以替换useChat默认传输层让一次对话生成在刷新后存活服务端用toDurableStreamResponse把toUIMessageStream()写入 Durable Streams使用 TanStack AI 集成见 website/docs/streams/integrations/tanstack-ai.md当你想用 TanStack AI 的连接适配器时durableStreamConnection会把客户端与服务端之间的通信从 request/response 范式切换为基于 Durable Streams 的同步范式天然支持多标签页、多设备、多用户/多 Agent 协作。换句话说Durable Proxy 是不改上游协议的通用兜底方案而两个 AI SDK 集成则是在特定框架内的更深度集成。同一套 Durable Streams 之上还提供了 JSON 模式、Durable State、StreamDB、StreamFS 等更高层原语。六、理解底层协议续读如何成立要正确使用 Durable Proxy需要理解它依赖的流协议语义完整协议见 website/docs/streams/index.md。6.1 流与 offset一条流是一个 URL 可寻址的字节序列只支持追加。协议定义六个操作PUT /streams/my-stream # Create POST /streams/my-stream # Append GET /streams/my-stream?offset… # Read HEAD /streams/my-stream # Metadata POST /streams/my-stream # Close (with Stream-Closed: true) DELETE /streams/my-stream # Deleteoffset 是不透明字符串有两个重要性质不要解析其内部格式但它可按字符串比较排序同一流内可判断先后。两个哨兵值值含义-1流开头等价于省略 offsetnow当前尾部——跳过已有数据只读新消息读取响应会带回Stream-Next-Offset头指示下一次从哪读。这正是客户端autoResume持久化的对象。6.2 实时模式Long-poll?livelong-poll服务器挂起连接直到新数据到来或超时200 OK表示有新数据204 No Content表示超时可用同一 offset 重试SSE?livessedata事件携带流负载control事件携带元数据next offset、up-to-date、closed。服务器约每 60 秒关闭 SSE 连接以支持 CDN 连接合并客户端用最后一个control事件的streamNextOffset重连。代理在把上游响应落盘后客户端既可走livesse实时接收也可在断线后用 offset 追赶两种模式对同一条流可交替使用。6.3 幂等生产者与流生命周期对于上游重试是否会产生重复数据的问题协议提供了幂等生产者机制Producer-IdProducer-EpochProducer-Seq三头服务器记录每个(stream, producerId, epoch)最后接受的序号重复请求返回去重成功响应重启后递增 epoch 还能隔离僵尸生产者。流还支持Stream-TTL相对秒数与Stream-Expires-AtRFC 3339 绝对时间二者互斥、Stream-Closed: true的持久化关闭语义关闭后仍可读、不可追加以及 DELETE 删除。这些语义决定了 Durable Proxy 持久化读取的可靠性边界——一旦写入位置上的数据永不变更这正是历史读取可被 CDN 缓存配合ETag/If-None-Match条件请求的前提。七、安全与生产部署要点JWT 密钥管理jwtSecret用于签发读取凭证务必从环境变量注入密钥泄露意味着读取凭证可被伪造收紧 allowlist只放行你真正需要代理的供应商域名与路径避免开放代理服务间凭证客户端proxyAuthorization应使用独立的 service secret与上游 API Key 分开管理读 URL 授权持久化读 URL 本身包含读取整个响应的能力建议由代理签发短期有效凭证或结合Stream-TTL设置流的过期时间避免响应数据无限期可读存储选择浏览器中localStorage适合跨刷新续读移动端或 SSR 场景可根据需要替换为其他持久化存储。八、快速体验从零跑通一条流若想先亲手验证 Durable Streams 的写入—读取—实时订阅闭环可参考 Quickstart# 1. 启动 in-memory 服务器默认 http://localhost:4437端点 /v1/stream/* ./durable-streams-server dev # 2. 创建一条流 curl -X PUT http://localhost:4437/v1/stream/hello \ -H Content-Type: text/plain # 3. 追加数据 curl -X POST http://localhost:4437/v1/stream/hello \ -H Content-Type: text/plain \ -d Hello, Durable Streams! # 4. 读取保存 Stream-Next-Offset 以便续读 curl http://localhost:4437/v1/stream/hello?offset-1 # 5. 终端 ASSE 实时订阅 curl -N http://localhost:4437/v1/stream/hello?offset-1livesse # 6. 终端 B追加新数据终端 A 会实时收到 curl -X POST http://localhost:4437/v1/stream/hello \ -H Content-Type: text/plain \ -d This appears in real time!在本地另起 Durable Streams 服务器durableStreamsUrl指向localhost:4441后即可将上文createProxyServer的示例跑通客户端通过createDurableFetch发起一次 OpenAI 流式请求中途断开后用同一个requestId重新连上继续读取未消费完的 token 流。九、延伸阅读协议全貌与六种操作、offset、实时模式、生命周期website/docs/streams/index.md五分钟上手QuickstartTypeScript 客户端stream()、IdempotentProducerwebsite/docs/streams/clients/typescript.mdPython 客户端website/docs/streams/clients/python.mdCLI 工具website/docs/streams/cli.mdJSON 结构化流website/docs/streams/json-mode.md结构化状态变更insert/update/delete 事件website/docs/streams/durable-state.md与 Vercel AI SDK 的深度集成website/docs/streams/integrations/vercel-ai-sdk.md与 TanStack AI 的连接适配器website/docs/streams/integrations/tanstack-ai.md流内数据库与文件系统抽象StreamDB / StreamFS【免费下载链接】electricThe agent platform built on sync.项目地址: https://gitcode.com/GitHub_Trending/el/electric创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表