跳到主要内容

多用户共享 AI 会话:尚无人解决的并发难题

· 阅读需 14 分钟
Tian Pan
Software Engineer

大多数 AI 产品都是为单一用户、单一意图、单一对话线程和单一身份构建的。当产品是个人生产力工具(如写作助手、代码补全引擎、摘要生成器)时,这运作得足够好。但当团队开始协作使用 AI 时,情况发生了变化:产品会以难以诊断且更难修复的方式悄然失效。两个用户同时向 AI 提问,其中一个输入消失了。五个工程师共享的上下文窗口充满了重复的历史记录。AI 使用用户 B 的权限回答用户 A 的问题。没有人为这些情况做过设计,因为交付多用户共享上下文意味着要面对现代 AI 基础设施中最难的分布式系统问题之一。

本篇文章将探讨为什么同步多用户 AI 会话如此困难、生产团队尝试了哪些方案,以及新兴的架构模式是什么。如果你正在构建协作 AI 功能并疑惑为何它感觉复杂得离谱,这就是原因。

为什么多用户 AI 在架构上是不同的,而不仅仅是更难

单用户 AI 模型拥有简洁的架构:一个用户、一个会话、一个对话历史、一个上下文窗口、一个身份。模型处理上下文并返回响应。状态机非常简单。

当你在同一个会话中增加第二个用户时,你不仅仅是增加了一倍的负载。你打破了该架构所建立的基础假设。

上下文是整体性的,而非组合性的。 在 Google Doc 中,两个用户同时编辑产生的更改是局部且有界的:用户 A 编辑第 3 段,用户 B 编辑第 7 段,操作变换(Operational Transform,简称 OT)或无冲突复制数据类型(CRDT)可以确定性地合并结果。但在共享 AI 会话中,上下文就是一切:系统提示词、累积的对话历史,以及 AI 对任务建立的隐性思维模型。当用户 A 和用户 B 同时发送消息时,任何编辑都不是局部的。两条消息都有可能重塑 AI 对整个局势的理解。对此没有简洁的合并函数。

LLM 的状态化方式与电子表格单元格不同。 电子表格单元格包含一个值。两个用户同时向同一个单元格写入时,冲突很简单,解析为其中一个写入者获胜即可。LLM 的推理是顺序且有状态的:生成的每个 token 都依赖于上下文中的所有先前 token。如果两个用户在同一瞬间提交输入,你无法在共享上下文上同时运行两次推理,然后将输出合并成连贯的内容。你必须做出选择:要么将一个用户的输入序列化在另一个用户之前,要么分叉上下文并丢失共享状态。

错误会在所有用户之间放大。 在单用户模式下,如果 AI 误解了问题并给出了无用的回答,损失仅限于一个用户,该用户可以在下一轮纠正误解。在共享会话中,如果 AI 误读了团队的意图,每个参与者现在都基于同一个糟糕的输出进行工作。错误不会停留在局部——它会变成组织层面的问题。

这些不是靠更好的工具就能消除的工程挑战。它们是结构性约束,每个多用户 AI 系统都必须对此做出深思熟虑的选择。

实时协作原语究竟教会了我们什么

寻求多用户 AI 方案的工程师自然会看向成熟的实时协作方案库:如 Google Docs 使用的操作变换(OT),或 Figma 及 Notion 等支持离线编辑器的无冲突复制数据类型(CRDTs)。这些工具功能强大且已被充分理解。但它们解决的是不同的问题。

OT 的工作原理是将每次编辑视为一个操作——在第 5 个位置插入字符,删除第 10–12 个字符——并在并发编辑冲突时对操作进行相互转换。其核心见解是,对文档的编辑操作是局部且可组合的。当用户 B 删除第 2–4 个字符时,用户 A 在第 5 个位置的插入可以在数学上进行调整,因为位置是算术性的。

CRDTs 将冲突解决直接嵌入到数据结构中。任何副本都可以偏离其他副本,并仍通过数学上保证可交换、结合和幂等的合并函数收敛到同一状态。对于无法保证中央协调器的分布式、支持离线的系统,它们是理想的选择。

