Blog

Retrieval-augmented generation for source-backed article writing

Инженерные заметки Naly: черновое создание статей RAG с приоритетом источников для постоянной проверяемой публикации

В этой заметке описана production-архитектура, где извлечение — полноценная управляющая плоскость, а не подсказка на этапе prompt. Задания статей Naly собирают доказательства из web и arXiv, сохраняют нормализованные факты источников и заставляют вывод модели пройти через структурированный, проверяемый контракт перед рендерингом HTML, чтобы статьи оставались опирающимися на источники

June 27, 202610 sources

КраткоRAG (retrieval-augmented generation) превращает конвейер статей Naly в систему публикации на основе источников вместо композиции по памяти модели. Каждый запрос черновика сначала собирает доказательства из web и arXiv, нормализует и сохраняет URL источников, а затем просит модель создать черновик с форматом answer-first и итоговую статью в HTML. Это переносит риск с вопроса «может ли модель галлюцинировать?» на вопрос «полон ли и прослеживаем ли слой извлечения», давая редакторам стабильные артефакты, воспроизводимые задания и обоснованные публичные утверждения.

Аннотация

RAG в Naly должен быть выстроен вокруг сохранения источников и детерминированных контрактов. 27 июня 2026 практическая надежность зависит меньше от более крупной модели и больше от того, насколько артефакты извлечения можно запрашивать, версионировать и валидировать до публикации. Эта заметка предлагает двуслойную архитектуру: слой доказательств для извлечения/хранения и слой генерации для черновика, затем объясняет, как эта архитектура напрямую повышает редакционную доверенность и обработку инцидентов.

Место в Naly

Naly реализует это как production-подсистему контента внутри стека Next.js 16.0.7 App Router (next + react), где публикация статьи является частью runtime-логики, а не отдельным офлайн-шагом подготовки. Путь article-job — это место, где должны применяться все ограничения: статья не считается «написанной» до тех пор, пока существуют записи источников, не проходит валидация структуры сводки и HTML не материализован.

Согласование стека намеренно выстроено так:

  • next@16.0.7 + React Server Components размещают рендеринг, запущенный job, в серверном контексте, соблюдая серверные контракты вывода для статей.
  • drizzle-orm@0.44.7 + @neondatabase/serverless@1.0.2 определяются типизированные персистентные таблицы jobs и источников, чтобы каждое утверждение можно было проследить.
  • ai@6.0.0-beta.105 обеспечивает генерацию с управлением схемой вывода.
  • marked@17.0.1 конвертирует сгенерированные Markdown-резюме в рендеринг HTML для публикации.
  • @vercel/blob@2.0.0 хранит сгенерированные активы как устойчивые URL для повторного использования.
  • Инструменты Anthropic можно добавить как альтернативного провайдера модели внутри того же контракта, но не как обходной канал от структурных ограничений.

Это заменяет модель «сначала сгенерировать, затем вычитать» на замкнутый цикл с опорой на источники: извлечение, валидация, генерация, рендеринг и публикация должны пройти до того, как статья станет видимой.

Технический механизм

Надежный дизайн Naly состоит из пяти ограниченных этапов:

  1. План по источникам и оркестрация запросов
  • Определить спецификацию задания с темой, временным окном и политикой по источникам.
  • Запустить и веб-поиск, и поиск по arXiv для первичных источников.
  • Дедупликация по каноническому URL и нормализация protocol, host и строки запроса.
  1. Слой персистентности источников
  • Сохранять метаданные по каждому URL (urlканонизированный URL, статус выборки, время выборки, заголовок, выдержка, тип источника).
  • Хранить фрагменты, ориентированные на модель, отдельно от сырых полезных нагрузок, чтобы повторные запуски были детерминированными даже при изменении исходных страниц.
  • Добавлять контрольные суммы для каждого источника, чтобы обнаруживать дрейф.
  1. Формирование контекста и ограничения
  • Построить контекст извлечения, отсортированный по релевантности и актуальности.
  • Требовать в контракте prompt явные source IDs.
  • Принудительно задавать структуру ответа с подходом answer-first (intro claim, evidence bullets, risk caveats, uncertainty), плюс упорядоченные ссылки на источники.
  1. Структурная генерация со строгой схемой
  • Использовать структурированный вывод, чтобы некорректные ответы или нарушения схемы завершались быстро и повторно запускались с ужесточенным контекстом.
  • Сохранять генерацию в серверном контексте и отклонять черновики, которые заявляют неподтвержденные факты без привязанных source IDs.
  1. Рендеринг, публикация и проверка
  • Конвертировать валидный markdown в HTML и сохранять и markdown, и HTML.
  • Кешировать финальный результат только после успешной валидации.
  • Выводить метрики аналитики и аудита: количество источников, отклонённые утверждения, число повторов и задержка генерации.

Ключевое архитектурное решение — это разделение обязанностей: качество извлечения и качество генерации — это разные области отказа с разными метриками. React Server Components Next.js подходят под это разделение, потому что рендеринг может оставаться детерминированным, пока извлечение и генерация выполняются как контролируемые асинхронные задачи.

