Quản lý dữ liệu tối phi cấu trúc bằng Gemini và Danh mục kiến thức

1. Giới thiệu

Hơn 80% dữ liệu doanh nghiệp nằm ở định dạng không có cấu trúc – sách hướng dẫn kỹ thuật ở định dạng PDF, quy trình vận hành tiêu chuẩn (SOP), chứng chỉ tuân thủ và sơ đồ thiết bị được lưu trữ trong Cloud Storage. Vì danh mục truyền thống chỉ lập chỉ mục các lược đồ bảng quan hệ, nên những tài liệu này vẫn là "Dữ liệu tối": không xuất hiện trong kết quả tìm kiếm của doanh nghiệp, không kết nối với các bảng hàng tồn kho có cấu trúc và chưa được xác minh để tuân thủ quy định.

Khi một kiểm toán viên hoặc tác nhân AI hỏi: "Những SKU phần cứng nào yêu cầu chứng nhận an toàn UL-153 và mức độ nguy hiểm về nhiệt của chúng là gì?", một danh mục chỉ lập chỉ mục các bảng SQL không thể trả lời. Các dữ kiện được lưu trữ trong các tệp PDF không có cấu trúc trong Cloud Storage.

Giải pháp kiến trúc: siêu dữ liệu đa phương thức dưới dạng mã

Trong lớp học lập trình này, bạn sẽ xây dựng một quy trình Metadata-as-Code (Siêu dữ liệu dưới dạng mã) toàn diện trong Google Cloud. Quy trình này sẽ chuyển đổi các sổ tay PDF không có cấu trúc trong Cloud Storage thành các thành phần Danh mục kiến thức được thực thi theo lược đồ bằng Nền tảng tác nhân Gemini Enterprise (Google GenAI SDK, google-genai):

Quy trình quản trị dữ liệu tối không có cấu trúc

  1. Đăng ký nhóm tệp (EntryGroup và Entry): Nhóm các tệp PDF không có cấu trúc trong Cloud Storage thành các mục nhóm tệp logic được quản lý trong Danh mục kiến thức.
  2. Gemini Multimodal Extraction (Pydantic Schema): Triệu hồi Nền tảng Tác nhân Gemini Enterprise trên các byte PDF thô bằng quy trình xác thực response_schema có tính xác định.
  3. Control Plane Aspect Binding: Đính kèm các tải trọng JSON được xác thực về hoạt động và việc tuân thủ dưới dạng các thực thể Aspect được nhập mạnh vào mục nhập danh mục.
  4. Khám phá danh mục hợp nhất: Giúp các tệp PDF không có cấu trúc và siêu dữ liệu đã trích xuất của chúng có thể khám phá được thông qua SearchEntriesRequest.

Các khái niệm chính: Các thành phần cơ bản của lớp điều khiển Knowledge Catalog

