从 MCP 到多智能体:企业级 Agent 工程化落地指南

开发者/工程MCPA2A多智能体Agent工程化LLMOps2026-10-04

从 MCP 到多智能体:企业级 Agent 工程化落地指南

客户提了一个需求:「把 Agent 接到我们的 CRM 里,让它自己查订单、自己发退款。」听起来简单,真正动手时工程团队会卡在几个具体的地方:工具定义散在业务代码里,每接一个新系统就要改一遍 Agent 的 prompt;退款这种写操作该不该让模型自己决定;线上跑挂的 case 没法复现,改了 prompt 也不知道是变好还是变坏。

这几个问题在 2026 年有相对成熟的解法。MCP 负责工具和数据源的标准化接入,A2A 负责跨服务的 Agent 协作,权限、评测、成本、部署需要自己搭。

1. MCP、A2A 与多智能体架构选型

MCP 解决的是「Agent 怎么用工具」

Model Context Protocol 由 Anthropic 在 2024 年 11 月开源,基于 JSON-RPC 2.0,传输层支持 stdio 和 Streamable HTTP 两种。它解决的问题很窄:宿主应用和工具提供方之间,用什么格式交换能力描述和调用结果。

Server 侧暴露三类东西——tools(可调用的动作)、resources(可读取的数据)、prompts(预置的提示模板)。Client 侧把 sampling、roots 和 elicitation 暴露给 server。elicitation 是 2025-06-18 那版规范加进来的,允许工具在调用中途向用户追问缺失的参数,不用把整轮对话推倒重来。规范从 2025-03-26 那版开始支持基于 OAuth 2.1 的授权,Streamable HTTP 也是那一版引入的,替代了早先的 HTTP+SSE 方案。

协议本身不绑定模型,Claude、GPT、开源模型都能接。真正的收益在于解耦:工具代码只写一遍,换模型、换宿主、加新工具都不用动 Agent 主逻辑。内部有十个系统要接,每个写成独立 MCP Server,宿主侧只维护一份配置。

A2A 解决的是「Agent 怎么找 Agent」

Google 在 2025 年 4 月发布 Agent2Agent 协议,2025 年 6 月把项目捐给了 Linux 基金会。它同样跑在 JSON-RPC 2.0 上,用 SSE 推流。核心概念是 Agent Card——发布方在约定路径放一份描述,写清楚这个 Agent 能做什么、端点在哪、怎么鉴权。调用方读到 Card 之后发起任务,双方不需要共享代码,也不需要知道对方内部怎么实现。

判断要不要用 A2A,看一个条件:协作的双方是否在同一个代码仓库、同一个部署单元里。如果采购了第三方的客服 Agent,或者集团内两个事业部各自维护自己的 Agent,A2A 是合适的粘合层。如果只是 Planner 调两个 Worker,用框架内置的编排就够了。

选型对照

场景用什么原因
Agent 读数据库、调内部 APIMCP Server工具描述和鉴权从 Agent 代码里剥离,加系统不用重发版
接入采购的第三方 AgentA2A双方不共享代码和运行时,靠 Agent Card 协商能力
同进程内 Planner 调 Worker框架内置编排(LangGraph、OpenAI Agents SDK 的 handoff 等)拆成两个网络服务只增加延迟和故障点,没有换来任何隔离收益
跨事业部、跨云的 Agent 协作A2A组织边界清晰,各自演进互不影响
flowchart TD A[要接入的能力] --> B{是否由外部团队<br/>或第三方提供} B -- 是 --> D[A2A] B -- 否 --> C{是不是工具或数据源} C -- 是 --> E[MCP Server] C -- 否 --> F[框架内编排<br/>LangGraph / Agents SDK]

别把三者混着用。见过一个项目把内部两个 Worker 也写成 A2A 服务,结果每次任务多两跳网络调用,p95 延迟从 1.8 秒涨到 6 秒,排查了两周才发现是架构选错了。

2. 权限、沙箱与审计设计

给每个 Agent 一个独立身份

第一次上线 Agent 时,很多团队直接复用后端的 service account。出事之后翻审计日志,只能看到「某个服务调了退款接口」,看不出是哪个用户、哪次对话触发的。

正确做法是每个 Agent 部署实例拿一个独立身份,调用链上同时携带 Agent 身份和最终用户身份,两者都要落进日志。MCP Server 作为 Resource Server 必须校验 token 里的 audience,拒绝拿 A 服务的 token 去调 B 服务——这一步不做,水平越权在微服务架构里几乎必然发生。

