Ключевые концепции API частного агрегирования
Для кого предназначен этот документ?
API частного агрегирования позволяет собирать агрегированные данные из рабочих леток с доступом к межсайтовым данным. Представленные здесь концепции важны для разработчиков, создающих функции отчётности в рамках API общего хранилища и защищённой аудитории.
- Если вы разработчик, создающий систему отчетности для межсайтового измерения.
- Если вы маркетолог , специалист по обработке данных или другой потребитель сводных отчетов , понимание этих механизмов поможет вам принимать решения по проектированию для получения оптимизированного сводного отчета.
Ключевые термины
Перед прочтением этого документа будет полезно ознакомиться с ключевыми терминами и понятиями. Каждый из них будет подробно описан здесь.
- Ключ агрегации (также известный как контейнер) — это предопределённый набор точек данных. Например, вам может потребоваться собрать контейнер данных о местоположении, в котором браузер сообщает название страны. Ключ агрегации может содержать несколько измерений (например, страну и идентификатор вашего виджета).
- Агрегируемое значение — это отдельная точка данных, собранная в ключ агрегации. Если вы хотите узнать, сколько пользователей из Франции просмотрели ваш контент, то
France— это измерение в ключе агрегации, аviewCountравный1, — это агрегируемое значение. - Агрегируемые отчёты генерируются и шифруются в браузере. Для API частного агрегирования они содержат данные об одном событии.
- Служба агрегации обрабатывает данные из агрегируемых отчетов для создания сводного отчета.
- Сводный отчет является окончательным результатом работы Службы агрегации и содержит обобщенные данные о пользователях и подробные данные о конверсиях.
- Ворклет — это элемент инфраструктуры, позволяющий выполнять определённые функции JavaScript и возвращать информацию запрашивающей стороне. Внутри ворклета можно выполнять JavaScript, но нельзя взаимодействовать с внешней страницей.
Рабочий процесс частного агрегирования
При вызове API частного агрегирования с ключом агрегации и агрегируемым значением браузер генерирует агрегируемый отчёт. Отчёты отправляются на ваш сервер, который формирует пакеты. Пакетные отчёты впоследствии обрабатываются службой агрегации, и формируется сводный отчёт.

