从“超级 Agent”到能力平台:多 Agent 系统的架构取舍

61 阅读12分钟

当一家公司开始拥有多个 Agent,问题很快就不再是“如何做一个聊天机器人”。

产品团队会提出一个统一入口:用户只登录一次,在同一个会话中使用不同领域的能力。各个项目组则可能已经拥有自己的单页应用、HTTP 接口或 WebSocket Agent。平台还要统一用户身份、权限、模型选择、计费、日志和监控。更进一步,Agent 之间也要能够互相调用。

这类需求很容易把架构推向两个极端:

  • 所有东西都做成 Agent,再用一个“总父 Agent”负责调度;
  • 所有能力都拆成工具服务,Agent 只负责把工具串起来。

前一种方案会让简单能力变得昂贵而脆弱,后一种方案又可能把系统拆成一堆没有业务语义的微服务。更稳妥的答案不是二选一,而是先把“能力”“Agent”“平台治理”分清楚,再决定哪些东西需要独立部署。

一、先判断:手里拿到的到底是 Agent,还是一个调用适配器

现实中经常出现这样的交付物:一个 Skill 文件、一个 MCP Server,以及一段连接外部 WebSocket 的脚本。它在某个 Agent 宿主里可以工作,于是看起来像“已经接入了另一个 Agent”。

实际上,这通常只是下面这条链路:

宿主 Agent
  -> Skill 提示
  -> 本地 MCP 进程
  -> WebSocket 客户端
  -> 外部 Agent

这种方式很适合做验证:宿主 Agent 能否调用对方、协议是否能连通、会话标识能否续接。它甚至可以作为一个低成本的 PoC。

但它通常不能直接成为平台级能力,原因也很具体:

  1. 只返回最终文本,丢弃中间事件,无法提供真正的流式体验;
  2. 没有明确的取消、重连、幂等和运行状态;
  3. 只靠一个可提交的 sessionId 维持上下文,没有用户和租户绑定;
  4. 认证、计费和审计发生在平台之外;
  5. MCP SDK 版本变化就可能导致宿主无法发现工具;
  6. 一旦外部 Agent 和宿主 Agent 互相调用,还可能形成递归。

这说明一个重要事实:

Skill 和 MCP 可以是 Agent 使用能力的方式,但它们不等于平台的 Agent 互联架构。

二、为什么不应该把所有能力都包装成 Agent

Web 搜索、OCR、文件解析、向量检索、格式转换、数据库查询,这些能力当然可以各自配一个 Agent,但通常没有必要。

例如,搜索请求本质上更接近一个确定性接口:

web.search(query, filters, top_k)

如果先调用一个“搜索 Agent”,让它再理解一次“请搜索这个关键词”,系统就多了一次模型推理、多一层上下文和一套不可预测的输出格式。成本、延迟和故障点都会增加。

工具或能力服务更适合具有以下特征的功能:

  • 输入和输出边界清晰;
  • 结果可以结构化表达;
  • 不需要长上下文推理;
  • 需要统一限流、缓存、密钥和审计;
  • 有独立的计算资源或安全边界;
  • 会被多个 Agent 重复使用。

因此,下面这些通常应优先做成能力服务或工具:

能力推荐形态原因
Web Search工具服务参数明确,可统一限流和缓存
OCR能力服务计算密集,适合独立扩容和异步处理
文件解析能力服务多种文件格式,适合统一维护
知识检索数据/能力服务负责索引、权限和检索,不负责最终回答
记忆存取平台服务需要租户隔离、生命周期和权限控制
工作流执行工作流服务执行步骤应确定、可重试、可审计
MCP接入协议它描述“如何暴露工具”,不是一种业务能力

Agent 的价值则在另一侧:理解模糊目标、制定计划、选择工具、解释结果、处理领域规则,以及在必要时调用其他 Agent。

三、也不能把所有东西都拆成工具

如果所有能力都变成工具,另一个问题会出现:工具数量不断增长,但系统缺少业务语义。

一个合同审核过程可能需要:读取文件、提取条款、检索法规、识别风险、生成意见、触发审批。这不是简单地把六个工具平铺出来就结束了。谁来决定顺序?哪些风险必须人工确认?结果如何解释?这些问题需要领域 Agent 或工作流来承担。

可以用一个简单的判断方式:

确定性执行      -> 工具或服务
模糊目标理解    -> Agent
固定业务流程    -> Workflow
跨调用治理      -> Gateway / Control Plane

换句话说:

