MoEngage 如何借助 AgentCore Gateway 将 400 多个 API 变成智能体工具
本文由 MoEngage 的 Nikhil Kumar 和 Shakir Khan 共同撰写。
工程团队开始做 AI 智能体(agent)时,智能体需要的能力往往早就以内部 API 的形式存在了:创建活动、查询人群分群、查看投放效果统计。难点不在于开发新功能,而在于让智能体能安全地访问数百个私有 API——既不能把它们暴露到公网,也不能把身份控制权交给模型,还不能把几百个工具定义一股脑塞进上下文窗口。
MoEngage 正面临这个问题。它是一家提供智能体化客户互动能力的平台,超过 1350 个消费品牌用它通过推送、邮件、应用内消息、短信、WhatsApp 和 RCS 触达用户、提供个性化体验。产品背后约有 400 个内部 REST API,由 25 个工程团队开发,部署在七个 AWS 区域的私有虚拟私有云(VPC)中。为满足数据驻留要求,MoEngage 按区域隔离这些 API,并且不把它们暴露到公网。
智能体需要的能力其实早就在生产环境里跑着了,难的是安全地把它接出来。本文介绍 MoEngage 如何用 Amazon Bedrock AgentCore 中的 AgentCore Gateway,把这些私有 API 变成带权限范围的智能体工具。这套做法为 MoEngage 省下约六个月的平台工程投入,如今接入一个新 API 只需几小时,而不是几天。整个过程里,没有任何产品团队写过模型上下文协议(MCP,一种让智能体发现并调用工具的标准协议)的服务端代码,没有为每个集成单独配置网络,整条链路上也不存在任何公网端点。
为什么“20 个 MCP 服务器”是错误答案
MCP 为智能体提供了一套标准方式,用来发现和调用工具。最直接的做法,是让每个团队各自暴露一个 MCP 服务器。MoEngage 算过这笔账,最后否掉了这条路。
20 多个 MCP 服务器,就意味着 20 多个部署要监控、打补丁,还要跟着 MCP 协议的演进去保持兼容。而真正有用的跨域智能体——比如先读取一个活动、检查它的人群分群、再看投放统计——得连上好几个服务器,还要把它们的结果对齐拼起来。
同时,每个团队都得掌握 MCP,而这跟他们的产品工作没有关系。于是 MoEngage 定下一条原则,后续所有工作都围绕它展开:各工程团队不实现 MCP。团队只负责构建 REST API,并声明哪些操作应该变成工具。MCP 层由 AI 平台团队端到端负责。团队的职责止于一份描述清晰的 OpenAPI 规范。
这条原则立刻带来三个要求:一个集中的工具入口,智能体只连一次,不用按服务分别连接;按智能体做授权,并且在服务端强制执行,而不是靠约定;私有连接,每新增一个 API 都不用重做。从零自建整套系统也是一种选择。自建一个中央 MCP 服务器,能解决 20 个服务器的问题,但 MoEngage 还得自己做工具生成流水线、策略文件格式、用于重命名的工具别名注册表,以及熔断器。这些全是定制代码,全由一个团队维护,也都是没有差异化的基础工作——既不会让 MoEngage 的智能体更聪明,也不会让客户的营销活动效果更好。
塑造架构的四个约束
在评估任何方案前,MoEngage 先定义了四个约束。四个必须同时满足。只解决两个、却踩坏第三和第四个约束的方案,不可行。
任何东西都不能有公网端点。MoEngage 的内部 API 按政策只存在于 VPC 私有网络。任何方案只要要求把它们暴露出去,哪怕外面再加一层认证,都不在考虑范围内。
常见的变通做法是按集成单独组网:这里放一个 NAT 网关,那里放一个反向代理,第三个再拉一条 VPN 隧道。乘以七个区域,运维面扩大的速度会比智能体数量增长还快。每加一个新 API,就多一次网络变更申请、多一轮安全审查、多一块要维护的基础设施。
身份不能由智能体决定。每次内部 API 调用都带着租户、用户、角色和数据库上下文。如果这些上下文变成大语言模型(LLM)能看到的工具参数,模型就可能填错,也可能被诱导着改掉。
MoEngage 需要让身份信息在架构层面远离模型,由调用方服务注入,而不是作为模型可以设置或覆盖的内容暴露出来。400 个工具的目录根本塞不进上下文窗口。按每个工具约 50 个 token 的 JSON schema 计算,完整拉取一次 tools/list 要传输超过 20,000 个 token,而且每次连接都要传一遍。这些 token 在 agent 还没开始干活之前就花掉了,还挤占了 agent 真正用于推理任务的上下文空间。客户端过滤(ADK 或 MCP SDK 里的 tool_filter)解决不了这个问题——完整目录已经通过网络传过来了,而靠客户端约定做过滤根本不构成授权边界。一个不该看到写操作的 agent,一开始就不应该收到这些工具。最后这条约束,让 MoEngage 避开了那些显而易见但行不通的方案。自建一个中央 MCP 服务器能解决 20 个服务器的问题,但 MoEngage 还是得自己搭工具生成流水线、设计策略文件格式、维护工具别名注册表来处理重命名,还要做熔断机制。全是自定义代码,全归一个团队维护,没有一行能让 MoEngage 的产品变得更好。
AgentCore Gateway 如何对应这些约束
Amazon Bedrock AgentCore Gateway 是一个全托管的 MCP 服务器。你把 OpenAPI 规范注册为目标,网关就会根据规范生成 MCP 工具,然后把调用路由到后端服务。它的四个特性直接对应上了 MoEngage 的约束。
OpenAPI 进,MCP 工具出。 不需要构建或运维 MCP 服务器,也没有额外的产物需要和 API 保持同步。团队已经在维护的规范,就是工具定义。每个操作会变成一个名为 Target___operationId 的工具,比如 CampaignsAPI___searchCampaigns。规范变了,工具就跟着变。团队加一个端点,工具就出现;删一个端点,工具就消失。不用部署,不需要协议专业知识,也不用和 AI 平台团队协调。
Cedar 策略,在目录序列化之前评估。 AgentCore 的策略引擎使用部分求值(partial evaluation),按主体过滤 tools/list。
MoEngage 如何借助 AgentCore Gateway 把 400 多个 API 变成智能体工具
每个智能体都用自己的 IAM 角色(AWS 的身份与权限角色)完成身份验证,而它能看见哪些工具、能调用哪些工具,由各自对应的 Cedar 策略决定。正是这套机制,让 400 个工具变得可管理。它不是在拿到结果之后再到客户端过滤,而是在响应构造之前就在服务端划定范围。举例来说,一个营销活动质检机器人可以读取活动与分群相关的工具,但无法调用写操作:permit(
principal == Agent::"campaign-qa-bot-v1",
action == Action::"tools/call",
resource in ToolGroup::"campaigns-read"
);
forbid(
principal == Agent::"campaign-qa-bot-v1",
action == Action::"tools/call",
resource in ToolGroup::"write-actions"
机器人不会在 tools/list 响应里看到写操作工具。客户端无需做任何过滤,因为这些工具根本没有被下发。通过 Amazon VPC Lattice 实现托管出口。网关经由 AgentCore 托管出口访问 MoEngage 的内部服务,不需要 MoEngage 自建和运维网络。入站方向,网关只能通过带私有 DNS 的 VPC 接口端点访问,没有公网路径。接入一个新 API 只需添加一个目标,不用改动网络拓扑。正是这一点解决了“乘以七个区域”的难题——网络只建一次,所有 API 共用。语义搜索作为网关能力。借助 x_amz_bedrock_agentcore_search 能力,agent 可以通过描述任务来查找工具,而不必说出工具名称。这省去了自建发现层的需要,也顺带消除了重命名带来的脆弱性:如果 get_segment_user_count 变成 get_segment_size,agent 搜索“segment user count”仍然能找到它,因为匹配依据是描述而非标识符。架构实战。从 agent 到内部 API 的请求流程很短,每一层都有明确职责。Agent 服务通过 VPC 接口端点连接到 AgentCore Gateway,Gateway 评估 Cedar 策略,并通过 Amazon VPC Lattice 上的托管出口将工具调用路由到内部 API。下图展示了各组件如何连接。图 1:MoEngage AgentCore Gateway 架构。运行在 Amazon Elastic Compute Cloud(Amazon EC2)或容器中的 agent 服务调用 MCP 客户端。客户端可以是官方 MCP SDK、LangChain、Google ADK 或 MoEngage 自己的 agent runner。客户端使用服务已有的 AWS Identity and Access Management(IAM)角色,通过 SigV4 对请求签名。请求经 HTTPS 发送到带私有 DNS 的 VPC 接口端点,全程没有公网跳转。AgentCore Gateway 收到请求后评估 Cedar 策略,确定该主体能看到或调用什么,然后通过 Amazon VPC Lattice 上的托管出口将工具调用路由到内部 API。
MoEngage 在认证上做了两个值得一提的决定。第一,内部网关选用 SigV4 而不是 JWT。这里的 agent 本身就是已有 IAM 角色的服务,用 SigV4 可以直接拿现有凭证签名,不用再签发、轮换或存储新的凭证。至于面向公众的独立 MCP 服务器,它服务的是来自 Claude 等客户端、已完成人类认证的会话,所以在 AgentCore runtime 上使用的是 OIDC JWT。这是另一个接口面,需求也不同。第二,身份信息通过 header 传递,而不是放在工具参数里。租户、用户、角色和数据库上下文由客户端库从一个精简的 Identity 对象转换成 X-MOE-* 系列 header,模型既看不到也设置不了这些内容。有一个细节对想搭建类似系统的人很重要:由于 SigV4 签名要占用 Authorization header,调用方转发的 bearer token 必须挪到别处。MoEngage 的做法是用一个专门的 MoEngage 前缀 header 来传递。header 的传播范围也做了限制,所以这组 header 是精心挑选的,而不是越积越多。工具发现和工具执行对身份的要求不同:列出和搜索工具不需要租户身份,只有 tools/call 才需要。这样拆分让发现过程保持轻量,审计记录也清清楚楚——每个带身份的请求都对应一次真实的数据访问。即便用 Cedar 把 agent 限定在目录的一个子集内,这个子集也可能很大。MoEngage 的客户端库向模型只暴露一个元工具 search_tools。模型描述自己的需求,网关的语义搜索返回候选工具,只有这些候选在当轮对话剩余时间里变为可调用。整个目录不会进入上下文。agent 的上下文一开始只有一个工具定义,搜索之后也只有少量相关工具,而不是几百个永远用不到的定义。
接入一个新 API
一个团队要把某个 API 暴露成 agent 工具,只需在现有的 OpenAPI spec 里加一段:
paths:
/campaigns:
get:
operationId: listCampaigns
description: |
Returns a paginated list of campaigns. Supports filtering by
status, channel, date range, and tags.
x-moe-mcp:
expose:
external: false
internal: true
tool_description: |
Find campaigns by status or channel. Returns campaign ID, name,
status, and channel. Use the returned campaign_id with
get_campaign for full details, or send_campaign to launch it.
param_overrides:
status:
description: |
Filter by campaign status. Use 'active' for running
campaigns 表示查询进行中的活动,scheduled 表示查询即将上线的活动,不传则返回全部。这段配置里有四个设计决策值得说明。
是否暴露由团队显式开启。 一个接口如果没有 x-moe-mcp 配置块,它就不是工具。CI 也不会因为缺少这个配置块而报警,因为对大多数接口来说,“不暴露”才是正确状态。缓存预热路由、迁移触发接口这类东西本来就不该做成 agent 工具,也不应该有任何机制去暗示团队把它们做成工具。
借助 internal 和 external 两个标志,团队可以独立决定把一个操作开放给内部 agent、开放到公共 MCP 服务器,或者两边都开放。
工具描述不是 API 描述。 API 描述告诉读文档的开发者这个接口返回什么;工具描述告诉模型什么时候该调用这个工具、要传什么参数。MoEngage 发现,直接照搬 API 描述会让模型选错工具——模型会盯着实现细节(“返回一个分页列表”),而不是意图(“按状态或渠道查找活动”)。tool_description 和 param_overrides 这两个字段就是专门给团队留的位置,让他们写面向模型的文字,而不用改动面向开发者的文档。
从规范到可运行的工具,CI 流水线全包。 团队提交规范变更后,流水线会校验 x-moe-mcp 配置块、把目标注册到 AgentCore Gateway,并应用 Cedar 策略。全程没有手工步骤,也不用给 AI 平台团队提工单。一个从没接触过 MCP 的团队,只要等流水线跑完,就能把自己的操作变成 agent 工具。
客户端库提供两种模式。 插件模式把 AgentCore Gateway 的 MCP 服务器包装成 LangChain、Google ADK 或其他兼容 MCP 的框架里的工具提供方;Agent 运行器模式则跑一整套 agent 循环,适合想用独立 agent、又不想引入框架的团队。
MoEngage 目前的使用情况
MoEngage 的 AgentCore Gateway 部署目前覆盖七个 AWS 区域。网关向 10 个内部 agent 提供约 400 个已注册的 API 操作。没有哪个产品团队写过 MCP 服务器代码,没有哪个产品团队为 agent 集成配置过网络,也没有哪个产品团队实现过 Cedar 策略。
AI 平台团队负责这套体系的全部维护,接入一个新 API 的成本,只是一次规范标注加一次 CI 运行。AgentCore 的功能可用性因区域而异,支持的区域列表见 Amazon Bedrock AgentCore 文档。这套系统已经在生产环境运行了三个月。
这些智能体覆盖了营销团队成员每天都会接触到的工作流:活动 QA 智能体在活动上线前校验定向规则和内容;投递健康智能体监控各渠道的发送率和退信模式;细分构建智能体把自然语言的受众描述翻译成细分查询。每个智能体都用独立的 IAM 角色认证,只能看到其 Cedar 策略允许的工具,查找工具时只需描述任务,不用记住工具名。
过去要搭建并运维 20 个独立的 MCP 服务器,还要在七个区域为每个 API 配置网络。现在这些工作都不需要了,MoEngage 估计这套方案节省了大约六个月的工程工作量。接入新 API 从原先需要数天的网络配置和安全审查,缩短到数小时的规范标注。
“搜索优先”的模式改变了 MoEngage 对智能体设计的思考方式。新智能体启动时不含任何硬编码的工具引用,它们描述意图、接收候选工具,然后调用找到的工具。当某个团队重命名一个操作或发布新操作时,现有智能体无需改动代码就能自动识别。
结语
MoEngage 这套方案背后的关键洞察,是“关注点分离”,而且这种分离正好对应工程团队实际的分工方式:产品团队拥有 API,并负责把它们描述清楚;平台团队负责协议层、策略层和连接层。AgentCore Gateway 让这种分工变得可行,它消除了中间那些重复性的工作:不用写 MCP 服务器代码,不用为每个 API 单独配置网络,也不需要用客户端过滤来冒充授权。
最终得到的智能体系统里,添加新工具只需改规范,限制访问只需改策略,两者都不需要另一个团队介入。要开始使用 AgentCore Gateway,请参阅 Amazon Bedrock AgentCore 文档。要编写 Cedar 策略,请参阅 Cedar 策略语言参考。
私有连接方案可参考 Amazon VPC Lattice 文档。如果你的组织也想搭建类似架构,可以联系 AWS 客户团队,或直接联系 AWS 咨询。
关于作者
Nikhil Kumar:MoEngage CTO 办公室的首席软件工程师,带领 AI Labs 团队打造智能体(agentic AI)能力。他的工作涵盖 MCP 服务器与工具目录架构、大语言模型(LLM)网关与路由基础设施,以及为内部工具和面向公众的智能体体验评估各类智能体框架。他有 4 年以上构建大规模软件与云基础设施的经验。
Shakir Khan:MoEngage 架构师,负责 API 治理,并构建支撑公司客户互动平台的核心流式基础设施。他的工作涵盖网关架构、基于 Flink 和 Kafka 的实时流处理,以及大规模数据迁移。他有 11 年以上设计系统的经验,这些系统承载了数十亿次客户交互,其中 5 年在 MoEngage 度过。
Bhupesh Chadha:Amazon Web Services 的资深客户经理,与独立软件供应商(ISV)合作,帮助其平台战略与业务目标对齐。他与高管层和高级领导团队协作,推动业务增长、把新能力推向市场,并将技术投入转化为客户覆盖面和差异化优势。
Anant Murarka:Amazon Web Services 的解决方案架构师,与 ISV 客户合作设计多租户架构,并把 AI 驱动的方案落地到生产环境。他专精于智能体 AI、智能体编排模式、负责任 AI,以及帮助产品型公司在 AWS 上采用生成式 AI。工作之外,Anant 热衷于探索新兴 AI 范式如何重塑软件产品的构建与交付方式。
MoEngage 借助 Amazon Bedrock AgentCore Gateway,将分布在 7 个 AWS 区域的约 400 个私有 REST API 转成了权限可控的智能体工具。既不用为每个服务单独搭建 MCP(模型上下文协议)服务器,也没有暴露公网端点,更不会出现 400 个工具全部塞进上下文导致的臃肿。文章将介绍其中的实现方式:OpenAPI 规范、Cedar 策略,以及托管的 Amazon VPC Lattice 出口流量。