১. ভূমিকা
এন্টারপ্রাইজ ডেটার ৮০% এরও বেশি অসংগঠিত ফরম্যাটে থাকে—যেমন পিডিএফ ইঞ্জিনিয়ারিং ম্যানুয়াল, স্ট্যান্ডার্ড অপারেটিং প্রসিডিউর (এসওপি), কমপ্লায়েন্স সার্টিফিকেট এবং ক্লাউড স্টোরেজে সংরক্ষিত ইকুইপমেন্ট স্কিমেটিকস। যেহেতু প্রচলিত ক্যাটালগগুলো শুধুমাত্র রিলেশনাল টেবিল স্কিমা ইনডেক্স করে, তাই এই ডকুমেন্টগুলো "ডার্ক ডেটা" হিসেবেই থেকে যায়: যা এন্টারপ্রাইজ সার্চের কাছে অদৃশ্য, স্ট্রাকচার্ড ইনভেন্টরি টেবিল থেকে বিচ্ছিন্ন এবং নিয়ন্ত্রক সম্মতির জন্য যাচাই করা হয় না।
যখন কোনো অডিটর বা এআই এজেন্ট জিজ্ঞাসা করে, "কোন হার্ডওয়্যার SKU-গুলোর জন্য UL-153 নিরাপত্তা সার্টিফিকেশন প্রয়োজন এবং সেগুলোর তাপীয় ঝুঁকির মাত্রা কী?" , তখন শুধুমাত্র SQL টেবিল ইনডেক্স করা একটি ক্যাটালগ তার উত্তর দিতে পারে না। আসল তথ্যগুলো ক্লাউড স্টোরেজে থাকা অসংগঠিত পিডিএফ ফাইলের ভেতরে সুরক্ষিত থাকে।
স্থাপত্য সমাধান: মাল্টিমোডাল মেটাডেটা-অ্যাজ-কোড
এই কোডল্যাবে, আপনি গুগল ক্লাউডে একটি এন্ড-টু-এন্ড মেটাডেটা-অ্যাজ-কোড পাইপলাইন তৈরি করবেন, যা জেমিনি এন্টারপ্রাইজ এজেন্ট প্ল্যাটফর্ম ( গুগল জেনএআই এসডিকে , google-genai ) ব্যবহার করে ক্লাউড স্টোরেজে থাকা অসংগঠিত পিডিএফ ম্যানুয়ালগুলোকে স্কিমা-এনফোর্সড নলেজ ক্যাটালগ অ্যাসেটে রূপান্তরিত করে।

