دليل المطوِّر حول ميزة "التخصيص على الجهاز"

تم تصميم خيار "التخصيص على الجهاز" (ODP) لحماية معلومات المستخدمين النهائيين من التطبيقات. تستخدم التطبيقات واجهة برمجة التطبيقات ODP لتخصيص منتجاتها وخدماتها للمستخدمين النهائيين، ولكن لن يتمكّنوا من الاطّلاع على عمليات التخصيص الدقيقة التي تم إجراؤها للمستخدم (ما لم تكن هناك تفاعلات مباشرة خارج واجهة برمجة التطبيقات ODP بين التطبيق والمستخدم النهائي). بالنسبة إلى التطبيقات التي تتضمّن نماذج تعلُّم آلي أو تحليلات إحصائية، يوفّر "الوضع الخاص بالبيانات" مجموعة من الخدمات والخوارزميات لضمان إخفاء هوية المستخدمين بشكلٍ صحيح باستخدام آليات الخصوصية التفاضلية المناسبة. للحصول على مزيد من التفاصيل، يمكنك الاطّلاع على الشرح حول التخصيص على الجهاز.

يُشغِّل "الوضع الخاص بالتطوير" رمز المطوّر في IsolatedProcess لا يمكنه الوصول مباشرةً إلى الشبكة أو الأقراص المحلية أو الخدمات الأخرى التي تعمل على الجهاز، ولكن يمكنه الوصول إلى مصادر البيانات الثابتة التالية على الجهاز:

  • RemoteData: بيانات غير قابلة للتغيير خاصة بقيمة المفتاح ويتم تنزيلها من الخلفيات عن بُعد التي يديرها المطوّر، إذا كان ذلك منطبقًا
  • LocalData - بيانات قيمة المفتاح القابلة للتحويل التي يحتفظ بها المطوِّر محليًا، إذا كان ذلك منطبقًا
  • UserData - بيانات المستخدم المقدَّمة من المنصة

النتائج التالية متاحة:

  • النتائج الثابتة: يمكن استخدام هذه النتائج في عمليات المعالجة المحلية المستقبلية، أو لإنشاء نتائج معروضة، أو لتسهيل تدريب النماذج من خلال "التعلُّم الموحّد"، أو لتسهيل التحليل الإحصائي على جميع الأجهزة من خلال "إحصاءات Google الموحّدة".
    • يمكن للمطوّرين كتابة الطلبات بالإضافة إلى نتائج المعالجة في جدول REQUESTS المحلي.
    • يمكن للمطوّرين كتابة بيانات إضافية مرتبطة بطلب سابق في جدول EVENTS.
  • الناتج المعروض:
    • يمكن للمطوّرين عرض رمز HTML المعروض من خلال بروتوكول ODP في WebView داخل SurfaceView. ولن يظهر المحتوى المعروض هناك للتطبيق الذي بدأ عملية الربط.
    • يمكن للمطوّرين تضمين عناوين URL للأحداث المقدَّمة من ODP في إخراج HTML لبدء تسجيل تفاعلات المستخدمين مع HTML المعروض ومعالجتها. يعترض بروتوكول ODP الطلبات لعناوين URL هذه ويستدعي الرمز لإنشاء بيانات تتم كتابتها في جدول EVENTS.

يمكن لتطبيقات العميل وحِزم تطوير البرامج (SDK) استدعاء ODP لعرض محتوى HTML في SurfaceView باستخدام واجهات برمجة تطبيقات ODP. لا يظهر المحتوى المعروض في SurfaceView لتطبيق الاتصال. يمكن أن يكون التطبيق العميل أو حزمة تطوير البرامج (SDK) كيانًا مختلفًا عن الكيان الذي يتم تطويره باستخدام ODP.

تدير خدمة ODP تطبيق العميل الذي يريد استدعاء ODP لعرض محتوى مخصص ضمن واجهة المستخدم الخاصة به. ويتم تنزيل المحتوى من نقاط النهاية التي يوفّرها المطوّر ويستدعي منطق المعالجة اللاحقة للبيانات التي يتم تنزيلها. وتتوسّط هذه الخدمة أيضًا في جميع المراسلات بين IsolatedProcess والخدمات والتطبيقات الأخرى.

