跳到正文
AWS Machine Learning Blog· Suntosh Murthy·· 4 天前精选AI 评分55

如何在 AWS 上使用 Denodo 和 Amazon Bedrock AgentCore 构建智能体 AI 语义层

Build a semantic layer for agentic AI on AWS with Denodo and Amazon Bedrock AgentCore

AI 导读

文章演示如何在 AWS 上使用 Denodo 和 Amazon Bedrock AgentCore 构建智能体 AI 语义层,让 Strands 智能体通过 Denodo MCP Server 查询 Amazon Aurora、Amazon Redshift 和本地 PostgreSQL 中的客户 360 数据。

推荐理由

文章以客户 360 场景串起跨云与本地数据联邦、用户身份传递和查询时权限控制,提供了构建受治理智能体数据访问层的具体路径。

正文 · AI 翻译

智能体 AI 应用需要受治理的实时企业数据访问权限。这些数据可能位于运营系统、分析型数据仓库、SaaS 应用、其他云或本地环境中。在本系列的上一篇文章中,我们使用 Stardog 的知识图谱,在 Amazon Aurora 和 Amazon Redshift 之上构建了 AWS 语义层。部署在Amazon Bedrock AgentCore上的 Strands 智能体查询了该语义层。Amazon Bedrock AgentCore 是一个平台,可使用任意框架或模型大规模构建、连接和优化智能体。本文采用相同的客户 360 模式,但换用了另一种语义层实现,并扩展了数据源组合。

这里有两处变化。首先,语义层采用 Denodo Platform:这是一个 AI 数据层,可提供主动上下文以及对分布式企业数据的实时零复制访问。智能体通过 Denodo 的 SQL 方言 VQL 与其交互。其次,数据源组合中加入了本地 PostgreSQL 数据库,与 Amazon Aurora 和 Amazon Redshift 并用,因此数据联邦不再局限于 Amazon Virtual Private Cloud (Amazon VPC)。

其余模式保持不变。Amazon Bedrock 上的基础模型负责规划并编写查询。Denodo MCP Server通过模型上下文协议 (MCP) 向智能体提供受治理的视图。Amazon Bedrock AgentCore托管智能体、终止入站身份验证,并管理智能体向 Denodo 提交的出站凭证。模型推理所需的一切都位于语义层中,而非提示词中:包括联接、指标定义,以及适用于调用方的行和列筛选条件。

读完本文后,你将了解:

  • 如何在 Denodo 中将 Amazon Aurora、Amazon Redshift 和本地 PostgreSQL 数据库进行联邦,整合为智能体可查询的单一客户 360 视图。
  • 如何通过 Denodo MCP Server 向由 AgentCore 托管的智能体公开该语义视图,以及如何将 MCP Server 注册为 AgentCore Gateway 目标。
  • 最终用户的身份如何从企业身份提供商,经由 AgentCore Identity 的代表用户 (On-Behalf-Of) 令牌交换,传递至 Denodo。
  • 全局安全策略如何在查询时应用行和列筛选条件。
  • Denodo 在 AWS 上的两种部署选项:全托管云服务 Agora,以及在 Amazon Elastic Compute Cloud (Amazon EC2) 或 Amazon Elastic Kubernetes Service (Amazon EKS) 上的自主管理安装。

我们假设你已熟悉上一篇文章:其中介绍了语义层架构是什么、用途是什么,以及为什么模型负责规划查询而不负责管理联接。如果这些内容对你来说比较陌生,可以阅读上一篇文章了解相关背景。

示例:数据源位于 AWS 之外的客户 360

我们继续使用上一篇文章中的相同客户 360 模式。前文使用的 Stardog C360 Knowledge Kit 为一家电商零售商建模,围绕两个主要用例展开:了解客户流失情况,以及识别适合自动加入奖励计划的客户。本文不会改变架构;变化之处在于一张表的位置:rewards_account位于本地 PostgreSQL 集群,而不是与其他客户资料数据一起存放在 Amazon Aurora 中。

这个数据源的位置并非特例。企业数据源可能位于 AWS 之外:本地环境中、CRM 等 SaaS 工具中,或另一朵云中。语义层必须能够连接到适用的数据源。在演示中,我们使用本地 PostgreSQL 来代表来自第三方应用程序的数据。扩展到其他数据源一节介绍了当数据源是 SaaS 工具、CRM 或大型机时需要做哪些调整。该节还介绍了Denodo 默认支持的其他数百种数据源。

Amazon Aurora(兼容 PostgreSQL):客户资料

表 关键列
customer cid (PK), first_name, last_name, email, ssn, phone, location
address id (PK), city, state, zip, street_name
credit_card id (PK), cid, card_num, card_type

Amazon Redshift:订单历史记录

表 关键列
order id (PK), cid, pid, order_date, quantity, price, card
product id (PK), name, brand, price, dept

本地 PostgreSQL:奖励计划

表 关键列
rewards_account id (PK), cid, account_id, create_date

共享标识符是 cid,一个普通整数,在 Aurora 客户表中作为主键出现。它也作为非外键列出现在 Amazon Redshift 订单表和本地 rewards_account 中。在 Aurora 内部,customer.location 列是指向 address.id 的整数外键,客户资料正是通过它与地址记录关联。两个引擎之间不存在跨引擎外键,也没有用于构建这种外键的 ETL 作业。要回答将客户与其购买记录及奖励计划注册信息关联起来的问题,必须在查询时协调 cid。

