想聊就聊,没收 AI 对话框的中止按钮!一天让你的 Agent 支持异步后台深度研究

0 阅读12分钟

想聊就聊,没收 AI 对话框的中止按钮!一天让你的 Agent 支持异步后台深度研究

真正的 Personal Agent,不应该让一项长研究占住整个聊天框。 用户把任务交出去之后,应该还能随时问别的问题、查看原研究进度、追加新的要求;研究各自继续,回答和控制操作也不能串到别的任务上。

这听起来像一个前端交互优化,但我们开发 ETF Agent 时发现:难的不是让两个模型请求同时运行,而是让同一段对话里的不同意图和执行始终对应正确的任务。

我们实际做了这样一次演示:

  • 先问:“为什么纳斯达克大跌?”——启动一项较长的研究。
  • 再问:“黄金与美债有什么关联?”——在前台独立回答,不必等前一项结束。
  • 中途补充:“需要与 A 股的大跌进行对比。”——明确交给原研究,而不是新开一份无关答案。

前台对话与后台研究并行推进的交互示意

交互关系示意:独立问题独立回答,明确追加的要求交给原研究;图中距离不代表执行耗时。

页面上的效果很直观:后台研究入口保留在顶部,黄金与美债的回答仍出现在主对话,新增的 A 股比较要求显示“已交给研究模型”。用户不用为了继续聊天先中止原任务;真正的停止按钮仍在,只是属于对应的研究,而不是整个输入框。

标题里说的“一天”,指的是在 ETF Agent 已经具备研究循环、工具、持久历史、恢复和正文发布能力的基础上,接通这套并发交互;不是说一天从零实现了完整研究 Agent。

一、把研究交出去,聊天框就不应该变成进度条

原来的 ETF Agent 已经能在用户离开页面后继续执行研究。但前端仍容易围绕一个全局的“正在生成”状态组织输入:后台任务存在,新消息便很容易被理解成对它的补充。

这造成一个产品上的悖论:服务端已经能独立工作,用户却仍要围着那项工作等待。

我们比较过三种看似容易的办法。收到新消息就抢占旧回答,会让一个随口的提问打断重要研究;把短问题排队,仍然无法及时响应;再创建一个常驻前台 Agent 来统一协调,则会引入第二套长期上下文和任务生命期。

最后选择的是更克制的结构:同一段会话可以存在多次独立执行,而不是靠一个永远忙碌的前台 Agent 维持秩序。

长研究沿原有 Research Run 运行;短问题有自己的执行身份;前端的连接与流只负责让用户看见进展,并不拥有研究是否继续的决定权。收起面板、换到另一条对话、网络断线,都不等于停止已经接纳的研究。

后台研究入口与前台黄金、美债问答共处一个页面

研究仍有独立入口,前台可以显示另一条已经完成的回答。

这项选择没有另建后台任务账本,而是复用已有的任务、控制、恢复和发布身份。新增加的是消息属于哪个任务、用户现在想做什么、页面应该更新哪一块。

二、用户新说的一句话,到底是在问问题,还是修改研究?

这是整个体验最容易被忽略、却最影响正确性的判断。

“纳斯达克研究正在进行”是系统状态;“黄金与美债有什么关系”是用户的新问题。不能仅因为系统忙碌,就自动把后一句塞进前一项研究。

我们保留普通入口对自然语言意图的理解,但用户明确指定目标时,不再让模型重新猜测:

用户动作系统应当如何处理
在主聊天框提出独立短问单独回答;不把回答自动注入正在运行的研究
在原研究面板追加要求直接交给该研究的调整流程,不另开研究
在主对话中自然语言要求“把 A 股也加进去”识别并关联目标 Run,目标不明确时先澄清
点击某项研究的停止按钮直接对该任务发出控制操作,不靠模型推测

实现里有一个 Coord 协调结果,但它不是新的常驻 Agent,也不拥有第二份研究状态。

还有一个现实约束:输入框能持续接收消息,不等于系统可以无限并发执行。初期配置允许三个短交互和一项后台研究;短问并发、单次研究预算、供应商请求容量仍是三类不同的资源。后台名额满了,就明确说明新研究未被接纳,而不是悄悄把它变成旧研究的补充。

这给产品设计一个直接启发:不要用“页面正忙”替代对用户意图的判断,也不要用一个全局 loading 状态表达多项任务的真实关系。

三、“已收到调整”和“研究真的采用了调整”,不是一回事

当用户说“还需要与 A 股的大跌进行对比”,系统首先保存的是这句原始用户消息,再把消息身份与目标研究关联。

为什么不直接让入口模型重写成一段精炼的研究指令?

因为模型的转述可能丢掉日期、对象和用户限制;请求失败重试时,还可能把同一个修改重复送入研究。我们让入口负责判断要调整哪项任务,交接内容则从已经保存的原消息读取。同一次合法重试读回原交接结果,而不是再造一次调整。

追加 A 股对比要求后,页面显示已交给研究模型

用户消息和交接回执都留在对话里;研究使用自己的执行与历史记录。

但这时也不能立刻宣布“研究已理解并完成调整”。这里至少有三个不同事实:

消息已保存,说明要求没有丢;后续模型请求实际带上了它,说明交接发生;最终报告满足新要求,还要看资料和研究结果。它们不能互相冒充。

这也是为什么前台的随口聊天不会自动成为后台研究的上下文。短问只读取提交时有资格取得的历史快照;只有明确交接的调整,才进入原研究的后续请求。后发的短问即使先完成,也不能倒过来改变先发请求当时看到的材料。

