V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
Junian
V2EX  ›  Go 编程语言

写了个 Go 库解决 LLM 流式输出断线重连的问题

  •  
  •   Junian · 4 小时 40 分钟前 · 163 次点击
    最近在做一个项目,后端 Go ,前端 SSE 推流 LLM 的输出。遇到一个很烦的问题:用户刷新页面或者网络抖一下,流就断了,但后端还在跑,token 照烧不误。

    更麻烦的是我们的 LLM worker 和 HTTP handler 不在同一个实例上,负载均衡一转发,重连过来的请求根本找不到原来那个流。

    JS/TS 那边有 Vercel 的 resumable-stream 可以用,但 Go 这边翻了一圈啥也没有,就自己撸了一个:

    https://github.com/gtoxlili/streamhub

    思路不复杂:
    - Redis Streams 存 chunk ,断线重连的订阅者先 replay 历史再接实时数据
    - Redis Pub/Sub 传 cancel 信号,用户在 A 节点点停止,B 节点上的生成就能收到
    - 每个 producer 有个 generation ID 做 fencing token ,防止旧 producer 写脏数据
    - 同一个 session 只允许一个 producer 注册,不会重复调 LLM

    代码大概长这样:

    ```go
    // 生产端
    stream, created, err := hub.Register("chat:123", cancelFunc)
    if !created {
    return // 已经有人在跑了
    }
    defer stream.Close()
    stream.Publish("hello")

    // 消费端(任意实例)
    chunks, unsub := hub.Get("chat:123").Subscribe(128)
    defer unsub()
    for chunk := range chunks {
    // 先 replay 再 live
    fmt.Fprint(w, chunk)
    }
    ```

    目前还比较早期,API 可能还会改。做类似场景的同学可以看看,有想法欢迎提 issue 。
    目前尚无回复
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   937 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 22:18 · PVG 06:18 · LAX 15:18 · JFK 18:18
    ♥ Do have faith in what you're doing.