这一配置能够回答的一个典型问题是:“按终身消费金额排名前 20 的客户中,哪些还没有注册奖励计划?”这是 Stardog 工具包中的自动注册场景;要回答这个问题,需要从 Aurora 获取客户资料、从 Amazon Redshift 获取终身消费金额,以及从本地集群获取注册状态。

Denodo 会在执行时规划联合查询,决定哪些内容推送到 Aurora,哪些推送到 Amazon Redshift,从本地集群获取哪些数据,以及如何合并结果。数据不会在数据源之间移动;语义层只需定义一次,即可供所有使用者重复使用。

本文使用的 Denodo 术语

Denodo 将语义层实现为数据虚拟化平台。Denodo Virtual DataPort (VDP) 是其核心查询引擎:语义层对象存放于此,VQL 在此执行,访问策略也在此评估。Design Studio 是用于编写 VDP 内容的基于浏览器的界面。本文中建模的每个对象都在其中定义。

本文会反复提到三种对象类型。

  • 基础视图是源系统中的物理表、API 或文件与 VDP 中的逻辑视图之间的映射。Aurora 中的一张表对应一个基础视图。
  • 派生视图是一个 VQL 查询,基于一个或多个基础视图或其他派生视图。本文中的 customer_360 视图就是派生视图。
  • 度量视图只需定义一次业务度量(例如 lifetime_customer_value),其他派生视图即可引用它。度量视图将度量的定义与使用该度量的任何特定查询分离开来。

VQL 是 Denodo 的 SQL 方言。它是在 ANSI 标准基础上扩展的 SQL,并包含一组 Denodo 专用结构,尤其是用于表示数据源的 DDL 结构,以及用于语义指标视图的语法。在智能体场景中,VQL 的特定语法由一项技能提供,LLM 在使用 Denodo 工具时会调用该技能,以确保正确使用 Denodo 语法。

全局安全策略 (GSP) 是一种运行时访问控制规则,适用于带有特定标签的视图或列。GSP 用于在查询时强制实施行筛选和列掩码,并针对每个调用者进行评估。

如需更完整的参考资料,请参阅 Denodo Platform 文档。

参考架构

运行时包含两个流程。入站:客户端通过 Amazon Bedrock AgentCore Gateway 将用户请求发送给智能体。Gateway 会针对企业身份提供商 (IdP) 验证用于标识人类用户的 JSON Web Token (JWT),然后将请求路由到托管 Strands 智能体进程的 Amazon Bedrock AgentCore runtime。智能体调用 Amazon Bedrock 上的基础模型(本演练使用 Anthropic Claude Sonnet 4.6)来理解提示并规划查询。

出站:AgentCore Gateway 也充当智能体工具调用的出站代理。Denodo MCP Server 在 Gateway 上注册为一个 MCP 目标,因此智能体发起的企业数据工具调用会经由 Gateway 路由到 MCP Server。在请求到达 Denodo 之前,AgentCore Identity 会执行 代表用户 (On-Behalf-Of) 令牌交换,将人类用户的入站令牌转换为一个范围受限的访问令牌,该令牌代表同一用户,并以 Denodo 为受众。Denodo MCP Server 接受交换后的令牌作为持有者凭证,并通过 JDBC 将 VQL 请求转发到 Denodo Virtual DataPort (VDP)。VDP 会独立验证令牌,将调用者解析为 Denodo 角色,应用访问策略,并针对 Amazon Aurora、Amazon Redshift 和本地 PostgreSQL 集群规划联合查询。

只有 VQL 请求会下发到 VDP,结果集则会返回。源数据不会在引擎之间移动。Aurora、Amazon Redshift 和本地集群会响应由 VDP 联合优化器重写的原生 SQL。以下各节将详细介绍身份传播和策略强制实施。其他章节将介绍 MCP Server 注册和智能体部署步骤。

Figure 1. Inbound authentication path and outbound query path between the caller, Amazon Bedrock AgentCore components, the Denodo MCP Server, Denodo Virtual DataPort, and the three data sources.

图 1:调用者、Amazon Bedrock AgentCore 组件、Denodo MCP Server、Denodo Virtual DataPort 与三个数据源之间的入站身份验证路径和出站查询路径

构建语义层

Denodo 中的语义模型并非单一构件,而是由 VDP 中的基础视图、派生视图、指标视图和标签组成的集合,这些内容共同向使用者呈现具有业务含义的数据。本文所说的构建语义模型,指的是创建上述各个部分。

我们分三个阶段构建:在每个源表上创建基础视图;创建一个派生视图 (customer_360),在客户级别根据 cid 联接基础视图;再创建一个指标视图 (lifetime_customer_value),定义可复用的支出聚合,以便查询在需要时联接使用。

实际上,这种建模是在 Denodo Design Studio 中通过可视化方式完成的。你可以将 Aurora、Amazon Redshift 和本地部署的 PostgreSQL 数据源拖到画布上,在它们之间绘制联接,并通过表单重命名字段或更改字段类型(例如,将 cust_ref 映射到 customer_id),而不是手动编写 DDL。在本文后面介绍的安全策略,也是在同一个 UI 中附加的。

指标视图与引用它们的派生视图并列存放,定义一次即可重复使用。如果两个团队基于相同的基础数据构建了两个不同的客户级视图,两者呈现的指标定义也相同。

基础视图

在 VDP 中,每个源表都会成为一个基础视图。对于 Aurora 客户表,这意味着在 Design Studio 中使用特定连接器引入 Aurora,指定架构,并让 VDP 检查列。检查工作由 Design Studio 处理。生成的基础视图将物理列与其对应的 VDP 列一一映射,不会转换源数据。

