1. مقدمة
يستكشف هذا الدرس التطبيقي حول الترميز إدارة الدخول في Agent Gateway لوكلاء الذكاء الاصطناعي المستضافين على Agent Runtime.
تتيح Agent Gateway التي تعمل في وضع الدخول (من العميل إلى الوكيل) إدارة الاتصالات بين العملاء، مثل المستخدمين النهائيين من البشر، ووكلاء أجهزة الكمبيوتر، وبيئات التطوير المتكاملة (IDE) الخاصة بالترميز، ووكلاء النظراء، وما إلى ذلك، والوكلاء المستضافين في Agent Runtime. يتم استخدام هذا الوضع لحماية البرامج من هجمات حقن الطلبات الواردة أو المحتوى الضار الذي يرسله العملاء. تتم معالجة جميع الزيارات الواردة باستخدام إضافات التفويض وModel Armor لتأمين نقطة دخول الشبكة لجميع تفاعلات الوكيل.
ما يمكنك إنشاؤه
- Agent Gateway في وضع الدخول (من العميل إلى الوكيل)
- إضافة تفويض Model Armor
- وكيل Agent Runtime ADK مع هوية الوكيل
- بيانات ملفات Cloud Storage التي يستعلم عنها الوكيل باستخدام MCP
- نماذج Model Armor لفحص طلبات واستجابات النماذج اللغوية الكبيرة
- نماذج حماية البيانات الحسّاسة لإزالة المعلومات التعريفية من البيانات
الشكل 1. بنية Codelab
ما ستتعلمه
- كيفية نشر Agent Gateway لفحص عدد الزيارات الواردة إلى أحد الوكلاء
- كيفية ضبط إضافات تفويض Model Armor وتفويضها
- كيفية إنشاء نماذج Model Armor مخصّصة ونشرها
- كيفية إنشاء نماذج مخصّصة لخدمة "حماية البيانات الحسّاسة" ونشرها
- كيفية اختبار سياسات الفحص المستندة إلى النماذج اللغوية الكبيرة والتحقّق من صحتها
ما تحتاج إليه
- مشروع Google Cloud تم تفعيل الفوترة فيه
- أذونات إدارة الهوية وإمكانية الوصول لتوفير خدمات الشبكات ومجموعات بيانات BigQuery وموارد "منصّة الوكيل"
- برنامج shell متوافق مع POSIX (
bashأوzsh) مع تثبيت واجهة سطر الأوامر (CLI) في Google Cloud (المكوّنgcloud) - أدوات سطر الأوامر:
gitوcurlوjq(معالج JSON) وPython 3 وuv(مدير حزم Python)
2. المفاهيم
أدوار توجيه حركة المرور والبوابة
تعمل "بوابة الوكيل" كخادم وكيل للشبكة يدرك الوكيل، ولكن يتغيّر دورها التشغيلي حسب اتجاه حركة البيانات:
- وضع "الوكيل إلى أي مكان" (الخروج): يعمل كخادم وكيل صادر. عندما يستدعي أحد الوكلاء أدوات قواعد البيانات الخارجية أو خوادم MCP التابعة لجهات خارجية أو واجهات برمجة التطبيقات، تدير بوابة الخروج عملية البحث عن الخدمات والتوجيه وبروتوكول TLS المتبادل (
mTLS) والإدخال الديناميكي لبيانات اعتماد OAuth والتحكّم في الوصول إلى نقاط النهاية. - وضع العميل إلى الوكيل (الدخول): يعمل كبوابة أمان للواجهة الأمامية. هدفها الأساسي هو حماية نقطة الدخول إلى وقت تشغيل تنفيذ الوكيل من خلال اعتراض الطلبات الواردة باللغة الطبيعية وتنظيفها قبل أن تصل إلى رمز الوكيل أو نماذج الذكاء الاصطناعي.
مسار Ingress إلى Agent Runtime
تتّجه طلبات العميل التي تستهدف وكيلاً مستضافًا على Agent Runtime إلى نقطة نهاية واجهة برمجة التطبيقات aiplatform.googleapis.com.
POST https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:query
يمثّل مسار الاتصال الوارد هذا إلى نقطة نهاية واجهة برمجة التطبيقات مسار الدخول من العميل إلى الوكيل.
لتأمين مسار الدخول الذي تديره Google، يتم دمج Agent Gateway مباشرةً مع Google Front End (GFE) على مستوى بنية أساسية لتقديم واجهة برمجة التطبيقات. عند نشر وكيل مُدار في Agent Runtime، تربط Google بشكلٍ أصلي سياسة منح الإذن لبوابة الدخول بطلبات العملاء الواردة على مستوى الشبكة الطرفية.
الشكل 2. إدارة الدخول باستخدام Agent Gateway إلى Agent Runtime
بما أنّ عملية الفحص تتم في مستوى الواجهة الأمامية قبل أن تدخل الطلبات إلى Agent Runtime، لا يفرض هذا التصميم أي تكاليف إضافية على الشبكة أو أي تأخير في التنقل الداخلي. تتولّى البنية الأساسية للواجهة الأمامية عملية توسيع النطاق تلقائيًا، ما يلغي الحاجة إلى إدارة نطاقات عناوين IP الداخلية أو موازنات التحميل أو مسارات نظام أسماء النطاقات المخصّصة.
تنظيف التهديدات المضمّنة باستخدام Model Armor
يتم التعامل مع تقييم بيانات اعتماد المتصل وفرض التحكّم في الوصول إلى "إدارة الهوية وإمكانية الوصول" (roles/aiplatform.user) بشكلٍ أصلي من خلال فئة استضافة واجهة برمجة التطبيقات aiplatform. لا تنفّذ بوابة الدخول نفسها عملية تفويض الهوية، بل تركّز على أمان المحتوى باستخدام إضافات التفويض التي تم إعدادها باستخدام ملف CONTENT_AUTHZ. يعمل المدخل كنقطة تنفيذ سياسة مضمّنة، حيث يعترض الطلبات باللغة الطبيعية أثناء نقلها قبل وصولها إلى حلقة الاستدلال الخاصة بوكيل الذكاء الاصطناعي أو نموذج اللغة الكبير الأساسي.
عندما يصل طلب من المستخدم إلى خدمة الواجهة الأمامية، تبدأ البوابة عملية ext_proc (معالجة خارجية) إلى خدمة إضافة تفويض Model Armor الإقليمية، والتي تنقل المكالمة إلى Model Armor dataplane. تعمل ميزة Model Armor كجدار حماية للغة الطبيعية، حيث تقيّم النص استنادًا إلى النماذج النشطة للبحث عن مخاطر السلامة والأمان:
- محاولات حقن الطلبات غير المباشرة ومحاولات تجاوز القيود
- عناوين URL ضارّة أو لغة مسيئة أو محتوى غير آمن
- تسريب المعلومات التي تكشف عن الهوية الشخصية (
PII) والبيانات الحسّاسة
إذا كان النموذج يتضمّن فلاتر حماية البيانات الحسّاسة (SDP)، سيُجري Model Armor طلب gRPC إضافيًا إلى خدمة Cloud SDP. تفحص خدمة Cloud SDP الحمولة باستخدام النموذج المحدّد، وتنفّذ أي عملية إزالة تعريف أو تنقيح مطلوبة، وتعرض النتيجة المنقّحة مرة أخرى في السلسلة ليتم إعادة توجيهها بأمان.
في حال رصد انتهاك للسياسة أو تطابق مع بيانات حساسة غير منقّحة، تحظر البوابة أو تنقّح الحمولة على الحافة قبل الدخول إلى وقت التشغيل. نتيجةً لذلك، يظل تطبيق وكيل الذكاء الاصطناعي قيد التشغيل محميًا ولا يعالج أبدًا الحِملات الضارة أو غير المنقّحة.
بهذا نكون قد انتهينا من جزء المفاهيم... لننتقل الآن إلى قسم الإعداد.
3- الإعداد
أدوار "إدارة الهوية وإمكانية الوصول" المطلوبة
يجب توفّر الأدوار التالية لإنشاء الموارد في هذا الدرس العملي:
الفئة | دور "إدارة الهوية وإمكانية الوصول" المطلوب (المعرّف) | الوصف |
إدارة واجهة برمجة التطبيقات |
| تفعيل خدمات Google Cloud API |
الشبكات والبوابة |
| Provision Agent Gateway |
إضافات الخدمات |
| ضبط إضافات التوجيه |
أمان الشبكات |
| نشر سياسات التفويض |
حماية البيانات الحساسة |
| إدارة نماذج فحص بيانات SDP وإزالة تحديد الهوية |
Model Armor |
| إنشاء نماذج الأمان وإدارتها |
منصة الوكلاء |
| نشر أحمال عمل Agent Runtime |
Cloud Storage |
| إدارة عمليات النشر ومجموعات بيانات العملاء |
إدارة "إدارة الهوية وإمكانية الوصول" |
| ربط الأذونات على مستوى المشروع بهوية الوكيل |
السجلات والتدقيق |
| فحص عمليات التتبُّع وسجلّات التدقيق |
بدلاً من ذلك، استخدِم دورًا أساسيًا واسع النطاق، مثل roles/admin أو دورًا قديمًا، مثل roles/owner.
الوصول إلى مشروعك
يستخدم هذا الدرس التطبيقي حول الترميز مشروعًا واحدًا على Google Cloud. تستخدم خطوات الإعداد واجهة سطر الأوامر gcloud وأوامر واجهة مستخدم Linux.
ابدأ بالوصول إلى سطر الأوامر في مشروعك على Google Cloud:
- Cloud Shell في
shell.cloud.google.comأو - تطبيق طرفي محلي مع
gcloudCLI مثبَّت
تحديد رقم تعريف المشروع
gcloud config set project SET_YOUR_PROJECT_ID_HERE
مصادقة الجلسة
# login to gcloud cli
gcloud auth login
# login for gcloud api
gcloud auth application-default login
ضبط متغيرات بيئة shell
# set custom var for slug (eg, "foo") and region preference
export SLUG="foo"
export REGION="us-central1"
echo ${SLUG}
echo ${REGION}
# create project vars (automatic)
export PROJ_ID=$(gcloud config list --format="value(core.project)")
export PROJ_NO=$(gcloud projects describe ${PROJ_ID} --format="value(projectNumber)")
export ORG_ID=$(gcloud projects get-ancestors ${PROJ_ID} --format="value(id)" | tail -n 1)
export USER_IDENTITY=$(gcloud config get-value account)
echo ${PROJ_ID}
echo ${PROJ_NO}
echo ${ORG_ID}
echo ${USER_IDENTITY}
# create resource vars (automatic)
export AGW_NAME="agw-${SLUG}-${REGION}-cta"
export AGW_URI="projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
export RE_AGENT_NAME="agent-crm"
export RE_AGENT_ID_SET="principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJ_NO}"
export STAGING_BUCKET="agent-staging-${PROJ_NO}"
export DATA_BUCKET="customer-data-${PROJ_NO}"
export MCP_URL="https://storage.mtls.googleapis.com/storage/mcp"
echo ${AGW_NAME}
echo ${AGW_URI}
echo ${RE_AGENT_NAME}
echo ${RE_AGENT_ID_SET}
echo ${STAGING_BUCKET}
echo ${DATA_BUCKET}
echo ${MCP_URL}
# create local dir for config files
mkdir -p cfg
تعديل gcloud cli (إجراء مُقترَح)
في حال تنفيذ عملية تثبيت مُدارة ذاتيًا لحزمة تطوير البرامج (SDK) من Google Cloud (أي خارج Cloud Shell)، يجب تعديل المكوّنات إلى أحدث إصدار.
# update gcloud cli
gcloud components update
تفعيل خدمات واجهة برمجة التطبيقات
# enable google apis (agent platform bundle, part 1)
gcloud services enable \
agentregistry.googleapis.com \
aiplatform.googleapis.com \
apphub.googleapis.com \
apptopology.googleapis.com \
cloudapiregistry.googleapis.com \
cloudtrace.googleapis.com \
compute.googleapis.com \
dataform.googleapis.com \
iam.googleapis.com \
iamconnectors.googleapis.com \
iap.googleapis.com \
logging.googleapis.com \
modelarmor.googleapis.com \
monitoring.googleapis.com \
networksecurity.googleapis.com \
networkservices.googleapis.com \
notebooks.googleapis.com \
observability.googleapis.com
# enable google apis (agent platform bundle, part 2)
gcloud services enable \
securitycenter.googleapis.com \
saasservicemgmt.googleapis.com \
storage.googleapis.com \
telemetry.googleapis.com \
texttospeech.googleapis.com
# enable google apis (all the rest)
gcloud services enable \
dlp.googleapis.com
بهذا نكون قد انتهينا من جزء الإعداد... ننتقل الآن إلى قسم البوابة.
4. البوابة
نشِّر Agent Gateway تديره Google ويعمل في وضع العميل إلى الوكيل (CLIENT_TO_AGENT). على عكس بوابات الخروج التي تتطلّب ربط "سجلّ الوكلاء" لتوجيه المكالمات الصادرة، ترتبط بوابة الدخول مباشرةً بطبقة الواجهة الأمامية لتعمل كنقطة تنفيذ مضمّنة للمطالبات الواردة التي تستهدف "وقت تشغيل الوكيل".
في حين أنّ سياسات الخروج تبدأ غالبًا في وضع DRY_RUN على مستوى البوابة، يتم نشر إدارة محتوى الدخول (CONTENT_AUTHZ) مباشرةً في الوضع المفروض. بدلاً من ذلك، يتم التحكّم في التسجيل الدقيق للتدقيق فقط أو الحظر النشط في المصدر ضمن نماذج Model Armor الفردية.
إنشاء بوابة
# create agent gateway config file
cat > cfg/${AGW_NAME}.yaml <<EOF
name: ${AGW_NAME}
protocols:
- MCP
googleManaged:
governedAccessPath: CLIENT_TO_AGENT
EOF
# import agent gateway config file (create gateway)
gcloud network-services agent-gateways import ${AGW_NAME} \
--source="cfg/${AGW_NAME}.yaml" \
--location=${REGION}
تأكيد بوابة الدفع
# list agent gateways (in region)
gcloud network-services agent-gateways list --location=${REGION}
# show agent gateway details (verify deployment state)
gcloud network-services agent-gateways describe ${AGW_NAME} --location=${REGION}
بهذا نكون قد انتهينا من جزء البوابة... لننتقل الآن إلى قسم Model Armor.
5- Model Armor
نماذج SDP
أنشئ نموذج فحص وإزالة تعريف الهوية في خدمة "حماية البيانات الحسّاسة" (SDP) لاستخدامه في نموذج الردّ في Model Armor. يضع هذا الإعداد علامة على أرقام التأمين الاجتماعي في الولايات المتحدة (SSN) لإخفائها.
إنشاء نموذج فحص
يحدّد نموذج الفحص المعلومات الحسّاسة (US_SOCIAL_SECURITY_NUMBER) في البيانات.
# create inspect template
curl -fsS -X POST "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/inspectTemplates" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" \
-d @- << EOF
{
"templateId": "agw-ssn-inspect-template",
"inspectTemplate": {
"displayName": "ssn inspect template",
"inspectConfig": {
"infoTypes": [
{ "name": "US_SOCIAL_SECURITY_NUMBER" }
],
"minLikelihood": "POSSIBLE"
}
}
}
EOF
إنشاء نموذج إزالة التعريف
يحدّد نموذج إزالة التعريف التحويل الذي سيتم تطبيقه على أرقام الضمان الاجتماعي التي يعثر عليها نموذج الفحص. في هذه الحالة، يكون التحويل هو استبدال رقم التأمين الاجتماعي بنوع المعلومات.
# create de-identify template
curl -fsS -X POST "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" \
-d @- << EOF
{
"templateId": "agw-ssn-redaction-template",
"deidentifyTemplate": {
"displayName": "SSN Redaction Template",
"deidentifyConfig": {
"infoTypeTransformations": {
"transformations": [{
"primitiveTransformation": { "replaceWithInfoTypeConfig": {} }
}]
}
}
}
}
EOF
تأكيد نماذج SDP
# get (describe) inspect template
curl -fsS -X GET "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/inspectTemplates" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" | jq
# get (describe) de-identify template
curl -fsS -X GET "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" | jq
نماذج Model Armor
نقطة النهاية التلقائية لواجهة برمجة التطبيقات Model Armor API هي نقطة نهاية عالمية (modelarmor.googleapis.com). ومع ذلك، يتم توطين موارد Model Armor الخاصة بالنماذج ومحرّكات التقييم في مناطق جغرافية محدّدة. إنّ وكيل نقطة النهاية الإقليمية (REP) أو نقطة نهاية واجهة برمجة التطبيقات الإقليمية في Google Cloud لخدمة Model Armor هو https://modelarmor.${LOCATION}.rep.googleapis.com/.
تلقائيًا، عند تشغيل gcloud model-armor ...، تحاول واجهة سطر الأوامر إرسال طلبات إلى واجهة برمجة التطبيقات لنقطة النهاية العامة العادية (https://modelarmor.googleapis.com/). يتم استخدام عملية إلغاء نقطة نهاية واجهة برمجة التطبيقات لإعادة توجيه جميع طلبات HTTP الخاصة بحزمة تطوير البرامج (SDK) أو واجهة سطر الأوامر لخدمة Model Armor مباشرةً إلى مستوى واجهة برمجة التطبيقات الإقليمي rep.googleapis.com حيث يتم إنشاء هذه النماذج المرتبطة بالموقع الجغرافي وتخزينها والاستعلام عنها.
ضبط الإعدادات التلقائية لواجهة برمجة التطبيقات
# set api endpoint override per location
gcloud config set api_endpoint_overrides/modelarmor "https://modelarmor.${REGION}.rep.googleapis.com/"
تأكيد إلغاء واجهة برمجة التطبيقات
# view api overrides on active gcloud config
gcloud config list api_endpoint_overrides/
إنشاء نموذج فلتر طلب
أنشئ نموذج فلتر طلبات لحظر كلام يحض على الكراهية والتحرش والمحتوى الجنسي الفاضح وهجمات حقن معرّف الموارد الموحّد (URI). سيتم تفعيل التسجيل لتسجيل معلومات تفصيلية عن الأحداث المتعلقة بتنفيذ السياسة. يتم أيضًا ضبط رموز ورسائل الخطأ المخصّصة عند حظر طلب.
# create model armor template (request)
gcloud beta model-armor templates create ${AGW_NAME}-modar-req-template \
--project=${PROJ_ID} \
--location=${REGION} \
--rai-settings-filters='[
{ "filterType": "HATE_SPEECH", "confidenceLevel": "MEDIUM_AND_ABOVE" },
{ "filterType": "HARASSMENT", "confidenceLevel": "MEDIUM_AND_ABOVE" },
{ "filterType": "SEXUALLY_EXPLICIT", "confidenceLevel": "MEDIUM_AND_ABOVE" }
]' \
--pi-and-jailbreak-filter-settings-enforcement=enabled \
--pi-and-jailbreak-filter-settings-confidence-level=medium-and-above \
--template-metadata-enforcement-type=INSPECT_AND_BLOCK \
--malicious-uri-filter-settings-enforcement=enabled \
--template-metadata-custom-llm-response-safety-error-code=798 \
--template-metadata-custom-llm-response-safety-error-message="ahoy! model response blocked by content filter :(" \
--template-metadata-custom-prompt-safety-error-code=799 \
--template-metadata-custom-prompt-safety-error-message="ahoy! the request was blocked by ye content filter... so rephrase the prompt and try again!" \
--template-metadata-ignore-partial-invocation-failures \
--template-metadata-log-operations \
--template-metadata-log-sanitize-operations
إنشاء نموذج فلتر الردود
أنشئ نموذج فلتر ردّ لحظر المحتوى نفسه الذي يحظره نموذج فلتر الطلب. يتم ضبط "منع فقدان البيانات" على جزء الردّ لإزالة تعريف أرقام الضمان الاجتماعي للرسائل التي يتم إرجاعها إلى العميل من الوكيل.
# create model armor template (response)
gcloud beta model-armor templates create ${AGW_NAME}-modar-resp-template \
--project=${PROJ_ID} \
--location=${REGION} \
--rai-settings-filters='[
{ "filterType": "HATE_SPEECH", "confidenceLevel": "MEDIUM_AND_ABOVE" },
{ "filterType": "HARASSMENT", "confidenceLevel": "MEDIUM_AND_ABOVE" },
{ "filterType": "SEXUALLY_EXPLICIT", "confidenceLevel": "MEDIUM_AND_ABOVE" }
]' \
--malicious-uri-filter-settings-enforcement=enabled \
--advanced-config-inspect-template=projects/${PROJ_ID}/locations/${REGION}/inspectTemplates/agw-ssn-inspect-template \
--advanced-config-deidentify-template=projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates/agw-ssn-redaction-template \
--template-metadata-enforcement-type=INSPECT_AND_BLOCK \
--template-metadata-custom-llm-response-safety-error-code=798 \
--template-metadata-custom-llm-response-safety-error-message="ahoy! model response blocked by content filter :(" \
--template-metadata-custom-prompt-safety-error-code=799 \
--template-metadata-custom-prompt-safety-error-message="ahoy! the request was blocked by ye content filter... so rephrase the prompt and try again!" \
--template-metadata-ignore-partial-invocation-failures \
--template-metadata-log-operations \
--template-metadata-log-sanitize-operations
التحقّق من صحة نماذج Model Armor
# list model armor templates
gcloud model-armor templates list --location=${REGION}
# show request filter template details
gcloud model-armor templates describe ${AGW_NAME}-modar-req-template --location=${REGION}
# show response filter template details
gcloud model-armor templates describe ${AGW_NAME}-modar-resp-template --location=${REGION}
أذونات "إدارة الهوية وإمكانية الوصول"
تُجري Model Armor طلبات إلى واجهة برمجة التطبيقات لاستدعاء خدمة Sensitive Data Protection (SDP). امنح هوية خدمة Model Armor أذونات إدارة الهوية والوصول (IAM) لاستخدام نماذج الفحص وإزالة التعريف في "خدمة البيانات الحساسة".
ربط سياسة إدارة الهوية وإمكانية الوصول بخدمة "حماية البيانات الحسّاسة"
# grant dlp (sdp) user role to the model armor service identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-modelarmor.iam.gserviceaccount.com" \
--role="roles/dlp.user"
التحقّق من أذونات "إدارة الهوية وإمكانية الوصول"
# show iam policy for all dlp (sdp) roles on project
gcloud projects get-iam-policy ${PROJ_ID} \
--flatten="bindings[].members" \
--filter="bindings.role:roles/dlp" \
--format="table(bindings.role:label=ROLE, bindings.members:label=PRINCIPAL_IDENTITY)"
بهذا نكون قد انتهينا من جزء "حماية النموذج"، وسننتقل الآن إلى قسم التفويض.
6. التفويض
أذونات "إدارة الهوية وإمكانية الوصول"
لفحص الزيارات المضمّنة باستخدام Model Armor، يتطلّب وكيل خدمة "إضافات الخدمة" (DEP) عمليات ربط صريحة لإدارة الهوية وإمكانية الوصول (حتى في الموارد ضِمن المشروع نفسه):
-
roles/modelarmor.calloutUserوroles/serviceusage.serviceUsageConsumer: تم منحها في مشروع البوابة للسماح بوسائل شرح الفحص المضمّن. -
roles/modelarmor.user: يتم منحها في مشروع النموذج للسماح بالوصول إلى نماذج Model Armor وتقييمها.
ربط سياسة إدارة الهوية وإمكانية الوصول بـ Model Armor
# grant model armor callout user role to dep (service extension) service agent
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--role="roles/modelarmor.calloutUser"
# grant service usage consumer role to dep (service extension) service agent
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--role="roles/serviceusage.serviceUsageConsumer"
# grant model armor user role to dep (service extension) service agent
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--role="roles/modelarmor.user"
التحقّق من أذونات "إدارة الهوية وإمكانية الوصول"
# show iam policy on project for dep (service extension) service agent
gcloud projects get-iam-policy ${PROJ_ID} \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--format="table(bindings.members:label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"
إضافة التفويض
يحدّد إعداد إضافة التفويض لـ "بوابة الوكيل" إعدادات الدمج التي ستنطبق على حركة بيانات الحمولة الواردة والصادرة. يحدّد الإعداد خدمة المعالجة الخارجية (service) التي تشير إلى واجهة Model Armor API الإقليمية، ويربطها بنماذج الطلبات والاستجابات المحدّدة باستخدام حقل البيانات الوصفية model_armor_settings.
إنشاء إضافة تفويض
# create authz extension config file (enforced mode)
cat > cfg/${AGW_NAME}-svc-ext-authz-modar.yaml <<EOF
name: ${AGW_NAME}-svc-ext-authz-modar
service: modelarmor.${REGION}.rep.googleapis.com
metadata:
model_armor_settings: '[
{
"request_template_id": "projects/${PROJ_ID}/locations/${REGION}/templates/${AGW_NAME}-modar-req-template",
"response_template_id": "projects/${PROJ_ID}/locations/${REGION}/templates/${AGW_NAME}-modar-resp-template"
}
]'
failOpen: true
timeout: 5s
EOF
إضافة Import authz
# import authz extension file
gcloud service-extensions authz-extensions import ${AGW_NAME}-svc-ext-authz-modar \
--source=cfg/${AGW_NAME}-svc-ext-authz-modar.yaml \
--location=${REGION}
Verify authz extension
# list authz extensions
gcloud service-extensions authz-extensions list --location=${REGION}
# show authz extension details
gcloud service-extensions authz-extensions describe ${AGW_NAME}-svc-ext-authz-modar \
--location=${REGION}
سياسة التفويض
تستخدم سياسات التفويض ملفات تعريف السياسات لتحديد نوع التقييم الذي يتم إجراؤه. بينما تقيّم الملفات الشخصية المستندة إلى الطلبات (REQUEST_AUTHZ) عناوين HTTP، يستخدم هذا الإعداد ملفًا شخصيًا للمصادقة مستندًا إلى المحتوى (CONTENT_AUTHZ) لربط إضافة Model Armor بالبوابة من أجل فحص الحمولة بعمق.
إنشاء سياسة تفويض
# create authz policy config file (attach dry-run authz extension)
cat > cfg/${AGW_NAME}-authz-policy-modar.yaml <<EOF
name: ${AGW_NAME}-authz-policy-modar
target:
resources:
- "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
policyProfile: CONTENT_AUTHZ
action: CUSTOM
customProvider:
authzExtension:
resources:
- "projects/${PROJ_ID}/locations/${REGION}/authzExtensions/${AGW_NAME}-svc-ext-authz-modar"
EOF
استيراد سياسة التفويض
# import authz policy config file (enable authz policy)
gcloud beta network-security authz-policies import ${AGW_NAME}-authz-policy-modar \
--source=cfg/${AGW_NAME}-authz-policy-modar.yaml \
--location=${REGION}
التحقّق من سياسة التفويض
# list authz policies
gcloud beta network-security authz-policies list --location=${REGION}
# show authz policy details
gcloud beta network-security authz-policies describe ${AGW_NAME}-authz-policy-modar \
--location=${REGION}
بهذا نكون قد انتهينا من جزء التفويض... لننتقل الآن إلى قسم قاعدة الرموز البرمجية.
7. قاعدة الرموز البرمجية
يتم الاحتفاظ برمز الوكيل وبيانات الملفات المستخدَمة في هذا الدرس التطبيقي حول الترميز في مستودع Google Cloud GitHub بعيد. ستؤدي الخطوات التالية إلى استنساخ المستودع محليًا، ونسخ الملفات اللازمة إلى بنية دليل العمل الحالي، ثم تنظيف الملفات المؤقتة.
استرداد العناصر عن بُعد
# clone remote repository to temp local dir
git clone https://github.com/GoogleCloudPlatform/cloud-networking-solutions.git ./temp_agw_cuj_arun_ingress_modar
# copy agent runtime and endpoint definitions to working project dir
cp -r temp_agw_cuj_arun_ingress_modar/codelabs/agw-cuj-arun-ingress-modar/agent-crm ./agent-crm
# remove temporary directory
rm -rf temp_agw_cuj_arun_ingress_modar
تستخدم بيئة تشغيل الوكيل حاوية تخزين لتنفيذ عملية الإعداد، وذلك من أجل تحميل الرمز البرمجي لتطبيق الوكيل المجمَّع وعناصر الاعتمادية، وإنشائه، ونشره.
إنشاء حزمة تخزين لمرحلة الإعداد
# create storage bucket
gcloud storage buckets create gs://${STAGING_BUCKET} --location=${REGION}
إثبات ملكية حزمة التخزين
# list storage buckets
gcloud storage buckets list --format="value(storage_url)"
بهذا نكون قد انتهينا من جزء قاعدة الرموز البرمجية... ننتقل الآن إلى قسم بيانات العملاء في "خدمة العملاء من Google".
بيانات العملاء
أنشئ حزمة Cloud Storage لتخزين بيانات العملاء. سيقرأ الوكيل مباشرةً باستخدام مكتبة برامج Google Cloud العادية التي تستدعي نقطة نهاية MCP في Cloud Storage.
إنشاء حزمة تخزين لبيانات العملاء
# create storage bucket
gcloud storage buckets create gs://${DATA_BUCKET} --location=${REGION}
إثبات ملكية حزمة التخزين
# list storage buckets
gcloud storage buckets list --format="value(storage_url)"
تحميل بيانات العملاء
# copy local data to bucket
gcloud storage cp -r ./agent-crm/data/* gs://${DATA_BUCKET}/
التحقّق من بيانات العملاء
# list bucket objects
gcloud storage ls gs://${DATA_BUCKET}/ --long
بهذا نكون قد انتهينا من جزء "بيانات العملاء" في GCS، وسننتقل الآن إلى قسم برنامج ADK.
8. وكيل ADK
يتم إعداد وكيل agent-crm ADK الذي تم نشره في Agent Runtime باستخدام الإعدادات التالية في نص البرمجة الخاص بعملية النشر للدمج مع Agent Platform:
"identity_type": types.IdentityType.AGENT_IDENTITYلتوفير هوية أساسية فريدة مستندة إلى SPIFFE للوكيل"client_to_agent_config": {"agent_gateway": "${AGW_URI}"}لتوجيه جميع الزيارات الواردة إلى الوكيل إلى مسار تقييم السياسات وفرضها في Agent Gateway
يتم أيضًا تمرير عنوان URL لخادم mTLS MCP إلى وكيل خادم Cloud Storage MCP واسم حزمة البيانات لاستدعاء أداة GCS MCP عبر اتصال آمن.
نشر الوكيل
# deploy agent
uv --directory agent-crm run python3 deploy_agent.py \
--project=${PROJ_ID} \
--region=${REGION} \
--src-dir=./agent \
--staging-bucket=${STAGING_BUCKET} \
--display-name="${RE_AGENT_NAME}" \
--description="agent for customer data" \
--mcp-server-url="${MCP_URL}" \
--data-bucket=${DATA_BUCKET} \
--enable-telemetry \
--enable-agent-identity \
--agent-gateway-ingress=${AGW_URI} \
--allow-token-sharing
التحقّق من عملية النشر
جلب مؤشرات الأداء الأساسية لعمليات النشر
# fetch agent runtime (reasoning engine) resource id
export RE_ENGINE_ID=$(curl -s -X GET "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
| jq -r --arg name "${RE_AGENT_NAME}" '.reasoningEngines[] | select(.displayName==$name) | .name | split("/") | last')
echo ${RE_ENGINE_ID}
# fetch agent runtime (reasoning engine) agent identity
export RE_AGENT_IDENTITY=$(gcloud agent-registry agents list \
--project=${PROJ_ID} --location=${REGION} --filter="displayName=${RE_AGENT_NAME}" \
--format="value(attributes.'agentregistry.googleapis.com/system/RuntimeIdentity'.principal)")
echo ${RE_AGENT_IDENTITY}
التحقّق من إعدادات البوابة
# show agent runtime config details (gateway config)
curl -s -X GET "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
| jq '{displayName: .displayName, name: .name, effectiveIdentity: .spec.effectiveIdentity, agentGatewayConfig: .spec.deploymentSpec.agentGatewayConfig}'
أذونات "إدارة الهوية وإمكانية الوصول"
ربط سياسات إدارة الهوية وإمكانية الوصول بهوية الوكيل
# grant mcp tool user role to agent set (all agent runtime agents in project)
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_ID_SET}" \
--role="roles/mcp.toolUser"
# grant storage object viewer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/storage.objectViewer"
# grant aiplatform user role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/aiplatform.user"
# grant cloudtrace agent role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/cloudtrace.agent"
# grant cloud monitoring metric writer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/monitoring.metricWriter"
# grant cloud logging log writer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/logging.logWriter"
# grant telemetry writer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/telemetry.writer"
# grant service usage consumer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/serviceusage.serviceUsageConsumer"
# grant browser role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/browser"
التحقّق من أذونات "إدارة الهوية وإمكانية الوصول"
# show agent identity roles on project
gcloud projects get-iam-policy ${PROJ_ID} \
--flatten="bindings[].members" \
--filter="bindings.members:${RE_AGENT_IDENTITY}" \
--format="table(bindings.members.sub('^.*locations/', 'principal://agents.[...]/locations/'):label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"
# show agent set roles on project
gcloud projects get-iam-policy ${PROJ_ID} \
--flatten="bindings[].members" \
--filter="bindings.members:${RE_AGENT_ID_SET}" \
--format="table(bindings.members.sub('^.*platformContainer/', 'principalSet://agents.[...]/'):label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"
بهذا نكون قد انتهينا من جزء وكيل ADK... وسننتقل الآن إلى قسم الاختبار.
9. اختبار
إرسال طلبات البحث من واجهة سطر الأوامر
تجربة طلب آمن
# post query to agent streamQuery
curl --no-buffer -s -X POST "https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:streamQuery" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "X-Goog-User-Project: ${PROJ_ID}" \
-d @- <<EOF | jq -r --unbuffered 'if type == "array" then .[] else . end | select(.content.parts != null) | .content.parts[].text // empty'
{
"input": {
"message": "what are the names of our west customers?",
"user_id": "test-user"
}
}
EOF
يجب أن يظهر الردّ على النحو التالي... "عملاؤنا في الغرب هم: "باسم أحمد" و"ليلى علي".
اختبار مشغّل إخفاء المعلومات
# post query to agent streamQuery
curl --no-buffer -s -X POST "https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:streamQuery" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "X-Goog-User-Project: ${PROJ_ID}" \
-d @- <<EOF | jq -r --unbuffered 'if type == "array" then .[] else . end | select(.content.parts != null) | .content.parts[].text // empty'
{
"input": {
"message": "what are ssn's for bob johnson and alice brown?",
"user_id": "test-user"
}
}
EOF
تجربة طلب آمن آخر
# post query to agent streamQuery
curl --no-buffer -s -X POST "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:streamQuery" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "X-Goog-User-Project: ${PROJ_ID}" \
-d @- <<EOF | jq -r --unbuffered 'if type == "array" then .[] else . end | select(.content.parts != null) | .content.parts[].text // empty'
{
"input": {
"message": "what are bob johnson's and alice brown's email addresses?",
"user_id": "test-user"
}
}
EOF
سجلات التدقيق
عرض سجلّات التتبُّع
عند تفعيل القياس عن بُعد، يبثّ Agent Runtime أحداثًا منظَّمة تمثّل طلبات البحث التي يقدّمها المستخدمون ومَعلمات الأدوات ومسارات التنفيذ ونتائج اختيار النماذج.
# show agent runtime (reasoning engine) telemetry and trace logs
gcloud logging read \
"logName:\"projects/${PROJ_ID}/logs/aiplatform.googleapis.com%2Freasoning_engine_stdout\" AND labels.managed-by=\"reasoning-engine\"" \
--project=${PROJ_ID} \
--limit=15 \
--format="table(
timestamp.date(format=\"%I:%M:%S %p\", tz=LOCAL):label=TIME,
trace.basename().sub('^(.{8}).*$', '\\1'):label=TRACE_ID,
labels.\"event.name\".scope(-1):label=EVENT,
jsonPayload.content.role:label=ROLE,
jsonPayload.content.parts[0].text:label=TEXT_CONTENT,
jsonPayload.content.parts[0].function_call.name:label=TOOL_CALL
)"
تجمع TRACE_ID بين طلب المستخدم واستدعاءات الأدوات الوسيطة وقرارات النموذج في مخطط زمني واحد:
TIME TRACE_ID EVENT ROLE TEXT_CONTENT TOOL_CALL
HH:MM:SS PM 3070a1fd gen_ai.choice model Bob Johnson's SSN is 219-45-7895.
Alice Brown's SSN is 219-45-7896.
HH:MM:SS PM 3070a1fd gen_ai.user.message user
HH:MM:SS PM 3070a1fd gen_ai.user.message model read_customer_file
HH:MM:SS PM 3070a1fd gen_ai.user.message user
HH:MM:SS PM 3070a1fd gen_ai.user.message model read_customer_file
HH:MM:SS PM 3070a1fd gen_ai.user.message user
HH:MM:SS PM 3070a1fd gen_ai.user.message model list_customer_files
HH:MM:SS PM 3070a1fd gen_ai.user.message user what are ssn's for bob johnson and alice brown?
HH:MM:SS PM 3070a1fd gen_ai.system.message
HH:MM:SS PM 3070a1fd gen_ai.choice model read_customer_file
عرض سجلّات تنظيف Model Armor
تعرض هذه السجلات عمليات الحماية من التهديدات والتطهير المضمّنة الثنائية الاتجاه في الوقت الفعلي التي تنفّذها Model Armor أثناء تدفّق الزيارات عبر Agent Gateway.
# show model armor logs
gcloud logging read \
"logName:\"projects/${PROJ_ID}/logs/modelarmor.googleapis.com%2Fsanitize_operations\"" \
--project=${PROJ_ID} \
--limit=50 \
--format="table(
timestamp.date(format=\"%I:%M:%S %p\", tz=LOCAL):label=TIME,
jsonPayload.sanitizationResult.sanitizationVerdict:label=VERDICT,
jsonPayload.sanitizationInput.byteItem.byteData.decode(base64).decode(utf-8).sub('\n', ' \\\\\\\\n ').trailoff(123):label=INPUT_DATA
)"
لاحظ إدخال في السجلّ للطلب الذي تم تنظيفه وحظره.
TIME VERDICT INPUT_DATA
HH:MM:SS PM MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW Bob Johnson's email address is bob.j@example.com. \n Alice Brown's email address is alice.b...
HH:MM:SS PM MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW what are bob johnson's and alice brown's email addresses?
HH:MM:SS PM MODEL_ARMOR_SANITIZATION_VERDICT_BLOCK 6��
HH:MM:SS PM MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW what are ssn's for bob johnson and alice brown?
HH:MM:SS PM MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW Our west customers are: Bob Johnson and Alice Brown.
HH:MM:SS PM MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW what are the names of our west customers?
بهذا نكون قد انتهينا من جزء "الاختبار"، وسننتقل الآن إلى قسم التنظيف.
10. تنظيف
# remove agent iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/storage.objectViewer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/aiplatform.user"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/cloudtrace.agent"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/monitoring.metricWriter"
# next
# remove more agent and agent set iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/logging.logWriter"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/telemetry.writer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/serviceusage.serviceUsageConsumer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/browser"
# next
# remove rest of iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_ID_SET}" --role="roles/mcp.toolUser"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="serviceAccount:service-${PROJ_NO}@gcp-sa-modelarmor.iam.gserviceaccount.com" --role="roles/dlp.user"
# next
# delete agent runtime (reasoning engine) agent
curl -s -X DELETE "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}?force=true" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json"
# next
# delete storage
gcloud -q storage rm --recursive gs://${STAGING_BUCKET}
gcloud -q storage rm --recursive gs://${DATA_BUCKET}
# next
# delete authz resources
gcloud -q beta network-security authz-policies delete ${AGW_NAME}-authz-policy-modar --location=${REGION}
gcloud -q beta service-extensions authz-extensions delete ${AGW_NAME}-svc-ext-authz-modar --location=${REGION} --async
# next
# remove dep (service extensions) service agent iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--role="roles/modelarmor.calloutUser"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--role="roles/serviceusage.serviceUsageConsumer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--role="roles/modelarmor.user"
# next
# delete model armor templates
gcloud -q model-armor templates delete ${AGW_NAME}-modar-resp-template --location=${REGION}
gcloud -q model-armor templates delete ${AGW_NAME}-modar-req-template --location=${REGION}
# unset model armor api endpoint override
gcloud config unset api_endpoint_overrides/modelarmor
# next
# delete sdp (dlp) templates
curl -fsS -X DELETE "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates/agw-ssn-redaction-template" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "x-goog-user-project: ${PROJ_ID}"
curl -fsS -X DELETE "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/inspectTemplates/agw-ssn-inspect-template" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "x-goog-user-project: ${PROJ_ID}"
# next
# delete agent gateway ingress
gcloud -q network-services agent-gateways delete ${AGW_NAME} --location=${REGION} --async
# end
بهذا نكون قد انتهينا من جزء التنظيف... لننتقل الآن إلى قسم الخلاصة.
11. الخاتمة
تهانينا! لقد تم نشر Agent Gateway بنجاح وإدارة حركة البيانات الواردة إلى وكيل يعمل بالذكاء الاصطناعي.

ترى Cosmopup أنّ دروس Codelabs التطبيقية رائعة!
ما هي الخطوة التالية؟
- يمكنك الاطّلاع على مستندات "منصة وكيل Gemini Enterprise" للحصول على ميزات متقدّمة وبرامج تعليمية.
- ضبط ضوابط Model Armor على Agent Gateway لتعزيز أمان الذكاء الاصطناعي
- استكشاف سياسات الحوكمة الدلالية لفرض قواعد النشاط التجاري والامتثال لطلبات البحث باللغة الطبيعية
يمكنك تقديم أي تعليقات أو أسئلة أو تصحيحات باستخدام نموذج الملاحظات هذا.
شكرًا