- При вызове API частного агрегирования клиент (браузер) формирует и отправляет агрегированный отчет на ваш сервер для сбора.
- Ваш сервер собирает отчеты от клиентов и объединяет их в пакеты для отправки в службу агрегации.
- Как только вы соберете достаточное количество отчетов, вы объедините их в пакет и отправите в службу агрегации, работающую в доверенной среде выполнения, для формирования сводного отчета.
Рабочий процесс, описанный в этом разделе, аналогичен API Attribution Reporting . Однако Attribution Reporting связывает данные, собранные по показу и конверсии, которые происходят в разное время. Частное агрегирование измеряет одно межсайтовое событие.
Ключ агрегации
Ключ агрегации (далее «ключ») представляет собой контейнер, в котором будут накапливаться агрегируемые значения. В ключе можно закодировать одно или несколько измерений. Измерение представляет собой некий аспект, который вы хотите изучить более подробно, например, возрастную группу пользователей или количество показов рекламной кампании.
Например, у вас может быть виджет, встроенный на несколько сайтов, и вы хотите проанализировать страну пользователей, которые видели этот виджет. Вы хотите получить ответы на такие вопросы, как «Сколько пользователей, которые видели мой виджет, из страны X?». Чтобы составить отчёт по этому вопросу, вы можете настроить ключ агрегации, который кодирует два измерения: идентификатор виджета и идентификатор страны.
Ключ, предоставляемый 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 .
В рабочем лете Shared Storage вы можете получить доступ к модулям crypto и TextEncoder , которые помогут вам сгенерировать хеш. Подробнее о генерации хеша см. в SubtleCrypto.digest() на MDN .
В следующем примере описывается, как можно сгенерировать ключ контейнера из хешированного значения:
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
Агрегируемая стоимость
Агрегируемые значения суммируются по каждому ключу по многим пользователям для формирования агрегированных данных в виде сводных значений в сводных отчетах.
Теперь вернёмся к заданному ранее примеру вопроса: «Сколько пользователей, видевших мой виджет, находятся во Франции?» Ответ на этот вопрос будет выглядеть примерно так: «Примерно 4881 пользователь, видевший мой виджет с идентификатором 3276, находится во Франции». Агрегируемое значение равно 1 для каждого пользователя, а «4881 пользователь» — это агрегированное значение , которое представляет собой сумму всех агрегируемых значений для данного ключа агрегации .
| Ключ агрегации | Агрегируемая стоимость | |
| Идентификатор виджета | Идентификатор страны | Количество просмотров |
| 3276 | 061 | 1 |
В этом примере мы увеличиваем значение на 1 для каждого пользователя, увидевшего виджет. На практике агрегируемое значение можно масштабировать для улучшения соотношения сигнал/шум .
Бюджет взносов
Каждый вызов API частного агрегирования называется взносом . Для защиты конфиденциальности пользователей количество взносов, которые можно получить от одного человека, ограничено.
При суммировании всех агрегируемых значений по всем ключам агрегации сумма должна быть меньше бюджета вклада. Бюджет ограничен источником данных, днем и разделяется для рабочих летов Protected Audience API и Shared Storage. Для дня используется скользящий интервал, равный примерно последним 24 часам. Если новый агрегируемый отчет приведет к превышению бюджета, отчет не создается.
Бюджет взносов представлен параметром L 1 и установлен на уровне 2,16 (65 536) за десять минут в день с ограничением 2,20 (1 048 576). Подробнее об этих параметрах см. в пояснительной записке .
Значение бюджета вклада произвольно, но шум масштабируется к нему. Вы можете использовать этот бюджет для максимизации соотношения сигнал/шум в сводных значениях (подробнее см. в разделе « Шум и масштабирование» ).
Чтобы узнать больше о бюджетах взносов, ознакомьтесь с пояснениями . Также обратитесь к разделу «Бюджет взносов» для получения дополнительных инструкций.
Лимит вклада за отчет
В зависимости от вызывающей стороны лимит на внесение данных может различаться, и для Shared Storage эти ограничения установлены по умолчанию и могут быть переопределены . В настоящее время отчёты, создаваемые для вызывающих API Shared Storage, ограничены 20 вкладами на отчёт. С другой стороны, для вызывающих API Protected Audience ограничено 100 вкладами на отчёт. Эти ограничения были выбраны для баланса между количеством вносимых вкладов и размером полезной нагрузки.
В случае общего хранилища данные, внесенные в рамках одной операции run() или selectURL() объединяются в один отчёт. В случае защищённой аудитории данные, внесенные одним источником в рамках аукциона, объединяются.
Вклады с заполнением
Вклады дополнительно модифицируются с помощью функции заполнения. Заполнение полезной нагрузки защищает информацию об истинном количестве вкладов, встроенных в агрегируемый отчёт. Заполнение дополняет полезную нагрузку null вкладами (т.е. значением 0) до достижения фиксированной длины.
Агрегируемые отчеты
После вызова пользователем API частного агрегирования браузер генерирует агрегированные отчёты, которые будут обработаны службой агрегирования позднее для формирования сводных отчётов . Агрегированный отчёт имеет формат JSON и содержит зашифрованный список данных, каждый из которых представляет собой пару {aggregation key, aggregatable value} . Агрегированные отчёты отправляются со случайной задержкой до одного часа.
Данные зашифрованы и недоступны для чтения вне сервиса агрегации. Сервис агрегации расшифровывает отчёты и формирует сводный отчёт. Ключ шифрования для браузера и ключ дешифрования для сервиса агрегации выдаются координатором, который выполняет функции сервиса управления ключами. Координатор хранит список двоичных хешей образа сервиса, чтобы убедиться, что вызывающему объекту разрешено получать ключ дешифрования.
Пример агрегированного отчета с включенным режимом отладки :
"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 :

В целях тестирования можно использовать кнопку «Отправить выбранные отчеты» для немедленной отправки отчета на сервер.
Собирайте и создавайте пакетные агрегированные отчеты
Браузер отправляет агрегируемые отчеты в источник рабочего проекта, содержащего вызов API частного агрегирования, используя указанный общеизвестный путь:
- Для общего хранилища:
/.well-known/private-aggregation/report-shared-storage - Для защищенной аудитории:
/.well-known/private-aggregation/report-protected-audience
На этих конечных точках вам понадобится сервер, выступающий в роли сборщика данных, который будет получать агрегированные отчеты, отправляемые клиентами.
Затем сервер должен сформировать пакет отчётов и отправить его в службу агрегации. Пакеты формируются на основе информации, доступной в незашифрованном виде агрегируемого отчёта, например, из поля shared_info . В идеале каждый пакет должен содержать не менее 100 отчётов.
Вы можете выбрать ежедневную или еженедельную пакетную обработку. Эта стратегия гибкая, и вы можете изменить её для конкретных событий, когда вы ожидаете большего объёма, например, для дней в году, когда ожидается больше показов. Пакеты должны включать отчёты из одной версии API, источника отчётности и запланированного времени отчётности.
Идентификаторы фильтров
Частный API агрегации и служба агрегации позволяют использовать идентификаторы фильтрации для обработки измерений на более детальном уровне, например по рекламным кампаниям, а не обрабатывать результаты в более крупных запросах.