Hãy tưởng tượng nhóm của bạn lưu trữ hàng trăm hướng dẫn sử dụng sản phẩm ở định dạng PDF trong Cloud Storage. Để dễ dàng tìm thấy và kiểm tra các tệp đó trong Danh mục kiến thức, hãy nghĩ đến 5 khối xây dựng này như cách sắp xếp sổ tay giấy trong tủ đựng hồ sơ văn phòng:

  • EntryGroup (Tủ khoá cho một nhóm): Tủ có khoá. Chỉ những đồng đội có quyền (roles/dataplex.entryCreator) mới có thể đặt thư mục vào trong. Bạn phải dọn sạch mọi thư mục trong tủ thì mới có thể tháo tủ.
  • EntryType (Nhãn danh mục thư mục): Nhãn cho biết loại thành phần mà một thư mục đại diện – ví dụ: "Bộ sưu tập hướng dẫn bằng PDF" thay vì "Bảng cơ sở dữ liệu".
  • Entry (Thư mục tệp có đường liên kết đến bộ nhớ): Thư mục danh mục cho sách hướng dẫn ở định dạng PDF. Thay vì lưu giữ các bản sao giấy nặng nề, thư mục này sẽ lưu giữ một thẻ vị trí trỏ đến bộ chứa Cloud Storage (gs://...) chính xác nơi lưu trữ các tệp PDF thực.
  • AspectType (Biểu mẫu danh sách kiểm tra trống): Biểu mẫu trống có thể dùng lại với các ô được in sẵn (ví dụ: "Danh sách kiểm tra an toàn" yêu cầu operational_hazard_level dưới dạng văn bản và confidence_score dưới dạng số từ 0.0 đến 1.0). Bạn tạo biểu mẫu trống này một lần và dùng lại cho hàng nghìn thư mục.
  • Aspect (Một danh sách kiểm tra đã điền thông tin được đính kèm vào một thư mục): Sau khi Nền tảng Tác nhân Gemini Enterprise đọc hướng dẫn bằng PDF và điền thông tin vào chỗ trống, danh sách kiểm tra đã hoàn tất đó sẽ được đính kèm vào thư mục Entry. Vì mỗi danh sách kiểm tra đều có khoá riêng (aspect_keys), nên nhóm kỹ thuật và nhóm pháp lý có thể đính kèm danh sách kiểm tra riêng của họ vào cùng một thư mục mà không ghi đè công việc của nhau.

Tất cả 5 tài nguyên theo khu vực đều nằm trong projects/{project}/locations/{location}/:

Đường dẫn tương đối và đường dẫn cơ bản

Vai trò trong Knowledge Catalog

Xoá và quy tắc IAM

EntryGroup
.../entryGroups/{id}

Vùng chứa logic nhóm các mục và kiểm soát quyền truy cập của nhóm (roles/dataplex.entryCreator).

Phải chứa 0 tài nguyên Entry con trước khi xoá.

EntryType
.../entryTypes/{id}

Định nghĩa danh mục cho một lớp tài sản (entry.entry_type, chẳng hạn như các tệp PDF không có cấu trúc).

Chỉ xoá sau khi bạn xoá tất cả các mục sử dụng loại này.

Entry (Fileset)
.../entries/{entry_id}

Bản ghi danh mục liên kết một URI Cloud Storage thực (entry_source.resource) với một tên logic (gcs:{bucket}).

Nằm trong EntryGroup và lưu giữ các bản ghi Aspect được đính kèm.

AspectType
.../aspectTypes/{id}

Mẫu giản đồ có thể dùng lại xác định record_fields đã nhập (string, enum, double) và số trường bắt đầu từ 1 (index).

Được tạo một lần cho mỗi khu vực và được chia sẻ giữa các mục.

Aspect
Entry.aspects[key]

Siêu dữ liệu JSON đã xác thực khớp với một AspectType, được đính kèm vào một Entry thông qua UpdateEntryRequest.

Được cập nhật bằng update_mask và aspect_keys để các quy trình riêng biệt không ghi đè lẫn nhau.

Sản phẩm bạn sẽ tạo ra

Khi sử dụng các tập lệnh đồng hành trong codelabs/metadata-as-code-lab, bạn sẽ chạy và kiểm tra một quy trình gồm 7 giai đoạn:

  1. schemas.py – Giản đồ Pydantic kép BaseModel (DarkDataExtractedMetadata và DocumentGovernanceMetadata) được ghép nối theo tỷ lệ 1:1 với các mẫu Knowledge Catalog AspectType.
  2. step2_provision.py – Cung cấp bản thiết kế tuỳ chỉnh EntryGroup, EntryType và AspectType không thay đổi giá trị.
  3. step3_register_fileset.py – Tải LUM-LIG-DES-8G8J_manual.pdf lên Cloud Storage và đăng ký dưới dạng một Fileset được quản lý Entry.
  4. step4_extract_metadata.py – Khám phá mô hình Gemini hàng đầu linh hoạt và trích xuất PDF đa phương thức bằng google-genai.
  5. step5_attach_aspects.py, step6_search_catalog.py và step7_verify_assertions.py – Tệp đính kèm khía cạnh phẫu thuật, tìm kiếm danh mục theo cấp số nhân và các câu khẳng định về lớp kiểm soát toàn diện.

Điều kiện tiên quyết và những thứ bạn cần

  • Một dự án trên Google Cloud có bật tính năng thanh toán và Google Cloud Shell (được cài đặt sẵn gcloud, git, python3 và pip).
  • Quyền IAM để quản lý tài nguyên Danh mục kiến thức (roles/dataplex.admin), cung cấp các đối tượng và vùng chứa Cloud Storage (roles/storage.admin) và gọi Nền tảng tác nhân Gemini Enterprise (roles/aiplatform.user).
  • Một trình duyệt web, chẳng hạn như Google Chrome.

2. Thiết lập và yêu cầu

Sao chép kho lưu trữ đồng hành trong Cloud Shell

Mở Google Cloud Console, chạy Cloud Shell và thực hiện thao tác kiểm xuất thưa thớt đối với codelabs/metadata-as-code-lab, bao gồm cả sổ tay kỹ thuật mẫu ở định dạng PDF (LUM-LIG-DES-8G8J_manual.pdf) và tất cả các tập lệnh Python:

git clone --branch main --depth 1 --filter=blob:none --sparse \
  https://github.com/GoogleCloudPlatform/devrel-demos.git
cd devrel-demos
git sparse-checkout set codelabs/metadata-as-code-lab
cd codelabs/metadata-as-code-lab
ls -la

Định cấu hình các biến môi trường

Đặt mã dự án, vị trí của bảng điều khiển theo khu vực và bộ chứa Cloud Storage mục tiêu trong Cloud Shell:

export PROJECT_ID="${PROJECT_ID:-$(gcloud config get-value project)}"
gcloud config set project $PROJECT_ID

export REGION="us-central1"
export BUCKET_NAME="${PROJECT_ID}-dark-data-manuals"
export GEMINI_LOCATION="global"

echo "Configured Project ID        : $PROJECT_ID"
echo "Knowledge Catalog Region     : $REGION"
echo "Gemini Endpoint Location     : $GEMINI_LOCATION"
echo "Target Cloud Storage Bucket  : $BUCKET_NAME"

Bật API và cài đặt các phần phụ thuộc

Bật các API Google Cloud bắt buộc và cài đặt các phần phụ thuộc Python (google-genai, google-cloud-dataplex, pydantic và pandas) từ requirements.txt:

gcloud services enable \
  dataplex.googleapis.com \
  storage.googleapis.com \
  aiplatform.googleapis.com \
  --quiet
python3 -m pip install --upgrade --quiet --user --break-system-packages -r requirements.txt

3. Xác định giản đồ Pydantic và mẫu khía cạnh

schemas.py xác định hai hợp đồng bổ sung kết hợp xác thực Pydantic phía máy khách với các mẫu Danh mục kiến thức AspectType phía máy chủ:

  1. DarkDataExtractedMetadata: Các thuộc tính hoạt động được trích xuất từ tệp PDF (tiêu đề tài liệu, bản thể học miền, mức độ nguy hiểm về an toàn, nguồn gốc của tác giả/phiên bản, bản tóm tắt và điểm số độ tin cậy của thông tin trích xuất).
  2. DocumentGovernanceMetadata: Mã tuân thủ quy định (UL-153, Phần 15 của FCC, CE-LVD, RoHS), chủ sở hữu quyền quản lý, chính sách lưu giữ và chuỗi mã nhận dạng bảng tham chiếu (lakehouse_cross_ref_table) để liên kết hướng dẫn bằng PDF với các bảng khoảng không quảng cáo hạ nguồn.

Kiểm tra schemas.py

Trước tiên, DarkDataExtractedMetadata sử dụng các ràng buộc Pydantic Field (ge=0.0, le=1.0, nghĩa là lớn hơn/nhỏ hơn hoặc bằng, trên confidence_score) để hạn chế đầu ra JSON của Gemini Enterprise Agent Platform:

class DarkDataExtractedMetadata(BaseModel):
    document_title: str = Field(
        description="Official document title or product model name extracted from the PDF manual."
    )
    # ... domain_ontology, operational_hazard_level, author_provenance ...
    version_provenance: str = Field(
        description="Document version, revision code, or publication standard identifier."
    )
    # ... document_summary ...
    confidence_score: float = Field(
        ge=0.0,
        le=1.0,
        description="AI extraction confidence metric between 0.0 and 1.0.",
    )

Thứ hai, extracted_aspect_template phản ánh chính xác những tên trường đó và ánh xạ các loại str và float của Python sang string và double record_fields của Danh mục kiến thức. Xin lưu ý rằng hợp đồng protobuf AspectType.MetadataTemplate yêu cầu mọi trường trong record_fields phải khai báo một số nguyên dương, duy nhất, bắt đầu từ 1 index (1 đến 7) – việc bỏ qua hoặc sao chép index sẽ khiến create_aspect_type gặp lỗi với 400 INVALID_ARGUMENT:

extracted_aspect_template = {
    "name": "DarkDataExtractedMetadata",
    "type": "record",
    "record_fields": [
        {
            "name": "document_title",
            "type": "string",
            "index": 1,
            "annotations": {"description": "Official document title or product model name."},
        },
        # ... fields 2 through 6 (string) ...
        {
            "name": "confidence_score",
            "type": "double",
            "index": 7,
            # ... annotations ...
        },
    ],
}

Xác thực mô-đun giản đồ

Chạy schemas.py để xác minh cấu hình môi trường và biên dịch cả hai giản đồ:

python3 schemas.py
Configured Project ID         : your-project-id
Knowledge Catalog Region      : us-central1
Gemini Endpoint Location      : global
Governed Fileset Storage URI  :
  gs://your-project-id-dark-data-manuals/sop-pdfs/LUM-LIG-DES-8G8J_manual.pdf
Target Fileset Entry ID       : sop-manuals-fileset-lum8g8j
✓ Defined DarkDataExtractedMetadata and DocumentGovernanceMetadata
  Pydantic schemas.
✓ Prepared Knowledge Catalog AspectType metadata templates.

4. Cung cấp không gian tên và các loại khía cạnh tuỳ chỉnh

Trước khi đăng ký các mục trong nhóm tệp hoặc đính kèm siêu dữ liệu, step2_provision.py sẽ cung cấp 3 tài nguyên của lớp điều khiển trong Danh mục kiến thức:

  • EntryGroup: dark-data-fileset-group
  • EntryType: unstructured-pdf-fileset
  • AspectType Bản kế hoạch: dark-data-extracted-metadata và document-governance-aspect

Cấp phép bất biến trong step2_provision.py

Mỗi lệnh gọi tạo trong step2_provision.py sẽ bao bọc thao tác kéo dài (op.result()) trong một khối try / except AlreadyExists để tập lệnh có thể chạy lại một cách an toàn mà không gặp lỗi trên các tài nguyên hiện có:

# Provision AspectType 1: dark-data-extracted-metadata
try:
    at1_op = catalog_client.create_aspect_type(
        parent=parent_location,
        aspect_type_id=EXTRACTED_ASPECT_TYPE_ID,
        aspect_type=AspectType(
            name=extracted_aspect_type_name,
            display_name="Dark Data Multimodal Extracted Metadata",
            # ... description ...
            metadata_template=extracted_aspect_template,
        ),
    )
    if hasattr(at1_op, "result"):
        at1_op.result()
    print(f"Created AspectType: {extracted_aspect_type_name}")
except AlreadyExists:
    print(f"AspectType already exists; retrieving live resource: {extracted_aspect_type_name}")

live_extracted_aspect_type = catalog_client.get_aspect_type(name=extracted_aspect_type_name)

Sau khi metadata_template=extracted_aspect_template được đăng ký, Danh mục kiến thức sẽ thực thi giản đồ tại ranh giới API – mọi lệnh gọi update_entry() tiếp theo truyền một chuỗi đến confidence_score (double) đều bị từ chối.

Chạy step2_provision.py

Thực thi tập lệnh cung cấp và xác nhận rằng các loại khía cạnh tuỳ chỉnh đã được đăng ký trong khu vực của bạn:

python3 step2_provision.py
gcloud dataplex aspect-types list --location=$REGION
Created EntryGroup:
  projects/your-project-id/locations/us-central1/entryGroups/
  dark-data-fileset-group
Created EntryType :
  projects/your-project-id/locations/us-central1/entryTypes/
  unstructured-pdf-fileset
Created AspectType:
  projects/your-project-id/locations/us-central1/aspectTypes/
  dark-data-extracted-metadata
Created AspectType:
  projects/your-project-id/locations/us-central1/aspectTypes/
  document-governance-aspect
✓ All Knowledge Catalog namespaces and AspectType blueprints are active.

5. Đăng ký các mục trong nhóm tệp không có cấu trúc

Thay vì làm lộn xộn danh mục bằng hàng triệu con trỏ tệp riêng lẻ, Knowledge Catalog sẽ nhóm các tài liệu có liên quan trong Bộ nhớ đám mây (gs://YOUR_BUCKET/sop-pdfs/*.pdf) thành Mục nhập bộ tệp hợp lý – thông qua các lần quét khám phá tự động (DataScanServiceClient) hoặc đăng ký trực tiếp theo chương trình (CatalogServiceClient.create_entry).

Cách step3_register_fileset.py ánh xạ bộ nhớ vào danh mục

step3_register_fileset.py tải LUM-LIG-DES-8G8J_manual.pdf lên gs://${BUCKET_NAME}/sop-pdfs/LUM-LIG-DES-8G8J_manual.pdf và đăng ký Entry được quản lý:

fully_qualified_fileset_uri = f"gcs:{BUCKET_NAME}"
fileset_entry_spec = Entry(
    name=fileset_entry_name,
    entry_type=entry_type_resource_name,
    fully_qualified_name=fully_qualified_fileset_uri,
    entry_source=EntrySource(
        resource=VIRTUAL_STORAGE_URI,
        system="Cloud Storage",
        platform="Google Cloud",
        display_name="LUM-LIG-DES-8G8J Unstructured SOP & Technical Manual Fileset",
        # ... description ...
        location=REGION,
    ),
)

create_entry_op = catalog_client.create_entry(
    parent=entry_group_resource_name,
    entry_id=FILESET_ENTRY_ID,
    entry=fileset_entry_spec,
)

Lưu ý vai trò riêng biệt của 2 trường URI trên Entry:

  • fully_qualified_name=fully_qualified_fileset_uri (f"gcs:{BUCKET_NAME}"): Sử dụng lược đồ FQN gcs:{bucket_name} chính tắc mà Danh mục kiến thức yêu cầu để tương quan mục nhập danh mục logic với vùng chứa Cloud Storage cơ bản.
  • entry_source.resource=VIRTUAL_STORAGE_URI: Lưu trữ URI đối tượng gs:// thực tế do các worker trích xuất hạ lưu kiểm tra.

Chạy step3_register_fileset.py

python3 step3_register_fileset.py
Created Cloud Storage bucket:
  gs://your-project-id-dark-data-manuals in us-central1
Uploaded unstructured PDF manual to:
  gs://your-project-id-dark-data-manuals/sop-pdfs/LUM-LIG-DES-8G8J_manual.pdf
Registered governed Fileset Entry:
  projects/your-project-id/locations/us-central1/entryGroups/
  dark-data-fileset-group/entries/sop-manuals-fileset-lum8g8j
  -> Fully Qualified Name : gcs:your-project-id-dark-data-manuals
  -> Physical Resource URI:
  gs://your-project-id-dark-data-manuals/sop-pdfs/LUM-LIG-DES-8G8J_manual.pdf
  -> Source System        : Cloud Storage

6. Trích xuất siêu dữ liệu tài liệu bằng Gemini

step4_extract_metadata.py đọc các byte PDF thô và gọi Nền tảng Tác nhân Gemini Enterprise (genai_client.models.generate_content) bằng hai mẫu khoá:

1. Khám phá mô hình hàng đầu linh hoạt

Thay vì mã hoá cứng các chuỗi phiên bản mô hình dễ bị lỗi, tập lệnh sẽ truy vấn genai_client.models.list() và sắp xếp các đề xuất đang hoạt động theo (is_ga_channel, semantic_version_tuple) để chọn mô hình flash có tính năng Tiếp cận công khai (GA) mới nhất:

genai_client = genai.Client(
    vertexai=True,
    project=PROJECT_ID,
    location=GEMINI_LOCATION,
)

for model_obj in genai_client.models.list():
    raw_id = (model_obj.name or "").split("/")[-1]
    # Filter to flagship Gemini Flash models (version >= 3.0) and prioritize GA over preview
    ...
    discovered_candidates.append((is_ga_channel, ver_tuple, raw_id))

discovered_candidates.sort(key=lambda item: (item[0], item[1]), reverse=True)

2. Trích xuất đa phương thức có ràng buộc theo giản đồ (Part.from_bytes + response_schema)

Việc truyền response_mime_type="application/json" và response_schema=DarkDataExtractedMetadata (tiếp theo là DocumentGovernanceMetadata) sẽ hạn chế việc giải mã mã thông báo trực tiếp cho giản đồ JSON Pydantic:

with open(LOCAL_PDF_PATH, "rb") as pdf_file:
    raw_pdf_bytes = pdf_file.read()

extraction_response = genai_client.models.generate_content(
    model=candidate_model,
    contents=[
        types.Part.from_bytes(data=raw_pdf_bytes, mime_type="application/pdf"),
        extraction_prompt,
    ],
    config=types.GenerateContentConfig(
        response_mime_type="application/json",
        response_schema=DarkDataExtractedMetadata,
        temperature=0.1,
    ),
)

extracted_dark_data = json.loads(extraction_response.text)
validated_extraction = DarkDataExtractedMetadata(**extracted_dark_data)

Chạy step4_extract_metadata.py

python3 step4_extract_metadata.py
Dynamically discovered active GA model currency :
  gemini-3.8-flash (version (3, 8))
Loaded unstructured PDF manual at: LUM-LIG-DES-8G8J_manual.pdf
Read unstructured PDF document (1184 bytes).
  Executing multimodal extraction with gemini-3.8-flash...
✓ Multimodal extraction completed using model: gemini-3.8-flash
✓ Governance classification completed using model: gemini-3.8-flash

--- Extracted Multimodal Operational Metadata ---
Extracted Attribute    Multimodal Value
document_title    LUM-LIG-DES-8G8J Contemporary Linen Desk Lamp
domain_ontology    Electrical Hardware & Lighting Systems
operational_hazard_level    MEDIUM
author_provenance    Global Hardware Safety & Lighting Systems Engin
version_provenance    Rev 4.2
document_summary    This document outlines standard operating proce
confidence_score    0.99

--- Extracted Governance & Inventory Cross-Reference Metadata ---
Governance Attribute    Classification Value
compliance_classifications    UL-153 Portable Luminaires, FCC Part 15, CE-LVD
stewardship_owner    Global Hardware Safety & Lighting Systems Engin
retention_policy    10-Year Active Product Lifecycle Archival
lakehouse_cross_ref_table    lakehouse.your-project-id.retail_hardware
governance_status    VERIFIED_PRODUCTION

7. Đính kèm các khía cạnh đã xác thực vào mục nhập trong danh mục

step5_attach_aspects.py liên kết các tải trọng JSON đã xác thực (extracted_metadata.json và governance_metadata.json) vào mục sop-manuals-fileset-lum8g8j thông qua catalog_client.update_entry().

Đột biến khía cạnh phẫu thuật trong step5_attach_aspects.py

extracted_aspect_key = f"{PROJECT_ID}.{REGION}.{EXTRACTED_ASPECT_TYPE_ID}"
governance_aspect_key = f"{PROJECT_ID}.{REGION}.{GOVERNANCE_ASPECT_TYPE_ID}"

updated_entry_payload = Entry(
    name=fileset_entry_name,
    entry_type=entry_type_resource_name,
    fully_qualified_name=fully_qualified_fileset_uri,
    aspects={
        extracted_aspect_key: Aspect(
            aspect_type=extracted_aspect_type_name,
            data=extracted_data,
        ),
        governance_aspect_key: Aspect(
            aspect_type=governance_aspect_type_name,
            data=governance_data,
        ),
    },
)

update_op = catalog_client.update_entry(
    request=dataplex_v1.UpdateEntryRequest(
        entry=updated_entry_payload,
        update_mask={"paths": ["aspects"]},
        aspect_keys=[extracted_aspect_key, governance_aspect_key],
    )
)

Việc truyền cả update_mask={"paths": ["aspects"]} và aspect_keys=[extracted_aspect_key, governance_aspect_key] sẽ giới hạn nghiêm ngặt hoạt động đột biến trong 2 khoá khía cạnh này, không ảnh hưởng đến entry_source và mọi khía cạnh thuộc sở hữu của các nhóm khác.

Chạy step5_attach_aspects.py

python3 step5_attach_aspects.py
Successfully bound 2 Aspect(s) to Entry:
  projects/your-project-id/locations/us-central1/entryGroups/
  dark-data-fileset-group/entries/sop-manuals-fileset-lum8g8j

=== Live Attached Aspect: document-governance-aspect ===
Catalog Field    Authoritative Stored Value
compliance_classifications    UL-153 Portable Luminaires, FCC Part 15, CE-LVD
stewardship_owner    Global Hardware Safety & Lighting Systems Engin
retention_policy    10-Year Active Product Lifecycle Archival
lakehouse_cross_ref_table    lakehouse.your-project-id.retail_hardware
governance_status    VERIFIED_PRODUCTION

=== Live Attached Aspect: dark-data-extracted-metadata ===
Catalog Field    Authoritative Stored Value
document_title    LUM-LIG-DES-8G8J Contemporary Linen Desk Lamp
domain_ontology    Electrical Hardware & Lighting Systems
operational_hazard_level    MEDIUM
author_provenance    Global Hardware Safety & Lighting Systems Engin
version_provenance    Rev 4.2
document_summary    This document outlines standard operating proce
confidence_score    0.99

Xác minh kép

  • Track 1 (Xác minh bằng giao diện dòng lệnh): Kiểm tra mục nhập với tất cả các khía cạnh được đính kèm thông qua gcloud:
    gcloud dataplex entries describe sop-manuals-fileset-lum8g8j \
      --entry-group=dark-data-fileset-group \
      --location=$REGION \
      --view=ALL
    
  • Track 2 (Console UI Inspection):
    1. Mở Knowledge Catalog Search Console, tìm kiếm LUM-LIG-DES-8G8J Unstructured SOP & Technical Manual Fileset (sop-manuals-fileset-lum8g8j) rồi chọn mục phù hợp trong kết quả.
    2. Trong phần Thẻ và khía cạnh không bắt buộc, hãy xác minh rằng cả Siêu dữ liệu được trích xuất đa phương thức từ dữ liệu không rõ ràng và Khía cạnh quản trị tài liệu và bảng tham chiếu chéo về kho tài liệu đều hiển thị cấp độ nguy hiểm (MEDIUM), mã tuân thủ (UL-153, FCC Part 15, CE-LVD, RoHS) và chuỗi bảng tham chiếu chéo (lakehouse_cross_ref_table) đã được trích xuất.

8. Truy vấn dữ liệu tối được quản lý trong danh mục

Sau khi các khía cạnh tuỳ chỉnh được đính kèm, người dùng có thể tìm thấy các sổ tay PDF không có cấu trúc trong Cloud Storage thông qua tính năng tìm kiếm Danh mục tri thức (catalog_client.search_entries()).

Thăm dò ý kiến search_entries() trong step6_search_catalog.py

step6_search_catalog.py thăm dò ý kiến search_entries() với thời gian đợi luỹ thừa và đọc các khoá khía cạnh được chuẩn hoá thông qua .endswith():

search_query = f"entrygroup={entry_group_resource_name} name:{FILESET_ENTRY_ID}"

while elapsed_seconds < max_wait_seconds:
    catalog_search_results = list(
        catalog_client.search_entries(
            request=dataplex_v1.SearchEntriesRequest(
                name=parent_location,
                query=search_query,
            )
        )
    )
    if catalog_search_results:
        break
    backoff_seconds = min(5 * (2 ** attempt), 30)
    time.sleep(backoff_seconds)
    ...

for k, asp in detailed_entry.aspects.items():
    if k.endswith(f".{REGION}.{EXTRACTED_ASPECT_TYPE_ID}"):
        print(f"    Domain Ontology     : {asp.data.get('domain_ontology')}")
        print(f"    Hazard Level        : {asp.data.get('operational_hazard_level')}")
    elif k.endswith(f".{REGION}.{GOVERNANCE_ASPECT_TYPE_ID}"):
        print(f"    Compliance Codes    : {asp.data.get('compliance_classifications')}")
        print(f"    Lakehouse Join Table: {asp.data.get('lakehouse_cross_ref_table')}")

Chạy step6_search_catalog.py

python3 step6_search_catalog.py
Executing Knowledge Catalog search query:
  'entrygroup=projects/your-project-id/locations/us-central1/entryGroups/
  dark-data-fileset-group name:sop-manuals-fileset-lum8g8j'...

✓ Discovered 1 governed asset(s) in Knowledge Catalog:

[1] Entry Resource Name :
    projects/your-project-id/locations/us-central1/entryGroups/
    dark-data-fileset-group/entries/sop-manuals-fileset-lum8g8j
    Fully Qualified Name: gcs:your-project-id-dark-data-manuals
    Entry Type :
    projects/your-project-id/locations/us-central1/entryTypes/
    unstructured-pdf-fileset
    Physical Storage URI:
    gs://your-project-id-dark-data-manuals/sop-pdfs/LUM-LIG-DES-8G8J_manual.pdf
    Domain Ontology     : Electrical Hardware & Lighting Systems
    Hazard Level        : MEDIUM
    Compliance Codes    : UL-153 Portable Luminaires, FCC Part 15, CE-LVD, RoHS
    Lakehouse Join Table:
    lakehouse.your-project-id.retail_hardware.luminaire_sku_inventory_iceberg

Xác minh kép

  • Lộ trình 1 (Tìm kiếm bằng giao diện dòng lệnh): Truy vấn chỉ mục tìm kiếm trực tiếp thông qua gcloud:
    gcloud dataplex entries search "name:sop-manuals-fileset-lum8g8j" --project=$PROJECT_ID
    
  • Track 2 (Tìm kiếm bằng ngôn ngữ tự nhiên trên giao diện người dùng của bảng điều khiển):
    1. Mở Search Console cho Danh mục tri thức rồi tìm LUM-LIG-DES-8G8J hoặc UL-153.
    2. Quan sát cách Danh mục kiến thức hiển thị mục nhập được quản lý của nhóm tệp PDF Cloud Storage và các khía cạnh siêu dữ liệu được đính kèm.

9. Xác minh các khẳng định về hoạt động quản trị hai đầu

step7_verify_assertions.py chạy các câu khẳng định xác định đối với các phản hồi của lớp điều khiển Danh mục kiến thức đang hoạt động để xác minh rằng EntryGroup, EntryType, cả bản thiết kế tuỳ chỉnh AspectType, tải trọng khía cạnh EntryView.ALL được liên kết (giới hạn confidence_score và chuỗi lakehouse_cross_ref_table) và việc khám phá chỉ mục tìm kiếm đều thành công:

verify_eg = catalog_client.get_entry_group(name=entry_group_resource_name)
assert verify_eg.name == entry_group_resource_name, "EntryGroup resource name mismatch."

verify_entry = catalog_client.get_entry(
    request=dataplex_v1.GetEntryRequest(
        name=fileset_entry_name,
        view=dataplex_v1.EntryView.ALL,
    )
)
bound_extracted = next(
    (
        asp for k, asp in verify_entry.aspects.items()
        if k.endswith(f".{REGION}.{EXTRACTED_ASPECT_TYPE_ID}")
    ),
    None,
)
bound_governance = next(
    (
        asp for k, asp in verify_entry.aspects.items()
        if k.endswith(f".{REGION}.{GOVERNANCE_ASPECT_TYPE_ID}")
    ),
    None,
)

assert bound_extracted is not None, f"Aspect '{EXTRACTED_ASPECT_TYPE_ID}' not found on live Entry."
assert bound_governance is not None, (
    f"Aspect '{GOVERNANCE_ASPECT_TYPE_ID}' not found on live Entry."
)
assert (
    bound_extracted.data.get("document_title") == expected_extraction["document_title"]
), "Extracted title mismatch."
assert (
    0.0 <= float(bound_extracted.data.get("confidence_score", -1.0)) <= 1.0
), "Invalid confidence score in catalog."
assert (
    "lakehouse" in str(bound_governance.data.get("lakehouse_cross_ref_table", "")).lower()
), "Missing Lakehouse cross-reference."
...
assert len(search_results) >= 1, "Expected at least 1 search result in Knowledge Catalog."

Chạy step7_verify_assertions.py

python3 step7_verify_assertions.py && echo "Verification exit code: $?"
Running substantive end-to-end verification assertions...
✓ All 5 substantive verification assertions passed
  against live Google Cloud control plane state!
Verification exit code: 0

10. Thiết kế một quy trình dựa trên sự kiện

Mặc dù việc chạy tập lệnh Python một cách tương tác trong Cloud Shell là lựa chọn lý tưởng để xây dựng và kiểm thử các hợp đồng quản trị của bạn, nhưng các môi trường doanh nghiệp nhận được hàng nghìn sổ tay kỹ thuật PDF mới hoặc đã sửa đổi, chứng chỉ tuân thủ của nhà cung cấp và tài liệu SOP hằng ngày từ ERP, Quản lý vòng đời sản phẩm (PLM) và cổng thông tin của nhà cung cấp. Việc chạy tập lệnh hàng loạt theo cách thủ công sẽ nhanh chóng tạo ra các điểm mù về hoạt động quản trị giữa quá trình tải tài liệu lên và lập chỉ mục danh mục.

Trong quá trình sản xuất, các nhóm nền tảng sẽ vận hành chính xác mã mà bạn đã chạy ở Bước 4 và 5 dưới dạng một quy trình không cần thao tác, dựa trên sự kiện:

Quy trình xử lý dữ liệu tối không dựa trên sự kiện

  1. Liên tục nhập tài liệu (Cloud Storage → Eventarc): Bất cứ khi nào một hướng dẫn mới ở định dạng PDF được tải lên hoặc một bản sửa đổi mới ghi đè một đối tượng hiện có trong Cloud Storage, vùng chứa sẽ phát ra một CloudEvent google.cloud.storage.object.v1.finalized chứa mã nhận dạng vùng chứa, đường dẫn đối tượng và số thế hệ đối tượng.
  2. Trích xuất đa phương thức không trạng thái (Eventarc → Cloud Run → Gemini Enterprise Agent Platform): Eventarc định tuyến CloudEvent đến một worker Cloud Run không máy chủ đóng gói schemas.py, step4_extract_metadata.py và step5_attach_aspects.py. Worker truyền trực tuyến các byte PDF đến Nền tảng Tác nhân Gemini Enterprise với response_schema được thực thi, đảm bảo rằng mọi thuộc tính được trích xuất đều tuân thủ DarkDataExtractedMetadata và DocumentGovernanceMetadata.
  3. Cập nhật lớp điều khiển phẫu thuật (Cloud Run → Knowledge Catalog): Worker phân giải Fileset mẹ Entry và thực thi catalog_client.update_entry() bằng update_mask={"paths": ["aspects"]} và aspect_keys rõ ràng. Ngay cả khi hàng chục tài liệu hoàn tất quá trình xử lý cùng lúc, mỗi đột biến chỉ cập nhật các khoá khía cạnh được chỉ định.
  4. Kiểm soát cách ly dựa trên độ tin cậy: Nếu một tệp PDF cũ được quét cho ra kết quả trích xuất confidence_score dưới ngưỡng hoạt động của bạn (ví dụ: < 0.85), thì nhân viên sẽ đặt governance_status = "PENDING_STEWARD_REVIEW" cho khía cạnh được đính kèm để người quản lý dữ liệu có thể truy vấn Danh mục kiến thức về những tài sản có độ tin cậy thấp cần được con người xem xét.

Cách các doanh nghiệp áp dụng mẫu này trong phiên bản chính thức

Trường hợp sử dụng cho doanh nghiệp

Cách hoạt động của Siêu dữ liệu dưới dạng mã trong thực tế

Tác động đến hoạt động kinh doanh

Kiểm tra quy định tự động và khả năng thu hồi
(Sản xuất, phần cứng và năng lượng)

Các hệ thống tuân thủ kết hợp các khía cạnh an toàn của tệp PDF không có cấu trúc (compliance_classifications, operational_hazard_level) với các bảng hàng tồn kho SKU có cấu trúc (lakehouse_cross_ref_table) trong BigQuery và Lakehouse cho Apache Iceberg.

Khi một tiêu chuẩn như UL-153 hoặc CE-LVD được cập nhật, các kiểm toán viên sẽ xác định mọi SKU phần cứng và vị trí kho hàng bị ảnh hưởng trong vài giây thay vì phải mở hàng nghìn thư mục PDF theo cách thủ công.

Các tác nhân AI có cơ sở và tính năng lọc trước RAG
(Trợ lý kiến thức doanh nghiệp)

Trước khi một tác nhân tạo nội dung tăng cường khả năng truy xuất (RAG) trên Nền tảng Tác nhân Gemini Enterprise trả lời câu hỏi của kỹ sư hiện trường, tác nhân này sẽ lọc các mục trong Danh mục kiến thức theo governance_status = "VERIFIED_PRODUCTION" và version_provenance.

Ngăn chặn trợ lý AI đưa ra thông tin sai lệch hoặc trích dẫn các bản nháp kỹ thuật không còn được dùng, quy trình hoạt động chuẩn (SOP) đã hết hạn hoặc sổ tay chưa được xác minh của bên thứ ba.

Làm phong phú đồng thời nhiều nhóm
(Lưới dữ liệu phi tập trung)

Nhiều quy trình độc lập làm phong phú cùng một Fileset Entry: nhân viên kỹ thuật AI cập nhật dark-data-extracted-metadata, bộ phận Pháp lý đính kèm chính sách lưu giữ thông qua document-governance-aspect và bộ phận Bảo mật đính kèm các khía cạnh về độ nhạy của DLP.

Vì UpdateEntryRequest thay đổi phạm vi thông qua aspect_keys, nên mỗi nhóm miền triển khai và cập nhật quy trình siêu dữ liệu một cách độc lập mà không ghi đè dữ liệu quản trị của các nhóm khác.

CI/CD Schema Evolution via GitOps
(Platform & Data Engineering)

Các nhóm nền tảng lưu trữ schemas.py cùng với các định nghĩa Terraform google_dataplex_aspect_type trong Git. Các yêu cầu kéo xác thực rằng mọi trường Pydantic mới đều có một index dựa trên 1 tương ứng trong mẫu AspectType trước khi triển khai.

Loại bỏ sự khác biệt về giản đồ giữa mã trích xuất ứng dụng và lớp điều khiển Danh mục kiến thức trên các dự án dev, staging và prod.

11. Dọn dẹp môi trường

Trong Danh mục kiến thức, bạn không thể xoá các vùng chứa mẹ và mẫu giản đồ khi các mục con vẫn tham chiếu đến chúng. cleanup.py sẽ xoá các tài nguyên theo thứ tự phụ thuộc ngược nghiêm ngặt (Entry → EntryGroup → EntryType → AspectTypes → các đối tượng trong vùng chứa Cloud Storage → tệp JSON tạm thời):

# 1. Delete Fileset Entry first
catalog_client.delete_entry(name=target_entry_path)

# 2. Delete EntryGroup container
del_eg_op = catalog_client.delete_entry_group(name=target_eg_path)
if hasattr(del_eg_op, "result"):
    del_eg_op.result()

# 3. Delete EntryType and Custom AspectTypes
del_et_op = catalog_client.delete_entry_type(name=target_et_path)
if hasattr(del_et_op, "result"):
    del_et_op.result()
for aspect_id_val in (EXTRACTED_ASPECT_TYPE_ID, GOVERNANCE_ASPECT_TYPE_ID):
    target_at_path = f"{active_parent}/aspectTypes/{aspect_id_val}"
    del_at_op = catalog_client.delete_aspect_type(name=target_at_path)
    if hasattr(del_at_op, "result"):
        del_at_op.result()

Chạy cleanup.py

python3 cleanup.py
Starting reverse-dependency resource cleanup in Knowledge Catalog...
Deleted Fileset Entry:
  projects/your-project-id/locations/us-central1/entryGroups/
  dark-data-fileset-group/entries/sop-manuals-fileset-lum8g8j
Deleted EntryGroup   :
  projects/your-project-id/locations/us-central1/entryGroups/
  dark-data-fileset-group
Deleted EntryType    :
  projects/your-project-id/locations/us-central1/entryTypes/
  unstructured-pdf-fileset
Deleted AspectType   :
  projects/your-project-id/locations/us-central1/aspectTypes/
  dark-data-extracted-metadata
Deleted AspectType   :
  projects/your-project-id/locations/us-central1/aspectTypes/
  document-governance-aspect
Deleted Cloud Storage object :
  gs://your-project-id-dark-data-manuals/sop-pdfs/LUM-LIG-DES-8G8J_manual.pdf
Deleted Cloud Storage bucket : gs://your-project-id-dark-data-manuals
Removed local temporary file : extracted_metadata.json
Removed local temporary file : governance_metadata.json
✓ Standalone teardown complete. Environment cleanly reset.

Xoá thư mục kho lưu trữ được sao chép

Sau khi cleanup.py hoàn tất việc xoá các tài nguyên trên đám mây, hãy quay lại thư mục chính rồi xoá thư mục kho lưu trữ devrel-demos đã sao chép khỏi Cloud Shell:

cd ~
rm -rf ~/devrel-demos

12. Xin chúc mừng!

Bạn đã xây dựng và xác minh một quy trình quản trị Siêu dữ liệu dưới dạng mã từ đầu đến cuối, giúp chuyển đổi các tệp PDF không có cấu trúc trong Cloud Storage thành các tài sản có thể phát hiện và được thực thi theo lược đồ trong Danh mục kiến thức bằng Nền tảng tác nhân Gemini Enterprise.

Tiếp theo là gì?

  • Tự động hoá bằng Terraform: Quản lý tài nguyên google_dataplex_aspect_type và google_dataplex_entry_group một cách khai báo trong các quy trình CI/CD.
  • Triển khai Eventarc + Cloud Run Workers: Đóng gói step4_extract_metadata.py và step5_attach_aspects.py vào một dịch vụ Cloud Run dựa trên sự kiện.
  • Kết hợp khoảng không quảng cáo ở hạ nguồn trong BigQuery: Xuất siêu dữ liệu quản trị đã trích xuất (lakehouse_cross_ref_table) để kết hợp các thuộc tính tuân thủ tài liệu không có cấu trúc với các bảng khoảng không quảng cáo SKU có cấu trúc.

Tài liệu tham khảo