1. 概览
什么是主数据管理?
主数据管理 (MDM) 的核心目标是为组织的最关键数据创建单一可靠的可信来源。想象一下,在一个精心整理的图书馆中,每本书(数据点)都贴有正确的标签,并且是最新的,而且很容易找到。
主数据是指对公司运营至关重要的核心基础业务实体。主数据的关键要素如下:
- 业务实体:客户、产品、供应商、地点和员工等实体,这些实体是您业务的核心名词
- 标识符:确保每个实体在各个系统中都是唯一且可追踪的唯一标识符
- 属性:描述每个实体的特征,例如客户的地址、产品的价格等。
为了帮助您更好地了解主数据,我们将其与交易数据进行比较。交易数据会捕获各个事件(购买、发货等)。而主数据通过定义所涉及的实体来提供这些事件的背景信息。例如,销售交易会关联到客户、产品和销售人员的主数据。
虽然实施强大的 MDM 对于战略决策至关重要,但它可能很复杂且需要大量资源。这时,生成式 AI(尤其是 Gemini 1.0 Pro、Gemini 1.0 Pro Vision、Gemini 1.5 Pro 等模型)的变革性力量便可发挥作用。
2. 目标
在此 Codelab 中,您将演示 Gemini 1.0 Pro 如何简化主数据管理应用(例如丰富和去重),以处理 BigQuery 公共数据集中的 citibike_stations 数据。
您将使用的内容
- BigQuery 公共数据集
bigquery-public-data.new_york_citibike。 - Gemini 函数调用(一个 Java Cloud Functions 函数,用于使用 Reverse Geocoding API 获取 citibike_stations 数据中提供的坐标的地址信息)。
- Vertex AI Embeddings API 和 BigQuery 中的向量搜索功能来识别重复项。
构建内容
- 您将为该使用情形创建一个 BigQuery 数据集。在此数据集中,您将创建一个着陆表,其中包含来自公共数据集表
bigquery-public-data.new_york_citibike.citibike_stations的数据。 - 您将部署包含 Gemini 函数调用功能的 Cloud Functions 函数,以实现地址标准化。
- 您将把丰富后的地址数据存储在着陆表中(来自为此演示提供的两个来源)。
- 您将从 BigQuery 中调用 Vertex AI Embeddings API 来处理地址数据。
- 您将使用 BigQuery Vector Search 来识别重复记录。
下图展示了实现过程中涉及的数据流和步骤。

3. 要求
4. 准备工作
- 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。
- 确保您的 Cloud 项目已启用结算功能。了解如何检查项目是否已启用结算功能。
- 您将使用 Cloud Shell,这是一个在 Google Cloud 中运行的命令行环境,它预加载了 bq。点击 Google Cloud 控制台顶部的“激活 Cloud Shell”。

- 连接到 Cloud Shell 后,您可以使用以下命令检查自己是否已通过身份验证,以及项目是否已设置为您的项目 ID:
gcloud auth list
- 在 Cloud Shell 中运行以下命令,以确认 gcloud 命令了解您的项目。
gcloud config list project
- 如果项目未设置,请使用以下命令进行设置:
gcloud config set project <YOUR_PROJECT_ID>
- 前往 Gemini for Google Cloud Marketplace 启用该 API。您还可以在 Cloud Shell 终端中使用以下命令:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
- 确保已启用 BigQuery、BigQuery Connection、Cloud Function、Cloud Run、Vertex AI 和 Cloud Build API。除了使用 gcloud 命令,您还可以通过控制台使用此链接来完成操作。
如需了解 gcloud 命令和用法,请参阅文档。
5. 创建 BigQuery 数据集和外部连接
我们先来创建数据集和 Cloud 资源连接。
BigQuery 中的数据集是用于存放应用的所有表和对象的容器。
如需创建数据集,请执行以下操作:
- 在 Google Cloud 控制台中前往 BigQuery 页面。
- 在探索器面板中,选择您要在其中创建数据集的项目。
- 展开操作选项(垂直省略号图标),然后点击创建数据集。