Чтобы начать использовать это уже сегодня, вот несколько примерных шагов, которые можно применить к вашей текущей реализации.
Шаги общего хранилища
Если вы используете в своем потоке 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. Это значение по умолчанию позволяет избежать ненужного увеличения объёма данных и, следовательно, затрат на хранение и обработку. Подробнее читайте в пояснительной записке по гибкому вкладу .В
filtering-worklet.jsпри передаче вклада вprivateAggregation.contributeToHistogram(...)в рабочем листе 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. Перейдите к руководству по идентификаторам фильтрации, чтобы узнать об изменениях, которые необходимо внести в параметры задания службы агрегации.
После завершения пакетной обработки и отправки данных в развернутую службу агрегации отфильтрованные результаты должны быть отражены в вашем итоговом сводном отчете.
Шаги защищенной аудитории
Если вы используете в своем потоке API защищенной аудитории :
В вашей текущей реализации Protected Audience вы можете настроить следующие параметры для подключения к Private Aggregation. В отличие от Shared Storage, максимальный размер идентификатора фильтрации пока не может быть настроен. По умолчанию максимальный размер идентификатора фильтрации составляет 1 байт и будет установлен равным
0n. Имейте в виду, что эти параметры будут заданы в функциях отчётности Protected Audience (например,reportResult()илиgenerateBid()).const contribution = { ... filteringId: 0n }; privateAggregation.contributeToHistogram(contribution);Агрегируемые отчёты будут отправляться на указанную вами конечную точку
/.well-known/private-aggregation/report-protected-audience. После завершения пакетной обработки и отправки в развёрнутую службу агрегации отфильтрованные результаты должны быть отражены в итоговом сводном отчёте. Доступны следующие пояснения по API для отчётности атрибуции и API для частного агрегирования, а также первоначальное предложение.
Продолжайте изучать наше руководство по идентификаторам фильтрации в Службе агрегации или перейдите в разделы API отчетов об атрибуции, чтобы прочитать более подробную информацию.
Служба агрегации

Служба агрегации получает зашифрованные агрегированные отчёты от сборщика и генерирует сводные отчёты. Подробнее о пакетной обработке агрегированных отчётов в сборщике см. в нашем руководстве по пакетной обработке .
Сервис работает в доверенной среде выполнения (TEE), которая обеспечивает определённый уровень гарантий целостности данных, конфиденциальности данных и целостности кода. Если вы хотите подробнее узнать об использовании координаторов совместно с TEE, ознакомьтесь с их ролью и назначением .
Сводные отчеты
Сводные отчёты позволяют просматривать собранные данные с добавлением шума. Вы можете запросить сводные отчёты для заданного набора ключей.
Сводный отчёт содержит набор пар «ключ-значение» в формате словаря JSON. Каждая пара содержит:
-
bucket: ключ агрегации в виде двоичной строки. Если используемый ключ агрегации — «123», то корзина — «1111011». -
value: итоговое значение для заданной цели измерения, суммированное из всех доступных агрегируемых отчетов с добавленным шумом.
Например:
[
{"bucket":` `"111001001",` `"value":` `"2558500"},
{"bucket":` `"111101001",` `"value":` `"3256211"},
{"bucket":` `"111101001",` `"value":` `"6536542"},
]
Шум и масштабирование
Для сохранения конфиденциальности пользователей служба агрегации добавляет шум один раз к каждому сводному значению при каждом запросе сводного отчёта. Значения шума выбираются случайным образом из распределения вероятностей Лапласа . Хотя вы не можете напрямую контролировать способ добавления шума, вы можете влиять на его влияние на данные измерений.
Распределение шума одинаково независимо от суммы всех агрегируемых значений. Следовательно, чем выше агрегируемые значения, тем меньше вероятность того, что шум окажет влияние.
Например, предположим, что распределение шума имеет стандартное отклонение 100 и центрировано на нуле. Если собранное агрегируемое значение отчёта (или «агрегируемое значение») составляет всего 200, то стандартное отклонение шума составит 50% от агрегированного значения. Но если агрегируемое значение равно 20 000, то стандартное отклонение шума составит всего 0,5% от агрегированного значения. Таким образом, агрегируемое значение 20 000 будет иметь гораздо более высокое отношение сигнал/шум.
Таким образом, умножение агрегируемого значения на коэффициент масштабирования может помочь снизить уровень шума. Коэффициент масштабирования определяет, насколько вы хотите масштабировать данное агрегируемое значение.

Увеличение значений путём выбора большего коэффициента масштабирования снижает относительный шум. Однако это также приводит к тому, что сумма всех вкладов по всем сегментам быстрее достигает предела бюджета вклада. Уменьшение значений путём выбора меньшего коэффициента масштабирования увеличивает относительный шум, но снижает риск достижения предела бюджета.

Чтобы рассчитать подходящий коэффициент масштабирования, разделите бюджет взносов на максимальную сумму агрегируемых значений по всем ключам.
Более подробную информацию см. в документации по бюджету взносов .
Привлекайте и делитесь отзывами
API частного агрегирования находится в стадии активного обсуждения и может быть изменён в будущем. Если вы попробуете этот API и у вас есть отзывы, мы будем рады их услышать.
- GitHub : прочитайте пояснения , задайте вопросы и примите участие в обсуждении .