تستخدم تطبيقات العميل طرقًا في فئة OnDevicePersonalizationManager للتفاعل مع رمز المطوّر الذي يتم تشغيله في IsolatedProcess. يعمل الرمز البرمجي الخاص بالمطوِّر في IsolatedProcess على توسيع فئة IsolatedService وتنفيذ واجهة IsolatedWorker. وتحتاج IsolatedService إلى إنشاء مثيل لـ IsolatedWorker لكل طلب.

يوضّح الرسم البياني التالي العلاقة بين الطريقتَين في OnDevicePersonalizationManager وIsolatedWorker.

مخطّط بياني للعلاقة بين OnDevicePersonalizationManager وIsolatedWorker.

يستدعي تطبيق عميل ODP باستخدام الطريقة execute مع IsolatedService مُسمّى. تعيد خدمة ODP توجيه الطلب إلى طريقة onExecute في IsolatedWorker. يعرض IsolatedWorker السجلّات التي يجب الاحتفاظ بها والمحتوى الذي يجب عرضه. تُسجِّل خدمة ODP الإخراج الدائم في جدول REQUESTS أو EVENTS، وتُرجع مرجعًا غير شفاف إلى الإخراج المعروض لتطبيق العميل. ويمكن لتطبيق العميل استخدام هذا المرجع غير الشفاف في طلب requestSurfacePackage مستقبلي لعرض أيّ من محتوى العرض ضمن واجهة المستخدم.

الإخراج الدائم

تُحفظ خدمة ODP لسجلّ في جدول REQUESTS بعد تنفيذ المطوّر لـ onExecute. يحتوي كل سجلّ في جدول REQUESTS على بعض البيانات الشائعة لكل طلب تنشئها خدمة ODP، وقائمة بقيم Rows التي تم عرضها. يحتوي كل Row على قائمة بأزواج (key, value). وتكون كل قيمة عبارة عن مقياس رقمي أو سلسلة أو كائن الثنائي الكبير. يمكن الإبلاغ عن القيم الرقمية بعد التجميع، ويمكن الإبلاغ عن بيانات السلسلة أو الكائن الثنائي الكبير (blob) بعد تطبيق الخصوصية التفاضلية المحلية أو المركزية. يمكن للمطوّرين أيضًا كتابة أحداث تفاعل المستخدِم اللاحقة في جدول EVENTS، ويرتبط كلّ سجلّ في جدول EVENTS بصفّ في جدول REQUESTS. تسجِّل خدمة ODP بوضوح طابعًا زمنيًا واسم حزمة تطبيق الاتصال وملف APK لمطوِّر برامج ODP مع كل سجلّ.

قبل البدء

قبل بدء التطوير باستخدام ODP، عليك إعداد بيان الحزمة وتفعيل وضع المطوّر.

إعدادات بيان الحزمة

لاستخدام ODP، يلزم ما يلي:

  1. علامة <property> في AndroidManifest.xml تشير إلى مورد XML في الحزمة التي تحتوي على معلومات إعداد ODP.
  2. علامة <service> في AndroidManifest.xml التي تحدّد الفئة التي تمتد إلى IsolatedService، كما هو موضّح في المثال التالي. يجب ضبط السمتَين exported وisolatedProcess في الخدمة ضمن علامة <service> على true.
  3. علامة <service> في مورد XML المحدّد في الخطوة 1 والتي تحدّد فئة الخدمة من الخطوة 2 يجب أن تتضمّن علامة <service> أيضًا إعدادات إضافية خاصة بـ ODP داخل العلامة نفسها، كما هو موضّح في المثال الثاني.

AndroidManifest.xml

<!-- Contents of AndroidManifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.odpsample" >
    <application android:label="OdpSample">
        <!-- XML resource that contains other ODP settings. -->
        <property android:name="android.ondevicepersonalization.ON_DEVICE_PERSONALIZATION_CONFIG"
                  android:resource="@xml/OdpSettings"></property>
        <!-- The service that ODP binds to. -->
        <service android:name="com.example.odpsample.SampleService"
                android:exported="true" android:isolatedProcess="true" />
    </application>
</manifest>

ملف البيان الخاص بتنسيق ODP في ملف XML

