TL;DR
- Свежесть данных RAG — это политика обновления для исходных документов, векторных представлений и записей индекса, а не просто график работы веб-краулера.
- Сравнивайте нормализованный основной контент, а не сырой HTML, перед тем как заново разбить и встроить страницу.
- Дайте каждому фрагменту стабильный URL и версию, чтобы измененные и удаленные страницы могли чисто заменять старые векторы.
- Nstdata Crawl может извлекать публичные страницы в формате Markdown; ваше приложение отвечает за обнаружение изменений, векторные представления, хранение векторов и оценку ответов.
- Записывайте сбои сбора отдельно от подлинных удалений, чтобы один тайм-аут не смог стереть действительный источник знаний.
Почему базы знаний RAG становятся устаревшими
Для практического слоя сбора рассмотрите Nstdata Crawl совместно с рабочим процессом ниже.
Оригинальная статья RAG описывает генерацию с использованием внешней памяти для поиска. Генерация с увеличением извлечённых данных может ссылаться на устаревший материал, когда его индекс описывает более раннюю версию страницы. Целевая страница цен может измениться, пока старые фрагменты остаются в поиске; статья справочной службы может исчезнуть, в то время как её векторы продолжают отвечать на вопросы. Модель может вести себя последовательно с данными, которые ей были предоставлены, поэтому исправление должно находиться на стадии загрузки.
Цель свежести требует двух временных шкал. Возраст сбора — это время с момента, когда страница в последний раз была успешно проверена. Возраст индекса — это время с момента, когда соответствующие фрагменты были записаны в хранилище для поиска. Они могут расходиться, когда извлечение проходит успешно, но встраивание или индексация терпят неудачу. Отслеживайте оба. Для получения информации о преобразовании страниц в читаемый текст см. конверсию URL в Markdown и структурированное извлечение из веб-сайтов.
Как работает свежесть веб-данных в конвейере RAG
Конвейер состоит из поиска источников → извлечения страницы → основного контента в Markdown → нормализации → обнаружения изменений → разбиения → встраивания → обновления векторов → оценки поиска. Поиск источников может происходить из карты сайта, одобренного списка URL или ограниченного обхода сайта. На каждом этапе требуется свое состояние ошибки и политика повторной попытки.
Публичные URL источников -> Nstdata Crawl -> Markdown -> хеш контента | неизменный: сохранить индекс | измененный: разбить -> встроить -> обновить | удаленный: проверить -> удалить векторы хранилище векторов -> извлекатель -> ответ с цитатами
Nstdata Crawl охватывает извлечение и извлечение. Его текущая документация по краулингу показывает вывод в Markdown через его Python SDK. Он не создает векторные представления, не управляет векторной базой данных, не решает, изменилась ли страница, и не оценивает, актуален ли ответ. Эти стадии принадлежат вашему приложению или другим сервисам. Для отдельного рабочего процесса ИИ см. руководство по системе CrewAI.
Как обнаружить значительные изменения страницы
Хешируйте основной текст после стабильной нормализации. Игнорируйте случайные изменения пустых строк, но сохраняйте заголовки, ссылки, таблицы и значения, которые могут быть важны для пользователя. Не удаляйте цены, даты или метки версий как «шум». Широкий колонтитул сайта или баннер с cookies должны, по идее, быть удалены на этапе извлечения; изменяющаяся цена в теле должна создавать новый дайджест.
import hashlib import re def content_hash(markdown: str) -> str: normalized = re.sub(r"[ \t]+", " ", markdown.replace("\r\n", "\n")) normalized = re.sub(r"\n{3,}", "\n\n", normalized).strip() return hashlib.sha256(normalized.encode("utf-8")).hexdigest() assert content_hash("Цена: $12\n") != content_hash("Цена: $13\n") assert content_hash("A B\n\n\nC") == content_hash("A B\n\nC")
Хеш идентифицирует версию контента, а не семантическое суждение. Небольшое изменение может иметь большое значение; крупное изменение стандартного текста может не иметь значения. Просмотрите ложные срабатывания перед добавлением агрессивных нормализующих правил. Храните URL, дайджест, время успешной загрузки, версию извлекателя и версию индекса вместе. Для удалений требуется подтвержденный постоянный ответ или повторные проверки; временная сетевая ошибка должна сохранять последнюю действительную версию индекса, помечая её устаревшей.
Построить конвейер обновления веб-сайта в RAG
Начните с небольшого разрешенного списка URL публичной документации и четкого расписания повторного обхода. Вызовите SDK для каждого URL, рассчитайте дайджест и сравните его с вашей таблицей состояния. Если изменений нет, обновите только last_checked_at. Если изменилось, создайте фрагменты с устойчивыми идентификаторами, такими как sha256(url + chunk_index + content_version), рассчитайте вложения, а затем вставьте их в выбранное вами векторное хранилище. Удалите старую версию только после того, как новая версия станет доступной для поиска. Этот порядок избегает пустого окна извлечения.
Ниже приведен предел приобретения. Установите nstdata-ai-crawl и сначала установите NSTDATA_API_TOKEN. Вызов SDK следует текущему примеру Nstdata Python SDK; активный запрос все еще требует ваших собственных учетных данных.
import os from nstdata_ai_crawl import NstDataClient, ScrapeRequestDto, Format def read_markdown(url: str) -> str: token = os.environ["NSTDATA_API_TOKEN"] with NstDataClient(token) as client: result = client.submit_scrape_task_sync( ScrapeRequestDto( url=url, formats=[Format.MARKDOWN], timeout=60000, onlyMainContent=True, ) ) markdown = result.data.get_markdown() if not markdown or not markdown.strip(): raise ValueError(f"No readable content returned for {url}") return markdown
Ваше приложение затем выполняет операции с базой данных, используя методы и идентификаторы выбранного хранилища:
def refresh_one(url, state_store, vector_store, embedder): markdown = read_markdown(url) # Извлечение Nstdata; требуется токен API digest = content_hash(markdown) old = state_store.get(url) if old and old.digest == digest: state_store.mark_checked(url) return "unchanged" chunks = split_markdown(markdown) # Ваша политика деления records = [ {"id": f"{url}#{digest}#{i}", "url": url, "text": chunk, "vector": embedder.embed(chunk)} for i, chunk in enumerate(chunks) ] vector_store.upsert(records) # Сторонняя векторная база данных state_store.commit(url, digest, [r["id"] for r in records]) if old: vector_store.delete(old.vector_ids) return "updated"
split_markdown, state_store, vector_store и embedder являются интерфейсами приложения, а не функциями SDK Nstdata. Сделайте вставку и коммит состояния идемпотентными: повторный запуск неудачной задачи должен привести к одной актуальной версии. Следуйте семантике транзакций и удаления вашей векторной базы данных; например, см. документацию по вставке Pinecone. Проектная реализация также регистрирует частичные записи и безопасно повторяет попытки.
Где подходит Nstdata Crawl
Команды RAG нуждаются в надежном вводе веб-контента, прежде чем смогут обсудить качество вложений. Nstdata Crawl предоставляет извлечение страниц, извлечение данных и вывод в Markdown через API и SDK; ограниченный обход сайта может помочь с приобретением URL, если источник это позволяет. Markdown предоставляет нижестоящим делителям заголовки и читаемый текст, в то время как URL-источника остается доступным для цитирования. Сервис следует оценивать на фактических сайтах, которые вам разрешено собирать, так как структура страниц и поведение JavaScript варьируются.
Три практических проверки имеют значение. Качество вывода: убедитесь, что возвращенный текст содержит ожидаемый заголовок и не содержит страницы входа или согласия. Объем: ограничьте открытие и частоту получения правилами источника и вашим бюджетом. Стоимость: проверьте текущий продукт Crawl и цены на Crawl для имеющейся модели выставления счетов, включая отдельно выставляемое использование прокси, если это уместно. Nstdata предоставляет ввод; политика актуальности и записи в вектор остаются за вами.
Лучшие практики для поддержания свежести
Установите интервалы в зависимости от волатильности источника и делового воздействия, а не запускайте каждый URL по одному таймеру. Изменение продукта может требовать частой проверки; постоянные юридические термины могут нуждаться в меньшем количестве проверок. Используйте условное расписание по зафиксированной частоте изменений, но сохраняйте максимальный возраст, чтобы тихие источники все равно проверялись. Сохраняйте предыдущие версии для аудита и отката. Мониторьте успех извлечения, качество извлечения, уровень изменения хэша, сбои в внедрении, задержку индекса и возраст цитирования. Запускайте репрезентативные запросы после обновлений; индекс может быть технически актуальным, в то время как извлечение все еще возвращает нерелевантный фрагмент. Обрабатывайте персонально идентифицируемый или лицензированный материал в соответствии с разрешениями источников и правилами хранения. Публичная страница сама по себе не предоставляет неограниченного права на повторное использование.
Полезным результатом является отслеживаемый путь ответа: вопрос → извлеченный фрагмент → URL источника → версия контента → последняя успешная проверка. Это делает устаревший ответ отлаживаемым, а не загадочным.
ЧаВо
В: Как часто должны обновляться данные RAG?
Частота обновлений зависит от того, как быстро изменяется источник, и стоимости устаревшего ответа. Установите максимальный допустимый возраст для каждого источника, затем измеряйте фактические изменения и задержку индекса.
В: Как вы обнаруживаете изменения на веб-страницах?
Сравните хэш нормализованного основного контента с последней успешной версией. Отделите сбои извлечения от изменений контента.
В: Можно ли использовать Markdown для RAG?
Да. Markdown сохраняет полезную структуру для разбивки на фрагменты, но требует валидации, внедрения, индексации и тестов извлечения.
В: Как вы обновляете векторную базу данных, когда страница меняется?
Запишите новые версии фрагментов, убедитесь, что они являются поисковыми, а затем удалите предыдущие идентификаторы фрагментов. Используйте документированные операции upsert и delete выбранной базы данных.





