Blog

Retrieval-augmented generation for source-backed article writing

Інженерні нотатки Naly: чернетка статті RAG на основі першоджерел для стійкої, аудитно придатної публікації

У цій нотатці визначено продакшн-архітектуру, де пошук є керуючою площиною першого класу, а не підказкою під час запиту. Завдання статей Naly збирають веб- і arXiv-докази, зберігають нормалізовані факти з джерел і змушують вивід моделі проходити через структурований, аудитно перевірюваний контракт перед рендерингом HTML, щоб статті залишалися заснованими на re

June 27, 202610 sources

TL;DRRAG з доповненням витягуванням перетворює конвеєр статей Naly на систему публікації, засновану на джерелах, а не на складанні тексту з пам’яті моделі. Кожен запит чернетки спочатку збирає веб- та arXiv-докази, нормалізує й зберігає URL-адреси джерел, а потім просить модель згенерувати чернетку з акцентом на відповідь і фінальну HTML-статтю. Це зміщує ризик із питання «чи може модель вигадати факт?» до питання «чи повний і простежуваний шар витягування», даючи редакторам стабільні артефакти, відтворювані завдання та захищені публічні твердження.

Анотація

RAG у Naly має бути спроєктований навколо збереження джерел і детерміністичних контрактівСтаном на 27 червня 2026 року практична надійність залежить менше від більшої моделі й більше від того, чи є артефакти витягування запитуваними, версіонованими та перевіреними до публікації. Ця нотатка пропонує подвійну архітектуру: план витягування для пошуку/зберігання та план генерації для чернетки, а потім доводить, як ця архітектура безпосередньо підвищує редакційну довіру й керування інцидентами.

Місце в Naly

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

Агрегація стеку зроблена свідомо:

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

Це замінює модель «згенерувати, а потім відредагувати» на замкнутий цикл фактичного письма: витягування, валідація, генерація, рендеринг і публікація мають пройти всі етапи, перш ніж стаття стане видимою.

Технічний механізм

Стійка архітектура Naly має п’ять обмежених етапів:

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

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

Що каже література

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

Щодо контролю якості у production, огляд 2025 року, орієнтований на оцінку, явно розділяє оцінювання на внутрішні метрики ретривера/генератора та зовнішні системні метрики; така декомпозиція особливо корисна для конвеєрів статей, оскільки «погана стаття» може означати неправильний вибір джерела навіть за високої якості мови [Gan et al., 2025]. Напрямок, орієнтований на groundedness, також перейшов до шарів детекції, які класифікують підтримку тверджень за допомогою витягнутого контексту й NLI-перевірок, підсилюючи практичну цінність постгенераційної валідації [Gerner et al., 2025].

У короткому підсумку, усі ці праці сходяться на одній тезі: RAG — це не просто спосіб додати контекст, це інженерний контракт між витягуванням і генерацією. Тому Naly має оптимізувати цей контракт, а не лише prompt.

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

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

Режими збоїв

  • Дрейф джерел: URL-адреси починають повертати 404/м’які зміни після створення job. Пом’якшення: канонічний ключ + хеш знімку + резервний ланцюжок джерел.
  • Перевантаження витягуванням: висока recall за низької precision призводить до правдоподібного, але непідтвердженого синтезу. Пом’якшення: вимагайте обмежень evidence-first і блокуйте твердження без збігів за джерелами.
  • Невдача форматування моделі: невідповідність схеми або обрізаний JSON під час генерації. Пом’якшення: сувора валідація схеми та повторний запуск із зменшеним контекстом.
  • Гонки подвійної публікації: паралельні воркери можуть оприлюднити часткові артефакти. Пом’якшення: ключі ідемпотентності job, переходи стану на рівні рядків (pending -> drafting -> validated -> published).
  • Регіресії рендерингу: некоректний markdown або небезпечні перетворення HTML. Пом’якшення: детермінований marked шлях конвертації та тести HTML-виводу, прив’язані до зразкових маніфестів.
  • Ілюзії кешу: застарілі динамічні дані у серверному виводі можуть розсинхронізувати опублікований текст і індекс джерел. Пом’якшення: узгодити стратегію рендерингу маршруту з явною політикою свіжості runtime і не використовувати неявні кеші там, де потрібна свіжість доказів.

Нотатки з реалізації

Для практичного розгортання сприймайте це як контракт публікації:

  • Визначайте таблиці джерел у Drizzle з явними обмеженнями: унікальність URL за канонічним host/path, статуси fetch-енумів і стовпці контрольних сум.
  • Послідовно використовуйте шлях драйвера, сумісний із Neon, відповідно до поведінки виконання serverless; у документації Drizzle описано як runtime-специфічні, так і neon-* варіанти драйвера.
  • Під час генерації забезпечте виконання структурованих контрактів виводу й відмову на некоректних об’єктах до рендерингу.
  • Використовуйте рекомендації Next.js для серверних меж, сторінок помилок, кешування та SEO-метаданих для маршрутів статей, щоб публікація залишалася спостережуваною й швидкою.
  • Зберігайте згенеровані бінарні об’єкти (наприклад, обкладинки, вкладення, експорти) через Vercel Blob із чіткою політикою доступу та детермінованим іменуванням, щоб уникати колізій.
  • Випускайте операційні перевірки до публікації: мінімальна кількість джерел, мінімальна різноманітність джерел, свіжість доказів і мінімальний коефіцієнт завершення для зіставлених тверджень.

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

Посилання

Sources