跳到主要内容

8 篇博文 含有标签「concurrency」

查看所有标签

并行工具扇出的结构化并发:谁来负责部分失败?

· 阅读需 13 分钟
Tian Pan
Software Engineer

当你的智能体(Agent)扇出五个并行工具调用——跨三个索引进行搜索、查询两个数据库、调用一个外部 API——的那一刻,你已经跨越了一道无形的界限。你不再是在编写“提示-响应”(prompt-and-response)代码,而是在编写一个并发程序。大多数智能体框架都假装你没有在这样做,而账单会在凌晨 2 点准时送达。

这种假象是令人愉悦的。规划器(Planner)发出一个工具调用列表,运行时环境(Runtime)启动它们,收集返回的任何结果,最后由规划器消费这些汇总数据。从万英尺的高空俯瞰,这就像一个扇出 / 扇入(fan-out / fan-in)流水线,大多数团队在生产环境给他们上课之前,也确实是这样对待它的。问题在于,二十年的并发编程研究——部分失败语义(partial-failure semantics)、结构化取消(structured cancellation)、背压(backpressure)、确定性错误归因(deterministic error attribution)——已经解决了你即将重新发现的那些失败模式。而你的智能体框架在默认情况下,没有引入其中的任何一项。

双写竞态:当你的智能体与用户同时编辑同一个日历事件时

· 阅读需 14 分钟
Tian Pan
Software Engineer

智能体自信地报告:“我已将会议改至周四下午 3 点。”用户却盯着原本周二上午 10 点的时段发呆,因为在智能体制订计划到提交更改的这段时间内,用户自己编辑了该事件。“最后写入者胜”(Last-write-wins)策略让自动化的操作覆盖了人类的修改,而用户对助手的信任也因这一次事故而崩塌。这就是双写竞争(dual-writer race),也是智能体工具链从未专门设计应对的 bug 类别。

大多数智能体平台都无意中继承了这一问题。工具层将 update_event 视为一个简单的函数调用:获取 ID,获取新字段,返回成功。底层的提供商 API 十多年来一直提供乐观并发原语(optimistic concurrency primitives)——ETags、版本令牌(version tokens)、If-Match 前提条件——但几乎没有人将它们贯通。模型无法知道它一分钟前所推理的世界已不再是现状,因为由于它所获得的抽象层静默地丢弃了这些信息。

你的评测框架是单用户运行的,但你的智能体并非如此。

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的 Agent 通过了 92% 的评估测试集。你发布了它。在上线一小时的真实流量中,发生了一些从未在任何追踪(trace)中出现过的事情:Agent 在频率限制(rate-limit)重试风暴中停滞不前,一个客户在工具响应中看到了另一个客户的草稿邮件,你的模型供应商连接池处于 100% 的占用率,而 CPU 却处于闲置状态。这些失败没有一个源自模型。它们存在于你测试的方式与生产环境运行方式之间的鸿沟中。

这个鸿沟表现为同一种形式。你的评估工具(eval harness)在一个固定数据集上一次循环一个 Agent。而你的生产环境则在共享基础设施上同时运行许多 Agent。顺序评估隐藏了每一个前提条件为“两个事物接触同一个资源”的 Bug。在你将对抗性并发(adversarial concurrency)构建到评估工具本身之前,这些 Bug 只会以紧急运维(on-call)报警的形式出现。

智能体集群并发:在没有死锁或惊群效应的情况下协调数十个智能体

· 阅读需 13 分钟
Tian Pan
Software Engineer

十一个智能体在同一秒内启动。在第一个工具调用返回之前,就有三个阵亡了。那 27% 的失败率不是模型问题、提示词问题或工具问题。这是一个调度问题 —— 就像操作系统在五十个进程同时唤醒并争抢单个 CPU 时所解决的问题一样。区别在于,操作系统拥有四十年的智慧积累,而智能体运行时只有大约两年。

任何连接过超过几个并发 LLM 工作节点的人都见过类似的情况。你在 02:00 启动一个定时任务,三十个智能体同时启动,它们在 200 毫秒内同时请求同一个提供商,结果大多数都以 429、502 和连接重置告终。幸存者只能获得承诺的一半速率配额,因为提供商的公平共享逻辑已经开始对你的 API 密钥进行节流了。到 02:05 时,幸存的智能体运行结束,你的仪表盘显示的完成率足以让一个刚写出第一个生产者-消费者的计算机专业大一学生感到汗颜。你的值班人员会争论是该增加重试、增加队列,还是干脆减少运行数量。

