מושגים מרכזיים ב-Private Aggregation API
למי המסמך הזה מיועד?
Private Aggregation API מאפשר איסוף נתונים מצטברים מ-worklets עם גישה לנתונים מאתרים שונים. המושגים שמוסברים כאן חשובים למפתחים שיוצרים פונקציות דיווח ב-Shared Storage API וב-Protected Audience API.
- אם אתם מפתחים שיוצרים מערכת דיווח למדידה באתרים שונים.
- אם אתם משווקים, מדעני נתונים או צרכני דוחות סיכום, כדאי שתבינו את המנגנונים האלה כדי שתוכלו לקבל החלטות עיצוב שיעזרו לכם לאחזר דוח סיכום שעבר אופטימיזציה.
מונחי מפתח
לפני שקוראים את המסמך הזה, כדאי להכיר את המונחים והמושגים העיקריים. כל אחד מהמונחים האלה יתואר כאן לעומק.
- מפתח צבירה (נקרא גם bucket) הוא אוסף מוגדר מראש של נקודות נתונים. לדוגמה, יכול להיות שתרצו לאסוף נתונים של מיקום שבו הדפדפן מדווח על שם המדינה. מפתח צבירה יכול להכיל יותר ממד אחד (לדוגמה, מדינה ומזהה של ווידג'ט התוכן).
- ערך שניתן לצבירה הוא נקודת נתונים נפרדת שנאספת במפתח צבירה. אם רוצים למדוד כמה משתמשים מצרפת צפו בתוכן שלכם, אז
France
הוא מאפיין במפתח הצבירה, והערךviewCount
של1
הוא הערך שניתן לצבירה. - דוחות שאפשר לצבור נוצרים ומוצפנים בדפדפן. ב-Private Aggregation API, הוא מכיל נתונים על אירוע בודד.
- Aggregation Service מעבד נתונים מדוחות נצברים כדי ליצור דוח סיכום.
- דוח סיכום הוא הפלט הסופי של Aggregation Service, והוא מכיל נתונים נצברים לגבי משתמשים עם רעש ונתוני המרות מפורטים.
- Worklet הוא חלק מהתשתית שמאפשר להריץ פונקציות JavaScript ספציפיות ולהחזיר מידע למי שביקש אותו. בתוך worklet, אפשר להריץ JavaScript אבל אי אפשר ליצור אינטראקציה עם הדף החיצוני או לתקשר איתו.
תהליך העבודה של Private Aggregation
כששולחים קריאה ל-Private Aggregation API עם מפתח צבירה וערך ניתן לצבירה, הדפדפן יוצר דוח ניתן לצבירה. הדוחות נשלחים לשרת שלכם, שיוצר חבילות של דוחות. הדוחות שנאספים בחבילה מעובדים בשלב מאוחר יותר על ידי Aggregation Service, ונוצר דוח סיכום.

- כששולחים קריאה ל-Private Aggregation API, הלקוח (הדפדפן) יוצר את הדוח שניתן לצבירה ושולח אותו לשרת שלכם כדי לאסוף אותו.
- השרת שלכם אוסף את הדוחות מהלקוחות ומקבץ אותם כדי לשלוח אותם ל-Aggregation Service.
- אחרי שתאספו מספיק דוחות, תקבצו אותם ותשלחו אותם לשירות Aggregation Service, שפועל בסביבת ביצוע מהימנה, כדי ליצור דוח סיכום.
תהליך העבודה שמתואר בקטע הזה דומה לזה של Attribution Reporting API. עם זאת, בדוחות השיוך (Attribution) משויכים נתונים שנאספו מאירוע חשיפה ומאירוע המרה, שמתרחשים בזמנים שונים. ה-API של Private Aggregation מודד אירוע יחיד שמתרחש בכמה אתרים.
מפתח צבירה
מפתח צבירה (או בקיצור, key) מייצג את הדלי שבו יצטברו הערכים הניתנים לצבירה. אפשר לקודד מימד אחד או יותר במפתח. מאפיין מייצג היבט מסוים שאתם רוצים לקבל עליו תובנות נוספות, כמו קבוצת הגיל של המשתמשים או מספר החשיפות של קמפיין פרסום.
לדוגמה, יכול להיות שיש לכם ווידג'ט שמוטמע בכמה אתרים ואתם רוצים לנתח את המדינה של המשתמשים שראו את הווידג'ט. אתם רוצים לקבל תשובות לשאלות כמו "כמה מהמשתמשים שראו את הווידג'ט שלי הם ממדינה X?" כדי לדווח על השאלה הזו, אפשר להגדיר מפתח צבירה שמקודדים בו שני מאפיינים: מזהה הווידג'ט ומזהה המדינה.
המפתח שמועבר אל Private Aggregation API הוא BigInt, שמורכב מכמה מאפיינים. בדוגמה הזו, המאפיינים הם מזהה הווידג'ט ומזהה המדינה. נניח שמזהה הווידג'ט יכול להיות באורך של עד 4 ספרות, כמו 1234
, וכל מדינה ממופה למספר לפי סדר אלפביתי, כמו אפגניסטן היא 1
, צרפת היא 61
וזימבבואה היא 195
.
לכן, המפתח המצטבר יהיה באורך 7 ספרות, כאשר 4 התווים הראשונים שמורים ל-WidgetID
ו-3 התווים האחרונים שמורים ל-CountryID
.
נניח שהמפתח מייצג את מספר המשתמשים מצרפת (מזהה המדינה 061
) שצפו בווידג'ט עם המזהה 3276
. מפתח הצבירה הוא 3276061
.
מפתח צבירה | |
מזהה הווידג'ט | מזהה מדינה |
3276 | 061 |
אפשר גם ליצור את מפתח הצבירה באמצעות מנגנון גיבוב, כמו SHA-256. לדוגמה, אפשר לבצע גיבוב של המחרוזת {"WidgetId":3276,"CountryID":67}
ואז להמיר אותה לערך BigInt
של 42943797454801331377966796057547478208888578253058197330928948081739249096287n
.
אם ערך הגיבוב מכיל יותר מ-128 ביטים, אפשר לקצץ אותו כדי לוודא שהוא לא חורג מערך המקסימום המותר של 2^128−1
עבור דלי.
ב-worklet של Shared Storage, אפשר לגשת למודולים crypto
ו-TextEncoder
שיכולים לעזור לכם ליצור hash. מידע נוסף על יצירת hash זמין במאמר SubtleCrypto.digest()
ב-MDN.
בדוגמה הבאה מוסבר איך ליצור מפתח לקטגוריה מערך שעבר גיבוב (hashing):
async function convertToBucket(data) {
// Encode as UTF-8 Uint8Array
const encodedData = new TextEncoder().encode(data);
// Generate SHA-256 hash
const hashBuffer = await crypto.subtle.digest('SHA-256', encodedData);
// Truncate the hash
const truncatedHash = Array.from(new Uint8Array(hashBuffer, 0, 16));
// Convert the byte sequence to a decimal
return truncatedHash.reduce((acc, curr) => acc * 256n + BigInt(curr), 0n);
}
const data = {
WidgetId: 3276,
CountryID: 67
};
const dataString = JSON.stringify(data);
const bucket = await convertToBucket(dataString);
console.log(bucket); // 126200478277438733997751102134640640264n
ערך שניתן לצבירה
הערכים שניתן לצבור מסוכמים לכל מפתח אצל משתמשים רבים כדי ליצור תובנות מצטברות בצורה של ערכי סיכום בדוחות סיכום.
עכשיו נחזור לשאלה לדוגמה שהוצגה קודם: "כמה מהמשתמשים שראו את הווידג'ט שלי הם מצרפת?" התשובה לשאלה הזו תהיה בפורמט הבא: "בערך 4,881 משתמשים שראו את הווידג'ט שלי עם המזהה 3276 הם מצרפת". הערך הניתן לצבירה הוא 1 לכל משתמש, ו'4,881 משתמשים' הוא הערך המצטבר שהוא סכום כל הערכים הניתנים לצבירה עבור מפתח הצבירה הזה.
מפתח צבירה | ערך שניתן לצבירה | |
מזהה הווידג'ט | מזהה מדינה | מספר צפיות |
3276 | 061 | 1 |
בדוגמה הזו, אנחנו מגדילים את הערך ב-1 לכל משתמש שרואה את הווידג'ט. בפועל, אפשר לשנות את קנה המידה של הערך המצטבר כדי לשפר את יחס האות לרעש.
תקציב תרומות
כל קריאה ל-Private Aggregation API נקראת תרומה. כדי להגן על פרטיות המשתמשים, יש הגבלה על מספר התרומות שאפשר לאסוף מאדם מסוים.
כשמסכמים את כל הערכים שניתנים לצבירה בכל מפתחות הצבירה, הסכום חייב להיות נמוך מתקציב התרומה. התקציב מוגדר לפי worklet, לפי מקור ולפי יום, והוא נפרד ל-worklets של Protected Audience API ול-worklets של Shared Storage. היום מוגדר כחלון זמן מתגלגל של כ-24 שעות. אם יצירה של דוח חדש עם נתונים מצטברים תוביל לחריגה מהתקציב, הדוח לא ייווצר.
תקציב התרומה מיוצג על ידי הפרמטר L1, והוא מוגדר כ-216 (65,536) לכל עשר דקות ביום, עם רשת ביטחון של 220 (1,048,576). במאמר הזה מוסבר על הפרמטרים האלה.
הערך של תקציב התרומה הוא שרירותי, אבל הרעש מותאם אליו. אפשר להשתמש בתקציב הזה כדי למקסם את יחס האות לרעש בערכי הסיכום (הסבר נוסף מופיע בקטע רעש ושינוי קנה מידה).
מידע נוסף על תקציבים לשיתוף תוכן זמין בהסבר. הנחיות נוספות זמינות במאמר בנושא תקציב תרומה.
מגבלת התוכן שנוסף לכל דוח
יכול להיות שמגבלת התרומה תהיה שונה בהתאם למי שמתקשר, ובאחסון שיתופי, המגבלות האלה הן ברירות מחדל שאפשר לשנות. בשלב הזה, מספר התרומות בדוחות שנוצרים עבור קוראים של Shared Storage API מוגבל ל-20 לכל דוח. לעומת זאת, מספר התרומות לכל דוח של קריאות ל-Protected Audience API מוגבל ל-100. המגבלות האלה נבחרו כדי ליצור איזון בין מספר התרומות שאפשר להטמיע לבין גודל המטען הייעודי.
במקרה של אחסון משותף, תרומות שמתבצעות במהלך פעולה אחת של run()
או selectURL()
נכללות בדוח אחד. ב-Protected Audience API, התרומות של מקור יחיד במכרז מקובצות יחד.
תרומות עם ריווח פנימי
התכונה 'ריפוד' מאפשרת לשנות את התרומות. הפעולה של הוספת נתונים מיותרים (padding) למטען הייעודי (payload) מגנה על מידע לגבי המספר האמיתי של התרומות שמוטמע בדוח שניתן לצבירה. הריפוד מוסיף למטען null
תוספות (כלומר, עם ערך של 0) כדי להגיע לאורך קבוע.
דוחות שניתן לצבור
אחרי שהמשתמש מפעיל את Private Aggregation API, הדפדפן יוצר דוחות שניתן לצבור, כדי ש-Aggregation Service יעבד אותם בשלב מאוחר יותר וייצור מהם דוחות סיכום. דוח שאפשר לצבור בו נתונים הוא בפורמט JSON ומכיל רשימה מוצפנת של תרומות, שכל אחת מהן היא זוג {aggregation key, aggregatable value}
.
דוחות שאפשר לצבור נשלחים עם עיכוב אקראי של עד שעה.
התוכן שנוסף מוצפן ואי אפשר לקרוא אותו מחוץ ל-Aggregation Service. Aggregation Service מפענח את הדוחות ויוצר דוח סיכום. מפתח ההצפנה לדפדפן ומפתח הפענוח ל-Aggregation Service מונפקים על ידי הרכיב המתאם, שפועל כשירות לניהול מפתחות. המתאם שומר רשימה של גיבובים בינאריים של תמונת השירות כדי לוודא שלמבצע הקריאה החוזרת מותר לקבל את מפתח הפענוח.
דוגמה לדוח ניתן לצבירה עם מצב ניפוי באגים מופעל:
"aggregation_service_payloads": [
{
"debug_cleartext_payload": "omRkYXRhgaJldmFsdWVEAAAAgGZidWNrZXRQAAAAAAAAAAAAAAAAAAAE0mlvcGVyYXRpb25paGlzdG9ncmFt",
"key_id": "2cc72b6a-b92f-4b78-b929-e3048294f4d6",
"payload": "a9Mk3XxvnfX70FsKrzcLNZPy+00kWYnoXF23ZpNXPz/Htv1KCzl/exzplqVlM/wvXdKUXCCtiGrDEL7BQ6MCbQp1NxbWzdXfdsZHGkZaLS2eF+vXw2UmLFH+BUg/zYMu13CxHtlNSFcZQQTwnCHb"
}
],
"debug_key": "777",
"shared_info": "{\"api\":\"shared-storage\",\"debug_mode\":\"enabled\",\"report_id\":\"5bc74ea5-7656-43da-9d76-5ea3ebb5fca5\",\"reporting_origin\":\"https://localhost:4437\",\"scheduled_report_time\":\"1664907229\",\"version\":\"0.1\"}"
אפשר לבדוק את הדוחות שניתן לצבור בדף chrome://private-aggregation-internals
:

למטרות בדיקה, אפשר להשתמש בלחצן 'שליחת דוחות נבחרים' כדי לשלוח את הדוח לשרת באופן מיידי.
איסוף וצבירה של דוחות
הדפדפן שולח את הדוחות שאפשר לצבור אל מקור ה-worklet שמכיל את הקריאה אל Private Aggregation API, באמצעות הנתיב המוכר שמופיע ברשימה:
- ל-Shared Storage:
/.well-known/private-aggregation/report-shared-storage
- ב-Protected Audience:
/.well-known/private-aggregation/report-protected-audience
בנקודות הקצה האלה, תצטרכו להפעיל שרת – שישמש ככלי לאיסוף – שיקבל את הדוחות הניתנים לצבירה שנשלחים מהלקוחות.
לאחר מכן השרת צריך לקבץ את הדוחות ולשלוח את הקבוצה אל Aggregation Service. יוצרים קבוצות על סמך המידע שזמין במטען הייעודי (payload) הלא מוצפן של הדוח שניתן לצבירה, כמו השדה shared_info
. מומלץ שכל קבוצה תכיל 100 דוחות או יותר.
אפשר להחליט על אצווה על בסיס יומי או שבועי. השיטה הזו גמישה, ואפשר לשנות את אסטרטגיית האצווה לאירועים ספציפיים שבהם צפוי נפח גדול יותר – למשל, בימים בשנה שבהם צפוי מספר גדול יותר של חשיפות. חבילות צריכות לכלול דוחות מאותה גרסת API, מאותו מקור דיווח ומאותו זמן דיווח מתוזמן.
סינון מזהים
Private Aggregation API ו-Aggregation Service מאפשרים להשתמש במסנני מזהים כדי לעבד מדידות ברמה מפורטת יותר, למשל ברמת הקמפיין הפרסומי, במקום לעבד את התוצאות בשאילתות גדולות יותר.

כדי להתחיל להשתמש בזה עוד היום, הנה כמה שלבים כלליים להטמעה הנוכחית.
שלבים לשימוש ב-Shared Storage
אם אתם משתמשים ב-Shared Storage API בתהליך שלכם:
מגדירים את המקום שבו יוכרז מודול האחסון המשותף החדש ויורץ. בדוגמה הבאה, קובץ המודול נקרא
filtering-worklet.js
והוא רשום תחתfiltering-example
.(async function runFilteringIdsExample () { await window.sharedStorage.worklet.addModule('filtering-worklet.js'); await window.sharedStorage.run('filtering-example', { keepAlive: true, privateAggregationConfig: { contextId: 'example-id', filteringIdMaxBytes: 8 // optional } }}); })();
חשוב לזכור שאפשר להגדיר את
filteringIdMaxBytes
לכל דוח בנפרד, ואם לא מגדירים אותו, ערך ברירת המחדל הוא 1. ערך ברירת המחדל הזה נועד למנוע הגדלה מיותרת של גודל המטען הייעודי (payload), וכך גם של עלויות האחסון והעיבוד. מידע נוסף זמין במאמר שמסביר על תרומה גמישה.ב-
filtering-worklet.js
, כשמעבירים תרומה ל-privateAggregation.contributeToHistogram(...)
בתוך ה-worklet של Shared Storage, אפשר לציין מזהה סינון.// Within filtering-worklet.js class FilterOperation { async run() { let contributions = [{ bucket: 1234n, value: 56, filteringId: 3n // defaults to 0n if not assigned, type bigint }]; for (const c of contributions) { privateAggregation.contributeToHistogram(c); } … } }); register('filtering-example', FilterOperation);
דוחות שניתן לצבור יישלחו לנקודת הקצה שהגדרתם
/.well-known/private-aggregation/report-shared-storage
. כדי לקבל מידע על השינויים שצריך לבצע בפרמטרים של עבודות ב-Aggregation Service, אפשר לעבור אל המדריך בנושא סינון מזהים.
אחרי שהחבילה תסתיים ותישלח לשירות Aggregation Service שהטמעתם, התוצאות המסוננות אמורות להופיע בדוח הסיכום הסופי.
שלבים לשימוש ב-Protected Audience
אם אתם משתמשים ב-Protected Audience API בתהליך:
ביישום הנוכחי של Protected Audience, אפשר להגדיר את האפשרויות הבאות כדי להתחבר ל-Private Aggregation. בניגוד לאחסון משותף, עדיין אי אפשר להגדיר את הגודל המקסימלי של מזהה הסינון. כברירת מחדל, הגודל המקסימלי של מזהה הסינון הוא בייט אחד והוא מוגדר ל-
0n
. חשוב לזכור שההגדרות האלה יוגדרו בפונקציות הדיווח של Protected Audience (למשל,reportResult()
אוgenerateBid()
).const contribution = { ... filteringId: 0n }; privateAggregation.contributeToHistogram(contribution);
דוחות שניתן לצבור יישלחו לנקודת הקצה שהגדרתם
/.well-known/private-aggregation/report-protected-audience
. אחרי שהחבילה הושלמה ונשלחה לשירות Aggregation Service שפרסתם, התוצאות המסוננות אמורות להופיע בדוח הסיכום הסופי. בהמשך מופיעים הסברים על Attribution Reporting API ועל Private Aggregation API, וגם ההצעה הראשונית.
אפשר להמשיך אל המדריך לסינון מזהים בשירות הצבירה, או לעבור אל הקטעים בנושא Attribution Reporting API כדי לקרוא הסבר מפורט יותר.
Aggregation Service

Aggregation Service מקבל דוחות מוצפנים שניתנים לצבירה מהכלי לאיסוף נתונים, ומפיק דוחות סיכום. לקבלת אסטרטגיות נוספות לגבי דוחות שאפשר לצבור בחבילות במרכז האיסוף, אפשר לעיין במדריך שלנו בנושא חבילות.
השירות פועל בסביבת מחשוב אמינה (TEE), שמספקת רמת אבטחה גבוהה לשלמות הנתונים, לסודיות הנתונים ולשלמות הקוד. אם אתם רוצים לקבל מידע נוסף על השימוש ברכיבי תיאום לצד TEE, תוכלו לקרוא על התפקיד והמטרה שלהם.
דוחות סיכום
דוחות סיכום מאפשרים לכם לראות את הנתונים שאספתם עם רעש שהוסף. אתם יכולים לבקש דוחות סיכום עבור קבוצה מסוימת של מפתחות.
דוח סיכום מכיל קבוצה של צמדי מפתח-ערך בסגנון מילון JSON. כל זוג מכיל:
-
bucket
: מפתח הצבירה כמחרוזת של מספר בינארי. אם מפתח הצבירה שבו נעשה שימוש הוא '123', אז הקטגוריה היא '1111011'. -
value
: ערך הסיכום של יעד מדידה נתון, שמתקבל מסכום של כל הדוחות הזמינים שאפשר לצבור בהם נתונים, עם רעש שנוסף להם.
לדוגמה:
[
{"bucket":` `"111001001",` `"value":` `"2558500"},
{"bucket":` `"111101001",` `"value":` `"3256211"},
{"bucket":` `"111101001",` `"value":` `"6536542"},
]
רעש ושינוי גודל
כדי לשמור על פרטיות המשתמשים, Aggregation Service מוסיף רעש פעם אחת לכל ערך סיכום בכל פעם שמבקשים דוח סיכום. ערכי הרעש נבחרים באופן אקראי מתוך התפלגות הסתברות של לפלס. אין לכם שליטה ישירה בדרכים שבהן נוסף רעש, אבל אתם יכולים להשפיע על ההשפעה של הרעש על נתוני המדידה.
התפלגות הרעש זהה ללא קשר לסכום של כל הערכים שניתן לצבור. לכן, ככל שהערכים המצטברים גבוהים יותר, כך הסיכוי שהרעש ישפיע עליהם קטן יותר.
לדוגמה, נניח שהתפלגות הרעש היא עם סטיית תקן של 100 וממוצע של אפס. אם הערך המצטבר בדוח (או 'ערך מצטבר') הוא 200 בלבד, סטיית התקן של הרעש תהיה 50% מהערך המצטבר. אבל אם הערך המצטבר הוא 20,000, סטיית התקן של הרעש תהיה רק 0.5% מהערך המצטבר. לכן, הערך המצטבר של 20,000 יהיה בעל יחס אות לרעש גבוה בהרבה.
לכן, הכפלת הערך המצטבר בפקטור קנה מידה יכולה לעזור לצמצם את הרעש. גורם קביעת קנה המידה מייצג את המידה שבה רוצים לשנות את קנה המידה של ערך מצטבר נתון.

הגדלת הערכים על ידי בחירת גורם לקביעת קנה מידה גדול יותר מפחיתה את הרעש היחסי. עם זאת, זה גם גורם לכך שהסכום של כל התרומות בכל הקטגוריות יגיע מהר יותר למגבלת התקציב לתרומות. הקטנת הערכים על ידי בחירת קבוע קטן יותר של מקדם קנה מידה מגדילה את הרעש היחסי, אבל מפחיתה את הסיכון להגעה למגבלת התקציב.

כדי לחשב את גורם ההתאמה המתאים, מחלקים את תקציב התרומה בסכום המקסימלי של הערכים שניתנים לצבירה בכל המפתחות.
מידע נוסף זמין במאמרי העזרה בנושא תקציב תרומות.
השתתפות ושיתוף משוב
הממשק Private Aggregation API נמצא כרגע בתהליכי דיון ויכול להיות שהוא ישתנה בעתיד. אם תנסו את ה-API הזה ויהיה לכם משוב, נשמח לשמוע אותו.
- GitHub: אפשר לקרוא את ההסבר, לשאול שאלות ולהשתתף בדיון.
- תמיכה למפתחים: אפשר לשאול שאלות ולהצטרף לדיונים במאגר התמיכה למפתחים של ארגז החול לפרטיות.
- כדי לקבל את ההודעות האחרונות בנושא Private Aggregation, כדאי להצטרף לקבוצה בנושא Shared Storage API ולקבוצה בנושא Protected Audience API.