当5分钟不够时:将 AI Ingestion 从 Sync 转为 Async(并节省 99% Compute)

发布: (2026年2月13日 GMT+8 11:38)
5 分钟阅读
原文: Dev.to

Source: Dev.to

背景

在之前的文章中,我介绍了 Synapse——我为妻子构建的 AI 系统,它使用知识图谱为她的 LLM 提供“深度记忆”。早期演示显示,图谱在聊天结束后约 50 秒内更新,但实际使用很快暴露出一个根本性缺陷。

问题

在 45 分钟的聊天会话中发送了数十条消息后,“结束会话”按钮会转圈数分钟,最终崩溃。根本原因并不是简单的超时 bug,而是架构本身。

最初的同步实现

  1. Convex (Orchestrator) → 触发对我的 Python 后端的 HTTP POST。
  2. FastAPI (Brain) → 调用 Graphiti + Gemini 处理文本。
  3. FastAPI 等待结果并返回。
  4. Convex 将结果保存到数据库。

这是一种经典的同步请求‑响应模式。

失败原因: Convex Actions 有硬性执行时限(5–10 分钟,取决于套餐)。短会话在 1–2 分钟内完成,但较大的会话需要 12–18 分钟,远超限制。

连锁故障

  • 在 Convex actions 上添加了指数退避重试。
  • 每次重试都会启动一个新的后台进程,而之前的进程仍在运行,导致 token 使用翻倍并产生“僵尸”作业。
  • 用户仍然看到错误,后端被压垮。

诊断

发送到 Axiom 的 OpenTelemetry 跟踪显示,摄取并未失败——只是慢,针对大规模会话始终需要 12–18 分钟。

转向异步轮询架构

当任务超过客户端或服务器愿意等待的时间时,请求必须与响应解耦。

新的流程

  1. Convex 发送 POST /ingest
  2. FastAPI 立即返回 202 Accepted 并附带 jobId(≈ 300 ms)。
  3. FastAPI 在后台任务中启动耗时的处理(asyncio.create_task)。
  4. Convex 休眠,然后每隔几分钟轮询作业状态。

轮询策略

  • 从指数退避改为 线性退避
  • 调度:5 分钟后检查一次,随后 10 分钟后检查一次,之后每隔 10 分钟检查一次。
  • 减少了不必要的负载和服务器噪音。

资源使用对比

场景操作时间总计计费计算量Token 浪费
同步5 分钟(阻塞)→ 超时 → 重试(再 5 分钟)~10–15 分钟高(重复处理)
异步轮询触发 ≈ 300 ms,轮询 ≈ 300 ms,最终获取 ≈ 300 ms< 2 秒最小

我们将每个作业的计算浪费从约 10 分钟降至不到 2 秒的活跃执行时间,同时消除了重复处理。

经验教训

  • **AI 任务本质上很慢。**一次“快速”LLM 调用可能需要 30 秒;一次“深度”知识图谱更新可能需要 15 分钟。
  • **不要仅仅增加超时。**通过解耦请求与响应来保持系统的弹性和成本效益。
  • 线性退避用于轮询 与长时间运行作业的预期时长相匹配,能够降低服务器的聊天频率。

代码仓库

该异步请求‑响应模式的实现可在以下仓库中找到:

征求反馈

我想了解大家是如何处理长时间运行的 LLM 任务的。欢迎在 X 或 LinkedIn 上联系我。

0 浏览
Back to Blog

相关文章

阅读更多 »