Что говорят публикации

Недавние обзоры RAG подтверждают эту архитектурную модель. Обзор 2024 года по архитектуре RAG описывает, как системы с дополнительным извлечением снижают дрейф фактов через условие генерации на внешних доказательствах, но отмечает компромиссы в сложности пайплайна и модульной координации [Gupta et al., 2024]. Дополнительный обзор 2025 года добавляет, что устойчивость теперь зависит от адаптивного извлечения, контроля декодирования и сквозной оценки, а не только от качества генерации [Sharma, 2025].

Для контроля качества production в обзоре 2025 года с фокусом на оценку явно разделяются внутренние метрики retriever/generator и внешние системные метрики; это разложение особенно полезно для конвейеров статей, потому что «плохая статья» может означать неправильный выбор источника даже при высоком качестве языка [Gan et al., 2025]. Работа по groundedness тоже сместилась к уровням детекции, которые классифицируют поддержку утверждений на основе извлеченного контекста и проверок в стиле NLI, что подтверждает практическую ценность постгенерационной валидации [Gerner et al., 2025].

Коротко говоря, статьи сходятся к одному тезису: RAG — это не просто способ подмешать контекст, это инженерный контракт между извлечением и генерацией. Поэтому Naly должен оптимизировать этот контракт, а не только prompt.

Компромиссы дизайна

  • Актуальность против детерминизма: более строгие TTL снижают устаревание, но повышают стоимость повторного выборки. Сохранение снимков позволяет удерживать детерминированный рендеринг и одновременно повторно проверять окна актуальности.
  • Полнота против точности в извлечении: более широкое извлечение повышает покрытие, но добавляет шум; валидация релевантности на втором этапе защищает качество утверждений.
  • Строгость схемы против естественности текста: строгие схемы вывода повышают надежность для машин, но могут уменьшать творческую свободу формулировки. Шаблон answer-first сохраняет читаемость и удерживает ограждающие ограничения.
  • Скорость статического рендеринга против аудируемости: предварительно собранный HTML улучшает скорость доставки и снижает повторные вычисления, но только если используемые артефакты источников являются неизменяемыми ссылками.
  • Сложность против эксплуатационных затрат: каждая добавленная проверка (контроль источников, проверка схемы, сохранение артефактов) добавляет задержку. Важно придерживаться рекомендаций production по кешированию, границам маршрутов и верификации на этапе сборки, чтобы сделать это масштабируемым.

Режимы отказа

  • Дрейф источников: URL могут возвращать 404/тихо изменяться после создания задания. Митигирование: канонический ключ + хеш снимка + запасная цепочка источников.
  • Чрезмерное извлечение: высокая полнота при низкой точности вызывает правдоподобный, но неподтвержденный синтез. Митигирование: требовать ограничения evidence-first и блокировать утверждения без совпадений по источникам.
  • Сбой форматирования модели: несоответствие схеме или усеченный JSON из генерации. Митигирование: строгая валидация схемы и повторный запуск с сокращенным контекстом.
  • Гонки двойной публикации: конкурентные воркеры могут публиковать частичные артефакты. Митигирование: ключи идемпотентности заданий, переходы состояния на уровне строк (pending -> drafting -> validated -> published).
  • Регрессии рендеринга: некорректный markdown или небезопасные трансформации HTML. Митигирование: детерминированный marked путь конверсии и тесты HTML-вывода, привязанные к эталонным манифестам.
  • Оптические иллюзии кэша: устаревшие динамические данные в серверном выводе могут рассинхронизировать опубликованный текст и индекс источников. Митигирование: согласование стратегии рендеринга маршрутов с явной политикой свежести runtime и исключение имплицитных кэшей, где требуется актуальность доказательств.

Заметки по реализации

Для практического внедрения рассматривайте это как контракт публикации:

  • Определите таблицы источников в Drizzle с явными ограничениями: уникальность URL по каноническому host/path, перечисления статуса выборки и колонки контрольных сумм.
  • Используйте путь драйвера, совместимый с Neon, последовательно с учетом поведения serverless; в документации Drizzle описаны как runtime-специфичные, так и neon-* варианты драйвера.
  • В генерации обеспечивайте структурированные контракты вывода и останавливайте процесс при некорректных объектах до рендеринга.
  • Используйте рекомендации Next.js для production по границам сервера, страницам ошибок, кэшу и SEO-метаданным маршрутов статей, чтобы публикация оставалась наблюдаемой и быстрой.
  • Сохраняйте сгенерированные blobs (например, обложки, вложения, экспорты) через Vercel Blob с явной политикой доступа и детерминированным именованием во избежание коллизий.
  • Формируйте эксплуатационные проверки перед публикацией: минимальное число источников, минимальная разнообразность источников, свежесть доказательств и минимальный коэффициент завершения для сопоставленных утверждений.

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

Ссылки

Sources