1. مقدمة
يتم تخزين أكثر من% 80 من بيانات المؤسسات بتنسيقات غير منظَّمة، مثل أدلة الهندسة بتنسيق PDF وإجراءات التشغيل المعيارية وشهادات الالتزام بالمعايير ومخططات المعدات المخزَّنة في Cloud Storage. بما أنّ الفهارس التقليدية تفهرس فقط مخططات الجداول العلائقية، تظل هذه المستندات "بيانات غير مرئية": غير مرئية للبحث في المؤسسات، وغير مرتبطة بجداول المستودع المنظَّمة، وغير معتمَدة للامتثال التنظيمي.
عندما يسأل مدقّق أو وكيل الذكاء الاصطناعي، "ما هي وحدات حفظ المخزون من الأجهزة التي تتطلّب شهادة أمان UL-153 وما هي مستويات المخاطر الحرارية الخاصة بها؟"، لا يمكن لفهرس يتضمّن جداول SQL فقط تقديم إجابة. يتم تخزين الحقائق داخل ملفات PDF غير منظَّمة في Cloud Storage.
الحلّ المعماري: البيانات الوصفية المتعددة الوسائط كرمز
في هذا الدرس التطبيقي حول الترميز، ستنشئ مسار Metadata-as-Code متكاملاً في Google Cloud يحوّل أدلة PDF غير منظَّمة في Cloud Storage إلى أصول Knowledge Catalog متوافقة مع المخطط باستخدام Gemini Enterprise Agent Platform (Google GenAI SDK، google-genai):