四、真正的并发,不是同时出现几个转圈动画

把输入框解锁后,另一个问题随之暴露:一个回答在页面上出现的位置,可能与它在服务端的执行顺序不同。

例如,用户先后发起两条短问,后发的一条先完成。前端不能继续用“最后一条 assistant 消息”推断对应关系,而要沿原 Run 找到发问、回答、工具进度和控制操作。

我们曾遇到一个真实交接故障:页面先显示临时回答行,历史读取随后用正式消息替换它;流式内容却仍然更新旧临时 ID,导致回答找不到自己的位置。修复不是多补一份正文,而是沿原 Run 定位当前承载回答的消息,保留正文自己的发布身份。

类似地,结束通知先到了,数据库视图可能还未更新;早发出的历史读取还可能比新请求更晚返回。我们用有界的只读补查和页面读取顺序保护显示,避免把暂时没读到的结果误认为研究失败,也不让旧快照覆盖新内容。

实际准入也踩过坑:第一次并发观察中,短问还有名额,却因为数据库短暂锁竞争而被立即拒绝。我们修的是准入阶段对短事务的有界等待,而不是偷偷把用户任务放进一条新队列。

这些问题都有一个共同根源:当系统从“一个会话只有一个当前任务”演化到多个独立执行,消息身份、结果归属和资源占用就不能再借用界面的先后顺序。

五、一次“取消”差点让整项研究提前收尾

体验中更有代表性的反例发生在用户中途纠偏时。

模型请求可能正在生成;新要求抵达后,系统需要让当前请求在安全位置让位,再把完整要求交给下一次请求。

但一次真实研究中,纠偏已经被保存,当前模型请求也按预期中断。请求适配层却把这种局部抢占压成普通的“取消”;运行时于是误以为整项研究只能进入收尾,不再继续查资料。最终留下了部分回答,用户需要的完整比较没有完成。

问题不在“应该增加几次重试”,而是两个不同动作被混为一谈:

  • 用户主动停止研究:结束原 Run,不能因迟到的调整把它重新启动。
  • 为采纳新要求而中断当前请求:保留原 Run 的授权、预算、已完成结果与未知用量;若仍合格,继续研究。

后来我们修复了请求中断原因的交接,使后续研究仍能在原准入规则下取证,而不是被过早推入收尾阶段。

这条实践尤其值得 Agent Runtime 开发者借鉴:一次模型请求的生命期,不等于整项研究任务的生命期。 不能让一个通用的取消错误码,代替原任务作最终决定。

六、交互做成了,不等于每份研究都已经做对

最初的纳斯达克演示里,黄金与美债短问可以独立阅读,新增 A 股比较要求也实际送入了原研究。但原报告没有拿到完成同日比较所需的 A 股行情和资金数据,只能给出有明确限制的分析框架。

报告说明 A 股资料缺失,并限定对比框架的证据范围

这是原始演示的真实缺口:要求已经交接,充分的数据比较仍未完成。

之后的 2026 年 10 月 26 日,另一次独立的金融研究真实验收取得了更完整的交互证据:后台研究与三个短问题重叠运行、最终各自完成;定向调整的完整原文进入后续研究请求;短问正文没有串入后台输入;报告和对话历史也在实际浏览器中回读。对应工程验收已正式归档。

但连这次正常完成的研究,也不能直接宣称金融判断全部正确。人工复核发现模型根据两份文件的措辞推断某项跟踪约束“严一倍”,缺乏足够同口径依据。后续独立读取一手资料,明确撤回这项推断,并把更正与原报告分别保存。

这两段经历共同说明了一件事:前台是否真正可用、后台是否真正继续、研究是否准确回答问题,是三个需要分别核对的成果。

并发交互的真实验收,不意味着长期生产稳定性、所有资金与费用数字、金融语义质量都已经得到认证。我们保留这些边界,不用一个漂亮的“已完成”掩盖它们。

七、最值得复制的,不是后台面板,而是任务关系

如果要为现有 Chat 产品增加这种能力,我会优先作出三个选择。

第一,让长研究拥有独立生命期。 接纳后由服务端记录任务;前台连接只是进度与内容的观看方式,不是任务的存在条件。停止必须有明确目标,不靠整个聊天框的一个开关。

第二,让新消息按真实意图进入正确的任务。 独立短问独立回答,明确调整沿原消息和原研究身份交接。只收到、真正采用、最终完成分别留证;没有容量就明确拒绝,不偷偷改目标。

第三,让前端以任务身份组织乱序内容。 后发回答先到、临时消息被历史替换、结束信号快于持久化读取,都不应造成串话、消失或重复执行。

这三件事都不需要再造一个常驻的“前台总 Agent”。它们首先要求原有研究、控制、发布和历史事实之间能可靠对应。

好的 Personal Agent 不是永远占着输入框告诉你“我正在思考”,而是你把复杂工作交出去之后,仍然可以自然地继续提问、改变要求,并最终找回属于那项任务的真实结果。

这才是我认为异步后台深度研究最值得让读者看见的产品体验,也是支撑它的架构选择。


延伸阅读:异步研究的时间约定与离线交付讨论到点交付与历史重读;渐进回答的连贯性讨论同一回答如何持续改善。本文聚焦前台继续对话、后台任务归属和运行中调整,不重复这两篇的机制细节。

延伸阅读与交流

本文也收录于 ETF Agent 工程手记,另有完整英文版。如果这些工程记录对你有帮助,欢迎在 GitHub 文集 点个 Star,方便后续阅读。