Insights / Технические материалы

Руководство по реализации Cloudflare Vectorize: безопасная синхронизация опубликованного HTML

Подробное руководство по созданию corpus из опубликованного HTML, сохранению Pagefind и безопасной эксплуатации синхронизации Vectorize.

  • Технологии
  • Cloudflare
  • Vectorize
  • OpenAI
  • Поиск по сайту
Руководство по реализации Cloudflare Vectorize: безопасная синхронизация опубликованного HTML
Содержание
  1. Сначала разберемся: что такое Cloudflare Vectorize?
  2. Что улучшается при его добавлении?
  3. Сначала наложить его поверх существующего поиска
  4. Главный вывод: поиск — fail-soft, синхронизация и публикация — fail-closed
  5. Сначала определите четыре вещи
  6. Не заменять Pagefind, а разделить роли
  7. Создавать corpus из опубликованного HTML, а не из черновика CMS
  8. Сделать дифференциальную синхронизацию детерминированной с помощью content hash
  9. Зафиксировать embedding model и конфигурацию index как единый контракт
  10. Сначала выполнить upsert и дождаться сходимости, затем удалять
  11. При большой доле удаления или смене модели использовать заменяющий index
  12. Оставить Preview только с Pagefind, а Production сделать единственной высокопривилегированной целью синхронизации
  13. Синхронизировать с Production только corpus «опубликованного сейчас commit»
  14. Публичному поисковому API нужны границы стоимости и приватности
  15. Связанному поиску и генеративному AI-чату — отдельные контракты
  16. Не смешивать ответственность источников поиска
  17. Реальные сбои и изменения после них
  18. Разделить понятие «внедрено» на четыре состояния
  19. Минимальная архитектура для переноса на другие сайты
  20. Итог

Сначала разберемся: что такое Cloudflare Vectorize?

Cloudflare Vectorize — векторная база данных Cloudflare. Она хранит embeddings — числовые представления признаков и смысла текста, изображений и других данных — и находит информацию, близкую по смыслу к входному запросу. Как объясняет официальный обзор, ее можно использовать для семантического поиска, рекомендаций, классификации и слоя retrieval будущих RAG-приложений.

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

Vectorize сам по себе не является чат-ботом, который генерирует ответ. Это поисковая основа, выбирающая релевантные опубликованные страницы и их URL. Если позднее добавить генеративный AI, эти результаты могут стать слоем доказательств ответа.

Что улучшается при его добавлении?

  • Находятся перефразированные запросы и вопросы: читателю не нужно знать точные термины сайта, чтобы попасть на страницу, близкую к его намерению.
  • Связанные знания соединяются между разными материалами: статьи, FAQ и страницы услуг с разной формулировкой можно находить по близости смысла.
  • Существующий поиск усиливается, а не заменяется: если использовать его только для явного действия «найти связанную информацию» и сохранить поиск по ключевым словам, обнаруживаемость растет без переделки всей UI.
  • Слой retrieval можно использовать позже: возврат исходной страницы и URL позволяет применять тот же слой для AI-ответов с цитатами, связанных статей и рекомендаций.

Семантический поиск не является магией. Качество зависит от корректно выбранного публичного corpus, подходящего embedding model и оценки реальных результатов. Он не должен заменять обычный поиск точных названий продуктов или кодов.

Сначала наложить его поверх существующего поиска

Для первого внедрения удобнее сохранить поиск по ключевым словам и вызывать Vectorize только когда читатель явно просит найти связанную информацию.

  1. Использовать Pagefind или обычный поиск для названий продуктов, собственных имен и коротких точных терминов.
  2. Использовать связанную Vectorize-поиск для вопросов, перефразировок и близких тем.
  3. Оставлять обычный поиск доступным, если embedding provider или Vectorize недоступен.

Сначала следует оценить именно эту ценность и область применения. Остальная часть статьи показывает повторяемый подход для сайтов Astro/Cloudflare Pages.

