Веб-сайт для векторной базы данных: краулинг, чанкование, встраивание в одном потоке
TL;DR
Векторная база данных для веб-сайтов хранит поисковые фрагменты и метаданные происхождения; она не помещает весь веб-сайт в один вектор.
Обходите ограниченное множество страниц, проверяйте Markdown, разбивайте его на стабильные фрагменты, встраивайте каждый фрагмент, затем вставляйте или обновляйте его в пространстве имен Pinecone.
Размер выходных данных модели встраивания должен соответствовать плотному индексу Pinecone, и повторное извлечение должно использовать детерминированные идентификаторы вместо создания дубликатов.
Это ориентированный на построение дополнение к существующему обзору Crawl-to-Pinecone от Nstdata; здесь акцент сделан на контракте данных и безопасном пути обновления.
Введение: Что вы построите
Nstdata Crawl является слоем сбора в этом рабочем процессе; его обзор продукта описывает извлечение страниц и сайтов для последующих потоков данных.
Этот учебный курс превращает публичный сайт документации в поисковые записи в Pinecone. Поток выглядит как URL → Crawl → Markdown → фрагменты → встраивания → Pinecone → запрос. Он останавливается на извлечении; интерфейс чата, разрешения пользователей и мониторинг в производстве являются отдельными слоями приложения.
Векторная база данных обычно не хранит веб-сайт как один гигантский документ. Каждая запись является вектором для отрывка, плюс идентификатор и метаданные, которые позволяют вам найти источник и обновить его позже. Nstdata Crawl предоставляет этап сбора страниц и преобразования Markdown; Pinecone хранит и извлекает векторы. Для текущих конечных точек Crawl и ответов по задачам используйте справочник API Nstdata Crawl.
Как содержание веб-сайта становится векторными данными
Попробуйте Nstproxy Crawl - Начните Бесплатно Уже Сегодня
Страница
https://docs.example.com/auth
Идентичность источника и цитирование
Markdown
Заголовок, объяснение, пример кода
Читаемый текст источника
Фрагмент
Один связный раздел
Единица извлечения
Встраивание
Числовой вектор
Поиск семантического сходства
Метаданные
URL, заголовок, раздел, версия, хэш
Фильтрация, цитаты, обновления
Запись Pinecone
стабильный ID + значения + метаданные
Цель обновления и запроса
Сохраняйте оригинальный текст страницы в метаданных только тогда, когда это соответствует вашей модели данных и требованиям к конфиденциальности. В этом примере текст фрагмента прикреплён к метаданным каждого вектора, чтобы извлечение могло вернуть готовый к цитированию отрывок. Для более крупных проектов записей оцените текущее руководство по моделированию данных и обновлению Pinecone.
Предварительные условия: API для обхода, встраивания и Pinecone
Создайте токен Nstdata Crawl, ключ API OpenAI и проект Pinecone. Создайте плотный индекс Pinecone, размер которого соответствует выходу модели встраивания. Пример ниже использует стандартный выход размером 1,536; если вы устанавливаете пользовательский размер встраивания, настройте индекс на то же значение. Установите библиотеки и зафиксируйте точные версии, указанные в вашем файле блокировки развертывания:
Названия SDK и формы API ниже соответствуют текущей документации поставщика. В среде написания нет доступных учетных данных API, поэтому полный облачный рабочий процесс не был выполнен от начала до конца.
Шаг 1: Обход сайта в Markdown
Для известного URL используйте документированный синхронный Python-клиент. Для сайта документации отправьте ограниченный обход сайта с низким maxPages в первом валидирующем запуске. API на уровне сайта возвращает идентификатор задачи; опрашивайте статус, а затем результаты страницы. Документы ссылки на Crawling POST /api/v1/crawl, GET /api/v1/crawl/status/{crawlId} и GET /api/v1/crawl/pages/{crawlId}.
import os
from nstdata_ai_crawl import CrawlRequestDto, Format, NstDataClient
with NstDataClient(os.environ["NSTDATA_API_TOKEN"])as client: submitted = client.submit_crawl_task(CrawlRequestDto( url="https://docs.example.com/", formats=[Format.MARKDOWN], maxDepth=2, maxPages=100, includeUrls=["*docs.example.com/*"], excludeUrls=["*docs.example.com/search*","*docs.example.com/login*"], ignoreQuery=True, onlyMainContent=True, timeout=60_000,)) crawl_id = submitted.idprint("submitted crawl", crawl_id)
Пример SDK подтверждает метод отправки и поля запроса. Для производства добавьте опрос с монотонным сроком, экспоненциальным обратным откатом и максимальным временем ожидания; затем постранично извлекайте возвращённый список страниц, пока его nextCursor не будет пустым. Запись страницы может содержать ссылку на содержимое, а не весь Markdown, поэтому получите упомянутый артефакт через документированный конечный пункт чтения хранения перед разбиением на фрагменты. Проверьте успех каждой страницы, статус, метаданные и содержимое, а не считайте завершённый родительский обход доказательством того, что каждая страница пригодна для использования.
Справочный ответ руководства Crawl для больших выводов использует поля, такие как markdownRef, и аутентифицированный GET /api/v1/crawl/storage/read?st={ref}. Сохраняйте этот этап извлечения в адаптере для вашей версии SDK; не предполагайте, что каждый ответ содержит полный текст. Избегайте обхода контента, доступного только по логину, или другого несанкционированного контента.
Шаг 2: Очистка и нормализация перед встраиванием
Сохраняйте пути заголовков, кодовые блоки, таблицы и ссылки на источники. Удаляйте только повторяющийся хром, который явно не является частью документа. Базовый вспомогательный метод нормализации намеренно консервативен:
Не удаляйте каждую ссылку или таблицу только для того, чтобы сократить количество токенов. Документация API часто хранит полезный ответ в таблице параметров или на связанной странице версии. Захватывайте конечный канонический URL, заголовок, язык и версию продукта в качестве метаданных вместе с нормализованным телом.
Шаг 3: Разделение на части с учетом заголовков
Первая версия может разделить Markdown по заголовкам, оставляя вместе кодовые блоки. Этот пример создает одну запись для каждого раздела заголовка; добавьте вторичный проход с учетом токенизатора, когда раздел превышает лимит ввода вашего поставщика встраивания.
defsplit_sections(markdown:str): heading_path, lines, fenced =[],[],Falsefor line in markdown.splitlines():if line.strip().startswith("```"): fenced =not fenced
if line.startswith("#")andnot fenced and lines: text ="\n".join(lines).strip()if text:yield" / ".join(heading_path), text
level =len(line)-len(line.lstrip("#")) heading_path = heading_path[:level -1]+[line[level:].strip()] lines =[line]else: lines.append(line) text ="\n".join(lines).strip()if text:yield" / ".join(heading_path), text
Это первоначальная структура, а не универсальный делитель. Она не гарантирует максимальное количество токенов и не объединяет маленькие разделы. Руководство по разделению текста LangChain предоставляет другую реализацию фреймворка для сравнения. Добавьте рекурсивное разделение для больших разделов и проверьте поведение на границах по кодовым блокам и таблицам. Отслеживайте размер токенов с токенизатором, связанным с вашей моделью встраивания, а не рассматривайте количество символов как точное количество токенов.
Для следующих разделов предполагайте, что адаптер результатов страницы сгенерировал одну проверенную запись с именем page, с полями url, title, markdown, crawled_at и content_hash. Материализуйте вывод делителя один раз: sections = list(split_sections(page.markdown)). Предыдущий шаг обхода сайта отправляет задачу; ваш адаптер должен опрашивать ее, читать упомянутые артефакты Markdown и формировать эту запись страницы перед встраиванием.
Шаг 4: Генерация встраиваний
Руководство по встраиваниям OpenAI документирует конечную точку встраиваний. Встраивайте каждый кусок, используя одну фиксированную модель, и сохраняйте имя модели с версией индекса, чтобы последующая смена модели не могла бесшумно смешать несовместимые векторные пространства.
from openai import OpenAI
embedder = OpenAI()texts =[chunk_text for _, chunk_text in sections]response = embedder.embeddings.create( model="text-embedding-3-small",input=texts,)vectors =[item.embedding for item in response.data]assertlen(vectors)==len(texts)
Пакетная обработка уменьшает накладные расходы на запросы, но размер пакетов нужно устанавливать с учетом ограничений поставщика и повторно отправлять временные ошибки с использованием обратной связи. Проверьте длину векторов перед записью:
expected_dimension =1536ifany(len(vector)!= expected_dimension for vector in vectors):raise ValueError("Размер встраивания не соответствует индексу Pinecone")
Шаг 5: Создание индекса Pinecone
Создайте плотный индекс в консоли Pinecone или с помощью его текущего API управления. Установите размер индекса в соответствии с размером выхода встраивания и выберите метрику схожести, требуемую вашей архитектурой извлечения. URL-адрес хоста необходим для операций в плоскости данных. Используйте индекс разработки в первую очередь, чтобы не допустить загрязнения производственных данных провальными экспериментами.
Шаг 6: Обновление фрагментов с стабильными идентификаторами
Текущие примеры Python Pinecone принимают плотные записи с id, values и необязательными metadata. Используйте пространство имен для разделения коллекции документации или арендатора. Стабильный префикс позволяет удалить все фрагменты для измененной страницы источника перед их заменой.
Upsert перезаписывает существующую запись с тем же идентификатором. Он не удаляет автоматически старые идентификаторы частей, которые исчезли после редактирования страницы. Сохраняйте предыдущий список идентификаторов страниц и удаляйте старые идентификаторы после проверки заменяющего набора. Документы Pinecone описывают пакетирование и пространства имен в своем гайде по upsert.
Шаг 7: Запрос индекса сайта
Встроите вопрос в ту же модель и запросите Pinecone. Верните метаданные, чтобы приложение могло показать ссылку на источник и заголовок, а не выдавать лишь ответ.
Рассматривайте top_k как настраиваемый параметр извлечения, а не как гарантию качества. Оцените с небольшой группой реальных вопросов и проверьте, что каждый возвращенный отрывок поддерживает ответ. Для сайтов с контролем доступа также применяйте разрешения арендатора и документа перед возвратом контекста к модели.
Шаг 8: Обработка обновлений и удалений
Храните хэш нормализованного содержимого страницы. Когда следующий принятый обход вернет тот же хэш, пропустите встроение. Когда хэш изменится, создайте новый список частей, запишите его, проверьте, что он может быть запрошен, а затем удалите предыдущие идентификаторы. Храните манифест вне Pinecone с каноническим URL, хэшем содержимого, временем обхода, версией модели и идентификаторами частей. Если обход источника завершился неудачно, сохраните последний известный хороший индекс и отметьте страницу для пересмотра; истечение времени не должно стать случайным удалением.
Общие ошибки и модель затрат
Ошибка dimension mismatch означает, что индекс и выходные данные встроения не совпадают. Плеск дубликатов обычно означает, что идентификаторы были случайными или включали временную метку поступления. Отсутствие цитат обычно означает, что source_url был потерян во время фрагментации. Запрос метаданных, который не возвращает записи, может указывать на несоответствие пространства имен, а не на проблему со встроением.
Оцените стоимость за каждую принятую страницу с отдельными условиями: использование URL обхода, трафик прокси при включении, встроения для нового или измененного текста, записи и хранение Pinecone, а также вызовы модели во время запроса. Одна страница может производить множество частей, поэтому объем страниц сам по себе не является надежной оценкой хранения. Посмотрите текущее ценообразование Nstdata Crawl и текущее руководство по выставлению счетов Pinecone при подготовке бюджета; ставки и лимиты плана могут изменяться.
Pinecone против других хранилищ векторов для этого рабочего процесса
Pinecone является управляемым выбором, когда вы хотите хранилище векторов и не хотите управлять процессом базы данных. Chroma удобен для локальных прототипов; Qdrant и Weaviate обеспечивают другие управляемые или саморазмещаемые развертывания; pgvector может подойти команде, которая уже использует PostgreSQL. Сравните потребности в фильтрах, операции, резервное копирование, регион и модель разрешений — не только задержку поиска по вектору. Этот учебник использует Pinecone, потому что ключевые слова нацелены на эту интеграцию, а не потому, что одна база данных лучше для каждой рабочей нагрузки.
Надежный поток от веб-сайта к базе данных векторов зависит от контрактов между этапами: Обход производит артефакт страницы, ваш код проверяет и фрагментирует его, модель встраивания производит векторы известного измерения, и Pinecone хранит каждый вектор под стабильным идентификатором с метаданными источника. Постройте манифест URL и обновите/удалите поведение перед приемом большого сайта. Эта небольшая часть учета предотвращает устаревшие отрывки и сломанные цитаты позже.
В: Как мне обойти веб-сайт в Pinecone?
Откройте и просканируйте разрешенные страницы, проверьте и разбейте их текст, создайте векторные представления, затем добавьте или обновите каждый вектор с помощью стабильного идентификатора и метаданных источника.
В: Хранит ли Pinecone полную веб-страницу?
Pinecone хранит векторные записи и связанные метаданные; ваше приложение решает, хранится ли разбитый текст в качестве метаданных или в отдельном хранилище контента.
В: Какой лучший размер чанка для Pinecone?
Не существует универсального лучшего размера; подгоняйте границы чанков и настройки извлечения под представительные вопросы и входные ограничения модели векторных представлений.
В: Как я могу обновить векторные представления веб-сайтов?
Сравните нормализованный хэш контента, заново создайте векторные представления измененных страниц, добавьте или обновите заменяющие чанки и удалите предыдущие идентификаторы чанков после проверки.
В: Могу ли я хранить несколько веб-сайтов в одном индексе?
Да, но используйте пространства имен или фильтры метаданных преднамеренно и обеспечьте разрешения арендаторов в вашем приложении перед возвратом извлеченного контента.
Понимание семи измерений качества данных RAG и того, как проверять проиндексированные страницы, сравнивать чистые и сырые данные, сохранять происхождение и диагностировать ошибки извлечения. Это разделяет ошибки извлечения, получения и генерации, чтобы команды могли отлаживать правильный этап.
Lena Zhou
Oct. 20th 2026
Сканируйте целые сайты одним API-запросом
Успешность 99,8% с рендерингом JavaScript
Получайте чистые данные для LLM в разных форматах
Преобразуйте любой сайт в Markdown, HTML, JSON, ссылки, PDF и другие форматы без управления инфраструктурой сканирования.