工具负责“做事”,Agent 负责“判断”,Workflow 负责“按规则执行”,平台负责“管住边界”。

四、推荐的分层架构

一个可扩展的多 Agent 平台,至少需要三层。

                         用户、外部系统、其他 Agent
                                      |
                                      v
        +------------------------------------------------+
        |          Unified Invocation Gateway             |
        |  身份、授权、路由、计费、配额、审计、追踪、事件流  |
        +----------------------+-------------------------+
                               |
              +----------------+----------------+
              |                                 |
              v                                 v
        +-------------+                   +-------------+
        | 能力与工具层 |                   | Agent Runtime |
        |             |                   |             |
        | 搜索        |                   | 通用 Agent   |
        | OCR         |                   | 领域 Agent   |
        | 知识检索    |                   | 编排 Agent   |
        | 记忆        |                   |             |
        | 文件处理    |                   +-------------+
        +-------------+

1. 能力与工具层

提供稳定、可复用、可结构化调用的能力。它可以是平台内的模块,也可以是独立服务,不必一开始就每个能力部署一个微服务。

例如,搜索、OCR、知识库检索和文件解析可以先由一个能力网关统一管理,内部根据负载再拆分。真正需要独立部署的依据应该是资源、故障域、团队所有权和安全边界,而不是“每个名词一个服务”。

2. Agent Runtime 层

承载通用对话 Agent 和领域 Agent。Agent 负责理解任务、组织上下文、调用能力以及生成解释性结果。

一个领域 Agent 可以调用工具,也可以调用其他 Agent。但它不应该直接知道其他 Agent 的真实网络地址,而应该通过统一调用入口按逻辑标识调用。

3. Unified Invocation Gateway

这是整个系统真正应该统一的地方。它同时处理两类调用:

Agent -> Tool
Agent -> Agent

两类调用都使用统一的调用记录、权限模型、事件格式、用量统计和追踪信息。这样就不需要为“工具计费”和“Agent 计费”设计两套体系。

五、是否需要一个“总的父 Agent”

不建议建立一个永久存在、所有请求都必须经过的总父 Agent。

原因不是中心化一定不好,而是“认知中心”和“治理中心”不应该是同一个东西。

一个总父 Agent 会带来:

  • 所有请求都增加一层延迟和模型成本;
  • 它成为推理和路由的单点故障;
  • 所有领域 Agent 都退化成它的工具;
  • 上下文越来越大,权限和费用越来越难归属;
  • 发生循环调用时很难判断责任边界。

更好的方式是:每个具体任务都有一个 root run,它可以由不同的 Agent 或工作流担任根节点。

例如:

root run: general-assistant
  +-- child: product-search
  +-- child: financing-policy
  +-- child: document-generator

另一个外部 Agent 也可以把通用 Agent 作为子节点调用:

root run: crm-agent
  +-- child: general-assistant
        +-- child: knowledge-search

这里的“父子关系”只属于某一次任务,而不是系统的永久层级。

如果确实需要动态拆解任务,可以提供一个可插拔的编排 Agent。但它应该是角色,不应该是全公司的唯一入口。能够用确定性工作流解决的问题,也不应该交给大模型临时规划。

六、统一调用协议比统一传输协议更重要

不同项目组可能使用 HTTP、WebSocket、SSE、MCP,甚至其他协议。强制所有团队使用同一种传输方式,通常会拖慢接入。

更值得统一的是调用语义。一次调用至少要有:

{
  "invocationId": "inv-123",
  "source": "general-assistant",
  "target": "product-search",
  "tenantId": "tenant-1",
  "userId": "user-1",
  "sessionId": "session-1",
  "runId": "run-1",
  "parentRunId": "run-parent-1",
  "deadline": "2026-09-23T12:00:00Z",
  "idempotencyKey": "idem-123",
  "input": {}
}

事件则至少需要区分:

run.accepted
output.delta
output.snapshot
progress
run.completed
run.failed
run.cancelled
tool.started
tool.completed
approval.required

尤其不能把所有文本事件都当作字符串直接拼接。必须明确它是增量、快照还是替换,并提供序号或事件 ID,才能支持断线恢复和重复事件去重。

七、统一身份、计费和监控

Agent 和工具最终都要进入同一套治理体系。

身份与授权

用户身份在平台入口终止。平台向下游调用签发短期、最小权限的 delegation token,包含:

tenant_id
user_id
source
target
session_id
run_id
allowed_scopes
expires_at

