将暗数据转化为结构化黄金

1. 概览

我们都知道“暗数据”带来的困扰。这些非结构化数据包括云存储分区中的 PDF、图片和文本文件,SQL 查询和 BI 信息中心完全无法访问这些数据。过去,若要获取这些数据,需要使用复杂的 OCR 流水线、手动输入数据或编写脆弱的自定义脚本。

现在,您不必再为此烦恼了。

在本实验中,我将向您展示如何将 400 个非结构化 PDF 文件(包含文本、表格和图片)转换为结构清晰的 BigQuery 表,并自动推断它们之间的关系。我们将使用 BigQuery Knowledge Catalog 和 Dataplex 在几分钟内完成此操作。

构建内容

为了让大家更直观地了解这一点,我们来看一个虚构的商家:一家快速成长的酸奶冰淇淋连锁店。

假设您负责管理这家冷冻酸奶店的数据。您有数百个食谱和供应商规格表,全部保存为 PDF 文件。业务主管希望推出 AI 智能体,帮助商店经理和客户查询产品详情。

以下是噩梦般的场景:一位顾客问道:“我对你们的午夜漩涡冻酸奶非常感兴趣。里面有任何过敏原吗?”

为了回答这个问题,系统通常需要执行以下操作:

  1. 找到“午夜漩涡”食谱 PDF。
  2. 阅读成分(例如“可可粉”“乳制品基底”“乳化剂 X”)。
  3. 搜索数十个供应商 PDF,找到这些特定成分的规格表。
  4. 查看供应商提供的成分表,了解与这些成分相关的隐藏过敏原。

尝试构建一个 AI 智能体,让其在运行时读取 400 个原始 PDF 文件并即时执行此操作,这种做法速度慢、成本高,并且容易产生幻觉。相反,我们将使用语义推理先将所有这些内容提取到关系型数据库中,从而使未来的 AI 智能体能够以极快的速度运行,并完全基于事实 SQL 数据。

让我们开始构建吧!

2381f1453211387d.png

学习内容

  • 如何为源文件 (PDF) 设置 Cloud Storage 存储分区
  • 如何在 Knowledge Catalog 中设置和运行 Datascan 作业和语义推理,以从源 PDF 中提取数据,并以语义方式推断连接和上下文,然后将其存储在 BigQuery 中
  • 如何使用 BigQuery 智能体与新创建的数据集对话

要求

  • 一个浏览器,例如 ChromeFirefox
  • 启用了结算功能的 Google Cloud 项目。
  • 基本熟悉 SQL 和 Java。

2. 准备工作

创建项目

  1. Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目
  2. 确保您的 Cloud 项目已启用结算功能。了解如何检查项目是否已启用结算功能
  1. 您将使用 Cloud Shell,它是在 Google Cloud 中运行的命令行环境。点击 Google Cloud 控制台顶部的“激活 Cloud Shell”。

“激活 Cloud Shell”按钮图片

  1. 连接到 Cloud Shell 后,您可以使用以下命令检查自己是否已通过身份验证,以及项目是否已设置为您的项目 ID:
gcloud auth list
  1. 在 Cloud Shell 中运行以下命令,以确认 gcloud 命令了解您的项目。
gcloud config list project
  1. 如果您想进行身份验证
gcloud auth login
  1. 如果项目未设置,请使用以下命令进行设置:
export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project <YOUR_PROJECT_ID>
  1. 启用必需的 API:运行以下命令可启用所有必需的 API:
gcloud services enable \
    dataplex.googleapis.com \
    datacatalog.googleapis.com \
    discoveryengine.googleapis.com \
    bigqueryconnection.googleapis.com \
    bigquery.googleapis.com \
    aiplatform.googleapis.com \
    cloudresourcemanager.googleapis.com \
    serviceusage.googleapis.com \
    storage.googleapis.com

注意事项和问题排查

“幽灵项目” 综合征

您运行了 gcloud config set project,但实际上在控制台界面中查看的是另一个项目。检查左上角下拉菜单中的项目 ID!

结算 路障

您已启用项目,但忘记了结算账号。AlloyDB 是一款高性能引擎;如果“油箱”(结算)为空,它将无法启动。

API 传播 延迟

您点击了“启用 API”,但命令行仍显示 Service Not Enabled。等待 60 秒。云端需要一些时间来唤醒其神经元。