权限切在工具粒度

  • 读操作和写操作分成不同 scope,订单查询和发起退款是两条独立权限
  • 参数在 Server 端重新校验,模型给的订单号、金额、租户号一律不信任
  • 跨租户访问单独拦一道,按 tenant_id 过滤,不依赖模型自觉
  • 金额阈值以上的写操作强制走人工审批,阈值写死在配置里,不写在 prompt 里

要执行代码就上真沙箱

Agent 如果需要在环境里跑测试、清洗数据、验证修复方案,容器加权限限制不算是沙箱,内核共享带来的逃逸风险是真实存在的。

  • 用 gVisor 或 Firecracker 做隔离,别直接跑在宿主机容器里
  • 网络出口做白名单,默认拒绝全部出站
  • 文件系统只读挂载,只有 /tmp 可写,并且设大小上限
  • CPU、内存、墙钟时间都设上限,超时强杀
  • 一次任务一个实例,用完销毁,不复用
E2B、Daytona 这类托管沙箱能省掉运维成本,接入前先确认数据出网是否符合内部合规要求。

审计日志至少要留这些字段

字段示例为什么需要
trace_id01JQ8X...把 LLM 调用、工具调用、最终回复串成一条链
agent_idcs-agent-prod-v3定位是哪个版本的 Agent 做的决策
principaluser:12345最终责任人,日志里不能只有服务账号
toolcrm.refund.create具体调了什么
args_hashsha256:9f3a...可追溯又不落敏感原文
decisionhuman:678 approved审批人是谁,还是策略自动放行
latency_ms / cost_usd2140 / 0.037单次调用的性能和成本基线
日志写进只追加的存储,应用侧没有删除权限。这一点在金融和医疗场景里是硬性要求,被审计问到的时候没有回旋余地。

工具返回的内容按不可信数据处理

prompt injection 最常见的入口不是用户输入,是工具返回的网页正文、邮件内容、工单描述。模型不是安全边界——所有工具调用在真正执行之前都要过一遍服务端策略检查,模型说「可以执行」不算数。客服场景里,用户上传的截图、转发的邮件都属于这一类。

3. 评测、可观测与灰度发布

评测集从线上日志来

手工编 50 条测试用例的问题在于,编出来的往往是团队已经想到的情况,漏掉的正好是那些让人半夜爬起来修的情况。

上线跑两周之后,从生产日志里采样 300 到 500 条真实请求,按意图、难度、是否涉及写操作分层。每条标注期望的工具组合和期望结果。之后每次改 prompt、换模型版本、增删工具,都跑一遍这个集子,看指标变化。

要盯的指标:

  • 端到端任务成功率,不是单步准确率
  • 工具选择正确率(选错工具比填错参数更致命)
  • 参数正确率(工具选对了但参数填错,实际更常见)
  • 平均对话轮数(轮数涨说明模型在原地打转)
  • p95 延迟和单次任务平均成本

埋点用 OpenTelemetry,别自己发明字段

OpenTelemetry 的 GenAI semantic conventions 定义了 gen_ai.* 属性集。按这个埋点,后端从 Langfuse 换到 LangSmith 或者自建,业务代码不用动。Langfuse 支持自托管,数据不能出内网的团队可以部署在自己机房。

一次 Agent 运行的 span 结构大致是这样:

  • agent.run(顶层)
  • llm.chat(第一次规划)
  • tool.call(crm.order.get)
  • llm.chat(根据结果决定下一步)
  • tool.call(logistics.track)
  • llm.chat(生成回复)
每个 tool.call 都要带 trace_id 和 args_hash,这样才能从一条用户投诉反查到完整的执行链路。

LLM-as-judge 先校准再用

拿模型当评委打分能省人工,但必须先校准:挑 200 条已经人工标注的样本,让评委跑一遍,看它和人的一致率。一致率不达标就别拿它做发布门禁,只能当参考信号。校准数据要覆盖边界情况,比如「用户表达含糊时该转人工还是该追问」,这类判断评委很容易给出和人不一致的结论。

灰度分阶段推进

  • 影子模式:新版本全量跑,输出不返回给用户,只对比和线上版本的差异
  • 1% 流量,只放行读操作工具
  • 10% 流量,放开写操作但保留人工审批
  • 50% 流量,观察一周
  • 全量
每个阶段看四件事:任务成功率有没有掉、p95 延迟变化、单次成本变化、人工接管率。人工接管率突然下降要警惕,很可能是 Agent 该转人工的时候没转,把风险藏起来了。