Практичная первая конфигурация: Обычная Pages Preview использует только Pagefind с SEARCH_ENABLED=false. Binding Vectorize/D1 и автоматическая синхронизация ограничены Production. В Preview проверьте интерфейс поиска и fallback; в Production синхронизируйте только corpus, созданный из опубликованного commit. Так тестовые изменения и широкие права не попадут в рабочий поиск.

При планировании внедрения становится ясно, что недостаточно просто «создать embedding и вызвать query()». Нужно решить, как строить corpus поиска, как оставить Preview только с Pagefind и защищать Production, как не допустить массового удаления из-за ошибочной синхронизации и действительно ли опубликованные страницы совпадают с index. В реальной эксплуатации проектирование вокруг вызова API Vectorize важнее самого вызова.

Главный вывод: поиск — fail-soft, синхронизация и публикация — fail-closed

Наиболее переносимым принципом оказалось разделение стратегии сбоя для пользовательского поиска и служебной синхронизации.

Область Стратегия при сбое Причина
Обычный поиск по сайту fail-soft Даже при остановке Vectorize поиск продолжается через Pagefind
API связанного поиска fail-soft Быстро завершить ошибку, не нарушая результаты обычного поиска
Генерация corpus fail-closed Не создавать corpus при неверных страницах, locale, количестве или metadata
Синхронизация index fail-closed Ничего не менять, если нельзя проверить окружение, существующие ID, долю удалений или mutation
Включение в Production fail-closed Включать только после совпадения опубликованного commit и corpus и сходимости Production-синхронизации и mutations

Так одновременно выполняются два условия: «при сбое AI поиск по сайту остается доступен» и «при любом сомнении синхронизация не меняет ни одной записи».

Сначала определите четыре вещи

Прежде чем выбирать provider или имя index, ответьте на эти четыре вопроса. Так архитектуру будет намного проще оценивать.

Решение Простой первый выбор Зачем
Цель читателя «Найти связанные страницы» Вместо немедленной генерации ответов сначала можно оценить качество поиска.
Вход в поиск Pagefind при вводе; Vectorize после явного действия Скорость, стоимость и передача данных остаются понятными.
Исходный corpus Опубликованный HTML Черновики и административные экраны случайно не попадут в результаты.
Процесс публикации Проверить UI в Preview; синхронизировать только Production Тестовые данные и права не попадут в рабочий поиск.

После ответа на эти четыре вопроса выбирайте embedding provider, D1, R2 и будущую генерацию ответов в соответствии со своими требованиями.

Не заменять Pagefind, а разделить роли

Цель внедрения Vectorize не состояла в отказе от существующего поиска.

Pagefind создает статический index из собранного HTML и выполняет поиск в браузере. Он удобен как обычный поиск явных терминов — названий продуктов, услуг и собственных имен — и не зависит от состояния embedding provider или Vectorize.

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

Поэтому UI также разделен.

  1. Во время ввода показывать результаты Pagefind
  2. Вызывать API только после явного запуска связанного поиска пользователем
  3. Установить короткий timeout для API
  4. Не удалять результаты Pagefind при сбое API
  5. Позволить kill switch отключить только связанный поиск

В текущем поисковом модальном окне предложения во время ввода поступают только из Pagefind в браузере. Лишь после явного запуска «Поиск» термин, как указано в интерфейсе, отправляется в OpenAI Embeddings API и сопоставляется с публичной информацией этого сайта в Vectorize. Предупреждение просит не вводить персональные или конфиденциальные сведения и отличает эту передачу от обычных подсказок по ключевым словам.

В такой конфигурации Vectorize расширяет поиск, но не становится единой точкой отказа всего поиска.

Создавать corpus из опубликованного HTML, а не из черновика CMS

Самая заметная разница между сайтами возникала из-за выбора источника истины для поиска.

Если напрямую строить corpus из черновика CMS или Markdown, появляется расхождение с реально опубликованной страницей.

  • В index попадают материалы с draft или noindex
  • Остаются страницы с внешним canonical
  • Добавляются повторяющиеся тексты layout и интерфейсы администрирования
  • Не учитываются title, description и URL, возникающие только после преобразования
  • На многоязычном сайте становится неясной граница locale