配额 Quags

如果您使用的是全新试用账号,则可能会达到 AlloyDB 实例的区域配额。如果 us-central1 失败,请尝试 us-east1

“隐藏”服务代理

有时,AlloyDB 服务代理不会自动获得 aiplatform.user 角色。如果您的 SQL 查询之后无法与 Gemini 对话,通常是此问题所致。

3. Google Cloud Storage 存储分区设置

在本部分中,您将在 BigQuery 中创建一个组织结构,用于存储 Froyo 配方和供应商数据,特别是 Froyo 产品详情。它还会建立 Cloud 资源连接,充当安全“桥梁”,让 BigQuery 可以从 Cloud Storage 等外部来源读取文件。

准备工作:

此代码库包含我们将在本项目中使用的食谱和供应商 PDF 文件。请务必下载这些文件。如需下载文件,请执行以下操作。

在 Cloud Shell 中,运行以下命令:

git clone --depth 1 --filter=blob:none --sparse https://github.com/GoogleCloudPlatform/next-26-keynotes.git

进入新创建的文件夹:

cd next-26-keynotes

拉取 data-cloud-demo 文件夹

git sparse-checkout set genkey/data-cloud-demo

结账完成后,前往 data-cloud-demo 文件夹,然后解压缩 ZIP 文件以访问 Codelab 资源。

创建存储分区并上传 Froyo(食谱和供应商)PDF 文件

  1. 在 Google Cloud 控制台中,进入 Cloud Storage 存储分区页面。
  2. 点击“创建”。
  3. 创建存储分区页面上,输入您的存储分区信息。完成以下每一步后,点击“继续”以继续执行后续步骤:
  4. 开始使用部分中,输入存储分区名称。例如:froyo_data
  5. 选择数据存储位置部分中,选择“区域”,然后输入您的区域。us-central1
  6. 选择如何控制对对象的访问权限部分中,清除“禁止公开访问此存储分区”复选框。
  7. 点击“创建”。
  8. 在存储分区列表中,点击您创建的存储分区。
  9. 在相应存储分区的对象标签页中,依次点击“上传”和“上传文件夹”。
  10. 选择您在本 Codelab 的“准备工作”部分中提取的 recipes 文件夹。
  11. 点击上传。
  12. 针对 suppliers 文件夹重复执行上传流程。

上传完成后,您的存储分区结构应如下所示(存储分区名称可能有所不同):

596b8acb481016b7.png

4. BigQuery 连接设置

创建 Cloud 资源连接。这会生成一个唯一的服务账号,该账号充当 BigQuery 访问外部文件的“身份证”。

  • 前往 BigQuery 页面。
  • 在左侧窗格中,点击“探索器”。如果您没有看到左侧窗格,请点击“展开左侧窗格”以打开该窗格。
  • 在“探索器”窗格中,展开您的项目名称,然后点击“连接”。
  • 在“连接”页面上,点击“创建连接”。
  • 对于“连接类型”,请选择“Vertex AI 远程模型、远程函数、BigLake 和 Spanner(Cloud 资源)”。
  • 在“连接 ID”字段中,输入连接 ID 名称:
  • bq-connection。请务必记下此 ID,因为您稍后在此 Codelab 中设置数据扫描时需要用到它。
  • 将“位置类型”设置为“区域”,然后选择一个区域。例如,us-central1。连接应与数据集等其他资源位于同一区域。
  • 点击“创建连接”。
  • 点击“前往连接”。
  • 在“连接信息”窗格中,复制服务账号 ID 以在后续步骤中使用。该服务账号类似于 bqcx-**********-qn3a@gcp-sa-bigquery-condel.iam.gserviceaccount.com。

5. 权限设置

  1. 向 BigQuery 连接授予访问 Cloud Storage 对象和 Knowledge Catalog 所需的权限

前往“IAM 和管理”页面,然后在“按正文查看”部分中,点击“授予访问权限”按钮,粘贴您在上一步中复制的服务账号以添加正文。在“角色”部分中,逐个添加以下角色名称,然后保存:

  • roles/storage.objectUser
  • roles/storage.objectViewer
  • roles/bigquery.user
  • roles/bigquery.dataEditor
  • roles/aiplatform.viewer
  • roles/agentplatform.user
  • roles/storage.admin
  • roles/dataproc.serviceAgent
  • roles/dataplex.discoveryPublishingServiceAgent
  • roles/dataplex.serviceAgent
  • roles/dataplex.securityAdmin
  1. 向 Dataplex 服务账号授予访问 Cloud Storage 存储分区的权限

