在第 9 章中,我们看到注册表如何以结构化方式记录智能体、它们的元数据,以及对其进行约束的策略。但注册表本身是静态的;网格的真正价值,来自这些智能体开始彼此通信并协同工作之时。通信——无论是人与智能体之间,还是智能体彼此之间——驱动了网格中绝大多数活动,也正是它把“智能体目录”转变为“可运行的生态系统”。
本章将从“记录”转向“交换”。我们考察网格内发生的不同交互形态,分析任务如何被发起、上下文如何被保留、结果如何被跟踪。前面章节给出的是高层概览,而这里我们会更细致地拆解交互模式,展示它们如何支撑协同、信任与规模化。
那么,什么是交互模式(interaction patterns)?所谓 agentic mesh 的交互模式,是指智能体与人之间以可复用的方式交换消息、推进任务进展、并协调结果的做法。它们定义“谁与谁说话、走什么通道、携带什么上下文,以及对话如何推动状态前进”。从实践角度看,它们就是交通规则:确保成千上万个自治组件不会彼此“鸡同鸭讲”。
这些模式之所以重要,是因为“自治”并不自动等价于“协同”。如果缺少共同约定——如何启动一次交互、如何延续上下文、如何标记完成或错误——智能体要么卡住、要么重复劳动,用户也会失去对进展的把握。结构化模式提供了连续性(conversations)、作用域划分(interactions 与 steps),以及可观测性(状态、日志与告警)。它还让平台能够在每条流程的同一关键节点上施加护栏:身份、策略与认证检查。
在 agentic mesh 内,交互模式同时覆盖“人到智能体”和“智能体到智能体”。面向任务的交换,让人可以给某个特定智能体发消息,并把一个边界清晰的工作跟踪到完成。智能体到智能体的交接,让一个智能体无需人类介入就能把计划中的步骤委派给另一个智能体,并通过共享标识符保留上下文。工作区交互把模型扩展到面向目标的协作:多个智能体订阅同一条共享消息流,并依据策略或意图判断何时行动、何时保持沉默。合在一起,这些模式可以从单一请求扩展到复杂的多方工作流。
Agentic Mesh 交互管理(Interaction Management)
在网格内部,主要存在三种智能体交互方式,如图 10-1 所示;它们各自服务于不同目的,并以不同方式发生交互。第一种方式是用户与面向任务的智能体通信。这类交互从用户向网格中某个其认为能满足需求的特定智能体发送消息开始。智能体接收消息后,以任务导向的方式开始处理,直到处理完成,或进入无法继续推进的状态(例如缺少必需信息)。这类通信通过 interactions server 的 API 来处理,由其将信息路由到正确的位置。
图 10-1 不同交互类型
第二种方式是智能体到智能体的通信:当一个智能体联系另一个智能体,把它生成的行动计划中的某一部分责任委派出去时,就发生这种交互。在这种方式下,智能体彼此发送消息,并提供足以让接收方完成其任务的信息。此类智能体到智能体的通信是直接完成的:相关的 URL 从网格的注册表中检索获得,不需要 interactions server 作为中间入口。
第三种方式是工作区交互。如前所述,工作区是共享消息队列,被订阅它的任何智能体用作共享上下文。这使得这些智能体可以以目标导向的方式工作:订阅工作区的智能体自行判断如何达成目标。为了让用户启动这些目标导向的智能体,用户需要在工作区中创建一个目标(goal)并提交一条初始消息,告知其中的智能体它们应该完成什么。这会通过 interactions server 上的一组 API 来处理,但这组 API 与触发面向任务智能体所使用的 API 不同。
事件驱动通信(Event-Driven Communication)
当智能体在网格内通信时,仅靠标准的 HTTP 请求—响应并不够用。HTTP 默认端点是持续存在且可寻址的,并且假设同步可用性,这与智能体的运行方式并不匹配。智能体随时可能启动、停止、扩缩容、迁移,或暂停运行。这样的动态行为需要一种能够容忍异步活动与间歇性可用性的通信模型。
为此,我们认为,相比直接的 HTTP 通信,事件驱动架构更适合智能体。事件被发布到某些主题(subject)或通道(channel),任何订阅的智能体或服务都可以消费这些事件。这种设计将发送方与接收方解耦,使智能体能够独立运行,而不需要持续连接或直接寻址。它还支持消息持久化、重试机制,以及在多个智能体实例之间并行消费。因此,事件驱动模型能够在分布式系统中支持可扩展性、容错性与灵活协同。
HTTP 与事件驱动对比(HTTP Versus Event-Driven)
传统的 HTTP 通信非常适合那些固定、可寻址且持续在线的组件——比如注册表(registry)或交互服务器(interactions server)。这些服务运行在可预测的 URL 上,始终在线,并对用户或系统请求进行同步响应。然而,把这种模型直接套到智能体上会很快失效,因为智能体要动态得多:它们会随负载或管理策略被创建、暂停或终止;会跨主机迁移;也会水平扩展,生成多个实例来处理并发活动。在这样的环境中,维持稳定 URL、同步可用性与直接寻址,变得不切实际。
事件驱动架构通过解耦发送方和接收方来解决这些限制。组件不再把请求发往某个具体端点,而是把事件发布到某个通道或主题。任何对该事件感兴趣的智能体或服务订阅该通道,并在新事件到达时作出反应。系统不再依赖“知道某个智能体在哪里”或“它此刻是否在线”。通信变成异步、弹性且天然可扩展。
在这种模型中,消息队列与发布—订阅(pub/sub)系统构成了运行基础设施,使事件驱动系统能够在规模化场景下保持可靠与可观测。
消息队列:可靠投递与持久化(Message Queues: Reliable Delivery and Persistence)
如图 10-2 所示,消息队列确保每个事件都会被持久化保存,直到被消费。每个队列都充当生产者(发布者)与消费者(订阅者)之间的缓冲区,实现异步投递。这种持久化在智能体环境中至关重要,因为智能体可能会暂时不可用或频繁重启。消息会留在队列中直到被智能体取走,从而保证不会因短暂宕机而丢失通信。
图 10-2 事件驱动消息队列
通过为每个智能体分配一个具名队列,系统就无需关心该智能体的物理位置、宿主机或生命周期状态,通信仍可持续。负载均衡由队列系统自动管理——同一智能体的多个实例可以从同一个队列消费,按各自容量拉取消息。诸如 NATS JetStream、Kafka、RabbitMQ 等商用系统原生提供这些能力,从而减少自研基础设施的需求。
发布/订阅:动态且可扩展的分发(Pub/Sub: Dynamic and Scalable Distribution)
消息队列主要面向“一对一”或“负载均衡式”的可靠投递与持久化,而 pub/sub 将模型扩展到“一对多”分发。在 pub/sub 模式下,生产者把事件发布到某个逻辑主题或 subject,所有订阅该主题的消费者会同时收到事件。发布者不需要知道订阅者是谁、有多少个、位于何处。这种解耦使得大量独立的智能体、监控器或分析服务能够对同一事件流进行实时响应——并按其角色解释或处理数据。
在实践中,pub/sub 引入一层抽象,将消息生产与消息消费分离。事件被发布后,事件代理(broker)会把它路由到对应 subject 的所有订阅者。这让不同智能体可以并发响应同一信息:一个触发工作流,另一个更新仪表盘,第三个为合规记录日志。每个订阅者自主行动,但通过共享的事件织体(event fabric)保持同步。该设计支持规模化并发:成千上万的智能体可以并行处理事件,无需集中式协调,也不需要复杂寻址方案。
在 agentic mesh 内,pub/sub 同时为协同与透明性提供骨干。智能体可以订阅与其业务域或策略范围匹配的 subject,例如 mesh.financial.transaction.* 表示金融相关事件,或 mesh.infrastructure.alerts.# 表示监控告警事件。通过订阅特定 subject 层级,每个智能体把浩瀚事件空间过滤成与自身目的相关的子集。这种“选择性监听”确保智能体只对相关刺激行动,同时仍与系统整体保持松耦合。它也让新增智能体变得无缝:只要订阅已有主题,就立即成为网格持续事件流中的参与者。
Pub/sub 也构成网格可观测性的基础。监控组件(如 mesh monitor、registry observer)或外部分析服务可以订阅承载运行事件的同一组 subject,实现并行消费。这带来对“智能体在做什么、何时做、行为如何随时间演化”的完整可见性。由于订阅是非侵入式的,可观测不会干扰智能体正常运行;相反,它形成一层被动透明度,用于审计、调试与性能分析,而不会给消息流增加摩擦。
当 pub/sub 与消息队列和事件持久化结合时,架构会进一步增强。在许多现代系统(包括 NATS JetStream 与 Kafka)中,每个已发布事件都会被持久化存储在底层日志或流(stream)里。订阅者既可以在事件发布时实时消费,也可以通过回放历史日志在之后消费。这个混合模型统一了两类范式的优势:pub/sub 提供实时分发的动态性,而队列/流提供可靠性、缓冲与可回放性。二者结合,使系统既能“实时反应”,也能“事后分析”——这对分布式智能体的协同与治理是必需的双重能力。
从可扩展角度看,pub/sub 让网格成为“反应式系统”而非“命令驱动系统”。智能体不再下发直接指令,而是广播状态变化或结果事件,其他智能体自主决定如何响应。这把控制从集中式编排转向分布式协作,提升了韧性与吞吐,也为更高阶行为奠定基础,例如自适应扩缩容、涌现式协同与基于策略的响应——它们都依赖及时、透明的事件传播。因此,在 agentic mesh 中,pub/sub 不只是通信模式,更是让网格作为“集体系统”生长、适应并推理的基础机制。
事件回放(Event Replay)
事件驱动系统的关键优势之一,不仅在于实时传输消息,还在于能够在事后回放。事件回放意味着发布到系统的每个事件都可以被持久化存储,并在需要时重新消费,仿佛再次发生。诸如 NATS JetStream、Apache Kafka、Apache Pulsar 等平台把事件视为追加到日志中的不可变记录。每个订阅者维护一个独立指针(offset),表示其在日志中的消费进度。由于事件不会在投递后立即删除,订阅者可以把指针回退,并在任何时候重新处理早期事件。这种设计把消息织体变成了一个“时间型数据存储”:既保留历史通信的顺序,也保留内容。
在 agentic mesh 语境下,回放能力为分布式协同提供了透明的安全网。如果智能体在任务中途崩溃,或由新实例替换失败实例,它可以从中断处的确切事件继续执行。系统无需手工重建上下文,也无需向发送方请求重传;只要回放同一批事件即可。由于底层事件代理负责保留与 offset 管理,智能体在投递保障方面可以保持无状态。这一模型降低了开发复杂度,同时提升了跨智能体生命周期的容错性与连续性。
回放还增强了可审计性与可追溯性。网格中流转的每条消息——任务发起、计划更新、完成信号或错误通知——都可以被回放,以重建完整对话历史。监控器或审计人员可以回放某个时间窗口内的事件来验证合规或调试异常,而不干扰在线流量。在受监管环境中,重建智能体采取行动的完整序列,对取证与治理至关重要。与传统日志不同,可回放事件流不仅保留元数据,还保留完整载荷,从而支持在任意时间点的精确状态重建。
另一个重要收益是用于分析与学习的可复现性。由于事件不可变且可回放,分析型智能体或机器学习组件可以多次消费同一段历史数据,以测试新模型或评估算法变更。例如,一个优化智能体可以回放过去一个月的交易,衡量改进策略的假设表现;开发团队也可以在预发布环境中用生产数据回放进行仿真,而不影响在线系统。事件回放因此成为实验、回归测试与持续改进自治智能体行为的关键工具。
因此,事件回放为整个生态带来时间一致性。每个智能体或服务都能选择自己的回放起点,使网格具备在特定时刻推理系统状态的能力。这支持“时间旅行式调试”、确定性重计算,以及部分失败后的协同恢复。整体而言,这些能力把事件总线从短暂的传输层提升为持久的“系统记录”。通过将事件作为一等产物进行保存、索引与回放,agentic mesh 同时获得实时协同的即时性与耐久历史账本的可靠性——这对可扩展、可审计、且具韧性的智能体生态来说,是必不可少的组合。
监控队列(Monitoring Queues)
除了相较 HTTP 的优势之外,使用消息队列还能让 data mesh 的记录与监控更容易。要监控某个特定队列,网格只需为该队列再配置一个订阅者,它就会接收所有进入队列的消息。这对网格有多种用途。
为了让 data mesh 运行,消息不仅要交付给接收者,还必须被更大的网格记录与监控。正如本章后续会看到的那样,智能体依赖“当前对话”的完整历史——包括用户、其他智能体以及自身之间的交互——以提供执行任务所需的上下文。实现方式是让网格的 monitor 组件订阅用于智能体通信的消息队列。只要队列里新增一条消息,monitor 也会收到,从而把消息转为永久记录并存入注册表;之后需要时即可检索。
此外,把消息记录到注册表还能解决队列方案的一个少数缺点:消息持久化的时间跨度。消息队列通常围绕持续的新消息流设计,旧消息很少被回看,许多队列最终会把老消息“老化淘汰”。这对 agentic mesh 是个问题,因为某些任务与对话可能需要跨很长时间持续——从数天到数月,甚至数年。在这种情况下,消息队列并不是长期保存消息的最佳方式。注册表通过让旧消息在需要时仍可用,弥补了消息队列在长期留存上的不足,即使消息发送已过去数月或数年也能访问。
监控消息队列对希望实时观看对话展开的用户也很有价值,尤其是那些需要以对话方式与用户互动的智能体。虽然对话历史可以从注册表取回并展示,但在一切都经过消息队列的情况下,用户也可以直接订阅同一个队列,实时观察对话如何推进。这种可观测性帮助用户理解智能体在做什么,也帮助网格管理员理解网格在任一时刻的运行状态。
监控对 data mesh 的可审计性同样重要。尽管最终一切都会在注册表形成永久记录,但在审计系统时,实时观察消息在网格中流动,以验证系统“正在发生什么”,依然很有价值。同样,这也有助于调试网格。
用户与智能体通信(User-to-Agent Communication)
当用户与一个任务导向型智能体发起通信时,过程看起来很简单:发出一条消息,智能体给出回应。但随着交互变得更复杂,这种直线式模型很快就会失效。智能体往往需要额外输入才能完成任务,或必须同时管理多个任务。如果把每条消息都当作孤立事件,就无法把新增信息连接到正在进行的任务上——例如,就不可能恢复一个部分完成的流程,或补齐缺失细节。反过来,如果所有消息都共享同一个全局上下文,智能体又会被无关数据淹没,并且很容易把某个任务的信息误用到另一个任务上。agentic mesh 通过围绕对话(conversation) 与 交互(interaction) 来结构化通信,解决了这一问题:它提供了内建的层级结构,同时保留上下文与清晰度。
对话代表一条逻辑线程,把一组参与者——既包括人也包括智能体——之间所有相关交换连接在一起。如图 10-3 所示,每个对话包含用户与智能体之间多条消息的流动,且常常跨越多个通信通道。图中以可视化方式展示了这种关系:来自不同参与者的消息汇聚到一条共享的对话线程中,并以水平流表示。对话充当上下文记忆的容器,确保任何智能体接收到消息时,也能访问该对话关联的先前消息历史。这使每个参与者能够在充分了解既往交换的前提下对正在进行的活动进行推理——问过什么、答过什么、以及哪些仍需处理。
图 10-3 智能体—智能体与智能体—人通信
这种保上下文的设计带来若干实际收益。它让智能体能够复用先前已经提供的信息,减少用户摩擦并尽量避免重复录入。以开立银行账户为例:用户可能先完成身份确认并开新账户,随后再请求转账或申领借记卡。由于这三个动作都发生在同一对话内,智能体可以自动回忆用户身份与账户细节,而无需再次询问。在大型多智能体场景中,同样的结构确保每个参与的智能体都能访问对用户意图的共享理解,即便不同智能体分别负责工作流的不同部分。
在一个对话之内,网格引入了更细粒度的组织层级,称为交互(interaction) 。每个交互对应一个明确边界的独立任务——例如“开户”“转账”或“订购支票”。当一个新任务开始时,会被分配一个唯一的交互 ID(IID) ,用以与同一对话里其他并行活动区分开来。图 10-4 对结构进行了放大说明:更大的对话像一个容器,包含多个交互线程;每个交互线程由其各自的一串消息表示。IID 充当关联键(correlation key),把每条消息绑定到其对应任务,同时防止不同任务之间出现“误更新”(把某任务的更新串到另一个任务上)。
图 10-4 对话与交互
这种作用域隔离对网格扩展保持一致性至关重要。智能体处理某条带有指定 IID 的更新时,只会修改该 IID 对应交互的状态,而不会影响其他交互。例如,在银行账户场景中,如果“转账”交互因为余额不足而暂停,用户仍可以独立继续“订购支票”的交互。智能体之所以能自动区分这两种活动,是因为消息引用了不同的交互 ID。该结构允许在单一对话下并发推进多个任务,同时把各自进度隔离得可控、可管理。
因此,对话与交互共同提供了一套统一的连续性与控制框架:对话在相关交换之间维持共享记忆与上下文,交互则保留任务边界与执行流。这个分层方法可以无缝扩展:从简单的用户—智能体对话,一直到跨越多个智能体与时间区间的多方、多阶段工作流。
交互生命周期(Interaction Lifecycle)
网格中用户与智能体之间的每一次交互都遵循一个定义明确的生命周期。生命周期表示一个任务从创建、处理到最终完成或出错所经历的一系列状态。理解这一生命周期,是理解 agentic mesh 如何协调分布式工作、处理失败并在多智能体之间保持一致性的关键。图 10-5 以状态机的形式可视化了该过程,展示交互如何在不同阶段间推进,以及哪些事件会触发状态迁移。
生命周期从用户(或另一个智能体)发起新任务开始。这会触发创建一个新的交互,交互最初进入 “ground” 状态。此时交互已经存在,但尚未完全配置。智能体在这一阶段分配资源、登记标识符,并准备支撑数据结构。在图 10-5 中,这对应最左侧标注为 “ground” 的节点;当初始化完成后,它会直接连到 “ready” 状态。
图 10-5 交互生命周期
当初始化完成,交互迁移到 “ready” 状态。这表示所有先决条件已满足、智能体已准备开始处理,但尚未开始执行。在这一阶段,智能体通常会编译执行计划——识别完成请求所需使用的工具、外部智能体或数据源。例如,开户智能体可能准备的步骤包括身份核验、合规检查,以及在银行系统中创建新记录。计划组装完成后,交互进入 “working” 状态;在图中它位于中心枢纽位置,从这里可以发生多条后续迁移。
在 “working” 状态中,智能体开始对计划进行主动执行。它可能执行本地动作、联系其他智能体,或调用专用工具。如果进展顺利,任务会保持在该状态直至成功完成。但现实任务往往会遇到阻碍。如果智能体判断无法继续,因为缺少关键信息——比如用户未提供证件号码——交互就会切换到 “pending” 状态。在该状态下,处理暂停,直到缺失信息被补齐。用户提供所需数据后,交互会回到 “working” 并从中断处继续执行。如果在一段时间内仍未补齐信息,交互会自动从 “pending” 迁移到 “error” 。
“error” 状态表示智能体无法自主解决的情况——例如 API 调用失败、文件损坏或数据结构异常。此时交互会被挂起,等待外部干预。用户或管理员可以修复问题,使交互回到 “working”;或者判断无法解决,在这种情况下交互会直接迁移到 “complete” ,图中标注为“manually marked complete(手动标记完成)”。这种对不可恢复错误的显式处理,确保系统即便在异常场景下也能保持透明与可追踪。
最后,当所有必要步骤执行完毕、并且错误已处理(若有),交互进入 “complete” 状态。此时任务已成功结束,并从活跃交互列表中移除。智能体不再对其采取动作,但该交互记录仍会保留在对话历史中。这个归档步骤非常关键:已完成的交互既为未来对话提供历史上下文,也为分析、学习或审计提供数据基础。
对话(Conversations)
交互用于描述一个具有明确终止状态的单一任务的执行,而对话则可能包含多个相关交互,所有交互共享同一上下文。只要智能体收到一条属于某个对话的消息,它就会连同该对话的消息历史一起收到,使其能够利用既往交互来指导对当前消息的响应。
既然交互已经从开始到结束跟踪一个任务,你可能会问:为什么还需要把交互再分组到对话中?为什么不让交互彼此独立、彼此隔离地处理?答案是:上下文。在自然语言交流中,很多信息并不会被说话者显式说出,却能从对话上下文中被理解。例如,孤立地听到“把它放到台面上”,就会追问“它”指什么;但如果这句话是在对方刚让你打开一罐腌黄瓜之后说的,那么它的指代就显而易见。
继续用银行账户例子:用户可能先请求开户,这需要提供足够的个人与银行信息以完成开户;随后用户又请求寄送与该账户关联的借记卡。若把后者当作孤立交互,智能体可能不知道“这个请求指的是哪个账户”,这就要么迫使用户附带更多信息,要么让交互进入 pending 等待补充。但如果该交互发生在与“开户”交互相同的对话中,那么所指账户从上下文中就是明确的,智能体可以从先前交互中推断相关信息。这样就简化了向智能体发送新请求的流程,也显著提升用户体验——因为反复提供同样的信息对用户来说会非常烦人。
对话与交互端点(Conversation and Interaction Endpoints)
为了与对话或交互进行交互,交互服务器(interactions server)提供了一组 API 端点来支撑这些操作。用于检索现有对话与交互信息的端点已在第 9 章介绍,因此本节重点关注启动或修改对话与交互的端点。下文各小节所描述的端点由交互服务器提供;该服务器作为用户与智能体之间的中介。它们允许启动新的对话、交互与消息,以及关闭一个对话。
智能体到智能体通信(Agent-to-Agent Communication)
当一个自治智能体决定需要联系另一个智能体来获取信息,或把它不擅长的工作委派出去时,就会发生智能体到智能体的通信。这可能是因为对方在某个任务上更专业,或者因为当前智能体没有访问执行该任务所需工具的权限,又或者因为它在自身的执行方式(approach)中被明确要求这么做。不过,与用户到智能体的通信不同,这里不需要任何用户界面(UI),因此智能体到智能体通信的流程也与用户到智能体通信有所不同。
作为计划步骤的智能体(Agents as Plan Steps)
当一个智能体与另一个智能体通信时,本质上是在寻求帮助,以完成它被分配到的任务。那么,智能体如何决定要联系哪些智能体、按什么顺序联系?这属于每个智能体在接收新任务时都会经历的规划阶段(planning stage) 的一部分。
当一个智能体在系统中启动或重启时,它会先访问网格的注册表(registry)并取回自身的完整配置,然后从中获得:该智能体被允许通信的所有智能体、工作空间(workspace)以及工具(tool)的列表。这个信息会被缓存保存,直到该智能体收到某个交互(interaction)。
每当智能体收到一个新的交互,它做的第一件事就是拉取对话历史,以理解自己所处的上下文。该步骤需要去请求注册表,注册表会把完整的对话历史返回给智能体。随后,智能体会将这段对话历史作为上下文,再结合可用的智能体与工具列表,用于决定它的计划该如何推进。接下来会调用充当智能体“大脑”的大语言模型(LLM),并使用经过定制的提示词,让它生成一个任务计划(task plan)。这个任务计划由若干步骤组成,每一步都会调用另一个智能体或工具来完成流程中的一个环节,直到任务完成。
但是,计划一旦被构建出来,计划里包含的每个智能体都必须被实际联系,并被提供完成其任务所需的相关信息。
发送消息(Sending Messages)
与用户到智能体通信不同,智能体到智能体通信不会通过交互服务器(interactions server)作为用户与智能体之间的中介。相反,智能体会把消息直接发送到接收方智能体的消息队列(message queue) 中,由接收方智能体从队列中取走消息并据此执行。由于每个智能体监听的队列名称与智能体自身名称相同,因此发送方智能体始终知道应该投递到哪个队列。
不过,队列中的消息通常比较小,只包含那些在对话其他位置找不到的新增信息。为了获取对话历史,接收方智能体会使用对话 ID(conversation ID)去联系注册表,请求该消息所属对话的历史记录。注册表会把这段历史返回给接收方智能体,使其获得执行新消息所必需的关键上下文。这样,单条消息就可以保持很小、只包含新信息,而无需在智能体间的每次消息发送中重复携带对话历史的相关片段。其可视化如图 10-6 所示。
图 10-6 智能体到智能体通信
智能体到智能体通信使用与用户到智能体通信相同的对话机制:所有消息都存在于一个更高层的对话上下文之中,并且落在该对话内的某个交互(interaction)范围里。不过,虽然用户可以自主创建新的交互或对话,任务导向型智能体不能这样做(目标导向型智能体会在“工作空间(Workspaces)”一节讨论)。
当一个任务导向型智能体创建新消息时,它一定是在响应用户创建的消息或其他智能体生成的消息。如果是用户生成的消息,那么在智能体来得及基于该消息创建回复之前,交互服务器就已经创建了新的交互,从而使智能体可以使用新的交互 ID 来标注它要发送的消息。如果消息来自另一个智能体,那么该消息会附带一个消息 ID,接收方智能体会在它后续创建的新消息中复用这个消息 ID。两种情况下都有可复用的 ID,因此没有必要再创建新的 ID。
当一个智能体收到来自另一个智能体的新消息后,它会以“就像消息来自用户”一样的方式进行响应:利用其缓存的可访问智能体与工具信息,为它负责的那部分任务构造一个任务计划。这使得任意一条消息的接收方智能体都可以进一步去联系其他智能体,从而形成非常深的智能体调用嵌套。只要任务能够被拆解为适合这些嵌套智能体处理的子任务,就可以解决非常复杂的问题。并且由于每个智能体只负责整体任务中的一小部分,输出质量可以保持在较高水平。
用户告警(User Alerts)
在前面讨论的所有通信机制中,智能体都是交易中的接收方。但如果通信需要反向进行呢?如果需要通知用户某个智能体的行为呢?当然,定制化响应始终可以通过自定义工具按需处理,并使用任何你想要的通信机制;但这会给搭建这些智能体的人带来很高的工作量。为了减轻这种负担,并覆盖不适合做自定义工具的场景,agentic mesh 提供了一个告警(alerting)机制,让用户能够接收与智能体相关的信息。
当用户登录 agentic mesh 时,可以配置告警设置,用来决定网格如何从其对话或交互中生成告警。该控制主要体现在:用户创建的交互中,哪些状态变化会触发告警。例如,用户可能认为从 “working” 到 “pending” 的迁移就值得被通知,但从 “pending” 回到 “working” 不需要通知;又或者他们希望交互中的每一步完成时都生成告警。告警设置既可以作为用户级默认值配置,也可以对单个交互进行单独配置(当默认设置无法满足该交互需求时)。
当一个交互发生状态变化时,这个状态变化会由注册表处理,告警流程也从这里开始。注册表一旦记录到状态变化,就会查询其记录来确定是哪位用户发起了该交互。随后,它会检查该用户的通知设置,以判断这次状态变化是否应为该用户生成通知。如果检查通过,就会生成一个告警并写入注册表数据库。如果用户在告警生成时正处于登录状态,那么告警还会通过用户界面推送给他们;如果用户当时未登录,告警会保留在数据库中,待用户下次登录时再取回并展示。
然而,把告警完全留在 agentic mesh 系统内部,对所有用户来说未必是最佳选择。有些用户可能很少登录,导致许多告警在生成后很久都不会被看到。或者,用户希望对交互发生的任何事情都能快速获知,因为他们无法频繁保持登录状态。在这些情况下,与其他系统的集成能力可以增强该告警机制。最简单的方式是与电子邮件集成,让告警生成邮件通知用户正在发生的事件;当然也可以做其他集成。具体如何集成取决于你的用例与技术栈,因此应选择最适合你所处环境的方案。关于这些选项的高层可视化如图 10-7 所示。
图 10-7 告警流转(Alert flow)
Workspaces(工作区)
前面讨论过的通信机制,对任务导向(task-oriented) 的智能体非常有效:这类场景里通常有一个中心智能体,清楚知道要完成什么任务,并且具备构建执行计划的方法。
但并不是所有类型的任务都适合“任务导向智能体”的结构。比如,如果你想运行一个股票市场的仿真,当一条新消息进入时,可能需要多个智能体同时做出响应。如果把这种仿真强行放到一个中心智能体里运行,它根本无法生成你想要的那种行为。任何需要多个智能体并行工作、且没有单一高层智能体统一管理的目标,仅靠前述那些通信机制都不合适。**工作区(workspaces)**就是对此的答案。
到目前为止讨论的其他通信机制,本质上都是点对点(point-to-point)通信;而工作区代表了另一种范式。工作区是一种共享空间,智能体和用户都可以在其中发送消息,而这些消息会被多个用户或多个智能体看到。换句话说,工作区等效于一个消息队列(message queue) ,只不过它不是某个单一智能体专属的队列,而是多个智能体共同订阅的队列。这个共享空间使得用户发送的消息能够被所有订阅该工作区的智能体直接接收并处理;这些智能体会彼此独立地开始对消息采取行动。图 10-8 展示了工作区通信的可视化表示。
工作区通信示意图:用户与智能体将消息提交到一个共享消息队列;多个智能体都能接收,并把消息写回工作区,体现并行处理范式。
图 10-8. 工作区通信
Deciding to Respond(决定是否响应)
在任务导向智能体里,智能体被期望对收到的任何消息采取某种行动——无论是调用工具、调用其他智能体,还是创建并执行包含多个智能体/工具调用的计划。对于“只发给这个特定智能体”的消息而言,这很合理:除了它,还有谁会响应呢?
但在工作区里运行的智能体就不再是这样了。工作区中的每条消息都可能被工作区内的所有智能体收到,而并不是每个智能体都适合对每条消息作出响应。想象一个工作区里有 30 个智能体,如果用户发的每条消息都引发 30 个智能体一起回复,那场面会有多混乱——“难以跟进”都算轻描淡写。更别说当智能体开始互相回复彼此的消息时会发生什么了!为了让工作区可管理,智能体必须具备某种机制,用来决定:哪些消息需要响应,哪些不需要。
当智能体从工作区收到一条消息时,它的第一步就是判断是否应该对此消息做出响应。为了获得最佳效果,这个决策可以交给智能体底层的 LLM 来完成,因为它能够以智能方式解释复杂情境。系统会把当前工作区中的消息历史提供给 LLM,并询问:当前消息是否需要该智能体响应。LLM 还会给出其推理原因,以便维持对 agentic mesh(智能体网格)的可观测性(observability)。
不过在某些情况下,用 LLM 做决策可能有点“大炮打蚊子”,更简单的方法也能达到同样目的。例如,基于发送方智能体 ID 的允许列表(allowlist)/阻止列表(blocklist) :用来确保智能体不回复自己的消息,或只回复特定智能体发来的消息,从而在工作区内形成一定程度的层级结构。其他简单方法还包括对特定关键词进行检测。
更高级一些的做法是:对一条“示例消息”的向量嵌入(vector embedding)与当前消息的向量嵌入做余弦相似度(cosine similarity) 比较,让智能体只响应与示例在语义上相近的消息。或者,也可以比较与“一组相关关键词”的嵌入相似度,使智能体聚焦某个特定领域,而不是对某条示例消息的相似度。还有一种方法是:比较工作区内每个智能体的“相关字符串”的向量嵌入,只允许匹配度最高的那个智能体响应。尽管这会把一个消息限制为只有一个智能体响应,从而无法实现某些用例,但它在防止智能体用大量消息“淹没”工作区方面可能很有用。
这些方法在“判断该做什么”方面不如精心构造的 LLM 调用强,但它们以更低成本、更低时延的方式,完成了在工作区里判断是否响应某条消息的需求。每个智能体最适合采用哪种方法,将取决于它的具体用例与上下文。
Acting on Workspace Messages(对工作区消息采取行动)
这种“是否响应”的决策,会由工作区内的每个智能体对其遇到的每条新消息进行一次。完成判断后,每个认为“需要响应”的智能体,接下来会决定自己要如何响应。其响应方式基本与前文讨论过的方式一致——就好像该消息是通过该智能体的专属消息队列收到的一样:构建一个任务计划(task plan),其中包含对其他智能体或工具的调用。计划里的这些调用会通过各智能体各自的专属队列进行,通常不会直接涉及工作区;但工作区可能会作为上下文提供给下游智能体,使其具备完成任务所需的信息。
不过,这里的任务计划与之前讨论的也有几处关键差异。第一,它可能包含一个“respond-to-workspace(回应工作区)”工具:该工具接收一段字符串作为消息,并将其写回工作区,使智能体能够把最终输出或中间结果写回共享空间,让所有订阅者都能看到。
这会直接引出第二个差异:基于工作区构建任务计划时,智能体不需要把计划从目标的起点一路推到最终答案。因为智能体知道工作区里还有其他智能体,它可以构建只针对中间目标或中间结果的计划——这些结果对其他智能体可能有用。即使某个智能体只能看到部分解,它仍然可以对整体目标做出有意义的贡献:把自己得到的结果发回工作区,然后由人类用户或其他更合适的智能体接力,继续完成它未完成的部分。以工作区作为基础组件,这就允许构建更丰富多样的架构。图 10-9 展示了工作区如何促使智能体基于收到的消息来生成任务计划。
示意图:智能体根据从工作区收到的消息生成任务计划,展示不同智能体的响应以及对应的任务计划。
图 10-9. 智能体基于工作区消息生成计划
Workspace Goals(工作区目标)
到这里为止,我们对工作区的讨论似乎把它当成“内部结构很少的东西”,仿佛它只是一个消息队列。这个类比确实有用,但并不完整。当你把一组智能体放到一个共享环境里,会出现很多用例:同类任务会被反复执行,或者多个相似请求会同时涌入。如果工作区只是一个不加区分的消息队列,那么不同任务的消息就会混在一起,让工作区内的智能体产生混乱。
为避免这种情况,工作区中的消息会围绕目标(goals) 进行组织。目标是用户提供给工作区的一个目标对象:其中的初始消息会概述用户想要达成的事情。当第一条消息生成时,系统会给该目标分配一个目标 ID(GID),用于标识它属于哪个目标。后续针对该初始消息的回复消息,会被赋予同一个 GID,从而让所有与该目标相关的消息都能被归到同一组。
当智能体响应工作区中的一条消息时,它只会包含工作区历史中那些同样关联到该目标的部分;其他不相关的消息对它不可见,从而让不同目标彼此隔离。这种关注点分离(separation of concerns)使得工作区可以在不同目标之间复用,减少为这些目标所需的工作区与消息队列数量;同时也让某个目标的消息历史保持清晰聚焦,智能体只会拾取最相关的信息。在很多方面,一个目标在工作区里的作用,类似于任务导向智能体中的“对话(conversation)”:把相关消息归组在一起。
但目标在创建后并不是一成不变的。用户可以在目标创建后继续向目标添加新消息,用于给工作区中的智能体补充信息:这可能帮助卡住的智能体解阻,或提供澄清目标所需的上下文;也可能是当用户在监控工作区、发现智能体跑偏时,用来纠偏并重定向智能体。由于这些新增消息来自发起用户,智能体会把它们视为与目标更紧密相关的信息,相比来自其他智能体的消息会更“贴近目标”。
像一次对话或一次交互一样,工作区目标有一个定义好的状态,用于跟踪工作区当前所处的阶段。但与交互不同,工作区目标的生命周期更为有限:由于参与交互的智能体很多、且用户定义的目标可能比较含糊,系统只设置少数几种状态。目标在创建时处于 “ready” 状态,并一直停留在那里,直到收到第一条消息。随后目标会转入 “working” 状态,表示至少存在一条消息,智能体可能正在与其中的消息交互。目标的最终状态是 “complete” :通常由具有修改工作区权限的用户发起进入;当用户认为工作区已经达成目标时,会手动将其置为 complete;或者当工作区长期没有更新、超过某个足够长的超时时间后,也可能进入该状态。在 complete 状态下,工作区不能再添加新消息,也不会再对消息触发任何处理。该生命周期见图 10-10。
示意图:工作区目标生命周期,展示在用户交互与消息添加触发下,从 “ready” → “working” → “complete” 的状态迁移。
图 10-10. 目标生命周期
Workspaces as a Super-Context(把工作区当作“超级上下文”)
Agentic mesh 引入了 “超级上下文(super-contexts)” :一种共享的对话织网(conversational fabric),让多个智能体能够实时协同。把它想象成人类团队协作里的消息频道:每个人都能看到同一条讨论线索,知道发生过什么,也理解下一步是什么。超级上下文把同样的透明度与速度带到自治系统中,只是运行在机器节奏下。它为智能体提供一个共同的读、写、推理场所,把碎片化的任务串成连贯的流程。
它强大的地方不只是消息传递,而是共享记忆(shared memory) 。每个事件、消息、计划与结果都会在超级上下文中累积。新进入场景的智能体不需要“冷启动”;它带着历史而来:能看到既有决策、待办事项与未解问题,并且无需他人重复上下文就能采取行动。这种机制消除了多系统协作中常见的等待与传递损耗,用即时、知情的动作替代。
协同能力之所以可扩展,是因为智能体可以只订阅与自己角色相关的对话切片。观察者(observer)智能体监测外部信号并将其翻译成结构化事件;任务导向(task-oriented)智能体接手边界清晰的工作,调用工具、转换数据并汇报结果;目标导向(goal-oriented)智能体负责跨多步骤的结果编排,在条件变化时调整计划。这三类智能体都基于同一个超级上下文工作,因此贡献能够对齐而不是相互冲突。
该模型是事件驱动(event-driven) 的。智能体把事件发布到主题(subjects);感兴趣的智能体消费这些事件;对话织网会持久化并索引所有内容。发布/订阅(pub/sub)实现实时扇出(fan-out),使多个智能体能够并行反应;而持久化流(durable streams)提供可回放能力,用于恢复、审计与分析。最终形成的是:工作过程的“活记录”,以及关于决策“如何做、为什么做”的可靠台账(ledger)。
一个简单场景能说明它的运作机制:观察者检测到一个显著信号,将结构化事件写入超级上下文;目标导向智能体订阅该类事件后,将其转化为包含清晰步骤的计划;任务智能体领取与自身能力匹配的步骤,执行并把中间结果写回;当新信息到来,目标智能体会修订计划、取消或新增步骤并标记进度。没有人需要追问状态,因为状态就是对话本身。
由于每个智能体都能看到完整对话,它们可以判断何时开口、何时保持安静。相关性过滤(relevance filters)、策略(policies)与角色元数据(role metadata)用于抑制噪声,但可见性仍然保留。这种“环境式感知(ambient awareness)”正是超级上下文能够显著强化协同的原因:智能体不是在局部快照或私有孤岛上工作,而是从全局图景出发。通常需要交接与会议才能消除的误解,可以通过阅读同一份共享记录来解决。
超级上下文还会把结构形式化:Schema、消息类型与更高阶协议,使交互能够跨时间、跨团队被理解。你可以不必重新部署每个智能体就演进流程:新增字段、版本化状态、收紧策略、或以声明式方式调整路由规则。协同规则存在于“织网”中,而不是脆弱的点对点代码里,这使得大型生态系统更易治理与测试。
韧性(resilience)是内建的:如果某个智能体崩溃,替代者可以回放相关流并从中断处继续;如果计划因缺少信息而停滞,交互会进入一个对所有人可见的 pending 状态;当信息到达,执行继续推进。错误会进入明确的通道,并带有修复路径。生命周期是显式的——ground、ready、working、pending、error、complete——每一次状态迁移都会被记录。
随着时间推移,超级上下文会不断复利:历史对话成为更好 prompts、更聪明策略与更快计划的训练数据。成功与失败的模式能指导优化。新智能体加入后也能立刻产生效果,因为它所需的知识不是散落各处,而是编码在它可以查询与订阅的共享历史里。
我们认为超级上下文是一种协同加速器。它通过给智能体提供一个共享空间,让它们看到全局、决定自己能处理什么、并行贡献,从而把多个自治部件转化为同步的整体。这就是为什么它像是“给智能体用的 Slack”:一个可持久化、可搜索、实时的开放工作空间——而且因为参与者是 AI 智能体,所以它可以持续运行、规模化、并以速度取胜。
Summary(总结)
综合来看,交互管理(interaction management) 把整个 mesh(网格)从一个静态的注册表,转变为一个“活”的系统:对话(conversations)用来保留共享上下文;交互(interactions) 用清晰的标识符与生命周期把工作边界圈定起来;而一个事件驱动的织网(event-driven fabric) ——包括队列(queues)、发布/订阅(pub/sub)以及回放(replay)——让智能体在规模化场景下依然能够保持协同、可观测(observable)并且具备韧性(resilient)。用户可以启动有边界的任务,智能体可以在不丢失状态的情况下进行交接与嵌套计划,而工作区(workspaces) 提供了面向目标的协作方式:多个智能体看到同一条消息流,并自行决定何时采取行动。
本章确立了这些“行车规则”(rules of the road)——谁和谁说话、通过哪些通道、带着什么上下文、以及进展如何被记录——从而让协同变得可预测,而不是偶然发生。具备了这些机制之后,我们将在第 11 章转向让这类通信值得信任的防护措施:身份(identity) 、策略执行(policy enforcement) 以及 端到端安全(end-to-end security) 。