۱. مقدمه
بیش از ۸۰٪ از دادههای سازمانی در قالبهای بدون ساختار قرار دارند - کتابچههای راهنمای مهندسی PDF، رویههای عملیاتی استاندارد (SOPs)، گواهیهای انطباق و طرحهای تجهیزات ذخیره شده در فضای ذخیرهسازی ابری . از آنجا که کاتالوگهای سنتی فقط طرحهای جداول رابطهای را فهرست میکنند، این اسناد "دادههای تاریک" باقی میمانند: برای جستجوی سازمانی نامرئی، از جداول موجودی ساختاریافته جدا و برای انطباق با مقررات تأیید نشدهاند.
وقتی یک حسابرس یا عامل هوش مصنوعی میپرسد: «کدام SKUهای سختافزاری به گواهینامه ایمنی UL-153 نیاز دارند و سطح خطر حرارتی آنها چقدر است؟» ، کاتالوگی که فقط جداول SQL را فهرستبندی میکند، نمیتواند پاسخ دهد. حقایق در داخل فایلهای PDF بدون ساختار در فضای ذخیرهسازی ابری قفل شدهاند.
راهکار معماری: فراداده چندوجهی به عنوان کد
در این آزمایشگاه کد، شما یک خط لوله فراداده به عنوان کد سرتاسری در Google Cloud میسازید که کتابچههای راهنمای PDF بدون ساختار در Cloud Storage را با استفاده از پلتفرم Gemini Enterprise Agent ( Google GenAI SDK ، google-genai ) به داراییهای کاتالوگ دانش مبتنی بر طرحواره تبدیل میکند:

- ثبت مجموعه فایلها (
EntryGroupوEntry) : فایلهای PDF بدون ساختار در فضای ذخیرهسازی ابری را در مجموعه فایلهای منطقیِ مدیریتشده در Knowledge Catalog گروهبندی میکند. - استخراج چندوجهی Gemini ( Pydantic Schema) : پلتفرم عامل سازمانی Gemini را روی بایتهای خام PDF با اعتبارسنجی قطعی
response_schemaفراخوانی میکند. - اتصال جنبه صفحه کنترل : بارهای عملیاتی و انطباقی JSON معتبر را به عنوان نمونههای
Aspectبا نوع قوی به ورودی کاتالوگ متصل میکند. - کشف یکپارچه کاتالوگ : مجموعه فایلهای PDF بدون ساختار و فرادادههای استخراجشده از آنها را از طریق
SearchEntriesRequestقابل کشف میکند.
مفاهیم کلیدی: عناصر اولیه صفحه کنترل کاتالوگ دانش
تصور کنید تیم شما صدها دفترچه راهنمای محصول PDF را در فضای ذخیرهسازی ابری ذخیره میکند. برای اینکه بتوانید این فایلها را به راحتی پیدا کنید و در کاتالوگ دانش بررسی کنید، به پنج بلوک سازنده مانند سازماندهی دفترچههای راهنمای کاغذی در یک کابینت بایگانی اداری فکر کنید:
-
EntryGroup(یک کابینت قفلشده برای یک تیم): کابینتی با قفل روی آن. فقط همتیمیهای دارای مجوز (roles/dataplex.entryCreator) میتوانند پوشهها را داخل آن قرار دهند. قبل از اینکه بتوانید خود کابینت را بردارید، باید تمام پوشههای داخل کابینت را خالی کنید. -
EntryType(برچسب دستهبندی پوشه): برچسبی که به افراد میگوید یک پوشه نشاندهنده چه نوع دارایی است - برای مثال، به جای «جدول پایگاه داده» ، «مجموعه کتابچه راهنمای PDF» را انتخاب کنید . -
Entry(یک پوشه فایل با لینک ذخیرهسازی): پوشه کاتالوگ برای کتابچههای راهنمای PDF شما. این پوشه به جای نگهداری نسخههای کاغذی ضخیم، یک کارت مکان را در خود جای میدهد که دقیقاً به محل ذخیرهسازی ابری (gs://...) که فایلهای PDF واقعی در آن قرار دارند، اشاره میکند. -
AspectType(فرم چکلیست خالی): یک فرم خالی قابل استفاده مجدد با کادرهای از پیش چاپ شده (برای مثال، یک "چکلیست ایمنی" کهoperational_hazard_levelبه صورت متن وconfidence_scoreبه صورت عددی از0.0تا1.0درخواست میکند). شما این فرم خالی را یک بار ایجاد میکنید و آن را در هزاران پوشه دوباره استفاده میکنید. -
Aspect(یک چک لیست تکمیل شده که به یک پوشه متصل شده است): پس از اینکه Gemini Enterprise Agent Platform دفترچه راهنمای PDF را میخواند و جاهای خالی را پر میکند، آن چک لیست تکمیل شده به پوشهEntryمتصل میشود. از آنجا که هر چک لیست کلید مخصوص به خود (aspect_keys) را دارد، تیم مهندسی و تیم حقوقی میتوانند هر کدام چک لیست خود را بدون رونویسی کار یکدیگر به همان پوشه متصل کنند.
هر پنج منبع منطقهای در مسیر projects/{project}/locations/{location}/ قرار دارند:
مسیر اولیه و نسبی | نقش در کاتالوگ دانش | حذف و قانون IAM |
| یک کانتینر منطقی که ورودیها را گروهبندی کرده و دسترسی تیمی ( | قبل از حذف، باید حاوی منابع |
| تعریف دستهبندی برای یک کلاس از داراییها ( | فقط پس از حذف تمام ورودیهایی که از این نوع استفاده میکنند، حذف کنید. |
| رکورد کاتالوگ که یک URI فیزیکی فضای ذخیرهسازی ابری ( | درون یک |
| الگوی طرحواره قابل استفاده مجدد که | یک بار در هر منطقه ایجاد شده و در بین ورودیها به اشتراک گذاشته میشود. |
| متادیتای JSON اعتبارسنجی شده که با یک | با استفاده از |
آنچه خواهید ساخت
با استفاده از اسکریپتهای همراه در codelabs/metadata-as-code-lab ، یک خط لوله ۷ مرحلهای را اجرا و بررسی خواهید کرد:
-
schemas.py— طرحوارههای دوگانه PydanticBaseModel(DarkDataExtractedMetadataوDocumentGovernanceMetadata) که به صورت ۱:۱ با الگوهای Knowledge CatalogAspectTypeجفت شدهاند. -
step2_provision.py— آمادهسازی خودبهخودی طرحهای سفارشیEntryGroup،EntryTypeوAspectType. -
step3_register_fileset.py— آپلود فایلLUM-LIG-DES-8G8J_manual.pdfدر فضای ابری و ثبت آن به عنوان یکEntryمجموعه فایل تحت مدیریت. -
step4_extract_metadata.py— کشف مدل دینامیکی پرچمدار جمینی و استخراج چندوجهی PDF با استفاده ازgoogle-genai. -
step5_attach_aspects.py،step6_search_catalog.py، وstep7_verify_assertions.py— پیوست جراحی جنبه، جستجوی کاتالوگ با پسروی نمایی، و ادعاهای صفحه کنترل سرتاسری.
پیشنیازها و آنچه نیاز خواهید داشت
- یک پروژه گوگل کلود با قابلیت پرداخت و پوسته گوگل کلود (از پیش نصب شده با
gcloud،git،python3وpip). - مجوزهای IAM برای مدیریت منابع کاتالوگ دانش (
roles/dataplex.admin)، فراهم کردن سطلها و اشیاء ذخیرهسازی ابری (roles/storage.admin) و فراخوانی پلتفرم عامل سازمانی Gemini (roles/aiplatform.user). - یک مرورگر وب مانند گوگل کروم .
۲. تنظیمات و الزامات
مخزن همراه را در Cloud Shell کلون کنید
کنسول گوگل کلود را باز کنید، کلود شل را اجرا کنید و یک بررسی پراکنده از codelabs/metadata-as-code-lab انجام دهید که شامل نمونه راهنمای مهندسی PDF ( LUM-LIG-DES-8G8J_manual.pdf ) و تمام اسکریپتهای پایتون است:
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
پیکربندی متغیرهای محیطی
شناسه پروژه، موقعیت صفحه کنترل منطقهای و مخزن ذخیرهسازی ابری هدف خود را در 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"
فعال کردن APIها و نصب وابستگیها
APIهای مورد نیاز Google Cloud را فعال کنید و وابستگیهای پایتون ( google-genai ، google-cloud-dataplex ، pydantic و pandas ) را از 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
۳. طرحوارههای پیدانتیک و الگوهای جنبه را تعریف کنید
schemas.py دو قرارداد مکمل تعریف میکند که اعتبارسنجی Pydantic سمت کلاینت را با قالبهای Knowledge Catalog AspectType سمت سرور جفت میکند:
-
DarkDataExtractedMetadata: ویژگیهای عملیاتی استخراجشده از PDF (عنوان سند، هستیشناسی دامنه، سطح خطر ایمنی، منشأ نگارش/نسخه، خلاصه اجرایی و امتیاز اطمینان استخراج). -
DocumentGovernanceMetadata: کدهای انطباق با مقررات (UL-153، FCC Part 15، CE-LVD، RoHS)، مالک ناظر، سیاست نگهداری، و یک رشته شناسه جدول مرجع (lakehouse_cross_ref_table) برای پیوند دادن دفترچه راهنمای PDF به جداول موجودی پاییندستی.
بررسی schemas.py
اول، DarkDataExtractedMetadata از محدودیتهای Pydantic Field ( ge=0.0, le=1.0 ، به معنی بزرگتر/کوچکتر یا مساوی، در confidence_score ) برای محدود کردن خروجی JSON پلتفرم Gemini Enterprise Agent استفاده میکند:
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.",
)
دوم، extracted_aspect_template دقیقاً همان نام فیلدها را منعکس میکند و انواع str و float پایتون را به string و double مربوط record_fields مربوط به Knowledge Catalog نگاشت میکند. توجه داشته باشید که قرارداد AspectType.MetadataTemplate protobuf ایجاب میکند که هر فیلد در record_fields یک index عدد صحیح منحصر به فرد و کاملاً مثبت مبتنی بر ۱ ( 1 تا 7 ) اعلام کند - حذف یا تکرار index باعث میشود create_aspect_type با خطای 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 ...
},
],
}
اعتبارسنجی ماژول طرحواره
برای تأیید پیکربندی محیط و کامپایل هر دو طرحواره، schemas.py را اجرا کنید:
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.
۴. ارائه فضاهای نام و انواع جنبههای سفارشی
قبل از ثبت ورودیهای مجموعه فایل یا پیوست کردن فراداده، step2_provision.py سه منبع صفحه کنترل را در کاتالوگ دانش فراهم میکند:
-
EntryGroup:dark-data-fileset-group -
EntryType:unstructured-pdf-fileset - طرحهای
AspectType:dark-data-extracted-metadataوdocument-governance-aspect
تأمین خودکار در step2_provision.py
هر فراخوانی ساخت در step2_provision.py عملیات طولانیمدت ( op.result() ) را در یک بلوک try / except AlreadyExists قرار میدهد تا اسکریپت بتواند بدون خطا روی منابع موجود، دوباره و با خیال راحت اجرا شود:
# 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)
پس از ثبت metadata_template=extracted_aspect_template ، کاتالوگ دانش ، طرحواره را در مرز API اعمال میکند - هرگونه فراخوانی بعدی update_entry() که رشتهای را به confidence_score ( double ) ارسال کند، رد میشود.
اجرای step2_provision.py
اسکریپت تأمین را اجرا کنید و تأیید کنید که انواع جنبههای سفارشی در منطقه شما ثبت شدهاند:
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.
۵. ثبت ورودیهای بدون ساختار مجموعه فایلها
به جای شلوغ کردن کاتالوگ با میلیونها اشارهگر فایل مجزا، کاتالوگ دانش ، اسناد مرتبط در فضای ذخیرهسازی ابری ( gs://YOUR_BUCKET/sop-pdfs/*.pdf ) را در ورودیهای منطقی مجموعه فایل گروهبندی میکند - یا از طریق اسکنهای کشف خودکار ( DataScanServiceClient ) یا ثبت مستقیم برنامهنویسی ( CatalogServiceClient.create_entry ).
چگونه step3_register_fileset.py فضای ذخیرهسازی را به کاتالوگ نگاشت میکند؟
step3_register_fileset.py فایل LUM-LIG-DES-8G8J_manual.pdf را در gs://${BUCKET_NAME}/sop-pdfs/LUM-LIG-DES-8G8J_manual.pdf آپلود میکند و Entry کنترلشده را ثبت میکند:
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,
)
به نقشهای متمایز دو فیلد URI در Entry توجه کنید:
-
fully_qualified_name=fully_qualified_fileset_uri(f"gcs:{BUCKET_NAME}"): از طرح FQN استانداردgcs:{bucket_name}که توسط Knowledge Catalog مورد نیاز است، برای مرتبط کردن ورودی منطقی کاتالوگ با باکت Cloud Storage زیرین استفاده میکند. -
entry_source.resource=VIRTUAL_STORAGE_URI: آدرس فیزیکیgs://شیء که توسط کارگران استخراج پاییندستی بررسی شده است را ذخیره میکند.
اجرای 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
۶. استخراج فرادادههای سند با Gemini
step4_extract_metadata.py بایتهای خام PDF را میخواند و با استفاده از دو الگوی کلیدی، Gemini Enterprise Agent Platform ( genai_client.models.generate_content ) را فراخوانی میکند:
۱. کشف مدل پرچمدار پویا
به جای کدگذاری رشتههای نسخه مدل شکننده، اسکریپت از genai_client.models.list() پرسوجو میکند و نامزدهای فعال را بر اساس (is_ga_channel, semantic_version_tuple) مرتب میکند تا جدیدترین مدل flash دسترسی عمومی (GA) را انتخاب کند:
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)
۲. استخراج چندوجهی با محدودیت طرحواره ( Part.from_bytes + response_schema )
ارسال response_mime_type="application/json" و response_schema=DarkDataExtractedMetadata (و به دنبال آن DocumentGovernanceMetadata ) رمزگشایی توکن را مستقیماً به طرح 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)
اجرای 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
۷. جنبههای اعتبارسنجیشده را به ورودیهای کاتالوگ اضافه کنید
step5_attach_aspects.py دادههای JSON معتبر ( extracted_metadata.json و governance_metadata.json ) را از طریق catalog_client.update_entry() به ورودی sop-manuals-fileset-lum8g8j متصل میکند.
جهش جنبه جراحی در 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],
)
)
ارسال هر دو update_mask={"paths": ["aspects"]} و aspect_keys=[extracted_aspect_key, governance_aspect_key] جهش را منحصراً به این دو کلید جنبه محدود میکند - entry_source و هر جنبهای که متعلق به تیمهای دیگر است دست نخورده باقی میماند.
اجرای 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
تأیید دو مرحلهای
- مسیر ۱ (تأیید CLI): ورودی را با تمام جنبههای پیوست شده از طریق
gcloudبررسی کنید:gcloud dataplex entries describe sop-manuals-fileset-lum8g8j \ --entry-group=dark-data-fileset-group \ --location=$REGION \ --view=ALL - مسیر ۲ (بازرسی رابط کاربری کنسول):
- کنسول جستجوی کاتالوگ دانش را باز کنید، مجموعه فایل راهنمای فنی و دستورالعملهای عملیاتی بدون ساختار LUM-LIG-DES-8G8J (
sop-manuals-fileset-lum8g8j) را جستجو کنید و ورودی منطبق را از نتایج انتخاب کنید. - در بخش برچسبها و جنبههای اختیاری (Optional tags and aspects )، تأیید کنید که هر دو بخش Dark Data Multimodal Extracted Metadata و Document Governance & Inventory Cross-Reference Aspect ، سطح خطر استخراجشده (
MEDIUM)، کدهای انطباق (UL-153, FCC Part 15, CE-LVD, RoHS) و رشته جدول ارجاع متقابل (lakehouse_cross_ref_table) را نمایش میدهند.
- کنسول جستجوی کاتالوگ دانش را باز کنید، مجموعه فایل راهنمای فنی و دستورالعملهای عملیاتی بدون ساختار LUM-LIG-DES-8G8J (
۸. دادههای تاریکِ تحت کنترل پرسوجو در کاتالوگ
پس از پیوست شدن جنبههای سفارشی، کتابچههای راهنمای PDF بدون ساختار در فضای ذخیرهسازی ابری از طریق جستجوی کاتالوگ دانش ( catalog_client.search_entries() ) قابل کشف میشوند.
نمونهبرداری از search_entries() در step6_search_catalog.py
step6_search_catalog.py polls search_entries() را با backoff نمایی اجرا میکند و کلیدهای جنبه استاندارد شده را از طریق .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')}")
اجرای 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
تأیید دو مرحلهای
- مسیر ۱ (جستجوی CLI): جستجوی فهرست جستجو مستقیماً از طریق
gcloud:gcloud dataplex entries search "name:sop-manuals-fileset-lum8g8j" --project=$PROJECT_ID - مسیر ۲ (جستجوی زبان طبیعی رابط کاربری کنسول):
- کنسول جستجوی کاتالوگ دانش را باز کنید و عبارت
LUM-LIG-DES-8G8JیاUL-153را جستجو کنید. - مشاهده کنید که چگونه کاتالوگ دانش، ورودی مجموعه فایلهای PDF ذخیره سازی ابری تحت مدیریت و جنبههای فراداده پیوست شده به آن را نمایش میدهد.
- کنسول جستجوی کاتالوگ دانش را باز کنید و عبارت
۹. تأیید ادعاهای حاکمیتی سرتاسری
step7_verify_assertions.py ادعاهای قطعی را در برابر پاسخهای صفحه کنترل کاتالوگ دانش زنده اجرا میکند تا تأیید کند که EntryGroup ، EntryType ، هر دو طرح سفارشی AspectType ، بارهای جنبه محدود EntryView.ALL (محدودههای confidence_score و رشته lakehouse_cross_ref_table ) و کشف شاخص جستجو، همگی با موفقیت انجام میشوند:
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."
اجرای 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
۱۰. یک خط تولید رویداد محور طراحی کنید
اگرچه اجرای اسکریپتهای پایتون به صورت تعاملی در Cloud Shell برای ساخت و آزمایش قراردادهای نظارتی شما ایدهآل است، اما محیطهای سازمانی روزانه هزاران کتابچه راهنمای مهندسی PDF جدید یا اصلاحشده، گواهیهای انطباق با الزامات تأمینکنندگان و اسناد SOP را از ERP، مدیریت چرخه عمر محصول (PLM) و پورتالهای فروشندگان دریافت میکنند. اجرای دستی اسکریپتهای دستهای به سرعت نقاط کور نظارتی بین آپلود سند و فهرستبندی کاتالوگ ایجاد میکند.
در مرحله تولید، تیمهای پلتفرم دقیقاً همان کدی را که در مراحل ۴ و ۵ اجرا کردید، به عنوان یک خط لوله رویدادمحور و بدون نیاز به لمس، عملیاتی میکنند:

- دریافت مداوم سند (
Cloud Storage→Eventarc) : هر زمان که یک کتابچه راهنمای PDF جدید آپلود میشود یا یک نسخه جدید، یک شیء موجود در Cloud Storage را رونویسی میکند، باکت یکgoogle.cloud.storage.object.v1.finalizedCloudEvent منتشر میکند که حاوی شناسه باکت، مسیر شیء و شماره تولید شیء است. - استخراج چندوجهی بدون وضعیت (
Eventarc→Cloud Run→Gemini Enterprise Agent Platform) : Eventarc، CloudEvent را به یک Worker بدون سرور Cloud Run به نامهایschemas.py،step4_extract_metadata.pyوstep5_attach_aspects.pyهدایت میکند. Worker بایتهای PDF را با اعمالresponse_schemaبه Gemini Enterprise Agent Platform ارسال میکند و تضمین میکند که هر ویژگی استخراجشده باDarkDataExtractedMetadataوDocumentGovernanceMetadataمطابقت داشته باشد. - بهروزرسانی صفحه کنترل جراحی (
Cloud Run→Knowledge Catalog) : کارگرEntryFileset والد را حل میکند وcatalog_client.update_entry()را باupdate_mask={"paths": ["aspects"]}وaspect_keysصریح اجرا میکند. حتی اگر دهها سند به طور همزمان پردازش را تمام کنند، هر جهش فقط کلیدهای جنبه تعیین شده خود را بهروزرسانی میکند. - قرنطینهی ناظر با درِ اطمینان : اگر یک فایل PDF اسکنشدهی قدیمی،
confidence_scoreاستخراجی پایینتر از آستانهی عملیاتی شما (برای مثال،< 0.85) داشته باشد، ناظرgovernance_status = "PENDING_STEWARD_REVIEW"را روی جنبهی پیوستشده تنظیم میکند تا ناظرین داده بتوانند کاتالوگ دانش را برای داراییهای با اعتماد پایین که نیاز به بررسی انسانی دارند، جستجو کنند.
چگونه شرکتها این الگو را در تولید به کار میگیرند
مورد استفاده سازمانی | نحوه عملکرد فراداده به عنوان کد در عمل | تأثیر تجاری و عملیاتی |
ممیزیهای نظارتی خودکار و آمادگی برای فراخوان | سیستمهای انطباق، جنبههای ایمنی PDF بدون ساختار ( | وقتی استانداردی مانند |
عوامل هوش مصنوعی زمینی و پیش فیلترینگ RAG | قبل از اینکه یک عامل بازیابی-تقویتشده (RAG) در پلتفرم Gemini Enterprise Agent به سوال یک مهندس میدانی پاسخ دهد، ورودیهای کاتالوگ دانش را بر اساس | مانع از آن میشود که دستیاران هوش مصنوعی دچار توهم شوند یا به پیشنویسهای مهندسی منسوخشده، SOPهای منقضیشده یا دستورالعملهای شخص ثالث تأییدنشده استناد کنند. |
غنیسازی همزمان چند تیمی | چندین خط لوله مستقل، | از آنجا که دامنههای |
تکامل طرحواره CI/CD از طریق GitOps | تیمهای پلتفرم | انحراف طرحواره بین کد استخراج برنامه و صفحه کنترل کاتالوگ دانش در پروژههای |
۱۱. تمیز کردن محیط زیست
در Knowledge Catalog ، کانتینرهای والد و قالبهای طرحواره را نمیتوان حذف کرد، در حالی که ورودیهای فرزند هنوز به آنها ارجاع میدهند. cleanup.py منابع را به ترتیب وابستگی معکوس حذف میکند ( Entry → EntryGroup → EntryType → AspectTypes → Cloud Storage bucket objects → temporary JSON files):
# 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()
اجرای 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.
پوشه مخزن کلون شده را حذف کنید
پس از اینکه cleanup.py حذف منابع ابری را به پایان رساند، به دایرکتوری خانگی خود برگردید و پوشه مخزن devrel-demos کلون شده را از Cloud Shell حذف کنید:
cd ~
rm -rf ~/devrel-demos
۱۲. تبریک میگویم!
شما یک خط لوله مدیریت فراداده به عنوان کد (Metadata-as-Code) سرتاسری ساخته و تأیید کردهاید که فایلهای PDF بدون ساختار را در فضای ذخیرهسازی ابری (Cloud Storage) با استفاده از پلتفرم Gemini Enterprise Agent به داراییهای کاتالوگ دانش قابل کشف و مبتنی بر طرحواره تبدیل میکند.
بعدش چی؟
- خودکارسازی با Terraform : منابع
google_dataplex_aspect_typeوgoogle_dataplex_entry_groupرا به صورت اعلانی در خطوط لوله CI/CD مدیریت کنید. - استقرار Eventarc + Cloud Run Workers :
step4_extract_metadata.pyوstep5_attach_aspects.pyرا در یک سرویس Cloud Run مبتنی بر رویداد، کانتینر کنید. - اتصالات موجودی پاییندستی در BigQuery : فرادادههای حاکمیتی استخراجشده (
lakehouse_cross_ref_table) را صادر کنید تا ویژگیهای انطباق سند بدون ساختار را با جداول موجودی SKU ساختاریافته پیوند دهید.