创建时还需进行另外两项配置:

  • 用于治理的列标签。客户基础视图中的 ssn 会添加标签 pii_sensitive。credit_card 基础视图中的 card_num 也会添加相同的标签。这些标签是受治理的访问部分中定义的全局安全策略所绑定的对象。
  • 主键和联接字段。cid 在 aurora_customer 中标记为主键,并在 redshift_order 和 postgres_rewards_account 中标记为联接字段。如果源元数据中包含主键信息,Design Studio 会据此推断主键。否则,你可以在基础视图定义中设置一次。

对前面介绍的源表重复上述操作。最终会得到六个基础视图:Amazon Aurora 上的 aurora_customer、aurora_address 和 aurora_credit_card;Amazon Redshift 上的 redshift_order 和 redshift_product;以及本地部署的 PostgreSQL 上的 postgres_rewards_account。

Design Studio 还支持通过 Denodo Assistant 使用自然语言创作视图。开发人员可以用通俗的英语描述一个视图(例如,“在 cid 上,将 Aurora 中的客户资料与 Amazon Redshift 中的订单总额联接起来”),并获得一个候选 VQL 定义,然后可在同一画布中检查、完善并保存。完善过程是迭代式的:在最终确定定义之前,可以通过后续提示调整筛选条件、联接或字段映射。本节介绍的治理和类型规则仍适用于以这种方式创建的对象。

派生视图:客户 360

customer_360 是跨三个数据源的客户级视图,每位客户对应一行。订单详情和聚合数据则单独存放在我们接下来要定义的指标视图中。

CREATE OR REPLACE VIEW customer_360 AS
SELECT aurora_customer.cid,
aurora_customer.first_name,
aurora_customer.last_name,
aurora_customer.email,
aurora_customer.ssn,
aurora_address.city,
aurora_address.state,
aurora_credit_card.card_num,
aurora_credit_card.card_type,
postgres_rewards_account.account_id,
postgres_rewards_account.create_date AS rewards_since
FROM (
(
aurora_customer AS aurora_customer
LEFT OUTER JOIN aurora_address AS aurora_address
ON aurora_customer.location = aurora_address.id
)
LEFT OUTER JOIN aurora_credit_card AS aurora_credit_card
ON aurora_customer.cid = aurora_credit_card.cid
)
LEFT OUTER JOIN postgres_rewards_account AS postgres_rewards_account
ON aurora_customer.cid = postgres_rewards_account.cid;

该定义的两个属性对其余架构至关重要。首先,联接是在 Denodo Platform 中完成的,而非通过管道完成。没有 ETL 作业负责维护已具体化的 customer_360 表。VDP 在执行时解析联接:Aurora 返回资料和卡片信息,本地部署的集群返回奖励计划注册记录,VDP 则根据 cid 将它们合并。其次,该派生视图包含所有列,包括 ssn 和 card_num。

为了支持治理和 AI,我们还会添加元数据:为个人身份信息(PII)字段添加列标签,并添加视图及各字段的说明。Denodo Assistant 可以使用 LLM 来建议这些内容。后续章节将说明这些元数据的重要性。

Figure 2. The customer_360 derived view in Denodo Design Studio. Four base views appear on the canvas across the three sources, joined on cid and location. The ssn column on aurora_customer and the card_num column on aurora_credit_card carry the pii_sensitive tag referenced by the Global Security Policy in the Governed access section.

图 2:Denodo Design Studio 中的 customer_360 派生视图。画布上显示了来自三个数据源的四个基础视图,并按 cid 和 location 进行连接。aurora_customer 上的 ssn 列和 aurora_credit_card 上的 card_num 列带有 pii_sensitive 标签,该标签由 Governed access 部分中的全局安全策略引用

指标视图:客户终身价值

指标视图通过特定的 SOURCES/DIMENSIONS/METRICS 结构定义可重复使用的业务指标。完整语法请参阅 VQL 指南中的定义指标视图参考。lifetime_customer_value不属于customer_360。它与之并列,是一个独立对象:

CREATE OR REPLACE METRIC VIEW lifetime_customer_value
(
first_name, last_name, state, rewards_since, lifetime_spend, order_count, product_id,product_name, product_brand,product_dept, units_sold
)
SOURCES (
customer_360 AS customer_360,
redshift_order AS redshift_order,
redshift_product AS redshift_product
)
ASSOCIATIONS (
customer_360 redshift_order assoc_customer360_orders,
redshift_product redshift_order assoc_product_orders
)
DIMENSIONS (
customer_360(
first_name AS customer_360.first_name,
last_name AS customer_360.last_name,
state AS customer_360.state,
rewards_since AS customer_360.rewards_since
),
product(
product_id AS redshift_product.id,
product_name AS redshift_product.name,
product_brand AS redshift_product.brand,
product_dept AS redshift_product.dept
)
)
METRICS (
lifetime_spend AS sum((redshift_order.price*redshift_order.quantity)),
order_count AS count(redshift_order.id),
units_sold AS sum(redshift_order.quantity)
);

其他视图和外部报告工具可以像引用其他视图一样引用lifetime_customer_value。当业务规则发生变化时(例如,lifetime_spend应排除已取消的订单),只需在指标定义中更新一次。每个使用方在下次查询时都会获得更新,无需改动派生视图或下游应用程序。不同团队可以建立自己的派生视图,以传达各自业务线对业务的理解。基础数据保持共享,而语义解释彼此独立,因此任何一方的修改都不会影响另一方。