يجب أن يُعلن ملف موارد XML المحدّد في علامة <property> أيضًا عن فئة الخدمة في علامة <service>، وأن يحدّد نقطة نهاية عنوان URL التي ستنزِّل ODP المحتوى منها لتعبئة جدول RemoteData، كما هو موضّح في المثال التالي. إذا كنت تستخدم ميزات الحوسبة الموحّدة، عليك أيضًا تحديد نقطة نهاية عنوان URL لخادم الحوسبة الموحّدة التي سيتصل بها برنامج "عميل الحوسبة الموحّدة".

<!-- Contents of res/xml/OdpSettings.xml -->
<on-device-personalization>
   <!-- Name of the service subclass -->
   <service name="com.example.odpsample.SampleService">
     <!-- If this tag is present, ODP will periodically poll this URL and
          download content to populate REMOTE_DATA. Developers that do not need to
          download content from their servers can skip this tag. -->
     <download-settings url="https://example.com/get" />
     <!-- If you want to use federated compute feature to train a model, you
          need to specify this tag. -->
     <federated-compute-settings url="https://fcpserver.example.com/" />
   </service>
</on-device-personalization>

تفعيل "وضع المطوّر"

فعِّل وضع المطوّر باتّباع التعليمات الواردة في قسم تفعيل خيارات المطوّرين ضمن مستندات Android Studio.

إعدادات التبديل والإبلاغ

يحتوي ODP على مجموعة من المفاتيح والعلامات التي تُستخدَم للتحكّم في وظائف معيّنة:

  • _global_killswitch: التبديل العام لجميع ميزات ODP، يتم ضبطه على false لاستخدام ODP
  • _federated_compute_kill_switch: _التبديل الذي يتحكّم في جميع وظائف التدريب (التعلم الموحّد) في ODP، ويتم ضبطه على false لاستخدام التدريب
  • _caller_app_allowlist: للتحكّم في المستخدمين المسموح لهم بالاتصال بـ ODP، يمكن إضافة التطبيقات (اسم الحزمة، الشهادة [اختيارية]) هنا أو ضبطها على * للسماح للجميع
  • _isolated_service_allowlist: تتحكّم في الخدمات التي يمكن تشغيلها في عملية "الخدمة المعزولة".

يمكنك تنفيذ الأوامر التالية لضبط جميع مفاتيح التبديل والعلامات لاستخدام ODP بدون قيود:

# Set flags and killswitches
adb shell device_config set_sync_disabled_for_tests persistent
adb shell device_config put on_device_personalization global_kill_switch false
adb shell device_config put on_device_personalization federated_compute_kill_switch false
adb shell device_config put on_device_personalization caller_app_allow_list \"*\"
adb shell device_config put on_device_personalization isolated_service_allow_list \"*\"

واجهات برمجة التطبيقات من جهة الجهاز

يمكنك الاطّلاع على المستندات المرجعية لواجهة برمجة تطبيقات Android الخاصة ببروتوكول ODP.

التفاعلات مع "IsolatedService"

فئة IsolatedService هي فئة أساسية مجردة يجب أن ينشئها جميع المطوّرين الذين يريدون تطوير التطبيقات باستخدام ODP، ويجب أن يُعلنوا في بيان الحزمة أنّها تعمل في عملية معزولة. تبدأ خدمة ODP هذه الخدمة في عملية معزولة وترسل الطلبات إليها. يتلقى IsolatedService الطلبات من خدمة ODP وينشئ IsolatedWorker للتعامل مع الطلب.

على المطوّرين تنفيذ الطرق من واجهة IsolatedWorker لمعالجة طلبات تطبيقات العميل وإكمال عمليات التنزيل والأحداث التي تسبّب فيها تنسيق HTML المعروض. تتضمّن جميع هذه الطرق عمليات تنفيذ تلقائية لا تؤدي إلى أي إجراء، ما يتيح للمطوّرين تخطّي تنفيذ الطرق التي لا تهمّهم.

توفّر الفئة OnDevicePersonalizationManager واجهة برمجة تطبيقات للتطبيقات وحِزم تطوير البرامج (SDK) للتفاعل مع IsolatedService من تنفيذ المطوّر ويتم تشغيله في عملية معزولة. في ما يلي بعض حالات الاستخدام المقصودة:

إنشاء محتوى HTML لعرضه في SurfaceView

لإنشاء محتوى لعرضه، باستخدام OnDevicePersonalizationManager#execute، يمكن لتطبيق الاتصال استخدام عنصر SurfacePackageToken الذي تم عرضه في مكالمة requestSurfacePackage لاحقة لطلب عرض النتيجة في SurfaceView .

