MCP/A2A 实战:企业多Agent系统架构与避坑指南

开发者/InfoQMCPA2A多Agent架构权限审计可观测安全护栏2026-10-01

客服系统里,一个用户要改发票。编排 Agent 把任务发给账单 Agent,账单 Agent 通过 MCP 调发票系统。Demo 能跑,上线后问题集中在四件事:工具谁注册、权限谁批、审计怎么查、两个 Agent 互相调用超时怎么办。下面按这四件事拆。

MCP 和 A2A 分别解决什么

MCP 由 Anthropic 在 2024 年开源,当前常用规范版本是 2025-06-18。它把 tools、resources、prompts 暴露给模型或 Agent,走 JSON-RPC 2.0。本地常用 stdio,远程用 Streamable HTTP 或 SSE。适合接数据库、文件、SaaS API。

A2A 由 Google 在 2025 年发起,后进入 Linux Foundation。它让 Agent 通过 Agent Card 发现彼此,用 Task 管理长任务,支持流式响应和推送通知。适合跨团队、跨进程、跨厂商的 Agent 协作。

两者互补。Agent 对外协作走 A2A,对内取数走 MCP。

维度MCPA2A
定位Agent/LLM 与工具、数据、提示的接口Agent 与 Agent 的任务协作
核心对象tools、resources、prompts、roots、sampling、elicitationAgent Card、Task、Message、Part、Artifact
传输stdio、Streamable HTTP、SSE;JSON-RPC 2.0HTTP(S)、SSE、JSON-RPC;Agent Card
状态单次请求为主,远程可流式长任务有状态,可查询、取消、推送
权限OAuth 2.1、资源指示器、scopeAgent Card 声明安全方案,OAuth2、mTLS、API Key
典型坑工具描述模糊、参数缺 schema、stdio 难多租户信任未验证的 Agent Card、重复任务、取消语义不清

工具注册:先定 manifest,再谈接入

不要允许 Agent 运行时动态注册工具。生产环境走审批。

每个工具至少登记这些字段:

  • tool_id:crm.contact.search,不要用 search。
  • mcp_server 和版本:crm-mcp@1.4.0。
  • JSON Schema:参数、返回、错误码。
  • scopes:crm.contact.read。
  • risk:low、medium、high。
  • data_class:public、internal、PII、PCI。
  • rate_limit:例如 20 QPS/租户。
  • owner 和 oncall。
  • health_endpoint。
  • audit_required:true 或 false。
注册流程:
  • 提交 manifest 和 schema。
  • 安全评审 data_class 和 scopes。
  • staging 跑契约测试,覆盖正常、缺参、越权、超时。
  • 生产灰度 5%,看错误率和 P95。
  • 异常自动下线,保留旧版本回滚。
工具名和描述直接进模型上下文。search 会让模型在 CRM、工单、订单之间乱选。写清 crm.contact.search 和边界,才能降低误调用。

权限:别把全量 token 塞给 Agent

编排 Agent 拿用户身份,专家 Agent 拿工作负载身份,MCP 网关换短期 token。每个工具调用做一次策略判断。

策略四要素:subject、action、resource、context。可以用 OPA/Rego 或 Cedar。高风险工具,例如 invoice.reissue、refund.create,要求人工审批或二次确认。

权限点放在 MCP 网关和工具服务两层。只在编排层卡,专家 Agent 或直连 MCP 的客户端能绕过。

角色能做什么不能做什么
用户发起请求直接调 MCP
编排 Agent拆任务、调 A2A拿长期数据库密码
专家 Agent处理领域任务、申请 scope越权访问其他租户
MCP 网关校验 token、脱敏、审计信任客户端传的 user_id
工具服务最终鉴权、幂等执行假设网关已经鉴权

审计:记到能回答“谁在什么时候让哪个 Agent 调了什么”

每次调用记录:

  • trace_id、a2a.task_id、mcp.request.id
  • user_id、tenant_id、agent_id、tool_id、tool_version
  • 参数哈希、脱敏参数、策略版本、策略结果
  • 审批人、审批单号、耗时、成本、错误码
  • 模型版本、prompt 版本、工具 schema 版本
