
同一个模型、同一套工具,可以做出两种截然不同的 Agent 系统:一种跑几个演示用例没问题,真实业务一上就乱套;另一种能稳定承接长任务、可观测、可恢复、可扩展。差别几乎不在模型,而在架构。
很多人把 Agent 架构理解成"画一张多角色协作的流程图",这是误解。架构要回答的是一组更底层的问题:决策发生在哪里?状态归谁所有?组件之间怎么通信?控制流是线性、分支还是并行?失败时系统如何降级? 这些问题的答案决定了系统的可测试性、可恢复性和扩展成本,而这些恰恰是 Agent 从 demo 走向生产的分水岭。
本文讨论的不是如何调用模型,而是如何组织一个 Agent 系统的骨架——五种主流架构模式的取舍、核心组件的边界、以及落到代码时的关键机制。
设计任何 Agent 系统,都要先回答四个问题。它们的组合,基本决定了架构形态。
第一,决策边界在哪里。 是让一个 LLM 负责全部决策(单体式),还是把决策分散到多个专职角色(多 Agent)?决策集中则链路清晰、调试简单,但复杂任务容易上下文过载;决策分散则各角色专注,但引入通信成本和冲突协调。
第二,状态归谁所有。 状态是保存在 Agent 内部、外部存储,还是由编排器统一持有?状态归属决定了系统能否恢复、能否并行、能否做 human-in-the-loop。状态藏在对象里,系统就不可恢复;状态显式外置,才谈得上生产级。
第三,组件之间怎么通信。 是直接函数调用、共享状态、消息队列,还是事件总线?通信方式决定了耦合程度。同步调用简单但强耦合,异步消息灵活但调试难度上升。
第四,控制流如何编排。 是固定流程(工作流)、模型驱动的动态循环(ReAct),还是状态机式的条件跳转?控制流的确定性程度,直接对应系统的可预测性和测试难度。
把这四个问题想清楚,架构模式的选择就是自然结果。
一个 Agent、一套工具、一个决策循环,模型在每一步选择工具或给出答案。这是最简单也最常用的架构。优点是链路短、易调试、成本可控;缺点是在任务复杂度上升后,上下文迅速膨胀、模型容易绕圈。
适用场景:边界清晰的单任务,如信息检索、单次数据处理、客服问答。这是绝大多数业务应该起步的形态。
先由规划器产出任务分解,再由执行器逐步执行,执行中可反馈修订计划。相比单体循环,它把"想"和"做"分离,减少无效步数。
适用场景:步骤可分解、目标明确的任务,如报表生成、多步数据加工。风险在于计划质量——计划错了,执行越努力错得越远,因此需要执行阶段的校验与回退。
把 Agent 的执行建模成显式状态与转移,每个节点是一段确定性逻辑或一次模型调用,边是条件跳转。相比自由循环,它把控制流显式化,可测试、可断点、可可视化。
适用场景:业务流程明确但含模型判断节点的场景,如审批流、工单处理、带人工介入的长流程。这是生产系统最值得优先考虑的架构,因为它把不确定性收拢到节点内部,而整体结构保持确定。
多个角色分工协作,如规划者、执行者、评审者,或按领域划分的专家 Agent。协作拓扑可以是主管—下属(hierarchical)、对等协商(peer)、或流水线(pipeline)。
适用场景:任务天然可分工、且单 Agent 上下文确实装不下的复杂场景。代价是通信开销、冲突处理、以及调试难度的显著上升。多数团队在没有明确证据前不应贸然采用。
Agent 不主动轮询,而是订阅事件、响应事件、发出事件。适合与外部系统松耦合、需要长时间驻留、或需要并发处理多路输入的场景。
适用场景:监控告警、实时数据处理、与消息中间件集成的后台 Agent。架构上更接近分布式系统,需要处理幂等、顺序、背压等问题。
选择原则不是"越复杂越先进",而是"用满足需求的最小架构"。 单体循环能解决的,不要上多 Agent;固定流程能覆盖的,优先用状态机而不是自由循环。
无论选哪种模式,一个可维护的 Agent 系统通常包含五类组件,边界要清晰。
编排器(Orchestrator) 持有控制流,决定下一步调用谁、何时终止。它是架构的骨架,应只做调度,不含业务逻辑。
Agent 单元 封装一次"决策"能力:输入状态、输出动作或结论。它可以是模型调用,也可以是确定性逻辑。把确定性部分做成纯函数,能大幅降低测试成本。
工具与执行器 负责与外部世界交互。工具应无状态、幂等友好、错误结构化返回。执行器负责超时、重试、限流。
状态存储 保存消息、进度、中间结果、检查点。它必须可序列化,且独立于进程。
可观测层 记录每次决策的输入输出、耗时、成本、失败原因,并支持关联到同一条追踪链。
组件边界的关键判断:去掉模型,系统是否还能被测试和观测? 能,说明架构把不确定性和确定性分开了;不能,说明模型调用渗透到了各个角落。
相比自由循环,状态机把控制流显式化。下面用最小实现展示节点、转移与检查点。
from dataclasses import dataclass, field
from typing import Callable, Awaitable
import json
@dataclass
class Ctx:
state: dict = field(default_factory=dict)
trace: list = field(default_factory=list)
Node = Callable[[Ctx], Awaitable[str]] # 返回下一个节点名
async def run_graph(nodes: dict[str, Node], start: str, ctx: Ctx):
current = start
while current != "END":
handler = nodes[current]
nxt = await handler(ctx) # 节点内部可含模型调用或纯逻辑
ctx.trace.append({"node": current, "next": nxt})
await checkpoint.save(ctx) # 每个节点后可恢复
current = nxt
return ctx.state
# 节点示例:模型只负责"分类",路由是确定性的
async def classify(ctx: Ctx) -> str:
label = await llm_classify(ctx.state["ticket"])
ctx.state["label"] = label
return {"退款": "refund", "技术": "tech"}.get(label, "human")
async def refund(ctx: Ctx) -> str:
ctx.state["result"] = await refund_service(ctx.state["ticket"])
return "END"要点:控制流由代码显式定义,模型只出现在需要判断的节点;每个节点后保存检查点,支持中断恢复;路由是确定性的,可单测。这就是"把不确定性收拢到节点内"的典型做法。
多 Agent 的架构难点是通信与冲突。用消息总线解耦,用显式消息类型约束交互。
from dataclasses import dataclass
from collections import defaultdict
@dataclass
class Msg:
sender: str
topic: str
payload: dict
correlation_id: str # 用于关联同一次任务
class Bus:
def __init__(self):
self._subs = defaultdict(list)
self._log = []
def subscribe(self, topic, handler):
self._subs[topic].append(handler)
async def publish(self, msg: Msg):
self._log.append(msg) # 全量留痕,便于回放排错
for h in self._subs[msg.topic]:
await h(msg)
# 协作拓扑:主管分配任务,专家处理,评审汇总
bus = Bus()
bus.subscribe("task.assigned", expert.handle)
bus.subscribe("task.done", reviewer.handle)
bus.subscribe("review.failed", supervisor.reassign) # 失败重分配,显式兜底要点:消息带 correlation_id,一次任务的完整链路可追踪;发布全量留痕,支持回放和归因;失败路径是显式订阅的,而不是靠隐式异常传播。多 Agent 系统如果没有这两点,几乎无法调试。
第一,把编排逻辑和业务逻辑混在一起。 编排器里出现业务判断、数据查询、提示词拼接,系统会迅速变成无法测试的泥球。编排只做调度。
第二,状态散落在各处。 一部分在对象字段、一部分在数据库、一部分在模型上下文里,导致恢复、并行、审计全部失效。状态必须单一归属、显式外置。
第三,用自由循环处理本该确定性的流程。 明明可以用固定步骤完成的流程,交给模型自由决策,结果是又慢又不稳定。确定性流程用状态机,模型只处理真正需要判断的节点。
第四,多 Agent 没有失败兜底。 角色之间互相等待、任务丢失、重复执行,没有超时、重试和冲突消解机制。多 Agent 本质是分布式系统,必须按分布式系统的标准设计。
第五,可观测性是后补的。 上线后才加日志,会发现关键决策点没有记录、链路无法关联。可观测性必须在架构设计阶段就作为组件存在。
第六,没有预算与终止控制。 步数、token、时间、费用都没有上限,一次异常就可能造成明显损失。护栏是架构的一部分。
务实的演进顺序是:先用单体循环验证业务价值;当任务步骤变多、需要人工介入时,改造成状态机式编排,把确定性流程显式化;当上下文确实装不下、或任务天然可分工时,再引入多 Agent,并用消息总线加显式失败兜底;当需要与外部系统长时间协同、并发处理多路输入时,考虑事件驱动形态。
检验架构是否健康的三个问题:控制流能否被画出来并逐步单测?去掉模型后系统是否仍可测试?一次失败能否从追踪日志里定位到具体决策点? 三个都能回答,架构就是站得住的。
Agent 架构的本质,是在"模型的开放决策"与"系统的确定控制"之间划一条清晰的界。好的架构不会让模型决定一切,也不会把流程写死到无法应对变化;它把不确定性收拢到少数需要判断的节点,把其余部分交给确定性的编排、显式的状态和可追踪的通信。当你不再把 Agent 看成一个"会自己干活的模型",而是看成一个由编排器、决策单元、执行器、状态存储和观测层组成的系统时,模式选择和技术决策都会变得清晰。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。