عند نجاح العملية، يتم استدعاء المستلِم مع SurfacePackage لملف شخصي تعرضه خدمة ODP. يجب أن تُدرِج تطبيقات العميل SurfacePackage في SurfaceView ضمن التسلسل الهرمي لعرضها.

عندما يُجري تطبيق استدعاء requestSurfacePackage باستخدام SurfacePackageToken تم عرضه من خلال OnDevicePersonalizationManager#execute سابق، استدعاء طلبات خدمة ODP IsolatedWorker#onRender لجلب مقتطف HTML لعرضه داخل إطار محاط بسياج. لا يمكن للمطوّر الوصول إلى LocalData أو UserData خلال هذه المرحلة. ويمنع ذلك المطوّر من تضمين UserData التي يُحتمل أن تكون حسّاسة ضمن عناوين URL لاسترداد مواد العرض في ملف HTML الذي تم إنشاؤه. يمكن للمطوّرين استخدام IsolatedService#getEventUrlProvider لإنشاء عناوين URL للتتبّع لتضمينها في رمز HTML الذي تم إنشاؤه. عند عرض صفحات HTML، ستعترض خدمة ODP الطلبات الموجَّهة إلى عناوين URL هذه وستتصل بخدمة IsolatedWorker#onEvent. يمكن استدعاء getRemoteData() عند تنفيذ onRender().

تتبع الأحداث ضمن محتوى HTML

توفّر فئة EventUrlProvider واجهات برمجة تطبيقات لإنشاء عناوين URL لتتبُّع الأحداث التي يمكن للمطوّرين تضمينها في إخراج HTML. عند عرض HTML، سيستدعي ODP IsolatedWorker#onEvent مع حمولة عنوان URL للحدث.

تعترض خدمة ODP طلبات عناوين URL للأحداث التي أنشأتها ODP ضمن رمز HTML المعروض، وتستدعي IsolatedWorker#onEvent وتسجِّل EventLogRecord المعروضة في جدول EVENTS.

كتابة نتائج دائمة

باستخدام OnDevicePersonalizationManager#execute، تتوفّر للخدمة خيارات لكتابة البيانات في مساحة تخزين دائمة (جداول REQUESTS وEVENTS). فيما يلي الإدخالات التي يمكن للمرء كتابتها في هذه الجداول:

  • RequestLogRecord ليتمّت إضافتها إلى جدول REQUESTS
  • قائمة تضم كائنات EventLogRecord التي ستتم إضافتها إلى جدول EVENTS، ويحتوي كل منها على مؤشر إلى RequestLogRecord مكتوب مسبقًا .

يمكن أن تستخدم تقنية "التعلّم الموحّد" النتائج الثابتة في مساحة التخزين على الجهاز لتدريب النماذج.

إدارة مهام التدريب على الجهاز

تستدعي خدمة ODP IsolatedWorker#onTrainingExample عند بدء وظيفة تدريب على الحوسبة الموحّدة وتريد الحصول على أمثلة تدريبية يوفّرها المطوّرون الذين يتّبعون ODP. يمكنك استدعاء getRemoteData() وgetLocalData() وgetUserData() وgetLogReader() عند تنفيذ onTrainingExample().

لجدولة مهام الحوسبة الموحّدة أو إلغائها، يمكنك استخدام فئة FederatedComputeScheduler التي توفّر واجهات برمجة تطبيقات لجميع IsolatedService ODP. يمكن تحديد كل وظيفة حساب موحّد باستخدام اسم قاعدة البيانات.

قبل جدولة مهمة جديدة للحوسبة الموحّدة:

  • من المفترض أن تكون قد تمّت إنشاء مهمة باسم هذه المجموعة على خادم الحوسبة الموحّد عن بُعد.
  • يجب أن تكون نقطة نهاية عنوان URL لخادم الحوسبة الموحّد قد تم تحديدها مسبقًا في إعدادات بيان الحزمة باستخدام العلامة federated-compute-settings.

التفاعلات مع الناتج المستمر

يوضّح القسم التالي كيفية التفاعل مع الإخراج الدائم في ODP.

قراءة الجداول المحلية