- ফাইলসেট রেজিস্ট্রেশন (
EntryGroupওEntry) : ক্লাউড স্টোরেজে থাকা অসংগঠিত পিডিএফ ফাইলগুলোকে নলেজ ক্যাটালগে নিয়ন্ত্রিত যৌক্তিক ফাইলসেট এন্ট্রিতে শ্রেণিবদ্ধ করে। - জেমিনি মাল্টিমোডাল এক্সট্র্যাকশন ( পাইড্যান্টিক স্কিমা) : সুনির্দিষ্ট
response_schemaভ্যালিডেশন সহ কাঁচা পিডিএফ বাইটের উপর জেমিনি এন্টারপ্রাইজ এজেন্ট প্ল্যাটফর্মকে আহ্বান করে। - কন্ট্রোল প্লেন অ্যাসপেক্ট বাইন্ডিং : যাচাইকৃত অপারেশনাল এবং কমপ্লায়েন্স JSON পেলোডগুলিকে ক্যাটালগ এন্ট্রিতে স্ট্রংলি টাইপড
Aspectইনস্ট্যান্স হিসেবে সংযুক্ত করে। - একীভূত ক্যাটালগ আবিষ্কার :
SearchEntriesRequestমাধ্যমে অসংগঠিত পিডিএফ ফাইলসেট এবং সেগুলোর থেকে নিষ্কাশিত মেটাডেটাকে আবিষ্কারযোগ্য করে তোলে।
মূল ধারণা: নলেজ ক্যাটালগ কন্ট্রোল প্লেন প্রিমিটিভ
ধরুন আপনার টিম ক্লাউড স্টোরেজে শত শত পিডিএফ প্রোডাক্ট ম্যানুয়াল সংরক্ষণ করে। নলেজ ক্যাটালগে সেই ফাইলগুলো সহজে খুঁজে পাওয়া ও চেক করার জন্য, অফিসের ফাইলিং ক্যাবিনেটে কাগজের ম্যানুয়াল গোছানোর মতো করে পাঁচটি মূল উপাদানকে ভাবুন:
-
EntryGroup(একটি দলের জন্য একটি তালাবদ্ধ ক্যাবিনেট): একটি তালাযুক্ত ক্যাবিনেট। শুধুমাত্র অনুমতিপ্রাপ্ত (roles/dataplex.entryCreator) সতীর্থরাই এর ভিতরে ফোল্ডার রাখতে পারবে। ক্যাবিনেটটি সরানোর আগে আপনাকে অবশ্যই এর ভেতরের সমস্ত ফোল্ডার খালি করতে হবে। -
EntryType(ফোল্ডারের ক্যাটাগরি লেবেল): এমন একটি লেবেল যা ব্যবহারকারীদের জানায় ফোল্ডারটি কোন ধরনের অ্যাসেটকে প্রতিনিধিত্ব করে—উদাহরণস্বরূপ, "ডাটাবেস টেবিল "-এর পরিবর্তে "পিডিএফ ম্যানুয়াল কালেকশন "। -
Entry(স্টোরেজ লিঙ্ক সহ একটি ফাইল ফোল্ডার): এটি আপনার পিডিএফ ম্যানুয়ালগুলির জন্য ক্যাটালগ ফোল্ডার। ভারী কাগজের কপি রাখার পরিবর্তে, এই ফোল্ডারটিতে একটি লোকেশন কার্ড থাকে যা সঠিক ক্লাউড স্টোরেজ বাকেট (gs://...) নির্দেশ করে, যেখানে আসল পিডিএফ ফাইলগুলি থাকে। -
AspectType(একটি খালি চেকলিস্ট ফর্ম): আগে থেকে প্রিন্ট করা বক্সসহ একটি পুনঃব্যবহারযোগ্য খালি ফর্ম (উদাহরণস্বরূপ, একটি "সেফটি চেকলিস্ট" যেখানে টেক্সট হিসেবেoperational_hazard_levelএবং0.0থেকে1.0পর্যন্ত একটি সংখ্যা হিসেবেconfidence_scoreচাওয়া হয়)। আপনি এই খালি ফর্মটি একবার তৈরি করে হাজার হাজার ফোল্ডারে এটি পুনঃব্যবহার করতে পারেন। -
Aspect(একটি ফোল্ডারে সংযুক্ত পূরণ করা চেকলিস্ট): জেমিনি এন্টারপ্রাইজ এজেন্ট প্ল্যাটফর্ম পিডিএফ ম্যানুয়ালটি পড়ে এবং খালি জায়গাগুলো পূরণ করার পর, সেই সম্পূর্ণ চেকলিস্টটিEntryফোল্ডারে ক্লিপ করে দেওয়া হয়। যেহেতু প্রতিটি চেকলিস্টের নিজস্ব কী (aspect_keys) থাকে, তাই ইঞ্জিনিয়ারিং টিম এবং লিগ্যাল টিম প্রত্যেকেই একে অপরের কাজ ওভাররাইট না করে একই ফোল্ডারে তাদের নিজস্ব চেকলিস্ট সংযুক্ত করতে পারে।
পাঁচটি আঞ্চলিক সম্পদই projects/{project}/locations/{location}/ এর অধীনে অবস্থিত:
আদিম ও আপেক্ষিক পথ | নলেজ ক্যাটালগে ভূমিকা | মুছে ফেলা এবং IAM নিয়ম |
| যৌক্তিক কন্টেইনার যা এন্ট্রিগুলিকে একত্রিত করে এবং দলের অ্যাক্সেস নিয়ন্ত্রণ করে ( | মুছে ফেলার আগে এতে অবশ্যই কোনো চাইল্ড |
| এক শ্রেণীর সম্পদের জন্য বিভাগের সংজ্ঞা ( | এই ধরনের সমস্ত এন্ট্রি মুছে ফেলার পরেই কেবল ডিলিট করুন। |
| একটি ক্যাটালগ রেকর্ড যা একটি ভৌত ক্লাউড স্টোরেজ URI ( | এটি একটি |
| পুনরায় ব্যবহারযোগ্য স্কিমা টেমপ্লেট যা টাইপ করা | প্রতিটি অঞ্চলের জন্য একবার তৈরি করা হয় এবং সমস্ত এন্ট্রিতে শেয়ার করা হয়। |
| | |
আপনি যা তৈরি করবেন
codelabs/metadata-as-code-lab এ থাকা সহায়ক স্ক্রিপ্টগুলো ব্যবহার করে, আপনি একটি ৭-পর্যায়ের পাইপলাইন চালাবেন এবং পরীক্ষা করবেন:
-
schemas.py— দুটি পাইড্যান্টিকBaseModelস্কিমা (DarkDataExtractedMetadataএবংDocumentGovernanceMetadata), যা নলেজ ক্যাটালগAspectTypeটেমপ্লেটের সাথে ১:১ অনুপাতে যুক্ত। -
step2_provision.py— কাস্টমEntryGroup,EntryType, এবংAspectTypeব্লুপ্রিন্টগুলির আইডম্পোটেন্ট প্রোভিশনিং। -
step3_register_fileset.py— ক্লাউড স্টোরেজেLUM-LIG-DES-8G8J_manual.pdfফাইলটি আপলোড করা এবং একটি নিয়ন্ত্রিত ফাইলসেটEntryহিসেবে নিবন্ধন করা। -
step4_extract_metadata.py—google-genaiব্যবহার করে ডাইনামিক ফ্ল্যাগশিপ জেমিনি মডেল শনাক্তকরণ এবং মাল্টিমোডাল পিডিএফ নিষ্কাশন। -
step5_attach_aspects.py,step6_search_catalog.py, &step7_verify_assertions.py— সার্জিক্যাল অ্যাসপেক্ট অ্যাটাচমেন্ট, এক্সপোনেনশিয়াল-ব্যাকঅফ ক্যাটালগ সার্চ, এবং এন্ড-টু-এন্ড কন্ট্রোল প্লেন অ্যাসারশন।
পূর্বশর্ত ও আপনার যা যা প্রয়োজন হবে
- বিলিং সক্ষম এবং গুগল ক্লাউড শেল (
gcloud,git,python3, এবংpipসহ আগে থেকে ইনস্টল করা) সহ একটি গুগল ক্লাউড প্রজেক্ট। - নলেজ ক্যাটালগ রিসোর্স পরিচালনা (
roles/dataplex.admin), ক্লাউড স্টোরেজ বাকেট ও অবজেক্ট প্রোভিশন (roles/storage.admin), এবং জেমিনি এন্টারপ্রাইজ এজেন্ট প্ল্যাটফর্ম আহ্বান (roles/aiplatform.user) করার জন্য IAM অনুমতি। - গুগল ক্রোমের মতো একটি ওয়েব ব্রাউজার।
২. সেটআপ এবং প্রয়োজনীয়তা
ক্লাউড শেলে কম্প্যানিয়ন রিপোজিটরিটি ক্লোন করুন।
Google Cloud Console খুলুন, Cloud Shell চালু করুন, এবং codelabs/metadata-as-code-lab এর একটি স্পার্স চেকআউট সম্পাদন করুন, যার মধ্যে নমুনা পিডিএফ ইঞ্জিনিয়ারিং ম্যানুয়াল ( 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
পরিবেশ ভেরিয়েবল কনফিগার করুন
ক্লাউড শেলে আপনার প্রজেক্ট আইডি, আঞ্চলিক কন্ট্রোল প্লেন লোকেশন এবং টার্গেট ক্লাউড স্টোরেজ বাকেট সেট করুন:
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"
এপিআই সক্রিয় করুন এবং নির্ভরতা ইনস্টল করুন
requirements.txt থেকে প্রয়োজনীয় Google Cloud API-গুলো সক্রিয় করুন এবং Python নির্ভরতাগুলো ( google-genai , google-cloud-dataplex , pydantic , এবং pandas ) ইনস্টল করুন।
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 দুটি পরিপূরক কন্ট্রাক্ট সংজ্ঞায়িত করে, যা ক্লায়েন্ট-সাইড পাইড্যান্টিক ভ্যালিডেশনকে সার্ভার-সাইড নলেজ ক্যাটালগ AspectType টেমপ্লেটের সাথে যুক্ত করে:
-
DarkDataExtractedMetadata: পিডিএফ থেকে নিষ্কাশিত কার্যক্ষম বৈশিষ্ট্যসমূহ (ডকুমেন্টের শিরোনাম, ডোমেইন অনটোলজি, নিরাপত্তা ঝুঁকির স্তর, রচনার/সংস্করণের উৎস, কার্যনির্বাহী সারাংশ, এবং নিষ্কাশন আত্মবিশ্বাস স্কোর)। -
DocumentGovernanceMetadata: নিয়ন্ত্রক সম্মতি কোড (UL-153, FCC পার্ট 15, CE-LVD, RoHS), তত্ত্বাবধানের মালিক, সংরক্ষণ নীতি, এবং পিডিএফ ম্যানুয়ালটিকে পরবর্তী ইনভেন্টরি টেবিলের সাথে সংযুক্ত করার জন্য একটি রেফারেন্স টেবিল শনাক্তকারী স্ট্রিং (lakehouse_cross_ref_table)।
schemas.py পরিদর্শন করুন
প্রথমত, DarkDataExtractedMetadata Gemini Enterprise Agent Platform- এর JSON আউটপুটকে সীমাবদ্ধ করতে Pydantic Field constraints ( confidence_score এর উপর ge=0.0, le=1.0 , যার অর্থ বৃহত্তর/ক্ষুদ্রতর বা সমান) ব্যবহার করে:
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 সাথে ম্যাপ করে। উল্লেখ্য যে, AspectType.MetadataTemplate প্রোটোবাফ চুক্তি অনুযায়ী 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 সীমানায় স্কিমাটি প্রয়োগ করে—এরপর confidence_score ( double )-এ স্ট্রিং পাস করে এমন যেকোনো update_entry() কল প্রত্যাখ্যান করা হয়।
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,
)
Entry তে দুটি URI ফিল্ডের স্বতন্ত্র ভূমিকাগুলো লক্ষ্য করুন:
-
fully_qualified_name=fully_qualified_fileset_uri(f"gcs:{BUCKET_NAME}"): নলেজ ক্যাটালগের জন্য প্রয়োজনীয় ক্যানোনিকালgcs:{bucket_name}FQN স্কিম ব্যবহার করে, যা লজিক্যাল ক্যাটালগ এন্ট্রিকে অন্তর্নিহিত ক্লাউড স্টোরেজ বাকেটের সাথে সম্পর্কযুক্ত করে। -
entry_source.resource=VIRTUAL_STORAGE_URI: ডাউনস্ট্রিম এক্সট্র্যাকশন ওয়ার্কারদের দ্বারা পরিদর্শিত ফিজিক্যালgs://অবজেক্ট URI সংরক্ষণ করে।
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
৬. জেমিনি ব্যবহার করে ডকুমেন্টের মেটাডেটা বের করুন।
step4_extract_metadata.py কাঁচা PDF বাইটগুলি পড়ে এবং দুটি মূল প্যাটার্ন ব্যবহার করে Gemini Enterprise Agent Platform ( genai_client.models.generate_content ) চালু করে:
১. গতিশীল ফ্ল্যাগশিপ মডেল আবিষ্কার
ভঙ্গুর মডেল ভার্সন স্ট্রিং হার্ডকোড করার পরিবর্তে, স্ক্রিপ্টটি genai_client.models.list() কোয়েরি করে এবং সর্বাধুনিক জেনারেল অ্যাভেইলেবিলিটি (GA) flash মডেলটি বেছে নেওয়ার জন্য সক্রিয় ক্যান্ডিডেটদের (is_ga_channel, semantic_version_tuple) অনুসারে সাজায়:
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 স্কিমার মধ্যে সীমাবদ্ধ থাকে:
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 catalog_client.update_entry() এর মাধ্যমে যাচাইকৃত JSON পেলোডগুলো ( extracted_metadata.json এবং governance_metadata.json ) 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
দ্বৈত-ট্র্যাক যাচাইকরণ
- ট্র্যাক ১ (সিএলআই যাচাইকরণ):
gcloudএর মাধ্যমে সমস্ত সংযুক্ত দিকসহ এন্ট্রিটি পরিদর্শন করুন:gcloud dataplex entries describe sop-manuals-fileset-lum8g8j \ --entry-group=dark-data-fileset-group \ --location=$REGION \ --view=ALL - ট্র্যাক ২ (কনসোল UI পরিদর্শন):
- নলেজ ক্যাটালগ সার্চ কনসোল খুলুন, LUM-LIG-DES-8G8J আনস্ট্রাকচার্ড এসওপি ও টেকনিক্যাল ম্যানুয়াল ফাইলসেট (
sop-manuals-fileset-lum8g8j) লিখে সার্চ করুন এবং ফলাফল থেকে মিলে যাওয়া এন্ট্রিটি নির্বাচন করুন। - ঐচ্ছিক ট্যাগ এবং দিকগুলির অধীনে, যাচাই করুন যে ডার্ক ডেটা মাল্টিমোডাল এক্সট্র্যাক্টেড মেটাডেটা এবং ডকুমেন্ট গভর্নেন্স ও ইনভেন্টরি ক্রস-রেফারেন্স দিক উভয়ই নিষ্কাশিত ঝুঁকির স্তর (
MEDIUM), কমপ্লায়েন্স কোড (UL-153, FCC Part 15, CE-LVD, RoHS) এবং ক্রস-রেফারেন্স টেবিল স্ট্রিং (lakehouse_cross_ref_table) প্রদর্শন করছে।
- নলেজ ক্যাটালগ সার্চ কনসোল খুলুন, LUM-LIG-DES-8G8J আনস্ট্রাকচার্ড এসওপি ও টেকনিক্যাল ম্যানুয়াল ফাইলসেট (
৮. ক্যাটালগে কোয়েরি দ্বারা নিয়ন্ত্রিত ডার্ক ডেটা
কাস্টম অ্যাস্পেক্ট সংযুক্ত করা হলে, ক্লাউড স্টোরেজে থাকা অসংগঠিত পিডিএফ ম্যানুয়ালগুলি নলেজ ক্যাটালগ অনুসন্ধানের ( catalog_client.search_entries() ) মাধ্যমে খুঁজে পাওয়া যায়।
step6_search_catalog.py তে search_entries() পোলিং করা হচ্ছে
step6_search_catalog.py এক্সপোনেনশিয়াল ব্যাকঅফ সহ search_entries() পোল করে এবং .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
দ্বৈত-ট্র্যাক যাচাইকরণ
- ট্র্যাক ১ (সিএলআই সার্চ):
gcloudএর মাধ্যমে সরাসরি সার্চ ইনডেক্স কোয়েরি করুন:gcloud dataplex entries search "name:sop-manuals-fileset-lum8g8j" --project=$PROJECT_ID - ট্র্যাক ২ (কনসোল ইউআই স্বাভাবিক ভাষার অনুসন্ধান):
- নলেজ ক্যাটালগ সার্চ কনসোলটি খুলুন এবং
LUM-LIG-DES-8G8JঅথবাUL-153লিখে অনুসন্ধান করুন। - লক্ষ্য করুন কিভাবে নলেজ ক্যাটালগ নিয়ন্ত্রিত ক্লাউড স্টোরেজ পিডিএফ ফাইলসেট এন্ট্রি এবং এর সাথে সংযুক্ত মেটাডেটা দিকগুলো প্রদর্শন করে।
- নলেজ ক্যাটালগ সার্চ কনসোলটি খুলুন এবং
৯. এন্ড-টু-এন্ড গভর্নেন্স অ্যাসারশন যাচাই করুন
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
১০. একটি ইভেন্ট-চালিত পাইপলাইন ডিজাইন করুন
আপনার গভর্নেন্স চুক্তি তৈরি এবং পরীক্ষা করার জন্য ক্লাউড শেলে ইন্টারেক্টিভভাবে পাইথন স্ক্রিপ্ট চালানো আদর্শ হলেও, এন্টারপ্রাইজ পরিবেশে প্রতিদিন ERP, প্রোডাক্ট লাইফসাইকেল ম্যানেজমেন্ট (PLM) এবং ভেন্ডর পোর্টাল থেকে হাজার হাজার নতুন বা সংশোধিত পিডিএফ ইঞ্জিনিয়ারিং ম্যানুয়াল, সরবরাহকারী কমপ্লায়েন্স সার্টিফিকেট এবং SOP ডকুমেন্ট আসে। ম্যানুয়ালি ব্যাচ স্ক্রিপ্ট চালালে ডকুমেন্ট আপলোড এবং ক্যাটালগ ইনডেক্সিংয়ের মধ্যে দ্রুত গভর্নেন্স সংক্রান্ত ফাঁক তৈরি হয়।
প্রোডাকশনে, প্ল্যাটফর্ম টিমগুলো ধাপ ৪ এবং ৫-এ আপনার চালানো হুবহু কোডটিকে একটি জিরো-টাচ, ইভেন্ট-ড্রাইভেন পাইপলাইন হিসেবে কার্যকর করে:

- ক্রমাগত ডকুমেন্ট সংযোজন (
Cloud Storage→Eventarc) : যখনই কোনো নতুন পিডিএফ ম্যানুয়াল আপলোড করা হয় অথবা কোনো নতুন সংস্করণ ক্লাউড স্টোরেজে থাকা কোনো বিদ্যমান অবজেক্টকে ওভাররাইট করে, তখন বাকেটটি একটিgoogle.cloud.storage.object.v1.finalizedক্লাউডইভেন্ট নির্গত করে, যাতে বাকেট আইডেন্টিফায়ার, অবজেক্ট পাথ এবং অবজেক্ট জেনারেশন নম্বর থাকে। - স্টেটলেস মাল্টিমোডাল এক্সট্র্যাকশন (
Eventarc→Cloud Run→Gemini Enterprise Agent Platform) : ইভেন্টআর্ক ক্লাউডইভেন্টকে একটি সার্ভারলেস ক্লাউড রান ওয়ার্কারের কাছে রাউট করে, যাschemas.py,step4_extract_metadata.py, এবংstep5_attach_aspects.pyপ্যাকেজ করে। ওয়ার্কারটিresponse_schemaপ্রয়োগ করে পিডিএফ বাইটগুলোকে জেমিনি এন্টারপ্রাইজ এজেন্ট প্ল্যাটফর্মে স্ট্রিম করে, যা নিশ্চিত করে যে নিষ্কাশিত প্রতিটি অ্যাট্রিবিউটDarkDataExtractedMetadataএবংDocumentGovernanceMetadataএর সাথে সঙ্গতিপূর্ণ। - সার্জিক্যাল কন্ট্রোল প্লেন আপডেট (
Cloud Run→Knowledge Catalog) : ওয়ার্কার প্যারেন্ট ফাইলসেটEntryরিজলভ করে এবংupdate_mask={"paths": ["aspects"]}ও সুস্পষ্টaspect_keysসহcatalog_client.update_entry()এক্সিকিউট করে। এমনকি যদি কয়েক ডজন ডকুমেন্ট একই সাথে প্রসেসিং শেষ করে, প্রতিটি মিউটেশন শুধুমাত্র তার নির্ধারিত অ্যাসপেক্ট কী-গুলো আপডেট করে। - কনফিডেন্স-গেটেড স্টুয়ার্ড কোয়ারেন্টাইন : যদি কোনো স্ক্যান করা লিগ্যাসি PDF থেকে প্রাপ্ত এক্সট্র্যাকশন
confidence_scoreআপনার অপারেশনাল থ্রেশহোল্ডের নিচে নেমে আসে (উদাহরণস্বরূপ,< 0.85), তাহলে ওয়ার্কার সংযুক্ত অ্যাস্পেক্টটিতেgovernance_status = "PENDING_STEWARD_REVIEW"সেট করে দেয়, যাতে ডেটা স্টুয়ার্ডরা নলেজ ক্যাটালগ থেকে কম-কনফিডেন্সযুক্ত অ্যাসেটগুলো খুঁজে বের করতে পারে যেগুলোর জন্য মানবিক পর্যালোচনার প্রয়োজন।
কীভাবে উদ্যোগগুলি উৎপাদনে এই প্যাটার্নটি প্রয়োগ করে
এন্টারপ্রাইজ ব্যবহারের ক্ষেত্র | বাস্তবে মেটাডেটা-অ্যাজ-কোড কীভাবে কাজ করে | ব্যবসায়িক ও পরিচালনগত প্রভাব |
স্বয়ংক্রিয় নিয়ন্ত্রক নিরীক্ষা এবং প্রত্যাহার প্রস্তুতি | অ্যাপাচি আইসবার্গের জন্য বিগকোয়েরি এবং লেকহাউসে কমপ্লায়েন্স সিস্টেমগুলো অসংগঠিত পিডিএফ নিরাপত্তা দিকগুলোকে ( | যখন |
গ্রাউন্ডেড এআই এজেন্ট এবং RAG প্রি-ফিল্টারিং | জেমিনি এন্টারপ্রাইজ এজেন্ট প্ল্যাটফর্মে থাকা একটি রিট্রিভাল-অগমেন্টেড জেনারেশন (RAG) এজেন্ট কোনো ফিল্ড ইঞ্জিনিয়ারের প্রশ্নের উত্তর দেওয়ার আগে, এটি | এআই অ্যাসিস্ট্যান্টদের অলীক কল্পনা করা অথবা অপ্রচলিত ইঞ্জিনিয়ারিং ড্রাফট, মেয়াদোত্তীর্ণ এসওপি, বা যাচাইবিহীন তৃতীয় পক্ষের ম্যানুয়াল উদ্ধৃত করা থেকে বিরত রাখে। |
বহু-দলীয় যুগপৎ সমৃদ্ধি | একাধিক স্বাধীন পাইপলাইন একই ফাইলসেট | যেহেতু |
গিটঅপ্সের মাধ্যমে CI/CD স্কিমার বিবর্তন | প্ল্যাটফর্ম টিমগুলো Git-এ Terraform | |
১১. আপনার পরিবেশ পরিষ্কার করা
নলেজ ক্যাটালগে , চাইল্ড এন্ট্রিগুলো যতক্ষণ প্যারেন্ট কন্টেইনার এবং স্কিমা টেমপ্লেটকে রেফারেন্স করে, ততক্ষণ সেগুলো ডিলিট করা যায় না। 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 রিপোজিটরি ফোল্ডারটি সরিয়ে ফেলুন:
cd ~
rm -rf ~/devrel-demos
১২. অভিনন্দন!
আপনি জেমিনি এন্টারপ্রাইজ এজেন্ট প্ল্যাটফর্ম ব্যবহার করে একটি এন্ড-টু-এন্ড মেটাডেটা-অ্যাজ-কোড গভর্নেন্স পাইপলাইন তৈরি ও যাচাই করেছেন, যা ক্লাউড স্টোরেজে থাকা অসংগঠিত পিডিএফ ফাইলগুলোকে আবিষ্কারযোগ্য ও স্কিমা-সমর্থিত নলেজ ক্যাটালগ সম্পদে রূপান্তরিত করে।
এরপর কী?
- টেরাফর্ম দিয়ে স্বয়ংক্রিয় করুন : CI/CD পাইপলাইনে ডিক্লারেটিভভাবে
google_dataplex_aspect_typeএবংgoogle_dataplex_entry_groupরিসোর্সগুলো পরিচালনা করুন। - ইভেন্টআর্ক + ক্লাউড রান ওয়ার্কার স্থাপন করুন :
step4_extract_metadata.pyএবংstep5_attach_aspects.pyফাইল দুটিকে একটি ইভেন্ট-চালিত ক্লাউড রান সার্ভিসে কন্টেইনারাইজ করুন। - BigQuery- তে ডাউনস্ট্রিম ইনভেন্টরি জয়েন : আনস্ট্রাকচার্ড ডকুমেন্ট কমপ্লায়েন্স অ্যাট্রিবিউটগুলোকে স্ট্রাকচার্ড SKU ইনভেন্টরি টেবিলের সাথে জয়েন করার জন্য এক্সট্র্যাক্ট করা গভর্নেন্স মেটাডেটা (
lakehouse_cross_ref_table) এক্সপোর্ট করুন।