Figure 3. The lifetime_customer_value metric view in Design Studio. The SOURCES panel shows customer_360, redshift_order, redshift_product, the DIMENSIONS panel shows customer_360 and product views, and the METRICS panel shows lifetime_spend as SUM(redshift_order.price * redshift_order.quantity) , order_count as count(redshift_order.id) and units_sold as sum(redshift_order.quantity)

图 3:Design Studio 中的 lifetime_customer_value 指标视图,展示了定义 lifetime_spend、order_count 和 units_sold 的 SOURCES、DIMENSIONS 和 METRICS 面板

VDP 如何执行联邦查询

当代理运行示例中的自动注册问题(“按终身消费额排名前 20 的客户中,哪些尚未注册奖励计划?”)时,相应的 VQL 会使用指标视图计算结果集并评估所需指标:

SELECT first_name, last_name, state, EVALUATE_METRIC(lifetime_spend) AS lifetime_spend
FROM lifetime_customer_value
WHERE rewards_since IS NULL
GROUP BY first_name, last_name, state
ORDER BY EVALUATE_METRIC(lifetime_spend) DESC
LIMIT 20;

尽管此查询只引用了指标视图,VDP 的基于成本的优化器仍会规划联邦执行,并在相应数据所在的三个引擎之间进行协调。生成的计划大致如下:

  1. 下推至 Amazon Aurora:Denodo 将 customer、address 和 credit_card 的连接下推至 Aurora,返回客户档案字段,包括 first_name、last_name、state 和 cid。
  2. 下推至本地 PostgreSQL:Denodo 将 rewards_account 的投影下推,返回 cid 和 create_date。
  3. 下推至 Amazon Redshift:Denodo 将消费额聚合下推至 Amazon Redshift,作为按 cid 分组的 SUM(price * quantity)。
  4. 在 Denodo 内部合并:Denodo 按 cid 将 Aurora 档案结果与 PostgreSQL 奖励计划结果进行左连接,然后按 cid 将该结果与 Amazon Redshift 聚合消费额进行右外连接。Denodo 筛选 rewards_since IS NULL 的行,将指标计算为外层分组聚合(sum(sum) AS lifetime_spend),按 first_name、last_name 和 state 分组,按 lifetime_spend 降序排列,并最多返回 20 行。

该计划发挥了各数据源的优势。Amazon Redshift 负责聚合,Aurora 负责客户档案连接,因为三个档案表都位于其中;本地集群则返回少量奖励计划记录。VDP 处理最终的跨引擎连接和 Top-N 筛选,并使用三个紧凑的中间结果集,每个客户对应一行,而不是每笔订单对应一行。手写的数据管道通常也会采用大致相同的结构,但之后必须始终保持同步。

VDP 还会在最适合处理类型协调的位置执行转换。如果同一标识符在一个数据源中存储为整数,在另一个数据源中存储为字符串,VDP 会将类型转换下推到仍可根据转换后谓词进行筛选的数据源,而不是先跨引擎拉取数据,再协调类型。

Figure 4. The query flow from the C360 agent to Amazon Aurora, Amazon Redshift, and on-premises PostgreSQL and back. VDP rewrites one VQL request against customer_360 joined with lifetime_customer_value into source-native SQL per engine, collects the intermediate result sets, and joins them on cid inside VDP before returning the final rows to the agent.

图 4:从 C360 代理到 Amazon Aurora、Amazon Redshift 和本地 PostgreSQL,再返回的查询流程。VDP 会针对 customer_360 与 lifetime_customer_value 的联接,将一个 VQL 请求改写为各引擎的原生 SQL,收集中间结果集,并在 VDP 内部按 cid 联接,然后将最终行返回给代理

除了查询下推和按需联邦查询,VDP 还提供缓存、感知聚合的加速和点对点复制。在某些使用场景中,可能需要预先计算复杂转换;这些技术可与下推能力互为补充,同时保留访问控制规则和数据沿袭。

发布以便发现

如果语义视图只作为可查询的端点存在,就会留下难以发现的问题。下一个需要“客户终身价值”指标的团队,无从得知 lifetime_customer_value 是否已存在、它基于哪些内容构建,或还有哪些人依赖它。将 customer_360 和 lifetime_customer_value 发布到 Denodo Data Marketplace,可将其转变为可重复使用、受治理的企业数据产品,从而弥补这一缺口:这两个对象都会展示其 VQL 定义、所有权、业务说明、自定义属性,以及追溯至基础视图的数据沿袭。使用者可以按业务含义搜索,而不必了解架构。Denodo Data Marketplace 还提供其他面向非技术用户自助服务的功能,包括数据准备向导、管理员提供的认可和弃用说明,以及向数据产品所有者提出请求和提问的功能。

Denodo 还通过360 图谱扩展了这一功能,它围绕某个业务概念展示关系。该图谱会关联已使用 customer_360 的报表、仪表板、笔记本或代理工具,还会关联定义表中数据含义或使用条件的术语表等内容。使用者在编写查询前,可以查看数据集的相关上下文。

Figure 5. customer_360 Graph View listing in the Denodo Data Marketplace. The detail panel shows a BI Tool in Tableau Consuming the view and the Glossary Definition linked to the view.

图 5:Denodo Data Marketplace 中的 customer_360 图谱视图列表。详细信息面板显示了使用该视图的 Tableau BI 工具,以及与该视图关联的术语表定义

关于互操作性的说明