توفّر فئة LogReader واجهات برمجة تطبيقات لقراءة جدولَي REQUESTS وEVENTS. تحتوي هذه الجداول على بيانات كتبها IsolatedService أثناء مكالمات onExecute() أو onEvent(). يمكن استخدام البيانات الواردة في هذه الجداول لتدريب النماذج التي تسهّل ميزة "التعلّم التعاوني" أو التحليل الإحصائي على جميع الأجهزة الذي تسهّله ميزة "إحصاءات Google".

التفاعلات مع المحتوى الذي يتم تنزيله

يوضّح القسم التالي كيفية التفاعل مع المحتوى الذي تم تنزيله في ODP.

تنزيل المحتوى من الخوادم

تُنزِّل خدمة ODP بشكل دوري المحتوى من عنوان URL المذكور في بيان حزمة IsolatedService، وتستدعي onDownloadCompleted بعد انتهاء التنزيل. عملية التنزيل عبارة عن ملف JSON يحتوي على أزواج المفتاح/القيمة.

يمكن للمطوّرين الذين يستخدمون ODP اختيار المجموعة الفرعية من المحتوى الذي يتم تنزيله التي يجب إضافتها إلى جدول RemoteData وتلك التي يجب حذفها. لا يمكن للمطوّرين تعديل المحتوى الذي تم تنزيله، ما يضمن عدم احتواء جدول "RemoteData" على أي بيانات للمستخدمين. بالإضافة إلى ذلك، بإمكان المطوّرين تعبئة جدول LocalData حسب اختيارهم، ويمكنهم تخزين بعض النتائج المحسوبة مسبقًا في ذاكرة التخزين المؤقت.

تنزيل تنسيق الطلب

تتحقق أداة ODP بشكل دوري من نقطة نهاية عنوان URL المعلَنة في بيان الحزمة الخاص بالمطوّر لجلب المحتوى من أجل تعبئة جدول RemoteData.

من المتوقّع أن تعرض نقطة النهاية استجابة JSON كما هو موضّح لاحقًا. يجب أن يحتوي ردّ JSON على syncToken يحدِّد إصدار البيانات التي يتم إرسالها، بالإضافة إلى قائمة بأزواج المفتاح والقيمة المطلوب تعبئتها. يجب أن تكون قيمة syncToken طابعًا زمنيًا بالثواني، ويتم ضبطها على حدود ساعة بالتوقيت العالمي المتفق عليه. كجزء من طلب التنزيل، يوفّر ODP syncToken للتنزيل المكتمل سابقًا والبلد الذي يقع فيه الجهاز كمَعلمتَي syncToken وcountry في عنوان URL للتنزيل. يمكن للخادم استخدام سياسة syncToken السابقة لتنفيذ عمليات التنزيل المتزايدة.

تنزيل تنسيق الملف

الملف الذي تم تنزيله هو ملف JSON بالبنية التالية. من المتوقّع أن يحتوي ملف JSON على رمز مميّز للتزامن لتحديد إصدار البيانات التي يتم تنزيلها. يجب أن يكون الرمز SyncToken طابعًا زمنيًا بالتوقيت العالمي المنسّق مثبَّتًا بحدود ساعة، ويجب أن يتجاوز رمز SyncToken لعملية التنزيل السابقة. في حال لم يستوفِ الرمز SyncToken كلا الشرطين، يتم تجاهل المحتوى الذي تم تنزيله بدون معالجة.

حقل المحتويات هو قائمة بالصفوف (المفتاح، البيانات، الترميز). من المفترض أن تكون key سلسلة UTF-8. الحقل encoding هو مَعلمة اختيارية تحدّد كيفية ترميز الحقل data، ويمكن ضبطه على "utf8" أو "base64"، ويُفترض أن يكون الخيار "utf8" تلقائيًا. يتم تحويل الحقل key إلى عنصر String ويتم تحويل الحقل data إلى صفيف بايت قبل استدعاء onDownloadCompleted()..

{
  // syncToken must be a UTC timestamp clamped to an hour boundary, and must be
  // greater than the syncToken of the previously completed download.
  "syncToken": <timeStampInSecRoundedToUtcHour>,
  "contents": [
    // List of { key, data } pairs.
    { "key": "key1",
      "data": "data1"
    },
    { "key": "key2",
      "data": "data2",
      "encoding": "base64"
    },
    // ...
  ]
}

واجهات برمجة التطبيقات من جهة الخادم

يصف هذا القسم كيفية التفاعل مع واجهات برمجة تطبيقات خادم الحوسبة الموحّد.