Поэтому после build Astro мы читаем сгенерированный HTML и создаем corpus только после применения условий публикации.

На многоязычном сайте в первый corpus можно, например, включить только страницы выбранного языка, отвечающие следующим условиям:

  • Имеют same-origin canonical
  • Их lang соответствует японскому языку
  • Не отмечены noindex
  • Не относятся к /admin, /api, 404 или странице успешной отправки
  • Позволяют удалить элементы вне основного текста, включая data-vectorize-ignore и навигацию
  • Имеют публичный root-relative URL и title

Текст делится на chunks с целевой длиной 850 символов, максимальной длиной 1,200 символов и overlap 120 символов. Эти параметры не являются универсальным ответом: это эксплуатационные значения для длины наших страниц и японского текста. На другом сайте их нужно настроить по реальной структуре документов и оценке поиска.

Сделать дифференциальную синхронизацию детерминированной с помощью content hash

Если использовать последовательные номера или runtime UUID в качестве ID vectors, один и тот же corpus при повторной генерации получает полностью новые ID. Тогда приходится заново создавать embedding даже для неизменившегося текста и массово удалять старые ID.

Поэтому из locale, публичного URL, номера chunk и текста создается SHA-256, на основе которого детерминированно формируются ID и corpus version.

const identity = [locale, url, String(chunkIndex), text].join("\u001f");
const digest = sha256(identity);

const vector = {
  id: `v1-${digest.slice(0, 48)}`,
  text,
  metadata: {
    locale,
    url,
    chunkIndex,
    contentHash: digest,
  },
};

Во время синхронизации ожидаемые ID сравниваются с текущими ID index.

  • ID только на ожидаемой стороне получают embedding и upsert
  • ID с обеих сторон пропускаются как неизменившиеся
  • ID только в index становятся кандидатами на удаление
  • Наличие ID вне управления v1- останавливает процесс до любой mutation

Так один опубликованный контент всегда создает одинаковый corpus, а причину каждого различия легко объяснить.

Зафиксировать embedding model и конфигурацию index как единый контракт

Выбирайте embedding provider и model только после проверки реального вывода. Подходящим может быть model вроде @cf/baai/bge-m3 от Workers AI или OpenAI Embeddings, но его dimensions и metric должны соответствовать запланированному index. При последующей смене создайте отдельный целевой index, сохраните прежний для rollback и никогда не смешивайте vectors с разными dimensions.

Важнее конкретного названия модели — зафиксировать один контракт в четырех местах.

Место Фиксируемые значения
Metadata corpus model, dimensions, metric
Vectorize index dimensions, metric
Поисковый API model, embedding length
Sync-скрипт разрешенные model, dimensions, metric

Как указано в документации Cloudflare Create indexes, dimensions и metric index нельзя изменить после создания. Если документация модели неоднозначна, не следует создавать index на основе предположения: сначала нужно проверить актуальную документацию и реальный вывод.

Если используется metadata filtering, metadata index нужно создать до загрузки vectors. Добавление metadata index позже само по себе не сделает ранее загруженные vectors доступными для фильтрации — потребуется повторный upsert.

Лимиты продукта также меняются. Повторно подтверждено 31 июля 2026 года: в Vectorize V2 лимит upsert batch составляет 1,000 для Workers API и 5,000 для HTTP API. Обычный лимит topK равен 100, а при returnValues: true или returnMetadata: "all" — 50. При реализации обязательно заново проверяйте актуальные limits и client API.

Осознанно выбирайте меньшие, безопасно наблюдаемые размеры batch и значения topK, а не используйте непосредственно максимумы продукта. Лимит provider и размер batch, который команда способна безопасно повторять и контролировать, — разные решения.

Сначала выполнить upsert и дождаться сходимости, затем удалять

Insert, upsert и delete в Vectorize выполняются асинхронно. Успешный ответ API еще не означает, что изменение уже видно в query.