这两者都无法完美映射到共享 AI 上下文中,因为 AI 上下文不是 OT/CRDT 意义上的文本。系统提示词不是具有局部位置的字符序列。对话历史是一个具有跨条目语义依赖的全序日志。当用户 A 在第 7 轮的消息引用了用户 B 在第 4 轮做出的承诺时,没有可以围绕其进行转换的“位置”。意义纠缠在整个历史中,无法进行代数分解。

这并不意味着 OT 和 CRDT 技术对 AI 协作毫无用处。它们可能适用于子问题:例如,管理协作 UI 中非 AI 组件的共享状态,或者管理对系统提示词配置的并发编辑。但它们并不能解决在共享上下文上进行同步多用户 AI 推理的核心问题。

每个共享会话必须做出的三个决定

当剥离各种选项时,每个多用户 AI 架构都必须回答三个问题。

此时谁在控制 AI? 在单用户模式下,AI 始终只与一个人交谈。在多用户模式下,你需要一个轮循或优先级模型。最简单的选择是将消息排队并串行处理:处理用户 A 的消息,生成响应,然后处理用户 B 的消息。这保留了连贯性,但破坏了同步感——用户看到彼此的消息实时到达,但看到 AI 的响应按严格顺序出现,甚至可能是不符合预期的顺序。另一种方案是允许任何用户随时发送,并并行生成对所有输入的响应,但这需要将共享上下文 fork 成独立的副本,从而破坏了让共享会话具有价值的共享状态。

谁的身份决定了 AI 的权限? 当用户 A(具有管理员权限)和用户 B(具有查看者权限)处于同一个会话中时,共享服务账户身份会将两个用户折叠成单一的权限级别——通常是他们所有权限的并集,这是最宽松也最危险的选择。一个得当的每用户身份模型要求 AI 在委托的、具有时间范围的凭证下运行,以反映每个用户的实际授权。这在技术上是可行的,但需要大量的基础设施:AI 发起的每一次工具调用都必须归于特定的用户身份,且权限必须反映该用户在那个特定时刻的实际访问级别。即时凭证发放(Just-in-time credential issuance)——即 AI 为每个动作请求新鲜凭证,而不是持有一个长效服务账户——是正确的设计,但大多数框架并不支持。

如何跨用户管理上下文窗口? 共享上下文的填充速度比私有上下文快得多。五个用户参与同一个会话意味着在窗口达到容量限制之前,消息量大约是原来的五倍。一旦窗口填满,就必须对某些内容进行摘要或剔除。但谁的历史记录会被压缩?如果用户 A 的早期上下文被摘要掉了,用户 A 就会失去一段用户 B 无法重建的脉络。共享会话中的上下文压缩需要将历史归因于贡献者,并有意识地选择每个参与者需要保留的内容。大多数实现在用户开始注意到 AI 遗忘了重要事情之前,都会忽略这个问题。

生产团队实际交付的产品

一些商业产品已经在生产环境中处理了多用户 AI 会话,它们的设计揭示了真正的约束所在。

Microsoft Copilot Cowork 在实验性测试中允许团队成员在协作工作区中与共享的 Copilot 代理进行交互。AI 直接参与团队对话,在参与者之间维护共享上下文,并为共享文档做出贡献。“实验性”这一标签非常诚实:该产品代表了微软承认这个问题很难,他们目前的解决方案只是一个起点,而非最终答案。其架构主要基于广播:AI 产生一个对所有参与者可见的响应,而不是处理对共享上下文的并发多用户写入。

xAI Grok Build 支持多达 8 个代理同时在共享代码库上工作,并针对重叠的文件编辑提供冲突解决。8 个代理的上限并非随意设定——它反映了协调开销的阈值,超过该阈值后,系统的可靠性会明显下降。当用户的写入大多不重叠且冲突面有限(单个文件)时,多用户编辑运行良好;但当每个用户都向同一个无界的上下文中贡献内容时,情况就不同了。

生产部署中的模式是一致的:当用户主要读取共享上下文并偶尔写入时,多用户 AI 协作的效果最好;而当多个用户同时对同一个语义状态生成冲突的写入时,效果较差。大多数团队通过规避难题来解决它:AI 生成所有用户都能读取的共享输出,但来自每个用户的输入是串行处理而非合并的。

持久化会话:新兴架构

最近最受关注的一种模式重新定义了问题。它不再问“多个用户如何共享单个 AI 推理”,而是问“多个用户如何共享单个持久化会话”。