审计库 append-only。敏感参数不要原文落库;需要重现问题时,用哈希关联原始加密存储。保留期按合规要求,例如 180 天。别只存请求日志,策略决策和审批记录一起存。

多 Agent 编排演示:改发票

场景:用户要求“上个月发票抬头写错,重开”。

sequenceDiagram participant U as 用户 participant O as 编排 Agent participant B as 账单 Agent participant M as MCP 网关 participant I as 发票系统 U->>O: 重开上个月发票 O->>B: A2A tasks/send B->>M: MCP tools/call invoice.get M->>I: 查询发票 I-->>M: 发票信息 M-->>B: 脱敏结果 B-->>O: 需要用户确认 O->>U: 确认重开 U->>O: 确认 O->>B: A2A tasks/send 确认 B->>M: MCP tools/call invoice.reissue M->>I: 执行重开 I-->>M: 新发票号 M-->>B: 成功 B-->>O: Artifact O-->>U: 新发票号

A2A Agent Card 示例:

{
  "name": "billing-agent",
  "url": "https://billing.svc.cluster.local/a2a",
  "version": "1.0.0",
  "capabilities": {"streaming": true, "pushNotifications": true},
  "skills": [
    {"id": "invoice.reissue", "name": "重开发票", "description": "处理发票抬头、税号、金额错误导致的重开"}
  ],
  "securitySchemes": {
    "oauth2": {
      "type": "oauth2",
      "flows": {
        "clientCredentials": {
          "tokenUrl": "https://auth.svc.cluster.local/token",
          "scopes": {"invoice.reissue": "重开发票"}
        }
      }
    }
  }
}

MCP 调用示例:

{"jsonrpc":"2.0","id":7,"method":"tools/call","params":{"name":"invoice.reissue","arguments":{"invoice_id":"INV-2026-0001","reason":"title_error","idempotency_key":"req-8f3a"}}}

编排伪代码:

async def handle(user_msg, ctx):
    task_id = new_task_id()
    with tracer.start_as_current_span('orchestrate') as span:
        span.set_attribute('a2a.task.id', task_id)
        span.set_attribute('user.id', ctx.user_id)

result = await a2a.send( agent='billing-agent', method='tasks/send', params={ 'task': { 'id': task_id, 'message': {'role': 'user', 'parts': [{'type': 'text', 'text': user_msg}]} }, 'metadata': {'trace_id': trace_id(), 'tenant_id': ctx.tenant_id} } )

if result['status']['state'] == 'input-required': return ask_user(result['status']['message'])

if result['status']['state'] == 'completed': return result['artifacts'][0]['parts'][0]['text']

return '任务未完成,已转人工'

伪代码,SDK 方法名按你选用的 a2a-python 或自研客户端调整。关键点:A2A 任务用 task_id 贯穿;MCP 写操作带 idempotency_key;高风险工具在网关拦一次,在发票系统再拦一次。

可观测:Trace 要串起 A2A 和 MCP

用 OpenTelemetry。一次用户请求一个 trace,A2A task 一个 span,MCP tools/call 一个 span。

指标用途告警线示例
MCP 工具错误率工具或服务故障5 分钟大于 2%
A2A 任务失败率Agent 协作故障5 分钟大于 3%
P95 端到端延迟用户等待大于 15s
越权拦截数策略或攻击突增 10 倍
每任务成本预算大于 0.5 元/任务,按实际预算改
日志脱敏。PII 不进 span attribute。参数用哈希。

评测:分开评工具选择、参数和执行结果

只看最终答案,会漏掉工具调用错误。拆成四层:

  • 工具选择准确率:该调 invoice.get 却调 invoice.reissue,算错。
  • 参数正确率:缺 tenant_id、金额格式错。
  • 任务完成率:A2A 任务到 completed。
  • 安全指标:越权拦截率、敏感数据泄露数、人工审批绕过数。
用回放集:把线上脱敏 trace 存成评测样本。每次改 prompt、换模型、升级 MCP schema 都跑一遍。