Безопасная синхронизация идет в следующем порядке:

  1. Проверить corpus и конфигурацию index
  2. Получить все текущие ID vectors через pagination
  3. Рассчитать цели upsert и кандидатов на delete
  4. Выполнить upsert пакетами
  5. Ждать, пока возвращенная mutationId не будет достигнута в processedUpToMutation
  6. Выполнять delete только после сходимости upsert
  7. Аналогично подтвердить сходимость delete mutation

В Vectorize API Cloudflare также указано, что mutations асинхронны. Недостаточно фиксированного sleep: завершение нужно проверять по mutation ID.

Sync-скрипт также останавливается при следующих условиях:

  • Имя целевого index не совпадает в точности с allowlist Production index
  • Процесс синхронизации пытается автоматически создать Production index
  • Значение --confirm-production не совпадает с целевым index
  • dimensions/metric отличаются от контракта
  • locale, URL, metadata или content hash corpus некорректны
  • Число source pages или vectors превышает ожидаемый максимум
  • В существующем index присутствуют неуправляемые ID
  • Нужно удалить больше 20% существующих vectors
  • Превышен предел retry или время ожидания mutation

Даже намеренное массовое удаление выполняется отдельной проверенной процедурой миграции, а не через override обычного workflow. Обычные push и schedule не могут его разрешить.

При большой доле удаления или смене модели использовать заменяющий index

Удаление более 20 % не следует оставлять в обычной дифференциальной синхронизации. Эти 20 % — не продуктовый лимит Cloudflare, а операционный предохранитель: обычный workflow останавливается для ручной проверки.

Когда в существующем index ожидалось удалить 21,3 % векторов, мы не удаляли их на месте, а перешли к такой последовательности:

  1. Создать заменяющий index, соответствующий новому контракту model, dimensions и metric.
  2. Полностью синхронизировать опубликованный corpus и проверить сходимость набора ID и canary-запросы.
  3. Переключить binding Worker или Pages на заменяющий index.
  4. Проверить поисковый API Production, fallback обычного поиска и активный binding.
  5. Удалять старый index только после отдельного явного одобрения.

Если после удаления возникла проблема, сначала установите SEARCH_ENABLED=false, чтобы остановить только связанную выдачу и сохранить обычный поиск. Затем заново создайте и полностью синхронизируйте заменяющий index, проверьте queries и снова переключите binding. Удаление index никогда не должно быть первым действием rollback.

Оставить Preview только с Pagefind, а Production сделать единственной высокопривилегированной целью синхронизации

Разделение Preview и Production на начальном этапе помогло выявить права и условия остановки. Однако обычной Pages Preview не нужны binding Vectorize или D1. Текущая конфигурация оставляет SEARCH_ENABLED=false: в Preview проверяются предложения Pagefind, fallback и layout. Binding Vectorize и D1, токены синхронизации и Production Environment ограничены Production.

Раздельными должны быть:

  • Vectorize index
  • Вспомогательные ресурсы, например D1
  • Wrangler environment
  • API token
  • GitHub Environment
  • concurrency workflow синхронизации
  • repository variable для включения
  • kill switch

Sync-token ограничен правами Vectorize Read / Write в целевом Cloudflare account и отделен от OpenAI API key. Production запускается только из защищенного main и проходит reviewer в GitHub Environment.

У этого решения есть эксплуатационный trade-off. Если Production Environment требует required reviewer, синхронизация, запущенная по schedule, также может ожидать одобрения. До добавления cron нужно решить, одобряется ли только первая публикация, каждая регулярная синхронизация или эти операции следует разделить на разные jobs.

Синхронизировать с Production только corpus «опубликованного сейчас commit»

Ветка main в GitHub и commit, который сейчас опубликован в Cloudflare Pages, не всегда совпадают. Сразу после push может продолжаться build, а после неудачного deployment публичным может остаться предыдущий commit.