Denodo 中的语义模型以 VQL 定义,但 Denodo 原生支持通过多种开放协议公开任意视图。同一个 customer_360 视图可通过 JDBC、ODBC 或 ADBC 作为 SQL 访问;通过 Denodo GraphQL Service 作为 GraphQL 访问;通过 Denodo OData Service 作为 OData 2.0 或 4.0 访问;也可通过 Denodo MCP Server 作为 MCP 工具访问。在本次演示中选择 MCP,适合 AgentCore。无需额外建模,同一视图也可供 Power BI 仪表板、Tableau 工作簿或 Java 应用使用。

Denodo 还于 2026 年 3 月加入 Apache Ossie(孵化中)。该项目前身为 Open Semantic Interchange (OSI),是一项厂商中立的开源语义元数据规范。Apache Ossie 尚处于早期阶段,但其目标是让采用该规范的应用程序之间能够移植语义定义。尽管如此,Denodo 已可通过 Denodo Connects 与 SageMaker Catalog、Collibra、Purview 等其他数据目录共享元数据。

受控访问:身份传播与运行时强制执行

广泛覆盖各种数据源是企业级语义层的核心特征之一,但如果缺少运行时访问控制,这种覆盖范围也会带来切实风险。如果按用户进行的过滤写在代理的代码中,只需一次提示注入就可能绕过它。如果过滤写在 LLM 中,那它实际上就无处可寻。如果只在各个数据源系统中强制执行策略,那么策略可能不一致,也可能无法考虑跨数据源形成的业务含义。Aurora 不知道语义层中的“最高消费额”是什么意思,堡垒主机后面的本地 PostgreSQL 集群也不知道。而且,尤其是在混合本地系统和云系统的场景中,往往根本无法在所有系统中使用身份提供商。

该架构采用的方法是在语义层强制执行访问控制,并使用发起请求的用户身份,将其从 IdP 经 Amazon Bedrock AgentCore 端到端传播至 Denodo Virtual DataPort。

身份传播链

图 6 放大了图 1 参考架构中的身份部分,将从应用到 Denodo VDP 的出站路径展开为包含八个跃点的序列。以下编号步骤与图中的编号箭头一一对应。

Figure 6. Identity propagation and query flow from the user’s login through Amazon Bedrock AgentCore to Denodo (MCP Server and VDP) and the underlying data sources. Black arrows show the outbound identity and query path. Green dashed arrows show the return path with the filtered result set.

图 6:从用户登录经 Amazon Bedrock AgentCore 到 Denodo(MCP Server 和 VDP)及底层数据源的身份传播与查询流程。黑色箭头表示身份和查询的出站路径。绿色虚线箭头表示携带经过过滤的结果集的返回路径

  1. 用户通过企业 IdP 向应用进行身份验证。IdP 会返回一个 JWT,其中包含用户身份及属性声明——角色、区域、部门,以及 IdP 配置为发出的其他任何信息。
  2. 应用通过 AgentCore Gateway 调用代理,并将用户的 JWT 作为持有者令牌。
  3. Gateway 将请求路由至 AgentCore runtime,后者承载 Strands 代理进程。
  4. 代理调用出站工具时,AgentCore Identity 会执行代表用户的令牌交换,并返回一个新的访问令牌,其中 sub 声明为用户本人,aud 声明为 Denodo。
  5. 代理在 MCP 请求中将新访问令牌作为 Authorization: Bearer <access_token> 提交给 Denodo MCP Server。
  6. Denodo VDP 根据配置的 JWKS URL 验证 JWT,检查签发者和受众,提取 scope 声明,并将调用方映射到 Denodo 角色。
  7. VDP 在查询时评估全局安全策略,并向代理返回经过过滤的结果集。
  8. VDP 查询数据源以满足请求,并在返回结果前合并这些结果。

第 2 步中的 Gateway JWT 验证是可选的,因为 VDP 会在第 6 步重新验证令牌。启用 Gateway 验证后,格式错误的令牌会在请求路径中更早失败。

第 4 步中的令牌交换根据凭据提供方配置,使用 RFC 8693 令牌交换授权或 RFC 7523 JWT 持有者授权。凭据本身不会进入代理代码。AgentCore Identity 会在调用时注入凭据。

第 8 步中的调用方身份透传选项按数据源启用,并要求 Denodo 与数据源使用同一 IdP。适用时,调用方身份会端到端转发,从而在数据源端实现完整审计。

在 Denodo 中应用访问策略

Customer 360 数据受监管。例如,某些用户(人力资源人员、欺诈分析师)可能需要查看社会安全号码(SSN)和完整信用卡号等个人身份信息(PII)。但大多数用户(营销、分析人员)不得查看这些信息。

Denodo 为此提供了 全局安全策略,支持基于属性和角色的访问控制。全局安全策略是一条规则,适用于带有特定标签的视图或列,并在查询时根据调用者的角色和会话属性进行评估。底层视图无需重新构建。

为说明这一点,我们已将两个列(ssn 和 card_num)标记为 Aurora 基础视图中的 PII。我们创建一个全局安全策略 mask_pii_columns。

  • 适用对象:调用者的角色不是 hr_user。
  • 元素:适用于带有 pii_sensitive 标签的列。
  • 操作:用星号(****)进行掩码处理。

然后,我们定义两个 Denodo 角色。

  • hr_user:拥有 customer_360 的 Execute 权限。可以查看所有列。
  • marketing_user:拥有 customer_360 的 Execute 权限。由于策略适用,将看到 ssn 和 card_num,且它们显示为 ****。