安全护栏:入口、工具、出口三层

  • 入口:输入过滤,越狱检测,租户隔离。
  • 工具:白名单、schema 校验、scope 校验、速率限制、沙箱、网络出口限制。
  • 出口:输出脱敏、引用来源、高风险操作二次确认、人工审批。
MCP 服务不要暴露公网除非必须。必须暴露时加 mTLS、OAuth 2.1、IP 白名单、请求体大小限制。A2A Agent Card 要验证来源。未签名的 Card 只当提示,不能当授权。

部署拓扑和代码仓库

flowchart LR U[用户/客服系统] --> GW[API 网关] GW --> ORCH[编排 Agent] ORCH -->|A2A| BILL[账单 Agent] ORCH -->|A2A| CRM[CRM Agent] BILL -->|MCP| MCPGW[MCP 网关] CRM -->|MCP| MCPGW MCPGW --> T1[发票系统] MCPGW --> T2[工单系统] MCPGW --> T3[邮件/短信] ORCH --> POL[策略引擎 OPA/Cedar] MCPGW --> POL ORCH --> OBS[OpenTelemetry Collector] MCPGW --> OBS OBS --> TRACE[Trace 存储] POL --> AUDIT[审计库] MCPGW --> AUDIT

仓库结构:

mcp-a2a-enterprise/
  agents/
    orchestrator/
      main.py
      prompts/
    billing-agent/
      main.py
      agent-card.json
    crm-agent/
      main.py
      agent-card.json
  mcp_servers/
    invoice_server.py
    ticket_server.py
    manifests/
      invoice.reissue.json
      crm.contact.search.json
  policy/
    rego/
      mcp_authz.rego
      a2a_authz.rego
  audit/
    schema.sql
    sink.py
  deploy/
    docker-compose.yml
    k8s/
      orchestrator.yaml
      mcp-gateway.yaml
      otel-collector.yaml
  eval/
    replay_set.jsonl
    run_eval.py

把这个目录推到你的 Git 服务。官方规范:MCP 2025-06-18 见 https://modelcontextprotocol.io/specification/2025-06-18 ,MCP 仓库 https://github.com/modelcontextprotocol/modelcontextprotocol ,A2A 仓库 https://github.com/a2aproject/A2A 。A2A 已进入 Linux Foundation。链接可能随项目迁移变化,以官方仓库 README 为准。

视频参考:B站、腾讯视频、优酷、抖音搜“MCP 协议”或“A2A Agent2Agent”,优先看官方账号或开发者大会回放。免责声明:第三方视频的观点和代码版本可能过时,以本文引用的官方规范为准;本文不嵌入链接,避免失效和版权问题。

避坑清单

  • 把 MCP 当 A2A 用。MCP 适合工具调用,长任务协作交给 A2A。
  • 信任 Agent Card。Card 是发现信息,不是授权凭证。
  • 工具描述写“查询客户”。模型会乱选。写清边界。
  • 只在编排层做权限。专家 Agent 可能直连 MCP。双层校验。
  • 审计只记请求。策略版本、审批人、参数哈希也要记。
  • 写操作没有幂等键。重试会重复开票。task_id 加 idempotency_key。
  • 多 Agent 没有预算和轮次上限。循环调用烧钱。设 max_turns、max_cost、timeout。
  • 流式响应无背压。SSE 堆积拖垮网关。限并发和 token 速率。
  • 评测只看最终答案。工具选择错、参数错会被掩盖。
  • 忽略协议版本。MCP 和 A2A 都在演进。注册中心记录版本,灰度发布。
下一步:选一个只读工具,例如 `crm.contact.search`,按上面的 manifest 字段注册到 staging MCP 网关。故意用缺 scope 的 token 调一次,确认策略引擎返回 deny,审计库能查到 trace_id、策略版本和拒绝原因。这个检查过了,再接写操作。
PREMIUM

需要完整版教程?

包含详细步骤、视频演示、提示词模板和可下载资料包。微信支付即时获取。

购买完整版 ¥29.90