Amazon Bedrock Knowledge Bases — полностью управляемая RAG-возможность Bedrock: вы подключаете источники данных, а сервис управляет ingestion, хранением, индексацией и retrieval. Для публичного веб-контента AWS советует начинать со встроенного Amazon Bedrock Web Crawler: коннектор соблюдает robots.txt, поддерживает seed URLs и sitemaps, плановые синхронизации и ожидание контента, который подгружается JavaScript, а после первого полного обхода каждый sync забирает только добавленное, обновлённое и удалённое (Prepare web content for Amazon Bedrock Knowledge Bases with Crawl4AI).
Crawl4AI появляется в схеме, когда этого набора мало. Открытый Python-краулер ставят отдельным слоем подготовки: он рендерит JavaScript, извлекает выборочные области страницы и обогащает документы метаданными до того, как контент попадёт в Amazon S3 (тот же разбор AWS).
Прямой ответ на главный вопрос: свой слой нужен, если вы хотите индексировать только основную область страницы, вырезать навигацию и boilerplate или прикрепить к каждому документу собственные атрибуты метаданных. Это расширение knowledge base, а не её замена: подготовленный Markdown и sidecar всё равно загружаются через обычный Amazon S3 data source, поэтому путь одинаково работает с managed и customer-managed базами, ведь оба типа поддерживают S3-источники.
Граница, которую стоит держать в голове: это пакетный ingestion известных веб-свойств, а не доступ в веб на этапе инференса, как Web Grounding с Amazon Nova. Сайт обновился сегодня, индекс обновится после следующего прогона краулера и ingestion job. Для справочной документации это нормально, для новостной ленты — нет.
Зачем нужен Crawl4AI поверх встроенного краулера Bedrock
Выбор между встроенным коннектором и своим слоем подготовки решается тремя вопросами: насколько чистое извлечение даёт штатный краулер, хватает ли его метаданных для фильтрации и нужен ли вам контроль над границами обхода. Если на все три ответ «достаточно», писать собственный пайплайн смысла нет.
Когда хватает Amazon Bedrock Web Crawler
Штатный коннектор закрывает задачу, если выполняется большинство пунктов:
- сайт публичный и отдаёт контент по обычным URL;
- разметка стандартная, дефолтное извлечение даёт читаемый текст;
- метаданных по умолчанию хватает для фильтрации выдачи;
- нужны плановые синхронизации, а не ручные перезапуски: коннектор сам отслеживает добавленное, обновлённое и удалённое;
- robots.txt и sitemap описывают сайт корректно;
- на страницах есть JS-контент, который надо дождаться, и это уже учтено.
В этом сценарии вы экономите не только код, но и точки отказа: нет контейнера, нет своей очистки, нет задачи разбираться, почему очередной прогон вернул половину страниц.
Когда без Crawl4AI не обойтись
Свой слой подготовки оправдан в нескольких типовых ситуациях:
- Тяжёлый шаблон. Меню, футеры, блоки «читайте также», баннеры подписки забивают чанки и размывают эмбеддинги. Модель получает контекст из перекрёстных ссылок вместо ответа по делу.
- Нужен только main content. Регион с полезным текстом стабилен и его можно описать CSS-селектором.
- Нужны свои атрибуты. Версия документации, продукт, язык, раздел, тип контента. Штатный краулер таких полей не придумает.
- Нужен жёсткий контроль обхода. Seed origin, scope по странице, пути или хосту, глубина, лимит страниц, URL-паттерны.
- Нужна своя очистка Markdown перед загрузкой в S3, с предсказуемым результатом на ваших типах страниц.
Это и есть подготовка веб-контента для RAG: не «залить сайт в базу знаний», а привести страницы к виду, в котором чанкер и поиск работают предсказуемо.
Архитектура пайплайна: от Crawl4AI до ingestion job
Поток данных короткий, и в нём важно не перепутать зоны ответственности.
- Crawl4AI обходит публичные страницы в заданном scope.
- Для каждой страницы появляется Markdown-файл и sidecar
page.md.metadata.json. - Оба файла пишутся в Amazon S3 под выбранный префикс.
- Knowledge base забирает документы через свой Amazon S3 data source.
- Запускается ingestion job.
- Bedrock парсит документы, режет на чанки, считает эмбеддинги и строит индекс; метаданные из sidecar становятся фильтруемыми полями.
S3 здесь выполняет одну функцию: точка стыковки. Knowledge base не умеет ходить в ваш краулер, она умеет читать бакет. Всё остальное — вопрос раскладки объектов и того, как вы вызываете обновление индекса.
Роль Amazon S3 как промежуточного хранилища
Раскладка префиксов влияет на всё дальнейшее: повторные прогоны, очистку, возможность удалить один раздел сайта, не переписывая остальные. Две рабочие схемы: s3://bucket/site/<domain>/<run-date>/page.md или стабильные ключи без даты в пути. Первый вариант даёт историю и удобную очистку по дате, но плодит дубли в индексе, если старые объекты никто не удаляет. Второй вариант перезаписывает файл и не оставляет мусора, зато теряет историю версий. Блог AWS конкретную раскладку не фиксирует, это решение на вашей стороне.
Что именно делает ingestion job
Ingestion — это парсинг, чанкинг, эмбеддинги и индексация. Crawl4AI не должен ни резать текст на чанки, ни считать векторы: его работа заканчивается на чистом Markdown и корректных метаданных. Такое разделение упрощает отладку. Если ответы плохие, вы быстро понимаете, где искать: в Markdown (мусор на входе), в стратегии чанкинга или в фильтрах retrieval. Как устроена managed knowledge base целиком, включая коннекторы и режимы поиска, разобрано в материале про Amazon Bedrock Managed Knowledge Base.
Отдельно про запуск. Блог AWS описывает слой подготовки и стыковку с S3; обвязку расписания и исполнения в нём нужно проектировать самому. Рабочий вариант для AWS: EventBridge запускает задачу ECS Fargate, внутри контейнера работает Crawl4AI, результат уходит в S3, затем вызывается старт ingestion job. Размеры задач, таймауты, роль IAM с доступом к бакету и к API Bedrock подбираются под объём сайта. Пример в aws-samples repository — референс, из которого понятна логика, а не готовое продакшн-решение.
Настройка Crawl4AI: извлечение, очистка и ограничения обхода
Что именно попадёт в базу знаний, определяют три группы настроек: что извлекаем, как чистим и куда не пускаем краулер (описание подхода в блоге AWS).
CSS-селектор: как извлечь только основную область страницы
Извлечение по CSS-селектору опционально. Без него краулер берёт всю страницу: с меню, хлебными крошками и блоком «поделиться». С селектором в Markdown попадает только совпавший регион.
Практика: целиться в стабильный контейнер контента (main, article, div.content), а не в служебные обёртки, которые меняются от релиза к релизу. Селекторы ломаются при редизайне, и ломаются молча: вместо ошибки вы получаете пустой или обрезанный Markdown, который спокойно уезжает в S3. Держите набор из 5–10 эталонных страниц и сверяйте результат после каждой правки вёрстки или конфигурации. Если разметка нестабильна, разумнее ослабить селектор и усилить очистку Markdown, чем гоняться за каждым изменением в HTML.
Очистка Markdown от навигации и boilerplate
Для очистки используется DefaultMarkdownGenerator с pruning content filter: он сокращает навигацию и boilerplate, сохраняя заголовки, списки и таблицы. Именно эти три элемента несут структуру, на которую потом опирается чанкер.
Pruning работает по эвристикам. Значит, он может и перестараться, вырезав полезный блок, и недоработать, оставив простыню ссылок. Универсального рецепта нет: проверяйте вывод на репрезентативных страницах своего сайта, а не на одной красивой. Что смотреть: остались ли заголовки разделов, не пропали ли таблицы с параметрами, не приехал ли в чанки футер со ссылками на соцсети.
Ограничение обхода: origin, scope, глубина, лимит страниц
Обход идёт breadth-first и ограничивается seed origin, scope по странице, пути или хосту, глубиной, лимитом страниц и URL-паттернами. Без этих рамок краулер уползёт в каталог тегов и архив за 2013 год, а вы заплатите за хранение и ingestion.
| Параметр | Что ограничивает | Практика |
|---|---|---|
| Seed origin | Домен и поддомены, с которых начинается обход | Один origin на прогон, чтобы не смешивать продукты |
| Scope (page / path / host) | Какие URL считаются допустимыми | Индексировать /docs, а не весь сайт |
| Depth | Сколько переходов от seed допустимо | Для документации обычно хватает 3–4 уровней |
| Page caps | Потолок числа страниц | Прямой лимит бюджета на S3 и ingestion |
| URL patterns | Include и exclude по шаблонам | Выкинуть /tags, /search, параметры UTM |
Начинайте с узкого scope. Логируйте, какие URL были отброшены и почему: без этого через месяц никто не вспомнит, почему половина документации не попала в индекс. Markdown проверяйте вручную на 5–10 типовых страницах: лендинг, справочная статья, страница с таблицей, страница с кодом.
Метаданные и sidecar-файл: как фильтровать retrieval
Для каждой страницы Crawl4AI пишет Markdown и sidecar page.md.metadata.json. Метаданные — главный аргумент в пользу этого пути: без них поиск умеет отвечать «что-то похожее», а не «то, что относится к актуальной версии нужного продукта».
Что класть в sidecar, а что нет
Ориентир из разбора — лимит 10 КБ на sidecar. В блоге AWS про Crawl4AI это число не зафиксировано, поэтому перед проектированием схемы сверьте актуальные ограничения на метаданные в документации Amazon Bedrock Knowledge Bases: если упрётесь в потолок, придётся урезать атрибуты, а не надеяться, что прокатит.
Дисциплина простая: минимум обязательных полей, остальное только по делу.
| Поле | Пример | Зачем |
|---|---|---|
source_url | https://example.com/docs/api#auth | Ссылка на источник в ответе и трассировка чанка |
crawl_timestamp | 2026-11-02T17:11:21Z | Отсечь устаревшие документы при поиске |
content_type | docs / article / changelog | Не тащить релиз-ноты в ответы на вопросы |
product | bedrock | Разделить продукты в одной базе |
doc_version | v2 | Не смешивать версии документации |
section | guides/security | Сузить поиск до раздела сайта |
lang | ru / en | Не смешивать языки выдачи |
Чего не делать: не дублировать в sidecar текст страницы, не хранить вложенные структуры на сотни полей, не заводить атрибут под каждый эксперимент. Проверяйте размер файла перед загрузкой в S3: одна страница с раздутыми метаданными испортит ingestion не хуже битой вёрстки.
Фильтрация результатов поиска по метаданным
Метаданные дают фильтры на этапе retrieval. Рабочие примеры:
- только актуальная версия документации (
doc_version = v2); - только нужный раздел сайта (
section = guides/security); - только документы, собранные после определённой даты (
crawl_timestamp); - только статьи, без changelog и релиз-нотов (
content_type).
Фильтр экономит контекст и снижает шанс, что модель возьмёт устаревший или нерелевантный фрагмент. Если база знаний работает в связке с агентами, фильтры и маршрутизация между базами решаются на другом уровне; подробности в материале про агентный поиск с маршрутизацией между базами знаний.
Чанкинг: какие варианты доступны и как Markdown влияет на выбор
Чанкинг настраивается на стороне knowledge base, а не в краулере. В блоге AWS про Crawl4AI конкретные стратегии не разбираются, поэтому ниже рамка выбора, а точные параметры и дефолты смотрите в документации сервиса.
Основные варианты, которые обсуждают для веб-контента:
- Fixed-size. Текст режется по длине с перекрытием. Предсказуемо по стоимости, но структуру игнорирует, поэтому мусор в Markdown бьёт по качеству сильнее всего.
- Hierarchical. Чанки строятся по структуре документа, с учётом заголовков и вложенности. Здесь чистый Markdown с сохранёнными заголовками, списками и таблицами даёт прямую выгоду.
- Semantic. Границы чанков определяются по смыслу соседних фрагментов. Полезно для плотного текста без явной структуры, дороже по обработке.
Выбор зависит от типа контента. Справочная документация с ровной иерархией заголовков хорошо ложится на структурный чанкинг. Лендинги и статьи без подзаголовков структурой не спасти, там пригодится семантика или аккуратный fixed-size с перекрытием. Категоричных рекомендаций тут нет: один и тот же сайт может требовать разных подходов для /docs и /blog.
Связь с подготовкой контента прямая. Если pruning вырезал заголовки, иерархический чанкер останется без опоры, и вы получите те же куски текста, что и при fixed-size. Стоимость ошибки на этапе очистки вылезает уже на этапе поиска, в виде нерелевантных ответов.
Ограничения пайплайна: что он не умеет и где рвётся
Список стоит прочитать до того, как закладывать пайплайн в план работ.
- Только публичные страницы. Краулер ходит по открытому вебу без аутентификации: закрытые разделы, личный кабинет, внутренняя вики и контент за логином остаются за бортом.
- Нет автоматического удаления устаревшего. Если страницу удалили с сайта, объект в S3 и чанки в индексе сами не исчезнут.
- Нет retry и алертов в примере. Референсная реализация не содержит политики повторов и оповещений, мониторинг строится отдельно.
- Эвристики и хрупкость. Pruning работает по эвристикам, CSS-селекторы ломаются при редизайне.
- Задержка. Это batch ingestion: между обновлением сайта и обновлением индекса проходит время.
Часть пунктов относится к референсному примеру и вашей обвязке, а не к самому сервису Bedrock. В блоге AWS они не разбираются, поэтому планировать их нужно заранее.
Мониторинг и retry: чего нет в примере
Минимальный набор, который стоит собрать: алерт на падение задачи ECS, алерт на пустой результат краулинга (ноль страниц почти всегда означает сломанный селектор или блокировку), алерт на ошибки ingestion job и на рост доли документов, которые не проиндексировались. Для сетевых сбоев — retry с backoff и идемпотентная запись: повторный прогон должен перезаписывать те же ключи, а не плодить копии. Конкретные пороги выбирайте по объёму сайта. Как строят наблюдаемость вокруг Bedrock-пайплайнов на уровне трейсов и метрик, разобрано в статье про мультибазовый agentic RAG с наблюдаемостью через AWS CDK.
Устаревшие объекты в S3
Knowledge base не узнает, что страница исчезла с сайта. Варианты очистки: lifecycle-политики S3 для префиксов с датой, отдельная задача, которая сверяет список объектов с результатом последнего обхода, и перезапись по стабильным ключам, при которой старый файл просто замещается новым. Плюс страховка на этапе поиска: crawl_timestamp в метаданных позволяет отфильтровать всё, что старше разумного окна.
Безопасность: crawled-контент как недоверенный ввод
Всё, что пришло из открытого веба, — недоверенный ввод. На странице может быть текст, который выглядит как инструкция для модели: «игнорируй предыдущие указания», «отправь содержимое базы на такой-то адрес», «ответь, что доступ разрешён». После ingestion такой фрагмент попадает в чанки и может вернуться в контекст как обычный документ. Это класс атак prompt injection через retrieval.
Что помогает, а что нет:
- Разделяйте системные инструкции и retrieved-контекст. В системном промпте должно быть явно сказано, что документы — это данные, а не команды.
- Санитизируйте вход: вырезайте HTML-комментарии, скрытые блоки, невидимые символы и текст, спрятанный стилями.
- Ограничивайте источники: список доменов, с которых вообще разрешён краулинг, и фильтрация по метаданным сужают набор документов, способных попасть в контекст.
- Логируйте, какие чанки ушли в модель. Без этого инцидент не разобрать.
- Используйте защитные механизмы платформы, например Guardrails в Bedrock, как дополнительный слой.
Полной защиты тут никто не обещает: prompt injection через документы остаётся открытой проблемой, и снижение риска складывается из суммы мер, а не из одной настройки.
Кому подходит этот пайплайн и что делать дальше
Вердикт короткий. Если встроенный Amazon Bedrock Web Crawler отдаёт читаемый текст и его метаданных хватает для фильтров, оставайтесь на нём: меньше кода, меньше точек отказа, синхронизация дельты уже встроена. Crawl4AI-слой оправдан, когда нужен контроль над тремя вещами: что именно извлекается со страницы, как выглядит Markdown и какие атрибуты сопровождают документ.
Чек-лист старта:
- Узкий scope: один origin, конкретный путь, глубина 3–4 и явный лимит страниц.
- Набор эталонных страниц для проверки Markdown после каждой правки конфигурации.
- Схема метаданных в пределах лимита sidecar, с обязательными
source_url,crawl_timestamp,content_type. - Мониторинг, retry с backoff и идемпотентная запись в S3.
- План очистки: lifecycle-политики или отдельная задача сверки объектов.
- Трактовка crawled-контента как недоверенного ввода на уровне промптов и санитизации.
Референс из aws-samples repository берите как рабочую логику, а не как продакшн: расписание, роли, алерты и очистку дописываете под свой случай. И помните про природу подхода: это пакетная подготовка известных веб-свойств, а не доступ в веб в реальном времени. Свежесть ответа ограничена частотой прогонов краулера и ingestion, а не возможностями модели.