Поэтому Production-синхронизация размещает build marker на публичном сайте и проверяет:

  • Commit в marker является 40-символьным Git SHA
  • Этот commit существует в repository
  • Он является предком защищенного main
  • Этот commit можно checkout и повторно создать из него corpus
  • Corpus version в marker совпадает с повторно созданным результатом
  • Непосредственно перед mutation опубликован всё тот же commit

Условием завершения служит deployment Cloudflare Pages через интеграцию с GitHub repository. Результат, временно опубликованный локально или через Direct Upload, не используется как основа Production-синхронизации.

Это предотвращает расхождения вида «синхронизировать новый corpus со старым сайтом» или «показать в поиске только контент commit, deployment которого завершился ошибкой».

Публичному поисковому API нужны границы стоимости и приватности

Поисковый API отправляет введенную строку embedding provider через публичный endpoint. Поэтому архитектура должна учитывать не только качество поиска, но и злоупотребления, стоимость, логи и возвращаемые URL.

Публичный поисковый API должен как минимум иметь следующие границы:

Область Пример реализации
Method/формат Принимать только same-origin JSON POST
body До 2KiB; даже без Content-Length остановить чтение при превышении в stream
query От 2 до 160 символов после нормализации NFKC
locale Только ja
rate limit Ограничения для client и global, соответствующие стоимости, трафику и модели угроз
Отключение Через SEARCH_ENABLED останавливать только связанный поиск
query Не сохранять raw query в logs, corpus или metadata Vectorize
URL результата Разрешать только публичные same-origin root-relative URL
Ошибки Возвращать структурированные codes по этапам и не записывать текст запроса в logs

UUID на стороне client не является надежной границей стоимости, потому что пользователь может его изменить. Поэтому он сочетается с client key на основе данных подключения Cloudflare, global limit и мониторингом потребления. В зависимости от масштаба и модели угроз также рассматриваются Turnstile, WAF или Durable Objects.

В этой архитектуре D1 используется для rate limit, но не является обязательным условием Vectorize. То же относится к R2. Выбор зависит от места получения исходного текста и хранения данных rate limit.

Связанному поиску и генеративному AI-чату — отдельные контракты

Поиск «связанного содержимого» может отправлять термин embedding provider только после явного действия и сопоставлять embedding с публичной информацией сайта в Vectorize. Отдельный AI-чат, напротив, отправляет вопрос и при необходимости контекст беседы в сервис ответов для генерации ответа.

Их нельзя объединять под расплывчатым названием «AI-поиск». Передаваемые данные, область источников, отображение ошибок, использование и объяснения приватности должны проектироваться раздельно; fallback Vectorize-поиска никогда не должен молча отправляться AI-помощнику.

Не смешивать ответственность источников поиска

Сайты, центры поддержки, правила и внутренние базы знаний имеют разные зоны ответственности. Заранее определите, к какому источнику относится каждый тип вопроса.

  • Искать публичную информацию о продуктах и услугах в corpus сайта
  • Искать обязательные правила и инструкции в соответствующем официальном источнике
  • При сбое Vectorize не переходить к неподходящему источнику
  • Ссылаться только на источники, действительно выбранные как доказательство
  • Не придумывать неподтвержденные правила или сведения

Это важно и для RAG или справочных чатов. Чем больше источников доступно, тем раньше нужно определить, какие вопросы идут в какой источник и чего нельзя отвечать при отсутствии информации.

Реальные сбои и изменения после них

Вот проблемы, которые легко повторяются и требуют внимания с самого начала.