回滚要能一键切。prompt 版本、工具 schema 版本、模型版本都做成配置项,别硬编码在代码里。出事的时候改配置比发版快得多。

4. 推理成本与部署方案

成本大头往往不在对话本身

一次 Agent 请求的 token 消耗来自四块:系统提示加工具定义(每次请求都发)、对话历史、工具返回结果、模型输出。系统提示和工具定义是固定开销,工具越多这项越大——接了 20 个工具,光工具定义就可能占掉几千 token,用户还没说一句话。

三件最有效的事:

Prompt caching。 Anthropic 的缓存写入按基础输入价的 1.25 倍计费,命中按 0.1 倍;OpenAI 的 cached input 是基础价的 5 折。把系统提示和工具定义放在缓存断点之前,命中率能上去。具体价格以各家官方定价页为准,别拿旧数字做全年预算。

模型路由。 意图分类、参数抽取这类任务用便宜的小模型,只有真正需要多步推理的环节才调大模型。路由判断本身也可以是一个小模型。实践中能砍掉一半以上的支出,代价是要维护两套 prompt。

截断工具返回。 一个 CRM 查询返回 8000 字符的 JSON,模型真正需要的就 5 个字段。在 Server 端做字段投影,别把原始响应整个塞进上下文。这一步不做,上下文窗口会很快被无关数据填满,成本和延迟一起涨。

离线批处理场景(夜间跑报表、批量工单分类)用 Batch API,OpenAI 和 Anthropic 都是 50% 折扣,代价是延迟从秒级变成小时级。

部署形态怎么选

形态适合代价
云 API数据可以出网,要快速上线验证成本随调用量线性增长,模型版本受供应商节奏控制
私有化 vLLM / SGLang数据不出内网自己管 GPU,显存要按参数量 × 2 字节(fp16)估权重,再加 KV cache 和激活开销
混合入口用云模型做规划和意图理解,敏感数据走内网模型跨网调用要做脱敏和审计,链路变长
显存估算容易低估。7B 模型 fp16 权重约 14GB,但加上 KV cache 和运行时开销,24GB 卡跑起来并发一上来就要排队。实际部署要么上 INT8 / AWQ 量化,要么把并发限死。

5. 三个场景的具体做法

客服:读操作放开,写操作卡住

场景:用户在 App 里问「我上周的订单怎么还没发货」,Agent 要查订单、查物流,然后决定是直接回答还是转人工。

工具按风险拆开:

  • order.get(读,自动放行)
  • logistics.track(读,自动放行)
  • ticket.escalate(写,自动放行,但强制记审计)
  • refund.create(写,必须人工审批)
评测重点放在「该转人工的时候有没有转」。漏转带来的投诉成本远高于多转。灰度第一阶段只放开读操作,跑够两周、任务成功率稳定之后再考虑自动退款。

研发:沙箱里跑,别碰生产

场景:CI 挂了,Agent 去读日志、定位相关提交、给出修复建议,必要时在沙箱里跑一遍测试验证。

  • repo.read_file / repo.search:只读,指向代码仓库快照,不是生产代码
  • ci.get_logs:只读
  • sandbox.run:在 gVisor 隔离环境执行,无网络出口,5 分钟超时
禁止 Agent 直接推代码或修改 CI 配置。它的产出是 PR 草稿加一段解释,合并动作由人完成。这条规则要写在服务端策略里,不能只写在 prompt 里——写在 prompt 里等于没有。

金融:所有输出可追溯

场景:对账异常排查,从一堆流水里找出不平的那几笔并给出解释。

这类场景里,留痕比准确率更硬。每条结论要能回到原始凭证,做法是让所有工具返回都带 source_id,最终输出强制引用这些 ID,没引用到来源的结论一律不展示给业务人员。

禁止事项写死在服务端策略里:不能自动下单,不能修改客户账户信息,不能把明细数据发给外部模型。三条都要有对应的代码检查点,不能只靠文档约定。

这周能做的三件事

如果手上已经有一个跑在测试环境的 Agent:

  • 把工具定义从业务代码里抽出来,先挑两个只读接口写成 MCP Server,验证一下宿主侧能不能正常加载。
  • 给每次工具调用加上 trace_id 和 args_hash 日志,跑一天,攒出第一批评测样本。
  • 检查 Agent 现在用的是不是和别的服务共用的 API key,如果是,单独申请一个身份。

PREMIUM

需要完整版教程?

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

购买完整版 ¥29.90