当 marketing_user 运行 VQL 查询时:

SELECT cid, first_name, last_name, state, ssn
FROM customer_360
WHERE state = 'WI';

VDP 会在规划查询前评估全局安全策略。它发现 ssn 带有 pii_sensitive 标签,且调用者的角色不是 hr_user,因此会重写投影,为 ssn 返回 ***。

对于行级筛选(例如,只允许美国东部的分析师查看东海岸客户),同样的机制也可扩展使用。策略条件甚至可以依赖从 JWT 令牌映射而来的会话属性,或从外部表动态获取的会话属性。

关于负责任 AI 的说明

Denodo 的全局安全策略会在语义层筛选 PII,因此对于不应查看 ssn 或 card_num 的调用者,模型永远不会看到这些信息。即便如此,智能体的回复仍可能以自然语言复述客户标识符、位置或消费模式。对智能体输出,应采用与底层受监管数据相同的处理和保留策略:限制日志记录和对话记录存储的范围,应用 Amazon Bedrock Guardrails 控制内容和敏感主题,并限制可读取回复的人员。如需更全面的指导,请参阅 Amazon Bedrock 中的负责任 AI。

跨层审计与可观测性

请求路径中的每一层都会独立记录日志。AgentCore 运行时会将调用记录发送到 Amazon CloudWatch。AgentCore Gateway 会记录入站 MCP 请求,包括调用者的 JWT sub 声明。Denodo MCP Server 会将工具调用记录到自己的日志中。Denodo VDP 的审计日志会捕获完整的 VQL 请求、映射后的 Denodo 角色、解析后的联合计划以及策略评估结果。

这些日志也可以纳入 Amazon CloudWatch。当需要将每个数据源的审计记录关联到实际用户时(例如,为满足 HIPAA 或 SOX 合规要求),请为这些数据源的基础视图配置直通式会话凭证,以便 Denodo 在数据源支持的情况下将调用者身份转发到源系统,而不是依赖服务账户。

通过 Denodo MCP Server 暴露这一层

Denodo MCP Server 是位于 MCP 客户端和 VDP 之间的附加组件:下载发行包、解压、编辑 config/application.properties,然后启动。服务器会在 http://<mcp-host>:8080/<database>/mcp 监听可流式传输的 HTTP MCP 请求,并通过 JDBC 将请求转发到 VDP。

本演练中有三个重要的配置值。

  • mcp.security.oauth2.enabled=true:接受入站 MCP 请求中的 OAuth 2.0 bearer 令牌。与 VDP 的 OAuth 验证器配置配合使用时,该令牌会转发到 VDP 进行验证和角色解析(另请参阅受治理的访问部分)。
  • vdp.datasource.jdbcUrl=jdbc:vdb://<vdp-host>:9999/:VDP 的 JDBC URL。每个请求所针对的具体数据库由 MCP 端点路径指定。
  • mcp.visibility.tags=mcp 控制 MCP Server 中可见的视图。如果已定义,则只有至少带有这些标签之一的视图才会显示。

该服务器实现了 MCP OAuth 2.0 授权流程,包括 RFC 9728 受保护资源元数据和 RFC 7591 动态客户端注册。

关于 IdP 兼容性的说明

Denodo MCP Server 文档说明支持与 Okta、Ping Identity 和 Keycloak 配合使用自动动态客户端注册流程。对于其他身份提供商,MCP Server 还支持手动客户端配置:在带外获取 OAuth 令牌,并将其作为静态 Authorization 标头转发到 MCP 请求中,具体说明见 Denodo MCP Server 用户手册。

在服务器前端部署 Application Load Balancer

如果 Denodo MCP Server 运行在与 VDP 位于同一 VPC 中的 Amazon EC2 或 Amazon EKS 上,请通过配置了 HTTPS 侦听器及来自 AWS Certificate Manager 的证书的 Application Load Balancer 对外提供服务。这样可为 AgentCore Gateway 提供稳定的 HTTPS 端点,并将 TLS 终止工作从 MCP Server 进程卸载。目标组:HTTP,端口 8080。运行状况检查路径应将 200 和 404 都视为正常响应,因为根路径会返回 404,而服务器已启动并连接到 VDP 时,/health 会返回 200。

注册为 AgentCore Gateway 目标

完整的分步指南,包括创建 AgentCore Gateway、配置 IAM 服务角色以及验证 Gateway 目标,见 Denodo 的 通过 MCP Server 将 Amazon Bedrock AgentCore 与 Denodo 集成指南。

在代理框架中添加 Denodo VQL 技能

Denodo VQL 技能作为系统提示扩展,供代理框架(如 Strands 或 Bedrock AgentCore)中的 LLM 使用。在代理框架中注册后,它会指导模型了解 VQL 语法规则,以及如何帮助避免 SQL 错误。

部署并运行代理

Denodo AgentCore 文档参考中包含 Denodo 知识库里的完整代理代码。这一模式很简洁:在 Amazon Bedrock 上运行基础模型,使用指向 Denodo MCP Server 的 MCP 客户端,以及将二者连接起来的 AgentCore 运行时入口点。

验证

为确认语义层、代理和身份流程按预期运行,我们通过代理运行三类查询,并额外进行一次治理重跑,以展示受治理的访问部分所述的“同一查询、两个用户”特性。我们可以使用 Denodo 的 Data Marketplace 助手进行快速验证;它在后台依赖功能等效的工具,能够验证我们的场景。

查询 1:仅查询 Aurora