Симптом Причина Что делать в следующий раз
Binding добавлен, но функции поиска нет API, corpus, reindex, права и UI не спроектированы До создания index определить контракт поиска и эксплуатационный процесс
Dimensions при создании index выбраны наугад Проверено только имя модели, а не реальный вывод Проверить фактическую embedding length до создания
Существующие vectors не появляются в metadata filter Они загружены раньше metadata index Сначала создать metadata index, затем повторно upsert существующих vectors
Query нестабилен сразу после синхронизации Mutation выполняется асинхронно Дождаться сходимости по mutationId и информации index
Возникает массовый повторный embedding и delete ID vector меняется при каждом запуске Использовать детерминированный ID на основе content hash
Schedule остается в состоянии waiting Production Environment требует одобрения Проектировать регулярную синхронизацию и политику одобрения вместе
Tests или Git не работают в Windows Факторы окружения: spawn EPERM, locks или cache Сравнить baseline, закрепить версию Node и проверить после чистого npm ci
Timeout API сразу считается ошибкой кода Временный сбой, неверный payload или задержка provider Повторить проверку с правильным контрактом и отделить единичный результат от воспроизводимости

Проблемы зависимостей и среды выполнения также нельзя ошибочно относить к изменению Vectorize. Нужно проверить, возникает ли та же ошибка в baseline до изменения, и разделить ошибки кода и окружения.

Разделить понятие «внедрено» на четыре состояния

В статьях и итоговых отчетах меньше недопонимания, если состояния фиксируются раздельно.

Состояние Пример условия завершения
Реализовано API, corpus, sync-скрипт и UI находятся в branch
Проверено локально Успешны build, проверка типов, контрактные tests и dry-run
Подтверждено в Preview Проверены предложения Pagefind, отображение недоступности связанного поиска и UI
Работает в Production Синхронизирован опубликованный commit, проверены mutation, API и отключение

Фиксируйте эти состояния раздельно также в итоговых отчетах и release notes. Так наличие кода не будет путаться с действительно безопасной работой в Production.

Для следующего ответственного полезнее всего записывать не только число успешных tests, но и то, что еще не подтверждено.

Минимальная архитектура для переноса на другие сайты

Для другого сайта Astro/Cloudflare Pages минимальная архитектура выглядит так:

Astro build
  -> опубликованный HTML
  -> Pagefind index
  -> Vectorize corpus (с учетом locale / canonical / noindex)

Cloudflare Pages Function
  -> input validation
  -> OpenAI Embeddings API
  -> Vectorize query
  -> возвращать только публичные URL

GitHub Actions
  -> определить опубликованный commit
  -> повторно создать corpus
  -> синхронизировать только Production index из allowlist
  -> удалять после сходимости upsert
  -> записать corpus version

Pages Preview
  -> SEARCH_ENABLED=false
  -> проверить предложения Pagefind и UI fallback

Необязательно сразу добавлять генерацию ответа LLM. Сначала стоит создать поиск, который «безопасно возвращает связанные страницы» и допускает оценку качества. Даже при добавлении генерации ответа исходный текст, URL для цитирования и условия отказа от ответа нужно оформить отдельным контрактом.

Итог

Сложность внедрения Cloudflare Vectorize заключается не в самой nearest-neighbor query.

Качество переноса на другой сайт определяет эксплуатационная архитектура: что считается публичной информацией для index, как распознавать неизменившиеся chunks, как остановить ошибочную синхронизацию, как сопоставить ее с опубликованным commit и как сохранить обычный поиск при сбое.

Итог прост:

  • Сохранить Pagefind как основной поиск
  • Использовать Vectorize как дополнение для семантического поиска
  • Создавать corpus из опубликованного HTML
  • Детерминированно создавать ID и version из content hash
  • Оставить Preview только с Pagefind и ограничить Vectorize, D1 и права синхронизации Production
  • Сделать поиск fail-soft, а синхронизацию и публикацию fail-closed
  • Фиксировать «реализацию», «локальную проверку», «проверку интерфейса Preview» и «Production» как разные состояния

Если сначала установить эти границы, Vectorize будет не разовой AI-функцией, а поисковой инфраструктурой, которую можно непрерывно обновлять.

Vectorize rollout

От опубликованного HTML к безопасному связанному поиску