这些方法本身都不是正确答案。正确答案是:一个智能体集群是一个小型分布式系统,需要按照分布式系统的方式进行设计。

并行智能体系统中的隐性数据损坏问题

· 阅读需 14 分钟
Tian Pan
Software Engineer

当一个多智能体系统开始出现奇怪的行为——给出不一致的答案、丢失任务追踪、做出与早期推理相矛盾的决策——本能反应是责怪模型。调整提示词,换一个更强的模型,添加更多上下文。

真正的原因往往更平凡,也更危险:并发写入导致的共享状态损坏。两个智能体读取同一块内存,都计算出更新,其中一个默默地覆盖了另一个。结果状态在技术上是有效的——没有异常抛出,没有模式违规——但在语义上是错误的。之后读取它的每一个智能体都在对错误信息进行正确的推理。

这种故障模式在单个操作层面是不可见的,在测试环境中难以复现,仅通过查看输出几乎无法与模型错误区分开来。O'Reilly 2025年关于多智能体内存工程的研究发现,36.9%的多智能体系统故障源于智能体间的不对齐——智能体在对共享信息的不一致视图上运行。这不是一个理论上的顾虑。

多用户共享智能体状态:你真正需要的并发原语

· 阅读需 12 分钟
Tian Pan
Software Engineer

每篇智能体教程都从单个用户、单个会话和单个上下文窗口开始。智能体读取状态、推理、行动、写回。清晰、确定。对于团队实际使用的场景来说,这种假设完全错误。

真实的协作产品——共享规划看板、多用户支持队列、文档协作副驾驶、团队项目助手——需要多个用户同时与同一个智能体交互。当两个人在同一秒内向智能体发出相互矛盾的指令时,其中一个人的修改就会消失。智能体不会告诉他们,甚至自己都不知道发生了什么。

这就是多用户共享智能体状态问题,它是一个披着AI外衣的分布式系统问题。

并发智能体系统中的竞态条件:那些看起来像幻觉的 Bug

· 阅读需 15 分钟
Tian Pan
Software Engineer

三个智能体并发处理同一个客户账户更新。三者都记录了成功。最终数据库状态同时出现了三处错误,且始终没有抛出任何异常。团队花了两周时间怪罪模型。

问题不在模型。是竞态条件。

这是生产环境多智能体系统中被误诊次数最多的故障模式:由并发状态访问引发的数据损坏,因为下游智能体会基于损坏的输入自信地进行推理,从而被误认为是幻觉。模型并没有在编造内容,它只是在忠实地处理垃圾数据。

LLM Agent 中的并行工具调用:你可能尚未意识到的耦合测试

· 阅读需 11 分钟
Tian Pan
Software Engineer

大多数工程师之所以选择并行工具调用,是因为他们希望自己的 Agent 运行得更快。工具执行占 Agent 总延迟的 35–60%,具体取决于工作负载——编码任务处于高端,深度研究任务则处于中端。同时运行独立的调用是显而易见的优化方案。但接下来的情况却让大多数团队感到意外。

!["https://opengraph-image.blockeden.xyz/api/og-tianpan-co?title=LLM%20Agent%20%E4%B8%AD%E7%9A%84%E5%B9%B6%E8%A1%8C%E5%B7%A5%E5%85%B7%E8%B0%83%E7%94%A8%EF%BC%9A%E4%BD%A0%E5%8F%AF%E8%83%BD%E5%B0%9A%E6%9C%AA%E6%84%8F%E8%AF%86%E5%88%B0%E7%9A%84%E8%80%A6%E5%90%88%E6%B5%8B%E8%AF%95"]

一旦你启用了并行执行,工具设计中隐藏的每一个假设都会变得显而易见。在顺序执行时可靠工作的工具,在并发运行时可能会悄无声息地失效。原本稳定的行为变得不可预测,而且失败往往不会产生错误——只是在充满自信地返回一个错误的答案。

并行工具调用主要不是一项性能特性。它是一次非自愿的架构审计。