不要把长期用户 JWT、数据库凭据或其他服务的密钥直接交给 Agent。

计费

计费账本应记录完整的调用树:

parent run
  +-- Agent 模型用量
  +-- 搜索调用费用
  +-- OCR 处理费用
  +-- 子 Agent 调用费用

外部 Agent 可以按照 Token、调用次数、耗时或任务单价上报用量,但最终账本只能有一个事实来源,否则很容易重复扣费。

监控

所有调用都应该共享 trace_idcorrelation_idrun_idparent_run_id。这样才能回答:

  • 哪个 Agent 调用了哪个能力?
  • 总耗时主要花在哪里?
  • 哪个服务产生了费用?
  • 是模型慢、工具慢,还是网络慢?
  • 失败后是否发生了重复执行?

八、方案选择:平台适配器还是独立 Agent Gateway

这里常见的两个方案并不是完全互斥的。

方案 B:平台内置 Adapter

Platform Gateway
  +-- Tool Adapter
  +-- Agent Adapter
  +-- WebSocket Adapter
  +-- MCP Adapter

优点是上线快、运维简单,适合接入第一批能力。缺点是连接池、协议转换和外部故障会逐渐挤进平台主网关。

方案 C:独立 Agent Gateway

Platform Control Plane
  -> Agent Gateway
      -> Tool Services
      -> Agent Runtimes

优点是连接层可以独立扩缩容和隔离故障,也更适合多团队、多协议和 Agent-to-Agent 调用。缺点是早期会增加部署、鉴权和运维成本。

更实际的选择

如果目标只是接入一两个 Agent,先做 B。

如果目标已经是公司级 Agent 平台,不应把 B 作为终态。比较稳妥的路线是:

先在平台内部实现 C 的接口和数据模型,运行时先采用 B;当连接规模和并发达到阈值后,再把同一套运行时抽成独立 Agent Gateway。

这比第一天就拆出大量服务更务实,也比把所有连接代码永久塞进主网关更有余地。

九、哪些东西应该独立部署

不要按“名字”决定服务边界,而要按以下因素决定:

  • 是否有不同的资源需求;
  • 是否需要独立扩容;
  • 是否有独立的安全边界;
  • 是否由不同团队负责;
  • 故障是否需要隔离;
  • 是否有不同的发布节奏;
  • 是否需要独立计费或审计。

因此,OCR 可能很快需要独立的异步 Worker,但记忆服务未必需要单独部署;搜索可能使用统一网关和缓存,知识库索引则可能由独立任务系统处理。

“能力服务化”不等于“微服务化”。更准确的目标是能力边界清晰、调用协议稳定,部署方式可以随着规模演进。

十、建议的落地顺序

第一步:建立能力目录

先列出所有准备开放的能力,标记它们属于:

  • Tool;
  • Agent;
  • Workflow;
  • Data Service;
  • Platform Service。

同时记录每项能力的输入、输出、权限、计费单位、延迟目标和数据分类。

第二步:建立统一调用记录

先不要急着拆服务,先让工具调用和 Agent 调用都拥有统一的 invocation/run 记录、状态和事件。

第三步:建设统一 Invocation Gateway

把认证、授权、路由、限流、计费、审计和协议适配集中到一个边界。第一阶段可以和平台主网关部署在一起,但代码边界要独立。

第四步:优先接入可复用能力

先建设 Web Search、知识检索、文件解析、OCR、记忆等公共能力,再接入真正需要独立推理的领域 Agent。

第五步:引入 Agent-to-Agent 调用

先支持显式目标 Agent、父子 Run、超时、预算和调用深度限制,再考虑自动路由和复杂编排。

第六步:根据真实负载决定是否拆分 Gateway

当连接处理影响主平台稳定性、多个团队需要独立发布,或 Agent-to-Agent 调用规模明显增长时,再把 Invocation Gateway 抽成独立服务。

结语

多 Agent 系统真正难的地方,不是“让 Agent 互相发消息”,而是让这些调用能够被授权、被追踪、被计费、被取消、被恢复,并且在失败时不会互相拖垮。

因此,架构的中心不应该是一个永远高高在上的总父 Agent,而应该是一个统一的能力与调用治理层。

最终可以用四句话概括:

工具负责执行确定性能力;
Agent 负责理解、判断和解释;
Workflow 负责固定流程;
Gateway 负责身份、权限、计费、观测和边界。

当这四个边界清楚之后,Agent 可以增加,工具可以替换,协议可以演进,平台也不会被某一个项目组的实现方式绑死。