- 在数据集 ID 字段中,输入
mdm_gemini。 - 将位置类型设置为
Multi-region,并接受默认值US(multiple regions in United States. - 点击创建数据集。
- 检查该数据集是否已创建并列在探索器窗格中的项目 ID 下。
您需要建立 BigQuery 连接才能与 Cloud Functions 函数进行交互。如需创建远程函数,您必须创建 BigQuery 连接。在此 Codelab 中,我们将使用 BigLake 连接通过 Cloud Functions 从 BigQuery 访问模型。借助 BigLake 连接,我们可以连接外部数据源,同时保留精细的 BigQuery 访问权限控制和安全性(在本例中为 Vertex AI Gemini Pro API)。
如需创建 BigLake 连接,请执行以下操作:
- 在 BigQuery 页面的探索器窗格中,点击添加。

- 点击与外部数据源的连接。
- 在“连接类型”列表中,选择 Vertex AI 远程模型、远程函数和 BigLake(Cloud 资源)。
- 在连接 ID 字段中,输入连接名称
gemini-bq-conn。 - 将位置类型设置为
Multi-region,并接受默认值US(multiple regions in United States. - 点击创建连接。
- 点击前往连接,然后复制连接信息窗格中的服务账号 ID。

- 前往 IAM 和管理页面,然后点击授予访问权限。
- 将服务账号 ID 粘贴到新的主账号字段中。
- 从角色列表中选择
Vertex AI user角色,然后点击保存。

您现已成功创建数据集和 BigQuery 连接。
6. 部署 Gemini 函数调用(Java Cloud Functions 函数)
请按照以下步骤部署包含 Gemini 函数调用的 Java Cloud Functions 函数。
- 使用以下命令从 Cloud Shell 终端克隆 GitHub 代码库:
git clone https://github.com/AbiramiSukumaran/GeminiFunctionCalling
- 将占位符
YOUR_API_KEY和YOUR_PROJECT_ID替换为您的值。
如果您阅读了这篇博文,就会知道函数调用实现使用的是反向地理编码 API。您可以按照此处的说明创建自己的 API_KEY。
- 在 Cloud Shell 终端中,前往新克隆的项目目录 GeminiFunctionCalling,然后运行以下语句来构建和部署 Cloud Functions 函数:
gcloud functions deploy gemini-fn-calling --gen2 --region=us-central1 --runtime=java11 --source=. --entry-point=cloudcode.helloworld.HelloWorld --trigger-http
当系统提示“是否允许未通过身份验证的调用”时,请回答“y”。最好根据建议为企业应用设置身份验证。不过,由于这是一个演示版应用,我们将继续进行未经身份验证的操作。
输出是一个 REST 网址,格式如下:
https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/gemini-fn-calling
- 在终端中运行以下命令,测试此 Cloud Functions 函数:
gcloud functions call gemini-fn-calling --region=us-central1 --gen2 --data '{"calls":[["40.714224,-73.961452"]]}'
针对随机抽样提示的回答:
'{"replies":["{ \"DOOR_NUMBER\": \"277\", \"STREET_ADDRESS\": \"Bedford Ave\", \"AREA\":
null, \"CITY\": \"Brooklyn\", \"TOWN\": null, \"COUNTY\": \"Kings County\", \"STATE\":
\"NY\", \"COUNTRY\": \"USA\", \"ZIPCODE\": \"11211\", \"LANDMARK\": null}}```"]}'
此 Cloud Functions 函数的请求和响应参数以与 BigQuery 的远程函数调用兼容的方式实现。可以直接从 BigQuery 数据中就地使用。这意味着,如果您的数据输入(纬度和经度数据)位于 BigQuery 中,那么您可以对这些数据调用远程函数,并获取可以直接在 BigQuery 中存储或处理的函数响应。
- 在 BigQuery 中运行以下 DDL,以创建可调用此已部署 Cloud Functions 函数的远程函数:
CREATE OR REPLACE FUNCTION
`mdm_gemini.MDM_GEMINI` (latlng STRING) RETURNS STRING
REMOTE WITH CONNECTION `us.gemini-bq-conn`
OPTIONS (
endpoint = 'https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/gemini-fn-calling', max_batching_rows = 1
);
测试查询以使用新创建的远程函数:
SELECT mdm_gemini.MDM_GEMINI(latlong) from mdm_gemini.CITIBIKE_STATIONS limit 1;
如果使用在 BigQuery 中创建的新远程函数的测试查询因 Cloud Functions 权限问题而失败,请通过 Google Cloud 控制台前往 Cloud Functions,然后找到名为“gemini-fn-calling”的已部署 Cloud Functions 函数。前往“权限”标签页,添加“allUsers”作为正文,并授予“Cloud Functions Invoker”角色,以确保所有用户都可以访问 Cloud Functions(仅因为这是一个演示版应用)。
7. 尝试变通方案
如果您没有反向地理编码函数调用方法所需的 API_KEY,或者由于某种原因未部署 Cloud Function,则可以执行以下操作作为替代方案:
- 从代码库下载文件 CITIBIKE_STATIONS.csv 到您的 Cloud Shell 项目文件夹,然后进入该文件夹。
- 在 Cloud Shell 终端中使用以下命令,将数据从 CSV 文件导出到新的 BigQuery 数据集
mdm_gemini中:
bq load --source_format=CSV --skip_leading_rows=1 mdm_gemini.CITIBIKE_STATIONS ./CITIBIKE_STATIONS.csv \ name:string,latlng:string,capacity:numeric,num_bikes_available:numeric,num_docks_available:numeric,last_reported:timestamp,full_address_string:string
8. 创建表格并丰富地址数据
第 1 步:创建表格
重要提示:如果您已使用解决方法,则必须已创建表,因此请跳过此步骤。
如果您未使用此解决方法,请在 BigQuery SQL 编辑器中运行以下 DDL:
CREATE TABLE mdm_gemini.CITIBIKE_STATIONS as (
select name, latitude || ',' || longitude as latlong, capacity, num_bikes_available, num_docks_available,last_reported,
'' as full_address_string
from bigquery-public-data.new_york_citibike.citibike_stations) ;
现在,让我们通过对表中提供的纬度和经度坐标调用远程函数来丰富地址数据。为数据设置以下条件:
- 2024 年报告的
- 可供租借的单车数量 > 0
- 容量 > 100
请运行以下查询:
update `mdm_gemini.CITIBIKE_STATIONS`
set full_address_string = `mdm_gemini.MDM_GEMINI`(latlong)
where EXTRACT(YEAR FROM last_reported) = 2024 and num_bikes_available > 0 and capacity > 100;
第 2 步:为自行车站点位置数据创建第二个来源
即使您使用解决方法创建了表,也请勿跳过此步骤。
在此步骤中,您将创建第二个自行车站点位置数据源,以用于此 Codelab。这是为了演示 MDM 如何将来自多个来源的数据整合在一起并确定黄金事实。
在 BigQuery SQL 编辑器中运行以下 DDL,以创建第二个包含两条记录的位置数据源。我们将此表命名为 mdm_gemini.CITIBIKE_STATIONS_SOURCE2,并向其中插入两条记录。
CREATE TABLE mdm_gemini.CITIBIKE_STATIONS_SOURCE2 (name STRING(55), address STRING(1000), embeddings_src ARRAY<FLOAT64>);
insert into mdm_gemini.CITIBIKE_STATIONS_SOURCE2 VALUES ('Location broadway and 29','{ "DOOR_NUMBER": "1593", "STREET_ADDRESS": "Broadway", "AREA": null, "CITY": "New York", "TOWN": null, "COUNTY": "New York County", "STATE": "NY", "COUNTRY": "USA", "ZIPCODE": "10019", "LANDMARK": null}', null);
insert into mdm_gemini.CITIBIKE_STATIONS_SOURCE2 VALUES ('Allen St & Hester','{ "DOOR_NUMBER": "36", "STREET_ADDRESS": "Allen St", "AREA": null, "CITY": "New York", "TOWN": null, "COUNTY": "New York County", "STATE": "NY", "COUNTRY": "USA", "ZIPCODE": "10002", "LANDMARK": null}', null);
9. 为地址数据生成嵌入
嵌入是表示给定实体(如一段文本或音频文件)的高维数字向量。机器学习 (ML) 模型使用嵌入对此类实体的语义进行编码,以便更轻松地推断和比较实体。例如,聚类、分类和推荐模型中的常见操作是测量嵌入空间中矢量之间的距离,以查找语义上最相似的项。借助 Vertex AI 文本嵌入 API,您可以使用 Vertex AI 上的生成式 AI 创建文本嵌入。文本嵌入是文本的数值表示法,可捕获字词和短语之间的关系。如需详细了解 Vertex AI 文本嵌入,请点击此处。
- 运行以下 DDL,为 Vertex AI Text Embeddings API 创建远程模型:
CREATE OR REPLACE MODEL `mdm_gemini.CITIBIKE_STATIONS_ADDRESS_EMB`
REMOTE WITH CONNECTION `us.gemini-bq-conn`
OPTIONS (ENDPOINT = 'textembedding-gecko@latest');
- 现在,远程嵌入模型已准备就绪,接下来我们使用以下查询为第一个来源生成嵌入,并将其存储在表中:
CREATE TABLE `mdm_gemini.CITIBIKE_STATIONS_SOURCE1` AS (
SELECT *
FROM ML.GENERATE_EMBEDDING(
MODEL `mdm_gemini.CITIBIKE_STATIONS_ADDRESS_EMB`,
( select name, full_address_string as content from `mdm_gemini.CITIBIKE_STATIONS`
where full_address_string is not null )
)
);
除了创建新表之外,您还可以将嵌入结果字段存储在之前创建的同一 mdm_gemini.CITIBIKE_STATIONS 表中。
- 如需为表 CITIBIKE_STATIONS_SOURCE2 中的地址数据生成嵌入,请运行以下查询:
update `mdm_gemini.CITIBIKE_STATIONS_SOURCE2` a set embeddings_src =
(
SELECT ml_generate_embedding_result
FROM ML.GENERATE_EMBEDDING(
MODEL `mdm_gemini.CITIBIKE_STATIONS_ADDRESS_EMB`,
( select name, address as content from `mdm_gemini.CITIBIKE_STATIONS_SOURCE2` ))
where name = a.name) where name is not null;
这应该会为第二个来源创建嵌入。请注意,我们在同一表 CITIBIKE_STATIONS_SOURCE2 中创建了嵌入字段。
- 如需直观呈现为源数据表 1 和 2 生成的嵌入,请运行以下查询:
select name,address,embeddings_src from `mdm_gemini.CITIBIKE_STATIONS_SOURCE2`;
select name,content,ml_generate_embedding_result from `mdm_gemini.CITIBIKE_STATIONS_SOURCE1`;
现在,我们继续执行向量搜索,以识别重复项。
10. 运行向量搜索以标记重复地址
在此步骤中,您将在 mdm_gemini.CITIBIKE_STATIONS_SOURCE1 表的地址嵌入 ml_generate_embedding_result 列中搜索与 mdm_gemini.CITIBIKE_STATIONS_SOURCE2 表的 embeddings_src 列中每行数据最匹配的前两个嵌入。
为此,请运行以下查询:
select query.name name1,base.name name2,
/* (select address from mdm_gemini.CITIBIKE_STATIONS_SOURCE2 where name = query.name) content1, base.content content2, */
distance
from VECTOR_SEARCH(
TABLE mdm_gemini.CITIBIKE_STATIONS_SOURCE1,
'ml_generate_embedding_result',
(SELECT * FROM mdm_gemini.CITIBIKE_STATIONS_SOURCE2),
'embeddings_src',
top_k => 2
) where query.name <> base.name
order by distance desc;
要查询的表: mdm_gemini.CITIBIKE_STATIONS_SOURCE1,字段为 ml_generate_embedding_result
用作基础的表: mdm_gemini.CITIBIKE_STATIONS_SOURCE2,基于字段 embeddings_src
top_k::指定要返回的最近邻项的数量。默认值为 10。负值被视为无限大,这意味着所有值都被视为邻居并返回。
distance_type::用于指定计算两个向量之间距离时使用的指标类型。支持的距离类型为欧几里得距离和余弦距离。默认值为 欧氏距离。
查询结果如下所示:

如图所示,此函数已列出 CITIBIKE_STATIONS_SOURCE1 中 CITIBIKE_STATIONS_SOURCE2 的两个行的两个最近邻(换句话说,最接近的重复项)。由于未指定 distance_type,因此假设它是欧几里得,并且距离是指两个来源之间地址文本值的距离,最低距离表示地址文本最相似。
我们使用以下查询将 distance_type 设置为 Cosine:
select query.name name1,base.name name2,
/* (select address from mdm_gemini.CITIBIKE_STATIONS_SOURCE2 where name = query.name) content1, base.content content2, */
distance
from VECTOR_SEARCH(
TABLE mdm_gemini.CITIBIKE_STATIONS_SOURCE1,
'ml_generate_embedding_result',
(SELECT * FROM mdm_gemini.CITIBIKE_STATIONS_SOURCE2),
'embeddings_src',
top_k => 2,distance_type => 'COSINE'
) where query.name <> base.name
order by distance desc;
查询结果如下所示:

这两个查询(采用两种距离类型)均按距离降序排序,这意味着我们希望按距离由大到小的顺序列出结果。但您会注意到,第二个查询的距离顺序已反转。您能猜到原因吗?
太棒了!您答对了!在余弦相似度中,数值越大表示相似度越高,距离越小。在欧几里得距离中,数值越大,表示值之间的距离越远。
如需详细了解 MDM,以及了解欧氏距离和余弦距离之间的区别和应用方面的提示,请参阅这篇博文。
11. 清理
为避免系统因本博文中使用的资源向您的 Google Cloud 账号收取费用,请按照以下步骤操作:
- 在 Google Cloud 控制台中,前往管理资源页面。
- 在项目列表中,选择要删除的项目,然后点击删除。
- 在对话框中输入项目 ID,然后点击关停以删除项目。
- 如果您想保留项目,请跳过上述步骤,然后前往 Cloud Functions,从函数列表中选中要删除的 Cloud Function,然后点击删除,即可删除该函数。
12. 恭喜
恭喜!您已展示了使用 Gemini 1.0 Pro 和函数调用将一些 MDM 活动转变为简化但功能强大、确定性强且可靠的生成式 AI 功能。现在,您已经了解了这些信息,可以随意探索实现相同使用情形或其他 MDM 功能的其他方式。您是否可以验证数据集、填补信息缺口,或者通过在生成式 AI 回答中嵌入结构化调用来自动执行任务?如需更深入的指导,请参阅 Vertex AI、BigQuery 远程函数、Cloud Functions、嵌入和 Vector Search 的文档。以下是此项目的 GitHub 代码库。欢迎告诉我们您通过学习本课程开发了哪些内容!