“列出我们在威斯康星州的客户及其所在城市。”

代理生成并运行:

/* The query needs to retrieve first_name, last_name, and city from the customer_360 view where state = 'WI', ordered by last_name. The output will be multiple rows with 3 columns. The table is at customer granularity (one row per customer). No obligatory columns are present, so a simple WHERE filter on state suffices. */
SELECT "first_name",
"last_name",
"city"
FROM "customer_360"."customer_360"
WHERE "state" = 'WI'
ORDER BY "last_name"

VDP 的优化器判定投影和筛选只需要 Aurora 侧的数据,因此将单个查询下推到 Amazon Aurora。根据探测查询,代理可以将筛选条件中的 Wisconsin 转换为谓词 state = 'WI'。Amazon Redshift 和本地集群均未被访问。

查询 2:仅查询 Redshift

“按售出数量列出销量最高的 10 种产品。”

代理生成:

/* The user wants top 10 products by total units sold from a metric view. I need to use EVALUATE_METRIC for units_sold, GROUP BY product_name, ORDER BY the metric descending, LIMIT 10. The output will be multiple rows (up to 10) with two columns: product_name and total_units_sold. */
SELECT "product_name",
EVALUATE_METRIC("units_sold") AS "total_units_sold"
FROM "customer_360"."lifetime_customer_value"
GROUP BY "product_name"
ORDER BY "total_units_sold" DESC
LIMIT 10

Query plan view showing the Query 2 request pushed down in full to Amazon Redshift

图 7:由于产品和订单数据都位于 Amazon Redshift,VDP 将整个查询(联接、聚合、排序和限制)下推到 Amazon Redshift。Aurora 和本地集群均未被访问

查询 3:三方联邦查询

“按生命周期价值排名的前 20 位客户中,哪些尚未加入奖励计划?”

代理生成:

/* This is a metric view, so I need to use EVALUATE_METRIC for lifetime_spend and order_count. The query needs to: 1. Aggregate by first_name, last_name, state, rewards_since to get total lifetime_spend and order_count 2. Rank top 20 by total lifetime_spend 3. Filter those top 20 where rewards_since IS NULL I'll use a CTE with ROW_NUMBER() to get top 20, then filter for NULL rewards_since in outer query. */
WITH "ranked_customers" AS (
SELECT "first_name",
"last_name",
"state",
"rewards_since",
EVALUATE_METRIC("lifetime_spend") AS "total_lifetime_spend",
EVALUATE_METRIC("order_count") AS "total_order_count"
FROM "customer_360"."lifetime_customer_value"
GROUP BY "first_name",
"last_name",
"state",
"rewards_since"
ORDER BY "total_lifetime_spend" DESC
LIMIT 20
)
SELECT "first_name",
"last_name",
"state",
"rewards_since",
"total_lifetime_spend",
"total_order_count"
FROM "ranked_customers"
WHERE "rewards_since" IS NULL
ORDER BY "total_lifetime_spend" DESC

Agent output listing the top 20 customers by lifetime value who are not enrolled in the rewards program

图 8:三方联合查询的代理结果,列出尚未加入奖励计划且生命周期价值最高的客户

VDP 按照 构建语义层 一节中的描述,在三个引擎之间规划查询:从 Aurora 获取客户档案,从 Amazon Redshift 获取汇总支出,从本地集群获取加入记录,并在 VDP 内完成最终联接和 Top-N 查询。在 POC 数据中,排名第一的是来自威斯康星州密尔沃基的 Marcus Chen,其生命周期支出为 $47,832;这位客户消费金额高但尚未加入奖励计划,正是 示例 一节中示例问题所指的自动加入目标。请注意,LLM 无需推导 lifetime_spend 的定义,因为该公式已作为指标视图中定义的语义模型的一部分。

治理重新运行

我们在投影中添加 ssn,以两个不同的调用方身份运行查询 1:

SELECT cid, first_name, last_name, state, ssn
FROM customer_360
WHERE state = 'WI';

作为 hr_user,结果包含 ssn 值。作为 marketing_user,结果返回相同的行,但 ssn 显示为星号掩码值。两次运行之间,查询文本、代理代码、MCP Server、VDP 或 Aurora 均未发生变化。受治理的访问一节中的全局安全策略 mask_pii_columns 会在查询时根据调用方的角色进行评估,VDP 会相应地重写投影。同样的行为也适用于 card_num。

Query result with the ssn column returned in full for one role and masked with asterisks for another

图 9:相同查询的治理重新运行结果:hr_user 获取完整的 ssn,marketing_user 获取经过掩码处理的 ssn

扩展到其他数据源

向 customer_360 添加 AWS 之外的数据源,无论是用于 CRM 记录的 Salesforce、用于客户服务数据的 ServiceNow,还是用于 ERP 表的 SAP,其建模过程都与 Aurora、Amazon Redshift 和本地集群相同。创建一个基础视图,在派生视图中按 cid 将其联接,并为敏感列添加标签。指标视图、全局安全策略和代理的 VQL 均无需更改。变化的是 VDP 用于访问数据源的封装器。例如:

  • Salesforce 通过 Denodo Salesforce 连接器连接,使用 OAuth 2.0 身份验证,并通过 REST 或 Bulk API 进行 VQL-to-SOQL 转换。
  • ServiceNow、Microsoft Dynamics 365 和其他 SaaS 工具使用 Denodo 的 SaaS 向导模板,这些模板已针对常见 API 预先配置。
  • SAP ERP 通过使用 SAP Java Connector 的 BAPI 数据源连接。VDP 调用 SAP RFC,并将响应整理成行。