前往“IAM 和管理”页面,然后在“按正文查看”部分中,点击“授予访问权限”按钮,然后在“新的正文”文本栏中输入“Dataplex”,以添加正文。从自动完成的列表中,选择类似于以下内容的 Dataplex 服务账号正文:

service-*********@ gcp-sa-dataplex.iam.gserviceaccount.com

向此服务账号授予以下角色:

  • roles/storage.objectUser
  • roles/storage.objectViewer
  • roles/storage.viewer
  • roles/dataplex.discoveryBigLakePublishingServiceAgentroles/storage.objectUser
  • roles/storage.objectViewer
  • roles/storage.viewer
  • roles/dataplex.discoveryBigLakePublishingServiceAgentroles/storage.objectUser
  • roles/storage.objectViewer
  • roles/storage.viewer
  • roles/dataplex.discoveryBigLakePublishingServiceAgent

6. Knowledge Catalog 设置

构建 Knowledge Catalog,以统一非结构化数据并自动发现非结构化文件(例如 PDF 食谱和 PDF 供应商)。

  1. 通过 curl 创建 DataScan

您也可以通过控制台创建此作业,但在本部分中,我们将通过添加 datascan_ID 并将其指向 BigQuery 数据集来为 Cloud Storage 存储分区创建扫描作业。之后,Knowledge Catalog 将自动在 BigQuery 中为您的 PDF 创建条目。

在当前感兴趣的活跃项目的 Cloud Shell 终端中运行以下一组命令:

# 1. Set your variables
PROJECT_ID="<PROJECT_ID>"
REGION="<REGION>"
ENV_SUFFIX="stg1"
DATASCAN_ID="froyo-data-${ENV_SUFFIX}"
BUCKET_NAME="<BUCKET_NAME>"

# 2. Set this to the Name of the connection you created in Step 7
CONNECTION_ID="<CONNECTION_ID_NAME>"

# 3. Define the API Endpoint
DATAPLEX_API="dataplex.googleapis.com/v1/projects/${PROJECT_ID}/locations/${REGION}"

# 4. Create the DataScan via CURL
echo "Creating Dataplex DataScan: ${DATASCAN_ID}..."

curl -X POST "https://$DATAPLEX_API/dataScans?dataScanId=${DATASCAN_ID}" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"data": {
   "resource": "//storage.googleapis.com/projects/'"${PROJECT_ID}"'/buckets/'"${BUCKET_NAME}"'"
   },
"executionSpec": {
   "trigger": {
      "on_demand": {}
   }
},
"dataDiscoverySpec": {
   "bigqueryPublishingConfig": {
      "tableType": "BIGLAKE",
      "connection": "projects/'"${PROJECT_ID}"'/locations/'"${REGION}"'/connections/'"${CONNECTION_ID}"'"
   },
   "storageConfig": {
      "unstructuredDataOptions": {
      "entity_inference_enabled": true
      }
   }
   }
}'

替换上述占位变量的值,以便命令成功运行。请注意,此命令仅创建作业,不会运行作业。

  1. 过 1-2 分钟后,在 Google Cloud 控制台中,前往元数据整理页面。
  2. 在 Cloud Storage 发现标签页中,点击发现扫描项的名称(请注意,不要点击可能很诱人的来源链接,因为这会打开存储空间)。

31afb1dc3caba5f6.png

  1. 关键步骤:

修改作业,并确保“启用语义推理”复选框处于选中状态。如果没有,请将其选中,输入项目 ID 和区域,然后点击“保存”。

c021927bf80fe204.png

完成后,您可以从 Cloud Shell 终端运行以下命令,也可以点击 Cloud Storage 发现页面中的“立即运行”按钮:

gcloud dataplex datascans run $DATASCAN_ID --location=$REGION
  1. 扫描作业需要一些时间才能完成。作业完成后,检查是否存在已发布的数据集。如需查看作业状态,您可以在元数据整理页面中查看。在 Cloud Storage 发现标签页中,点击最近一次运行的发现扫描的名称。您应该会看到已发布的数据集,如下所示:

d0cd6ae1edb81ce9.png

注意:如果在扫描步骤中遇到错误,请稍等片刻,然后重试(创建作业并完成执行需要几分钟时间)。

点击并前往 froyo_data 数据集,即可在 BigQuery 中查看该表。在 BigQuery 中点击表 ID,然后在“查询编辑器”标签页中运行以下查询:

SELECT count(*) FROM `agent-data-cloud.froyo_data.froyo_data` LIMIT 1000;

这会生成 400(如果不是,您可以返回并再次运行数据扫描作业)。

7. 语义数据提取

太棒了!现在,我们来使用 Knowledge Catalog 提取这些非结构化对象的推理。

我们将使用“数据洞见”功能生成 SQL 语句,以从非结构化表中提取结构化数据

  1. 在 Google Cloud 控制台中,前往 Knowledge Catalog 搜索页面。
  2. 搜索要查看分析洞见的数据集表。在搜索栏中,输入上一步中的数据集 / 表名称“froyo_data”,然后按 Enter 键
  3. 在结果列表中,点击 TABLE 条目(而非数据集条目)
  4. 您应该会看到数据分析标签页。点击该链接(如果需要您启用任何 API,请按照说明操作并启用 API)。

如果您在此阶段启用了 API,则必须重新运行扫描作业。

  1. 在“数据洞见”标签页中,您会看到“提取”按钮下拉菜单。点击该选项,然后选择“使用 SQL 提取”选项。

89809b34c610569d.png

在弹出的“使用 SQL 提取”对话框中,将目标数据集设置为您在 Datascan 作业结果中看到的数据集。开始输入其名称,系统应会在自动补全功能中显示该名称。点击“提取”按钮。或者,您也可以在此处创建新数据集并进行提取。

这应该会打开 BigQuery 查询编辑器,其中会有一个标签页打开,其中填充了从数据扫描推理中提取的 SQL。

8. SQL 验证和架构创建

如果生成的查询看起来不错,并且在语义上与您的非结构化数据相关,请点击查询编辑器中的“运行”按钮来运行该查询。创建以结构化方式存储非结构化媒体所需的架构需要几分钟时间。

完成后,您应该能够在 BigQuery Studio 的探索器窗格中展开数据集来验证架构,如下所示:

6e65906240a9a8be.png

Alright!!! 我们非常顺利地完成了所有数据库操作。现在是时候进行最终测试了!

9. 终极测试!!!

假设我希望代理根据事实依据,以真实、完整且精心编排的信息来回答用户的问题。我将提出一个问题,智能体只有参考我来源中的多个媒体文件和参考资料才能回答。

我的用户问题如下

I'm really interested in your Midnight Swirl froyo. Are there any allergens in it?

现在,无论是进行宽泛搜索还是 LLM 搜索,系统都会显示“零种成分”。但我们构建了完整的语义推理,将所有非结构化媒体转换为结构化数据。下面是一个简单的 SQL 语句,可用于提取此信息:

SELECT p.product_name, i.ingredient_name, a.allergen_name, category, stability
FROM froyo_data.consistsof c
INNER JOIN froyo_data.product p
  ON c.product_id = p.product_id
INNER JOIN froyo_data.ingredient i
  ON c.ingredient_id = i.ingredient_name
LEFT OUTER JOIN froyo_data.containsallergen a
  ON i.ingredient_id = a.ingredient_id
WHERE
  UPPER(p.product_name) LIKE '%MIDNIGHT%SWIRL%'
  AND allergen_name IS NOT NULL;

棒极了!查看结果:

f582d55814a23e8.png

10. 清理

完成本实验后,请务必删除扫描作业以及该作业最终创建的 BigQuery 表。

前往 https://console.cloud.google.com/bigquery/governance/metadata-curation/cloud-storage-discovery。点击要删除的作业旁边的竖向省略号,然后点击“删除”,以选择要删除的作业。

9fcbbfa1a9ccba6d.png

它应该会清理作业。

11. 恭喜

我们的实现方案能够成功识别隐藏的过敏原。再也不用担心暗数据了,各位!!!在第 2 部分中,我们将通过 AlloyDB 在事务性系统中联合使用此 BigQuery 数据,以满足代理应用的统一数据需求。