多端复用一套对话逻辑,我抽了个 useChat hook

发现自己在复制粘贴同一坨流式逻辑,恶心了,停下来抽了个 hook。这篇讲讲我怎么收口的。

重复在哪

三个端不一样的其实只有两层:UI 长什么样、消息存哪。一样的东西多得多------发消息、读 SSE 流、维护"正在生成"状态、错误处理、中断、重发。这部分在三个端里我几乎一字不差地抄了三遍。该抽了。

抽出来的 useChat

我把所有跟 UI 无关的逻辑收进一个 useChat,只暴露状态和方法,长啥样交给各端自己:

javascript 复制代码
function useChat({ send, store }) {
  const messages = ref([])
  const isStreaming = ref(false)

  async function ask(text) {
    messages.value.push({ role: 'user', content: text })
    const reply = reactive({ role: 'assistant', content: '' })
    messages.value.push(reply)
    isStreaming.value = true
    try {
      await send(messages.value, (delta) => {
        reply.content += delta   // 流式追加
      })
    } finally {
      isStreaming.value = false
      store?.save(messages.value) // 存储交给外部
    }
  }

  return { messages, isStreaming, ask, stop, retry }
}

关键是两个依赖注入:

  • send:怎么发请求、怎么读流,由各端传。Web 传 fetch 版,webview 传走 bridge 的版本。

  • store:存哪,由各端传。H5 传 IndexedDB,后台传调接口的。

hook 本身不关心这俩怎么实现,只管编排流程。三个端共用同一份 ask / stop / retry 逻辑,UI 各画各的。

抽完的收益

  • 流式那段最容易出 bug 的代码,从此只有一份,改一处三端都好。

  • 新接一个端,只要实现 send 和 store 两个函数,半天接完。

  • 测试也省,核心逻辑对着 hook 测一遍就够。

踩到的坑和取舍

坑:响应式系统不统一。 后台是 Vue,有个端是 React。useChat 没法真正一份代码跑两个框架,我最后是抽了一份框架无关的"纯逻辑 class",外面再包一层各自的 hook 适配响应式。多了一层包装,但核心逻辑确实只有一份。

取舍: 依赖注入让 hook 很灵活,但也意味着调用方要懂得多------传错 send 的流式协议照样翻车。灵活和易用这里我偏了灵活,新人接手有点门槛。

模型统一走讯飞 MaaS,三端调同一个现成接口,连后端都不用各搭一套。你们多端复用逻辑都怎么抽?评论区交流。

相关推荐
张张123y几秒前
DSH 插件调试避坑:client.js 设置面板、热重载与高频报错排查表
开发语言·javascript·人工智能·开源·ecmascript·后端开发·ai agent
tellmewhoisi2 小时前
深度学习0:数学知识:正态分布4(坐标变换的缩放比例(面积微元变换))
人工智能·深度学习
布吉岛的石头2 小时前
Java 程序员第 50 阶段14:灾难性遗忘与回放
人工智能·深度学习·transformer
不吃鱼的羊2 小时前
诊断27解锁dll文件制作(Visual Stdio无法安装版)
人工智能
后端小肥肠2 小时前
漫画工坊上线用户破百:公众号漫画从需求到变现全复盘
人工智能·aigc·agent
赛博山人3 小时前
字节跳动下线扣子企业版,团队已并入豆包
人工智能
isboyjc3 小时前
Lomo Agent:面向创作型、持续协作 Agent 的架构设计与工程实践
人工智能·架构·agent
小蒋观天下3 小时前
码率、I帧间隔、智能编码冲突:H.265+导致AI取流解码异常
人工智能
roman_日积跬步-终至千里4 小时前
AI 能让一个人成为团队吗?从数据中台到 OPC,重新理解软件工程能力
大数据·人工智能·软件工程