代理无需知道底层使用的是哪种数据源。它通过 VQL 查询 customer_360。Denodo 的封装器负责将查询转换为数据源原生格式,而 Denodo 的全局安全策略会统一应用,无论数据行来自 JDBC 引擎、REST API 还是 RFC 调用。

部署时有一项决策会因数据源而异:是将调用方的身份传递到数据源,还是使用服务账户连接。如果数据源支持,身份传递可以实现端到端的源端审计(例如,通过 Kerberos 连接 SAP,或通过 OAuth 连接 Salesforce)。使用服务账户连接则更简单,但源端审计会显示查询来自 Denodo。

部署:Denodo Agora 与自托管

Denodo 在 AWS 上有两种部署形态。二者使用相同的 Virtual DataPort、VQL、全局安全策略和 MCP Server。两者的区别在于运维方式。

Agora:全托管

Denodo Agora 是 Denodo 的全托管云服务,可在 AWS Marketplace 上使用。Agora 采用分平面架构。控制平面(Solution Manager、Design Studio、Scheduler 管理、监控/诊断)运行在 Denodo 的云账户中,而 执行平面(VDP、Scheduler、Data Catalog)运行在客户的 AWS 账户中。接触数据的计算资源位于客户的 VPC 中。管理界面由 Denodo 运营。

如果您不想负责应用程序的运维,且 Denodo 发布的更新节奏适合您的组织,请选择 Agora。

在 Amazon EC2 或 Amazon EKS 上自行管理

自行管理的部署会在客户的 AWS 账户中完整安装 Denodo Platform。Denodo 在 AWS Marketplace 上发布 VM 映像,并为 Amazon EKS 提供 Helm 图表和容器映像。您需要负责集群、升级和备份。

如果合规要求特定的部署方式、您想控制版本更新节奏,或参考架构要求在特定 VPC 内运行 Denodo 集群,请选择自行管理。

连接 AWS 以外的数据源

在这两种部署方式中,VDP 都位于客户的 AWS 账户中。连接本地数据源在两种情况下都是同一个问题:需要从托管 VDP 的 VPC 到本地集群建立网络路径,并通过组织已在使用的混合连接选项进行配置。对于 Salesforce 或 ServiceNow 这类 SaaS 数据源,无需额外设置,因为执行平面默认可以访问出站互联网,这足以支持 OAuth 2.0 身份验证和 REST API 调用。

结论与入门指南

要可靠地访问企业数据并支持智能体工作,需要三者协同工作:能够规划并生成查询的基础模型、在实时源系统之上呈现具有业务意义数据的语义层,以及托管智能体并管理身份流程的运行时。Amazon Bedrock、Denodo Platform 和 Amazon Bedrock AgentCore 各自承担其中一项职责。

智能体与语义层交互,而不是直接访问底层数据库。基本视图、派生视图、指标视图、标签和全局安全策略都位于 VDP 中。当源架构发生变化、新数据源接入或治理规则变更时,只需在语义层中更新,所有使用方都会在下次查询时获取更新。语义层所承载的其他元数据(文档、描述、指标公式和 360 图)为模型提供了更有依据的业务上下文,供其推理,而不仅仅是原始架构。

入门指南

试用 AWS 上的 Agora,并按照说明进行部署。Agora 是 Denodo 的全托管云服务,用于在 AWS 上部署 AI 数据层,提供对分布式企业数据的实时受治理访问。

大多数团队会从小范围开始,逐步扩展,从而让这一方案投入使用。

  1. 选择一个智能体工作流,该工作流涉及两个或三个不同的数据源系统,而且目前需要花费过长时间才能得出答案。
  2. 写下三到五个具体问题,这些问题是该工作流需要回答的。这些查询是语义层在第一天就必须支持的内容。
  3. 连接数据源并创建基本视图,覆盖该工作流涉及的源表。创建时为 PII 列添加标签。
  4. 构建派生视图和问题所需的指标视图。
  5. 实施全局安全策略,以帮助保护 PII、受保护健康信息 (PHI)、支付卡行业 (PCI) 或其他敏感信息。
  6. 将 Denodo MCP Server 注册为 AgentCore Gateway 目标,并按照前面章节中的模式将 Strands agent 接入其中。使用 agentcore deploy 部署。

延伸阅读


作者简介

Suntosh Murthy

Suntosh Murthy

Suntosh 是 Denodo 的合作伙伴解决方案架构师,与战略合作伙伴协作设计和实施云数据架构、语义层解决方案及企业参考架构,帮助客户做出数据驱动的决策。

Pablo Alvarez-Yañez

Pablo Alvarez-Yañez

Pablo 是 Denodo 全球产品管理副总裁,负责制定产品战略、确定产品组合的方向和优先事项,并将客户需求转化为产品要求。他负责制定产品战略、收集客户反馈,并协调工程、市场营销和销售团队执行该战略。他目前的工作重点是云部署、大数据和数据科学。

JP Boreddy

JP Boreddy

JP 是 AWS 的高级解决方案架构师,与企业客户合作,处理云架构、数据和 AI 工作负载。

Sahil Thapar

Sahil Thapar

Sahil 是 AWS 的首席解决方案架构师,与 ISV 客户合作,在 AWS 云上构建高可用、可扩展且具备弹性的应用程序。他专长于容器、机器学习和生成式 AI,帮助企业设计可用于生产环境的解决方案。

来源:AWS Machine Learning Blog · aws.amazon.com