持久化会话(Durable Sessions)将会话本身——而非 LLM 的内部状态——视为同步原语。会话是一个有序的、持久的事件流。AI 将令牌流(token-streamed)输出作为事件产生。用户将消息作为事件提交。所有参与者订阅同一个事件流并按顺序接收更新,掉线重连的用户会自动补齐。

这绕过了推理层的序列化问题。LLM 一次处理一个输入(序列化),但由于所有输出都作为有序事件流广播,用户体验到的是会话的共享实时视图。关闭笔记本电脑并重新打开的用户会从事件日志中接收到完整的追溯。加入正在进行的会话的用户会收到历史记录。在线状态指示器(Presence indicators)显示当前谁连接到了会话。

类比一下,这就像一个永不掉线的电话会议:你可以在通话中把手机递给同事,通话继续,另一方能听到当前说话的人。基础设施维持了连续性,参与者决定谁在何时说话。

这种架构将难题从基础设施层转移到了产品层。轮循、优先级处理和权限归属仍然需要实现,但它们可以作为会话策略而非推理层约束来实现。事件流默认变得可审计,这满足了共享会话的合规性和调试需求。

无人解决的分歧意图问题

持久化会话(Durable Sessions)能够很好地处理并发机制。但它们没有解决更深层次的挑战:当同一会话中的多个用户希望 AI 做完全不同的事情时,会发生什么?

在现实世界的协作会话中,这并非边缘案例。产品经理和资深工程师往往有着冲突的意图:产品经理希望 AI 进行功能头脑风暴,而工程师则希望它识别技术约束。在单用户会话中,用户的意图是明确的。但在多用户会话中,AI 会收到相互竞争的指令,且必须以某种方式对其进行协调。

目前的系统处理得非常糟糕,甚至根本没有处理。大多数系统依赖于隐式的轮流机制:谁发送了最近的一条消息,谁就决定了当前的方向。这意味着打字最快的人控制着 AI 的输出,这对于协作工作既不公平也不实用。更复杂的方法可以实现显式的共识机制——要求两个用户在 AI 继续之前确认一个方向——但这增加了阻力,削弱了实时协作的价值。

分歧意图问题无法通过让 AI 更聪明地推断共识来解决。它需要产品层面的决策来确定会话的结构:会话是否有一个指定的协调者,是否有具有不同输入通道的不同角色,AI 是在冲突的输入之间进行调解,还是仅仅向参与者展示冲突。这些是产品设计选择,而不是工程选择,这正是大多数 AI 产品回避它们的原因。发布多用户 AI 功能意味着在协作动态上做出明确选择,而单用户产品永远不必面对这些。

优先构建什么(以及推迟什么)

如果你在构建多用户 AI 协作,正确的顺序大致如下。

从读共享(read-sharing)开始,而不是写共享(write-sharing)。让多个用户观察同一个 AI 会话,看到彼此的消息和 AI 的响应,但串行处理每个用户的输入,并清晰地在视觉上指示 AI 当前正在响应谁的消息。这比同步写协作要简单得多,且仍能提供巨大的价值。

在需要之前就在基础设施中构建每用户身份(per-user identity)。在共享服务账户设计上追溯身份归属要比从一开始就构建它难得多。AI 发起的每一次工具调用都应该携带一个用户标识符。每一个输出都应该是可追溯的。这在调试和审计需求方面会立即获得回报,并使以后实现适当的权限范围管理成为可能。

将上下文窗口管理视为一等特性(first-class feature)。从第一天起就实现上下文归属:跟踪哪些轮次属于哪些用户,并在构建压缩逻辑时考虑到这种归属。丢失对他们来说很重要的历史记录的用户,对该功能的信任流失速度会比几乎任何其他失败模式都快。

推迟同步写语义,直到你有明确的产品需求证明其复杂性的合理性。分歧意图问题和上下文分叉问题确实很难,在准确了解用户协作时的具体需求之前,为通用会话解决这些问题可能不值得工程投入。

正确的问题不是“我们如何让我们的 AI 具备协作性?”,而是“用户需要什么样的具体协作工作流,支持它所需的最简基础设施是什么?”多用户 AI 会话不是一个可以添加的功能。它们是一个需要从一开始就设计的架构——或者是以后进行重大改造的承诺。

References:Let's stay in touch and Follow me for more thoughts and updates