- تسجيل مجموعة الملفات (
EntryGroupوEntry): يتم تجميع ملفات PDF غير المنظَّمة في Cloud Storage في إدخالات مجموعة ملفات منطقية محكومة في Knowledge Catalog. - استخراج البيانات المتعدّدة الوسائط من Gemini (مخطط Pydantic): يستدعي Gemini Enterprise Agent Platform على وحدات بايت PDF الأولية مع التحقّق من صحة
response_schemaالحتمية. - ربط جوانب لوحة التحكّم: يربط حمولات JSON التي تم التحقّق من صحتها والمتعلّقة بالعمليات والامتثال كعناصر
Aspectمكتوبة بشكلٍ صارم في إدخال الفهرس. - استكشاف الكتالوج الموحّد: يتيح إمكانية استكشاف مجموعات ملفات PDF غير المنظَّمة والبيانات الوصفية المستخرَجة منها من خلال
SearchEntriesRequest.
المفاهيم الأساسية: عناصر التحكّم الأساسية في "كتالوج المعارف"
لنفترض أنّ فريقك يخزّن مئات من أدلة المنتجات بتنسيق PDF في Cloud Storage. لتسهيل العثور على هذه الملفات والاطّلاع عليها في كتالوج المعرفة، يمكنك التفكير في الوحدات الأساسية الخمس على أنّها طريقة لتنظيم الأدلة الورقية في خزانة ملفات مكتبية:
EntryGroup(خزانة مقفلة لفريق واحد): خزانة عليها قفل يمكن فقط لأعضاء الفريق الذين لديهم إذن (roles/dataplex.entryCreator) وضع مجلدات في الداخل. يجب إفراغ كل مجلد من الخزانة قبل أن تتمكّن من إزالة الخزانة نفسها.EntryType(تصنيف فئة مجلد): تصنيف يوضّح للمستخدمين نوع مادة العرض التي يمثّلها المجلد، مثلاً "مجموعة أدلة PDF" بدلاً من "جدول قاعدة بيانات"Entry(مجلد ملفات يتضمّن رابطًا لمساحة التخزين): هو مجلد الكتالوج الخاص بكتيبات PDF. بدلاً من الاحتفاظ بنسخ ورقية ثقيلة، يحتوي المجلد على بطاقة موقع جغرافي تشير إلى حزمة Cloud Storage الدقيقة (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}/:
المسار الأساسي والنسبي | الدور في "كتالوج المعارف" | الحذف وقاعدة "إدارة الهوية وإمكانية الوصول" |
| حاوية منطقية تجمع الإدخالات وتتحكّم في إمكانية وصول الفريق ( | يجب ألا يحتوي على أي موارد فرعية |
| تعريف الفئة لمجموعة من مواد العرض ( | يجب الحذف فقط بعد إزالة جميع الإدخالات التي تستخدم هذا النوع. |
| سجلّ الكتالوج الذي يربط معرّف موارد منتظم (URI) فعليًا لخدمة Cloud Storage ( | يقع داخل |
| نموذج مخطط قابل لإعادة الاستخدام يحدّد | يتم إنشاؤها مرة واحدة لكل منطقة ومشاركتها في جميع الإدخالات. |
| بيانات وصفية بتنسيق JSON تم التحقّق من صحتها وتتطابق مع | تم تعديلها باستخدام |
ما ستنشئه
باستخدام النصوص البرمجية المصاحبة في codelabs/metadata-as-code-lab، ستنفّذ وتفحص مسارًا مكوّنًا من 7 مراحل:
-
schemas.py: مخطّطات Dual PydanticBaseModel(DarkDataExtractedMetadataوDocumentGovernanceMetadata) مقترنة بنسبة 1:1 بنماذج كتالوج المعارفAspectType. step2_provision.py: توفير مخططاتEntryGroupوEntryTypeوAspectTypeالمخصّصة بشكل متكرّرstep3_register_fileset.py: تحميلLUM-LIG-DES-8G8J_manual.pdfإلى Cloud Storage وتسجيله كمجموعة ملفات خاضعة للإدارةEntrystep4_extract_metadata.py: اكتشاف نموذج Gemini الرئيسي الديناميكي واستخراج ملفات PDF المتعددة الوسائط باستخدامgoogle-genai-
step5_attach_aspects.pyوstep6_search_catalog.pyوstep7_verify_assertions.py: مرفق الجوانب الجراحية، والبحث في الفهرس باستخدام التراجع الأسي، وتأكيدات مستوى التحكّم الشاملة
المتطلبات الأساسية والأدوات اللازمة
- مشروع Google Cloud تم تفعيل الفوترة فيه وGoogle Cloud Shell (مثبّت مسبقًا مع
gcloudوgitوpython3وpip) - أذونات "إدارة الهوية وإمكانية الوصول" لإدارة موارد Knowledge Catalog (
roles/dataplex.admin)، وتوفير حِزم وعناصر Cloud Storage (roles/storage.admin)، واستدعاء منصة وكلاء Gemini Enterprise (roles/aiplatform.user) - متصفّح ويب، مثل Google Chrome
2. الإعداد والمتطلبات
إنشاء نسخة طبق الأصل من مستودع الرمز المرافق في Cloud Shell
افتح Google Cloud Console، وشغِّل Cloud Shell، ونفِّذ عملية استخراج جزئي لـ codelabs/metadata-as-code-lab، والتي تتضمّن دليل الهندسة بتنسيق PDF (LUM-LIG-DES-8G8J_manual.pdf) وجميع نصوص 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
ضبط متغيرات البيئة
اضبط رقم تعريف مشروعك وموقع لوحة التحكّم الإقليمية وحزمة Cloud Storage المستهدَفة في 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"
تفعيل واجهات برمجة التطبيقات وتثبيت الموارد التابعة
فعِّل واجهات برمجة التطبيقات المطلوبة في Google Cloud وثبِّت تبعيات Python (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
3- تحديد مخططات Pydantic ونماذج الجوانب
تحدّد 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 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.",
)
ثانيًا، يعكس extracted_aspect_template أسماء الحقول نفسها ويربط بين نوعَي str وfloat في Python ونوعَي string وdouble record_fields في كتالوج المعرفة. يُرجى العِلم أنّ عقد AspectType.MetadataTemplate protobuf يتطلّب أن يعرّف كل حقل في record_fields عددًا صحيحًا فريدًا وموجبًا تمامًا يبدأ من 1 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.
4. توفير مساحات الأسماء وأنواع العناصر المخصّصة
قبل تسجيل إدخالات مجموعة الملفات أو إرفاق البيانات الوصفية، يوفّر step2_provision.py ثلاثة موارد في لوحة التحكّم ضمن Knowledge Catalog:
EntryGroup:dark-data-fileset-groupEntryType:unstructured-pdf-filesetAspectTypeمخططات: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، يفرض كتالوج المعرفة المخطط على حدود واجهة برمجة التطبيقات، ويتم رفض أي طلب 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.
5. تسجيل إدخالات مجموعة الملفات غير المنظَّمة
بدلاً من إثقال الكتالوج بملايين مؤشرات الملفات المنفصلة، يجمّع كتالوج المعارف المستندات ذات الصلة في Cloud Storage (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}"): تستخدم نظام اسم النطاق المؤهّل بالكاملgcs:{bucket_name}الأساسي المطلوب من Knowledge Catalog لربط إدخال الكتالوج المنطقي بحزمة Cloud Storage الأساسية.entry_source.resource=VIRTUAL_STORAGE_URI: يخزّن معرّف الموارد المنتظم (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
6. استخراج البيانات الوصفية للمستند باستخدام Gemini
تقرأ step4_extract_metadata.py وحدات البايت الأولية لملف PDF وتستدعي Gemini Enterprise Agent Platform (genai_client.models.generate_content) باستخدام نمطَين رئيسيَّين:
1. اقتراح الطرازات الرئيسية الديناميكية
بدلاً من الترميز الثابت لسلاسل إصدارات النماذج المعرَّضة للخطأ، يستعلم النص البرمجي عن genai_client.models.list() ويصنّف المرشحين النشطين حسب (is_ga_channel, semantic_version_tuple) لاختيار أحدث نموذج flash متاح للجميع:
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. استخراج الوسائط المتعددة المستند إلى المخطط (Part.from_bytes + response_schema)
يؤدي تمرير response_mime_type="application/json" وresponse_schema=DarkDataExtractedMetadata (متبوعًا بـ DocumentGovernanceMetadata) إلى تقييد فك ترميز الرمز المميّز مباشرةً بمخطط Pydantic JSON:
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
7. إرفاق الجوانب التي تم التحقّق من صحتها بإدخالات الكتالوج
يربط step5_attach_aspects.py حمولات JSON التي تم التحقّق من صحتها (extracted_metadata.json وgovernance_metadata.json) بالإدخال sop-manuals-fileset-lum8g8j من خلال catalog_client.update_entry().
تغيير في سمة المنتج في 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
التحقّق من صحة المعلومات بطريقتَين
- المسار 1 (التحقّق من واجهة سطر الأوامر): افحص الإدخال مع جميع الجوانب المرفقة من خلال
gcloud:gcloud dataplex entries describe sop-manuals-fileset-lum8g8j \ --entry-group=dark-data-fileset-group \ --location=$REGION \ --view=ALL - المسار 2 (فحص واجهة مستخدم Console):
- افتح Knowledge Catalog Search Console، وابحث عن LUM-LIG-DES-8G8J Unstructured SOP & Technical Manual Fileset (
sop-manuals-fileset-lum8g8j)، ثم اختَر الإدخال المطابق من النتائج. - ضمن العلامات والجوانب الاختيارية، تأكَّد من أنّ كلاً من البيانات الوصفية المستخرَجة المتعدّدة الوسائط من البيانات غير المنظَّمة وجانب إدارة المستندات والمقارنة بين مصادر بيانات متعددة للمستودع يعرضان مستوى الخطورة المستخرَج (
MEDIUM) ورموز الامتثال (UL-153, FCC Part 15, CE-LVD, RoHS) وسلسلة جدول المقارنة بين مصادر بيانات متعددة (lakehouse_cross_ref_table).
- افتح Knowledge Catalog Search Console، وابحث عن LUM-LIG-DES-8G8J Unstructured SOP & Technical Manual Fileset (
8. طلب البحث عن البيانات غير المنظَّمة الخاضعة للحوكمة في الكتالوج
بعد إرفاق الجوانب المخصّصة، يمكن العثور على أدلة PDF غير منظَّمة في Cloud Storage من خلال البحث في Knowledge Catalog (catalog_client.search_entries()).
استطلاع search_entries() في step6_search_catalog.py
تستطلع step6_search_catalog.pysearch_entries() باستخدام خوارزمية الرقود الأسي الثنائي وتقرأ مفاتيح السمة التي تم تحديد عنوان URL الأساسي لها من خلال .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
التحقّق من صحة المعلومات بطريقتَين
- المسار 1 (البحث باستخدام واجهة سطر الأوامر): يمكنك البحث في فهرس البحث مباشرةً من خلال
gcloud:gcloud dataplex entries search "name:sop-manuals-fileset-lum8g8j" --project=$PROJECT_ID - المسار 2 (البحث باللغة الطبيعية في واجهة مستخدم Console):
- افتح Knowledge Catalog Search Console وابحث عن
LUM-LIG-DES-8G8JأوUL-153. - لاحظ كيف يعرض كتالوج المعرفة إدخال مجموعة ملفات PDF المُدارة في Cloud Storage وجوانب البيانات الوصفية المرفقة به.
- افتح Knowledge Catalog Search Console وابحث عن
9. التحقّق من صحة تأكيدات إدارة التشفير التام بين الأطراف
تُجري 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
10. تصميم مسار مستند إلى الأحداث
في حين أنّ تنفيذ نصوص Python البرمجية بشكل تفاعلي في Cloud Shell هو الخيار الأمثل لإنشاء عقود الحوكمة واختبارها، تتلقّى بيئات المؤسسات الآلاف من أدلة الهندسة الجديدة أو المعدّلة بتنسيق PDF وشهادات امتثال المورّدين ومستندات إجراءات التشغيل المعيارية (SOP) يوميًا من أنظمة تخطيط موارد المؤسسات (ERP) وإدارة دورة حياة المنتج (PLM) وبوابات المورّدين. يؤدي تشغيل نصوص برمجية مجمّعة يدويًا إلى إنشاء ثغرات في الحوكمة بين تحميل المستند وفهرسة الكتالوج.
في مرحلة الإنتاج، تعمل فِرق المنصات على تشغيل الرمز البرمجي الذي نفّذته في الخطوتَين 4 و5 كمسار آلي يعتمد على الأحداث ولا يتطلّب أي تدخل:

- إدخال المستندات بشكل متواصل (
Cloud Storage→Eventarc): عندما يتم تحميل دليل PDF جديد أو عندما تحلّ مراجعة جديدة محلّ عنصر حالي في Cloud Storage، تُصدر الحزمة حدثgoogle.cloud.storage.object.v1.finalizedCloudEvent يحتوي على معرّف الحزمة ومسار العنصر ورقم إنشاء العنصر. - الاستخراج المتعدّد الوسائط بدون حالة (
Eventarc→Cloud Run→Gemini Enterprise Agent Platform): توجّه خدمة Eventarc حدث CloudEvent إلى عامل Cloud Run بدون خادم يضمّschemas.pyوstep4_extract_metadata.pyوstep5_attach_aspects.py. يبث العامل وحدات بايت PDF إلى Gemini Enterprise Agent Platform مع فرضresponse_schema، ما يضمن أنّ كل سمة مستخرَجة تتوافق معDarkDataExtractedMetadataوDocumentGovernanceMetadata. - تعديل "لوحة التحكّم الدقيقة" (
Cloud Run←Knowledge Catalog): يحلّ المنفِّذ مجموعة ملفات الأصلEntryوينفّذcatalog_client.update_entry()باستخدامupdate_mask={"paths": ["aspects"]}وaspect_keysالصريح. حتى إذا انتهت معالجة عشرات المستندات في الوقت نفسه، لا يعدّل كل تغيير إلا مفاتيح الجوانب المحدّدة. - الحجر الصحي الذي يتطلّب إذنًا من المشرف: إذا أدّى فحص ملف PDF قديم إلى استخراج قيمة
confidence_scoreأقل من الحد الأدنى التشغيلي (على سبيل المثال،< 0.85)، يضبط العامل القيمةgovernance_status = "PENDING_STEWARD_REVIEW"على العنصر المرفق لكي يتمكّن مشرفو البيانات من طلب البحث في كتالوج المعرفة عن الأصول ذات الثقة المنخفضة التي تتطلّب مراجعة بشرية.
كيفية تطبيق المؤسسات لهذا النمط في مرحلة الإنتاج
حالة استخدام Enterprise | كيف تعمل ميزة "البيانات الوصفية كرمز" عمليًا؟ | التأثير التجاري والتشغيلي |
عمليات التدقيق التنظيمية الآلية والاستعداد لعمليات الاسترجاع | تجمع أنظمة الامتثال بين جوانب الأمان غير المنظَّمة في ملفات PDF ( | عند تعديل أحد المعايير، مثل |
Grounded AI Agents & RAG Pre-Filtering | قبل أن يجيب وكيل التوليد المعزّز بالاسترجاع (RAG) على Gemini Enterprise Agent Platform عن سؤال مهندس ميداني، يفلتر إدخالات كتالوج المعرفة حسب | يمنع مساعدات الذكاء الاصطناعي من تقديم معلومات غير صحيحة أو الاستشهاد بمخططات هندسية قديمة أو إجراءات تشغيلية موحّدة منتهية الصلاحية أو أدلة غير معتمدة من جهات خارجية. |
الإثراء المتزامن لعدة فِرق | تُثري مسارات متعددة ومستقلة مجموعة الملفات نفسها | بما أنّ نطاقات |
تطوير مخطط CI/CD من خلال GitOps | تخزِّن فِرق المنصات | تجنُّب عدم تطابق المخطط بين رمز الاستخراج في التطبيق ولوحة التحكّم في فهرس المعرفة على مستوى مشاريع |
11. تنظيف البيئة
في كتالوج المعرفة، لا يمكن حذف الحاويات الرئيسية ونماذج المخطط ما دامت الإدخالات الفرعية تشير إليها. يحذف cleanup.py الموارد بترتيب عكسي صارم للاعتماد (Entry → EntryGroup → EntryType → AspectTypes → عناصر حزمة Cloud Storage → ملفات JSON المؤقتة):
# 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
12. تهانينا!
لقد أنشأت وتحقّقت من صحة مسار إدارة البيانات الوصفية كرمز المتكامل الذي يحوّل ملفات PDF غير منظَّمة في Cloud Storage إلى أصول قابلة للاستكشاف ومتوافقة مع المخطط في Knowledge Catalog باستخدام منصة وكلاء Gemini Enterprise.
ما هي الخطوات التالية؟
- الأتمتة باستخدام 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) لربط سمات امتثال المستندات غير المنظَّمة بجداول مستودع وحدات حفظ المخزون المنظَّمة.