Back to writing archive

2026-04-16

v1.2 异步解耦:A 不等 B,B 低频产出报告

把 A 线和 B 线真正拆开:聊天继续走,报告低频异步生成。

Chinese onlyAIRAGLangGraphMedical DemoEngineering Log

v1.1 只解决了一半

v1.1 以后,A 线已经能多轮流式回复,但 B 线还是像挂在后面的重尾巴。

实际演示时很明显:用户刚补完一个小信息,系统不一定需要立刻生成新报告。问诊是连续的,报告应该是阶段性的。把它们绑在同一个节奏里,A 线会被拖慢,B 线也会变得廉价。

v1.2 就是把这件事拆开:A 不等 B,B 低频异步生成。

新增几个状态表

这一轮加了几类数据结构:

  • ReportJob:一次报告生成任务;
  • ReportVersion:某次报告的版本;
  • SessionIntake:会话里逐步收集到的问诊信息。

这些不是在做真实医疗系统,也不是病历管理。它们只是让 demo 里的 B 线从“同步返回一段文本”变成“有状态、有版本的阶段性产物”。

接口也跟着拆开

聊天继续走 A 线,报告走自己的接口:

  • POST /v1/report/schedule
  • GET /v1/report/{job_id}
  • GET /v1/sessions/{id}/reports

前端可以先展示 A 线流式回复,右侧报告等后台任务完成后再更新。用户不会因为报告还在生成,就卡在聊天输入后面。

什么时候触发 B 线

B 线不再每轮自动跑。触发策略更保守:

  • 累积到三轮左右;
  • 距离上次报告过了一段时间;
  • intake 里出现需要关注的红旗信息;
  • 用户手动要求生成报告。

这个策略不完美,但比“每句话都总结一次”更接近实际使用。报告应该帮人阶段性回看,而不是抢走对话节奏。

/v1/dual 继续留着

/v1/dual 没删。它仍然适合教学:一眼看出 A/B 两条线输出有什么差异,也方便做回归。

我不太喜欢为了新架构把旧路径立刻砍掉。这个项目本来就是一步步演进的,保留旧接口能让演示故事更完整:先同步双轨,再多轮,再异步解耦。

v1.2 做完后,双轨才真正像双轨。A 线继续问,B 线在后台低频产出报告。两个东西还在协作,但不再互相拖着走。

评论