واجهات برمجة التطبيقات لخادم الحوسبة الموحّدة

لجدولة مهمة حوسبة موحَّدة من جهة العميل، ستحتاج إلى مهمة باسم مجموعة تم إنشاؤها على خادم الحوسبة الموحّد عن بُعد. في هذا القسم، نتناول كيفية إنشاء مهمة كهذه على خادم الحوسبة الموحّد.

مخطّط بياني لبنية العميل والخادم في الحوسبة الموحّدة

عند إنشاء مهمة جديدة لأداة "إنشاء المهام"، على مطوّري ODP تقديم مجموعتَين من الملفات:

  1. نموذج tff.learning.models.FunctionalModel محفوظ من خلال طلب بيانات واجهة برمجة التطبيقات tff.learning.models.save_functional_model يمكنك العثور على نموذج واحد في مستودع GitHub.
  2. يشير هذا المصطلح إلى ملف fcp_server_config.json يتضمّن السياسات وإعداد التعلّم الموحّد وإعداد الخصوصية التفاضلية. في ما يلي مثال على ملف fcp_server_config.json:
{
  # Task execution mode.
  mode: TRAINING_AND_EVAL
  # Identifies the set of client devices that participate.
  population_name: "mnist_cnn_task"
  policies {
    # Policy for sampling on-device examples. It is checked every
    # time a device is attempting to start a new training.
    min_separation_policy {
      # The minimum separation required between two successful
      # consective task executions. If a client successfully contributes
      # to a task at index `x`, the earliest they can contribute again
      # is at index `(x + minimum_separation)`. This is required by
      # DP.
      minimum_separation: 1
    }
    data_availability_policy {
      # The minimum number of examples on a device to be considered
      # eligible for training.
      min_example_count: 1
    }
    # Policy for releasing training results to developers adopting ODP.
    model_release_policy {
      # The maximum number of training rounds.
      num_max_training_rounds: 512
    }
  }

  # Federated learning setups. They are applied inside Task Builder.
  federated_learning {
    # Use federated averaging to build federated learning process.
    # Options you can choose:
      # * FED_AVG: Federated Averaging algorithm
      #            (https://arxiv.org/abs/2003.00295)
      # * FED_SGD: Federated SGD algorithm
      #            (https://arxiv.org/abs/1602.05629)
    type: FED_AVG
    learning_process {
      # Optimizer used at client side training. Options you can choose:
      # * ADAM
      # * SGD
      client_optimizer: SGD
      # Learning rate used at client side training.
      client_learning_rate: 0.02
      # Optimizer used at server side training. Options you can choose:
      # * ADAM
      # * SGD
      server_optimizer: SGD
      # Learning rate used at server side training.
      server_learning_rate: 1.0
      runtime_config {
        # Number of participating devices for each round of training.
      report_goal: 2
      }
      metrics {
        name: "sparse_categorical_accuracy"
      }
    }
    evaluation {
      # A checkpoint selector controls how checkpoints are chosen for
      # evaluation. One evaluation task typically runs per training
      # task, and on each round of execution, the eval task
      # randomly picks one checkpoint from the past 24 hours that has
      # been selected for evaluation by these rules.
      # Every_k_round and every_k_hour are definitions of quantization
      # buckets which each checkpoint is placed in for selection.
      checkpoint_selector: "every_1_round"
      # The percentage of a populate that should delicate to this
      # evaluation task.
      evaluation_traffic: 0.2
      # Number of participating devices for each round of evaluation.
      report_goal: 2
    }
  }

  # Differential Privacy setups. They are enforced inside the Task
  # Builder.
  differential_privacy {
    # * fixed_gaussian: DP-SGD with fixed clipping norm described in
    #                   "Learning Differentially Private Recurrent
    #                   Language Models"
    #                   (https://arxiv.org/abs/1710.06963).
    type: FIXED_GAUSSIAN
    #   The value of the clipping norm.
    clip_norm: 0.1
    # Noise multiplier for the Gaussian noise.
    noise_multiplier: 0.1
  }
}

يمكنك العثور على مزيد من النماذج في مستودع GitHub.

بعد إعداد هذين المدخلين، استدعِ أداة إنشاء المهام لإنشاء العناصر وإنشاء مهام جديدة. ويمكنك الاطّلاع على تعليمات أكثر تفصيلاً في مستودع جيت هب.