用配置驱动 MCP 接入企业数据湖
教程在 ECS Fargate 上部署无服务器 MCP 服务,为 Agent 提供安全、由元数据驱动的数据湖访问。新增数据集只需添加 JSON 文件,无需逐个编写集成代码。
AI 深度解读
企业给 AI Agent 接数据湖,最容易重复建设的往往是查表、生成 SQL、连接数据库和校验权限。每多一个助手,这些逻辑就可能再写一遍。AWS 这篇文章给出的办法,是把数据访问集中到 MCP 服务,让 Agent 共用工具,新数据集则通过 JSON 元数据接入。
作者团队已将这套架构用于 Amazon 北美分拣中心网络(NASC)的规划场景。他们测试的端到端耗时为 15–20 秒。对程序员更有参考价值的,是哪些知识适合写进配置,以及统一入口距离完整的权限治理还有多远。
为什么数据接入要独立于 Agent
作者面对的数据湖包含数千个数据集,涉及运营指标、业务分析等领域。多个团队各自开发助手,每个 Agent 都维护 SQL 生成逻辑、表结构知识和连接处理。表结构一变,就得逐个修补;接入一张新表,通常需要数天。
他们提出了四个目标:配置驱动接入、兼容不同 Agent、集中执行权限控制,以及适应突发负载。
真正值得复用的是稳定的数据访问工具,而不是某个 Agent 的实现。
架构因此拆成客户端、MCP 服务、工具、知识库刷新四层。工具层背后有一个元数据目录,保存表结构、字段含义和表关系。Agent 查询时再获取这些知识,不必把结构硬编码进每个应用。
MCP 在这里承担统一工具接口的角色。服务使用 Python 框架 FastMCP,通过 /mcp 暴露 JSON-RPC 接口,Amazon Q Developer、IDE 扩展等兼容客户端可以发现并调用工具。更换模型或编排框架时,数据访问层有机会继续沿用。
不过,协议统一并不会自动解决业务问题。表该怎么解释、哪些数据允许查询、SQL 怎么校验,仍然需要服务端实现。
一份 JSON 怎样让模型查对表
所谓「新增数据集只需一个 JSON」,前提是查询工具、索引流水线和数据访问链路已经搭好。JSON 描述的是如何理解一张表,不会替团队完成原始数据入湖或底层授权。
原文的元数据示例把业务说明、类型、真实取值和查询提示放在了一起:
{
"database_service_name": "athena",
"database_name": "analytics_db",
"table_name": "regional_order_summary",
"business_description_for_the_table": "Regional order history with shipping status and delivery performance. Contains completed orders with delivery data. Refreshes daily. In Athena SQL, always use date() to wrap string literals when comparing against timestamp columns.",
"column_details": {
"order_id [varchar]": {
"description": "Unique order identifier assigned at checkout.",
"sample_values": ["ORD-20250115-001234", "ORD-20250116-005678"]
},
"order_date [timestamp(3)]": {
"description": "Date and time the order was placed. Use this column for time-range filtering.",
"sample_values": ["2025-01-15 08:00:00.000", "2025-01-16 12:30:00.000"]
},
"warehouse_id [varchar]": {
"description": "Fulfillment center that processed the order.",
"sample_values": ["FC-EAST-07", "FC-WEST-03", "FC-SOUTH-12"]
}
},
"load_type": "Incremental (refreshes last 7 days)",
"refresh_frequency": "Daily at 6:00 AM UTC",
"table_size": "~2.1B rows",
"creation_time": "2024-03-15",
"last_refresh_time": "2025-05-20T06:00:00Z"
}
要重点看 business_description_for_the_table 和 sample_values:前者加入 Athena 的 date() 使用提示,后者告诉模型,仓库字段实际存的是 FC-EAST-07 这类编码,而不是自然语言地区名。
这比只提供字段名更有用。模型既要知道字段存在,也要知道业务问题对应哪个字段、过滤值长什么样。示例还描述了约 21 亿行、每天 UTC 6:00 刷新、增量刷新最近 7 天的数据特征,但原文没有证明模型会怎样利用这些信息优化扫描成本。
刷新流水线使用 Amazon Titan Text Embeddings 生成向量,再索引到 Amazon Bedrock Knowledge Bases。完成一次流水线同步后,新表即可被发现,无需重启服务或手动重新索引。
可选的业务上下文映射负责缩小候选范围。例如 package_data 指向 analytics_db.regional_order_summary 和 operations_gold.load_summary,labor_planning 指向 workforce.capacity_details。配置包含 description、tables,以及示例中为空的 sources.wiki、sources.quip。
不指定上下文时,Agent 搜索所有已索引表;指定后,只在相关表中检索。作者认为这能降低噪声、改善 SQL 准确率,并报告交互耗时为 15–20 秒,但没有提供启用前后的对照数据。
一次查询经过哪些环节,安全在哪里执行
用户从 Web 聊天、Slack 或 IDE 发起请求,经 Amazon Route 53、配置 HTTPS 和 AWS WAF 的公共 Application Load Balancer 进入客户端服务。客户端运行在 Amazon ECS Fargate,结合 Amazon Cognito 验证 JWT,使用 Amazon DynamoDB 保存会话,再通过内部负载均衡器访问私有子网中的 MCP 服务。
MCP 服务也运行在 Fargate,任务本身不保存会话。Amazon Bedrock 负责分析问题、选择工具和生成回答;查询工具先检索元数据,再生成 SQL,执行兼容性校验和自动修正,最后交给 Amazon Athena。架构中的 Amazon Redshift 也承担 SQL 查询后端,文档语义检索则由 Knowledge Bases 提供,数据摄取由 AWS Lambda 处理。
原文用下面的 SQL 演示「查上个月金额最高的 10 笔订单」:
SELECT order_id, customer_id, total_amount, order_date
FROM analytics_db.regional_order_summary
WHERE order_date >= date_add('month', -1, current_date)
ORDER BY total_amount DESC
LIMIT 10
要留意 WHERE 这一行:它从当前日期向前推一个月,而且没有结束边界,并不严格对应上一个自然月。SQL 能执行,不代表业务口径正确。
结构化数据与文档可以在同一轮组合查询,例如先查 Q4 退货率,再检索产品团队的原因分析,最后合成回答。
安全控制分布在多个位置:网络使用私有子网和内部入口;客户端校验身份;Athena 工具强制 SELECT-only,在执行前拒绝写操作;模型交互应用 Amazon Bedrock Guardrails,尝试过滤有害内容、检查回答依据并阻挡提示注入。所有工具调用以结构化 JSON 记录到 Amazon CloudWatch,形成统一审计入口。
我的判断
这套方案最有价值的地方,是把表结构知识从 Agent 代码移到可维护的元数据里。对于多团队、多助手共享数据湖的环境,它比各自直连数据库更容易统一修正和审计。但如果只有少量固定报表,预定义查询或参数化工具也可能更直接;原文没有给出两种方案的维护成本比较。
元数据缩小搜索范围,不能替代权限检查。
文章强调集中权限和多租户,但未展示租户身份如何一路传到工具、如何隔离可见表,也没有提供行级权限实现。按权限组限制敏感列,还是作者计划中的扩展方向。因此,兼容客户端共用 /mcp 说明了接口复用能力,尚不足以证明完整的租户隔离。
运行层面也要保留判断。Fargate 免除了 EC2 实例管理,会话外置有利于扩缩容,但容器服务、负载均衡器、配额和成本仍需管理。作者称系统能支持单次查询到数百并发,却未给出压测条件、错误率和费用。已报告的 15–20 秒也是交互耗时,不能当成所有数据规模下的承诺。
此外,示例 SQL 使用了元数据片段未列出的 customer_id、total_amount,原文没有补全字段定义。知识库如何及时发现真实表结构变化,也没说清。计划中的失败反馈机制尚未完成,不能视为已有能力。
能拿来做什么
- 开发数据查询助手时,可以先把字段业务含义、真实枚举值和引擎限制整理成元数据,再让 Agent 按需读取,减少提示词和应用代码里的重复维护。
- 给不同业务页面接入助手时,可以传入明确的业务上下文,缩小候选表范围;同时由服务端根据身份独立检查访问权限。
- 验收生成 SQL 时,应同时检查语法和业务口径,尤其是「上个月」、Q4、金额最高等条件,不能只以数据库执行成功为准。
- 多个内部助手开始共享数据工具时,可以考虑集中到 MCP 服务,并记录调用身份、工具和执行结果;是否采用整套 Fargate 架构,应结合并发、运维条件和费用再决定。