Зміст
Коротко
Команда ставить питання природною мовою, LLM генерує SQL, DuckDB виконує запит in-process — користувач бачить лише відповідь. Архітектура з трьох стадій (контекст, генерація, виконання) і read-only guardrails знімає вузьке місце «єдина людина, яка знає SQL».
Що сталося
Типова біль: маркетинг і операції чекають на dashboard або тікет, хоча дані вже є в CSV/Parquet з HubSpot, Stripe чи ERP. Вузьке місце — не база, а переклад бізнес-питання в запит.
DuckDB тут доречний: працює in-process, без окремого сервера, одразу читає CSV, Parquet і JSON як таблиці. Експорти, які команда вже кладе на диск, стають queryable без міграції.
Між питанням і DuckDB стоїть reasoning-модель. Їй потрібен контекст схеми: імена колонок, типи, кілька sample rows — усе це потрапляє в system prompt до генерації SQL.
UI — Streamlit (~30 рядків Python): поле вводу та таблиця результату. Той самий пайплайн можна повісити на Telegram webhook, щоб відповідати прямо в чаті.
Автор виділяє три явні стадії:
- Context loading — при старті читається файл, виводяться типи, збирається metadata block для кожного промпта.
- Query generation — питання + metadata → LLM → SQL-рядок. Без виконання: спочатку валідація — лише існуючі колонки, без write/delete, синтаксис коректний.
- Execution and formatting — DuckDB виконує перевірений запит, результат форматується в таблицю або текст (для Telegram — message-safe string).
Розділення стадій дозволяє тестувати генерацію та execution незалежно — урок з production-пайплайнів, де flat-архітектура ламалася при зростанні навантаження.
Чому це важливо
Natural language analytics знижує бар’єр для BI: нетехнічні користувачі отримують insights без SQL. Але надійність визначають не Streamlit і не вибір моделі, а prompt design, validation і metadata.
Ключові обмеження:
- Metadata injection працює до ~50 колонок; далі контекст тисне на token limit — потрібен відбір релевантних полів.
- System prompt має вимагати лише SQL, без markdown і коментарів — інакше ламається валідація. One-shot example в prompt суттєво знижує malformed output.
- Telegram round-trip — 3–8 секунд; для простих агрегацій dashboard швидший, для непередбачуваних питань — виправдано.
- Security: динамічний SQL потребує read-only connections, allowlisting і лімітів на розмір видачі — інакше ризик при exposure поза командою.
Дворівнева маршрутизація (швидка модель для простих агрегацій, reasoning — для складних join’ів) тримає median latency низькою.
На практиці
Якщо збираєте такий agent поверх flat files:
- Validation layer першим — не підключайте LLM output напряму до DuckDB; перевіряйте column refs за metadata до execution.
- Генеруйте metadata block у runtime з актуального файлу, не хардкодьте в prompt.
- Додайте toggle «показати SQL» — non-technical users зможуть аудитувати інтерпретацію питання.
- Зв’яжіть із n8n або іншим ETL: agent стає read-шаром над тим, що пайплайни вже пишуть на диск.
Обсяг коду скромний (~25 рядків UI, ~15 DuckDB, ~30 LLM+validation), але час йде на prompt engineering і guards — туди й вкладайтеся.
Підсумок
AI data analyst без SQL — практична реалізація NL→SQL поверх DuckDB з жорстким розділенням стадій і read-only безпекою. Має сенс читати оригінал, якщо хочете дати команді ad-hoc analytics без черги до єдиного аналітика.