За основу синхронизации берутся не исходные материалы для редактирования, а реально публикуемый HTML и уже развернутый commit.

  1. Собрать публикуемый HTML

    Сгенерировать статический HTML с учетом canonical, locale и noindex.

  2. Детерминированно создать corpus

    Разделить текст на chunks и назначить ID на основе content hash вместе с metadata для аудита.

  3. Проверить интерфейс Preview

    Оставить семантический поиск там отключенным и проверить предложения Pagefind, fallback и видимое предупреждение.

  4. Синхронизировать опубликованный commit с Production

    Сверить build marker и corpus version и включать функцию только после сходимости mutation.

Для поиска и синхронизации нужны разные стратегии при сбое

Всё зависит от Vectorize

  • При остановке AI, Vectorize или D1 весь поиск по сайту становится недоступен
  • Разница между черновиком CMS и опубликованной страницей напрямую превращается в разницу результатов поиска
  • Ошибка настройки sync-скрипта позволяет изменить другое окружение или большое число vectors
  • Внедрение легко признать завершенным сразу после merge кода

Fail-soft-поиск + fail-closed-синхронизация

  • Pagefind отвечает за обычный поиск, а семантический поиск вызывается только явным действием как дополнительная функция
  • Corpus создается из опубликованного HTML с учетом canonical, noindex и locale
  • Allowlist Production, доля удалений, опубликованный commit и завершение mutation проверяются до и после синхронизации
  • Реализация, локальная проверка, проверка интерфейса Preview и Production фиксируются как разные состояния
Находить больше, чем точные термины
Поиск по смыслу

Помогает с вопросами, перефразировками и тематически связанными страницами.

Pagefind + Vectorize
Два пути поиска

Надежный поиск по ключевым словам остается доступен, а Vectorize выборочно его дополняет.

Искать то, что видят читатели
Опубликованный HTML

Index следует реально опубликованным страницам, а не черновикам CMS.

Сначала проверить, затем публиковать
Постепенное внедрение

Интерфейс, corpus и синхронизация имеют собственные границы безопасности.

Проверка перед внедрением на следующем сайте

  • Сохранить существующий поиск по ключевым словам, чтобы путь поиска оставался доступен при остановке Vectorize
  • Сверить реальный вывод embedding model с dimensions/metric index
  • Создавать corpus из опубликованного HTML, исключая noindex, внешние canonical и страницы администрирования
  • Не выполнять повторный embedding неизменившихся chunks благодаря ID на основе content hash
  • Оставить Preview только с Pagefind, а Vectorize, D1 и права синхронизации ограничить Production
  • Удалять только после подтверждения upsert и требовать явного одобрения для массового удаления
  • Ограничить в поисковом API body, query, locale, origin и rate limit и добавить kill switch
  • Синхронизировать с Production только deployment, где опубликованный commit совпадает с corpus version
  • Раздельно фиксировать состояния: реализовано, проверено, подтверждено в Preview и работает в Production

Часто задаваемые вопросы

Становится ли Pagefind ненужным после внедрения Vectorize?

Нет. Pagefind остается обычным поиском с небольшим числом зависимостей, который создается из статического HTML. Vectorize служит дополнительным поиском перефразировок и связанных понятий. Даже при сбое AI или Vectorize обычный поиск остается доступен.

Обязательны ли D1 или R2 для внедрения Vectorize?

Нет. D1 может, например, управлять rate limit поискового API, но не является обязательным хранилищем самого Vectorize. Место хранения исходного текста также выбирается по требованиям: опубликованный HTML, JSON, D1 или R2.

Как управлять embedding model и dimensions в текущей реализации?

Model, dimensions и metric — единый контракт между corpus, index, API и синхронизацией. Vectors с разными dimensions нельзя смешивать в одном index. Настройки index нельзя изменить после создания, поэтому перед созданием нужно проверить актуальную официальную спецификацию и реальную форму вывода.

В какой момент внедрение считается завершенным?

Одного merge или локальных tests недостаточно. В Preview мы проверяем Pagefind и UI fallback; в Production — совпадение опубликованного commit и corpus, синхронизацию index, сходимость mutation, связанный поиск, rate limit и процедуру отключения, прежде чем фиксировать работу в Production.